> Are you possibly using some 
> kind of HTTP auth?

No auth; this is a very simple case that doesn't have any auth. I noticed it in 
a case where I was POSTing to an endpoint I hadn't implemented yet, thus 
producing the 404.

> Why should it? The whole purpose of Expect: 100-continue is to avoid having 
> to 
> send the request body in a case like this when the server can tell the client 
> at once that the request (and body) isn't wanted.

This seemed to be covered in some depth in

   http://permalink.gmane.org/gmane.comp.web.curl.library/5947

as related to auth. Moreover, I don't see anything in rfc2616 that would 
indicate the behavior for 404 should be any different than that for 401. It 
specs the behavior for "a final status code".

The line I keyed off of in that email with respect to rational was

 "Before receiving the 401, client MAY have sent some of the request body"

my interpretation being the reason you have to transmit the body anyway is 
because the server has no way to ascertain that the client hasn't already 
started sending the body. In other words, if it's not required, the server has 
no idea how much data might be coming and so can't skip to the next request; it 
would be forced to ditch the connection.

I agree that this seems at first blush to mitigate the value of using 
100-continue, but both the client and the server can still improve on this 
"send it anyway" behavior:

- the server can close the connection (and could even be smart, looking at the 
content length to decide if getting the data is more expensive than recreating 
a connection).
- the client can use chunked encoding (this need-the-body only happens when 
content length has been passed by the client in the header)

http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html says, in 8.2.3 under 
"Requirements for HTTP/1.1 origin servers":

      - Upon receiving a request which includes an Expect request-header
        field with the "100-continue" expectation, an origin server MUST
        either respond with 100 (Continue) status and continue to read
        from the input stream, or respond with a final status code. The
        origin server MUST NOT wait for the request body before sending
        the 100 (Continue) response. If it responds with a final status
        code, it MAY close the transport connection or it MAY continue
        to read and discard the rest of the request.  It MUST NOT
        perform the requested method if it returns a final status code.

Earlier today I think I read somewhere where someone was suggesting a wording 
change since the 'it MAY ... or it MAY' might be construed to not be the 
complete set of choices. My spec-ease isn't so expert that I know if that's the 
case. Unfortunately, now I can't find the reference.

> Can you wireshark the connection or use CURLOPT_DEBUGFUNCTION to figure out 
> exactly what is sent and isn't sent in both the requests to figure out what's 
> wrong in the second one?

Yeah. I've seen the bytes on the wire. It definitely looks like libcurl is not 
sending the body, which I think we agree is the case? There's some question of 
why this is screwing up nginx. It doesn't give an exact error so I'm 
extrapolating a bit. On the next request, nginx says it saw a 400 bad request, 
with a request line of "  */*". I haven't exactly calculated the offsets, but 
it looks like it's skipping Content-Length bytes from the previous request 
(which libcurl never sent) and then trying to start a new request. It's ending 
up in the middle of the headers of the next request, in the middle of a header 
like "Accept: */*".
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to