[ 
https://issues.apache.org/jira/browse/HTTPCORE-768?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17872379#comment-17872379
 ] 

Joao Silva commented on HTTPCORE-768:
-------------------------------------

> You are confusing closure of an entity content stream and closure of the 
> underlying connection

I am calling close on the {{{}CloseableHttpResponse{}}}, and not on the entity 
content stream. Does that assertion hold regardless?

> If you do not intent to re-use the underling connection, you need to close it 
>instead of (or before) closing the entity content stream.

I do not intent do re-use the underlying connection — how would one close the 
underlying connection using the HttpClient 5 API?

> HttpClient 4 and 5 behave _exactly_ the same.

On a cursory analysis it would appear that they do not work the same. Perhaps 
some defaults have changed?

In HttpClient 4, the {{CloseableHttpResponse}} implementation is 
{{{}HttpResponseProxy{}}}, which calls the {{ConnectionHolder.close()}} method. 
This method is defined as:

 
{code:java}
@Override
public void close() throws IOException {
  releaseConnection(false);
}{code}
The {{false}} parameter in the {{releaseConnection(false)}} call defines that 
the connection should not be reused, hence the different behavior we are 
observing: the socket is immediately closed, thus avoiding the subsequent hang.

In HttpClient 5 there appears to be no way to close the HTTP response in such a 
way (as in, not meant to be reused).

 

> which is basically a severe protocol violation, albeit quite common.

Thanks for this clarification. The code is meant to use HttpClient as a proxy 
server, which has tests to exercise various scenarios, possibly including 
protocol deviations (as in, what happens when a upstream server stops 
responding during a chunked response).

> Closing chunked responses hangs
> -------------------------------
>
>                 Key: HTTPCORE-768
>                 URL: https://issues.apache.org/jira/browse/HTTPCORE-768
>             Project: HttpComponents HttpCore
>          Issue Type: Bug
>          Components: HttpCore
>    Affects Versions: 5.0.4, 5.1.4, 5.2.3, 5.3-beta1
>            Reporter: Joao Silva
>            Priority: Minor
>
> While migrating a proxy implementation from httpclient 4 to httpclient 5 we 
> ran into some interesting issues regarding chunked responses.
> There is a specific test that deals with the proxy behavior when the client 
> closes the connection halfway through the response is being served.
> Using chunked responses in httpclient 4, if we close the 
> {{{}CloseableHttpResponse{}}}, the connection closes without issue.
> However, in httpclient 5 the {{CloseableHttpResponse.close()}} hangs.
> Debugging the issue, we see that {{ChunkedInputStream.close()}} hangs when 
> called, because it tries to read from the socket, and the server is not 
> actively sending any data:
> {{{{"main@1" tid=0x1 nid=NA runnable}}}}
> {{{{  java.lang.Thread.State: RUNNABLE}}}}
> {{{{      at sun.nio.ch.Net.poll(Net.java:-1)}}}}
> {{{{      at sun.nio.ch.NioSocketImpl.park(NioSocketImpl.java:191)}}}}
> {{{{      at sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:280)}}}}
> {{{{      at sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:304)}}}}
> {{{{      at sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:346)}}}}
> {{{{      at sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:796)}}}}
> {{{{      at java.net.Socket$SocketInputStream.read(Socket.java:1109)}}}}
> {{{{      at 
> org.apache.hc.client5.http.impl.io.LoggingInputStream.read(LoggingInputStream.java:81)}}}}
> {{{{      at 
> org.apache.hc.core5.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:149)}}}}
> {{{{      at 
> org.apache.hc.core5.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280)}}}}
> {{{{      at 
> org.apache.hc.core5.http.impl.io.ChunkedInputStream.getChunkSize(ChunkedInputStream.java:248)}}}}
> {{{{      at 
> org.apache.hc.core5.http.impl.io.ChunkedInputStream.nextChunk(ChunkedInputStream.java:222)}}}}
> {{{{      at 
> org.apache.hc.core5.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:147)}}}}
> {{{{      at 
> org.apache.hc.core5.http.impl.io.ChunkedInputStream.close(ChunkedInputStream.java:314)}}}}
> {{{{      at org.apache.hc.core5.io.Closer.close(Closer.java:48)}}}}
> {{{{      at 
> org.apache.hc.core5.http.impl.io.IncomingHttpEntity.close(IncomingHttpEntity.java:111)}}}}
> {{{{      at 
> org.apache.hc.core5.http.io.entity.HttpEntityWrapper.close(HttpEntityWrapper.java:120)}}}}
> {{{{      at 
> org.apache.hc.client5.http.impl.classic.ResponseEntityProxy.close(ResponseEntityProxy.java:180)}}}}
> {{{{      at org.apache.hc.core5.io.Closer.close(Closer.java:48)}}}}
> {{{{      at 
> org.apache.hc.core5.http.message.BasicClassicHttpResponse.close(BasicClassicHttpResponse.java:93)}}}}
> {{{{      at 
> org.apache.hc.client5.http.impl.classic.CloseableHttpResponse.close(CloseableHttpResponse.java:205)}}}}
> {{{{      at 
> org.mitre.dsmiley.httpproxy.ChunkedTransferTest.testChunkedTransferClosing(ChunkedTransferTest.java:233)}}}}
>  
> Comparing to httpclient 4, we see that {{{{ChunkedInputStream.close()}}}} 
> does not hang because when it tries to read from the socket, it is already 
> closed, hence it fails. The resulting SocketException is caught in 
> ResponseEntityProxy and discarded.
> Tested in versions 5.4-beta1, 5.3.1, 5.2.3, 5.1.4 and 5.0.4, and they all 
> hang in the same way.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@hc.apache.org
For additional commands, e-mail: dev-h...@hc.apache.org

Reply via email to