Hi Stewart, My reading of RFC2616 on this question suggests that the server isn't wrong sending a Content-Length: 0 header with the initial 100-Continue response, regardless of whether or not, the final response will contain a chunked response body.
The 100- Continue is a normal response, structured in the same way as other responses, ie. it can include other header fields. In 14.18, the rfc mentions that the Date header is optional in 100-Continue responses. So, while it's not explicit, this suggests that other headers like Content-Length are also allowable. In 14.13 , it also mentions that a Content-Length value of zero, is valid. Like I said that is my reading of the spec at least. Regards, Michael. Stewart Gebbie wrote:
Hi, I would like to report a possible bug in the com.sun.httpserver.HttpServer implementation. In short this relates to the handling of "Expect: 100-continue" in the case where the server code intends to reply using "Transfer-encoding: chunked". ex.sendResponseHeaders(HttpURLConnection.HTTP_OK, 0); The problem arises because the response by the server (as implemented in sun/net/httpserver/ServerImpl.java) results in: HTTP/1.1 100 Continue Content-Length: 0 rather than just: HTTP/1.1 100 Continue This becomes a issue when interacting with cURL (curl-7.19.0 http://curl.haxx.se/) as the client, since cURL first sees the content length of 0, and then subsequently sees the server requesting chucked transfer encoding. cURL's "curl_easy_perform" function then fails with the error message (see conversation A below): Code 18: "transfer closed with outstanding read data remaining" the libcurl-errors man page explains this error as follows: "CURLE_PARTIAL_FILE (18) A file transfer was shorter or larger than expected. This hap‐ pens when the server first reports an expected transfer size, and then delivers data that doesn't match the previously given size." If I instead change the server to use a fixed length response (see conversation B below): ex.sendResponseHeaders(HttpURLConnection.HTTP_OK, DEFAULT_RESPONSE.length()); // length should be 0 for chucked transfer cURL is happy enough to continue (even though in this case it receives two "Content-Length" headers, the first with a 0 length and the second with the actual data length). To more clearly see what is happening I have included two abbreviated HTTP conversations below. I realise that the other alternative is that cURL ignore the Content-Length in the case of receiving a "Transfer-encoding" header. This seems to be implied by the HTTP RFC: http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 "3. If a Content-Length header field (section 14.13) is present, its decimal value in OCTETs represents both the entity-length and the transfer-length. The Content-Length header field MUST NOT be sent if these two lengths are different (i.e., if a Transfer-Encoding header field is present). If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored." I simply do not know the requirements of the HTTP protocol well enough to be sure of what the right resolution. However, to me, it still seems still seems reasonable that, in either case, the "Content-Length" header should not be included after the "100 Continue" response. Please could somebody look into this issue. Thanks. Regards, Stewart.