HttpServer - issue in handling of "Expect: 100-continue"

Stewart Gebbie sgebbie at gethos.net
Fri Mar 13 04:29:51 PDT 2009


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.

-- 
Stewart Gebbie <sgebbie at gethos.net>
(C) +27 84 738 2899


A: cURL <--> HttpServer Conversion: Fails
=========================================
(this conversion fails on the client with cURL error code 18)

client: POST /agent/call HTTP/1.1
client: Host: localhost:8081
client: Accept: */*
client: Content-Type: text/xml
client: Content-Length: 1526
client: Expect: 100-continue
client: 
server: HTTP/1.1 100 Continue
server: Content-Length: 0
server: 
client: ... CLIENT DATA ...
server: HTTP/1.1 200 OK
server: Transfer-encoding: chunked
server: 
server: ... SERVER DATA ...
server: 
server: 0


B: cURL <--> HttpServer Conversion: Succeeds
============================================
(this conversion succeeds)

client: POST /agent/call HTTP/1.1
client: Host: localhost:8081
client: Accept: */*
client: Content-Type: text/xml
client: Content-Length: 1252
client: Expect: 100-continue
client: 
server: HTTP/1.1 100 Continue
server: Content-Length: 0
server: 
client: ... CLIENT DATA ...
server: HTTP/1.1 200 OK
server: Content-length: 45
server: 
server: ... SERVER DATA ...



More information about the net-dev mailing list