[
https://issues.apache.org/jira/browse/HTTPCLIENT-1684?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14733977#comment-14733977
]
Piotr Kołaczkowski edited comment on HTTPCLIENT-1684 at 9/7/15 6:45 PM:
------------------------------------------------------------------------
You're right this section doesn't have anything specific to do with
expect-continue handshake. It is a general requirement and the expect-continue
handshake does not cancel it. You *must send the entity* or disconnect,
regardless of the server response.
The SHOULD requirement indeed need not to be complied to by the client, which
means, the client SHOULD not proceed with sending the body, but it *is allowed*
to do so. It is perfectly valid to do:
{noformat}
>> GET /.... HTTP/1.1
>> Expect: 100-continue
>> Transfer-encoding: chunked
<< HTTP/1.1 404 Not found
>> send chunk of data
>> send chunk of data
>> send last chunk (0 length)
>> GET /.... HTTP/1.1 // the server will handle this properly
...
{noformat}
As well as it is also valid:
{noformat}
>> GET /.... HTTP/1.1
>> Expect: 100-continue
>> Transfer-encoding: chunked
>> send chunk of data // the client *is allowed* to send the entity despite
>> not getting 100 Continue
>> send chunk of data
<< HTTP/1.1 100 Continue
>> send chunk of data
>> send last chunk (0 length)
<< HTTP/1.1 200 OK
>> GET /.... HTTP/1.1 // the server will handle this properly
...
{noformat}
However this is *wrong* and violates RFC, and this is unfortunately what
HttpClient is doing:
{noformat}
>> GET /.... HTTP/1.1
>> Expect: 100-continue
>> Transfer-encoding: chunked
<< HTTP/1.1 404 Not found
// no entity sent, connection still open
// you must close the connection here or send the entity
>> GET /.... HTTP/1.1 // 2nd request: will be interpreted as chunk of
>> data, discarded by the server and obviously fail
{noformat}
{quote}
HttpClient does not support this recommendation (defined by SHOULD requirement)
due to limitations of the Java classic (blocking) i/o,{quote}
If it does so, then it should always send the full entity, regardless of the
initial status it got from the server in the 100-continue handshake. The
100-continue handshake is just an optimization allowing the client to ask
server for validation of the headers before the client continues with the
entity, and in case of an error, allowing the client to *optionally* close the
connection. But if the client decides to not close the connection, it must send
a proper entity, which will be discarded.
was (Author: pkolaczk):
You're right this section doesn't have anything specific to do with
expect-continue handshake. It is a general requirement and the expect-continue
handshake does not cancel it. You *must send the entity* or disconnect,
regardless of the server response.
The SHOULD requirement indeed need not to be complied to by the client, which
means, the client SHOULD not proceed with sending the body, but it *is allowed*
to do so. It is perfectly valid to do:
{noformat}
>> GET /.... HTTP/1.1
>> Expect: 100-continue
>> Transfer-encoding: chunked
<< HTTP/1.1 404 Not found
>> send chunk of data
>> send chunk of data
>> send last chunk (0 length)
>> GET /.... HTTP/1.1 // the server will handle this properly
...
{noformat}
As well as it is also valid:
{noformat}
>> GET /.... HTTP/1.1
>> Expect: 100-continue
>> Transfer-encoding: chunked
>> send chunk of data // the client *is allowed* to send the entity despite
>> not getting 100 Continue
>> send chunk of data
<< HTTP/1.1 100 Continue
>> send chunk of data
>> send last chunk (0 length)
<< HTTP/1.1 200 OK
>> GET /.... HTTP/1.1 // the server will handle this properly
...
{noformat}
However this is *wrong* and violates RFC, and this is unfortunately what
HttpClient is doing:
{noformat}
>> GET /.... HTTP/1.1
>> Expect: 100-continue
>> Transfer-encoding: chunked
<< HTTP/1.1 404 Not found
// no entity sent, connection still open
// you must close the connection here or send the entity
>> GET /.... HTTP/1.1 // 2nd request: will be interpreted as chunk of
>> data, discarded by the server and obviously fail
{noformat}
> 100-Continue support broken
> ---------------------------
>
> Key: HTTPCLIENT-1684
> URL: https://issues.apache.org/jira/browse/HTTPCLIENT-1684
> Project: HttpComponents HttpClient
> Issue Type: Bug
> Components: HttpClient
> Affects Versions: 4.5
> Environment: Linux Mint 17.2, Oracle Java 8 u60
> Reporter: Piotr Kołaczkowski
>
> Handling of Expect: 100-Continue is partially broken.
> After getting the Expect header, the server is allowed to:
> 1. respond with an HTTP 100 Continue status
> 2. respond with HTTP 417 Expectation Failed status
> 3. respond with the final HTTP answer, typically an error.
> Handling of situation 1. seems to work ok. I haven't checked the scenario 2.
> But scenario 3. is broken, at least when using chunked transfer encoding.
> {quote}
> 8.2.2 Monitoring Connections for Error Status Messages
> An HTTP/1.1 (or later) client sending a message-body SHOULD monitor the
> network connection for an error status while it is transmitting the request.
> If the client sees an error status, it SHOULD immediately cease transmitting
> the body. If the body is being sent using a "chunked" encoding (section 3.6),
> a zero length chunk and empty trailer MAY be used to prematurely mark the end
> of the message. If the body was preceded by a Content-Length header, the
> client MUST close the connection.
> {quote}
> The problem is that HttpClient does *not* send the last chunk in this case,
> nor terminates the connection, nor continues sending the body which are the
> only options allowed by the specs. Instead it just happily returns the
> response to the user and doesn't send anything to the server, keeping the
> connection open. This breaks subsequent requests on this connection, since a
> standard-compliant server would expect the request body and would interpret
> any subsequent HTTP status line as an entity chunk instead of a new request.
> Debugging this is unfortunately quite hard, since many of the servers got
> this wrong either and they just close the connection in this case (which is
> not entirely correct because the HTTP specs requires the *client* to close
> the connection not the server).
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]