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

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

Hi [~olegk] 

Mainly two things: it used to work with httpclient 4, and it would to me seem 
surprising API behavior.

I'm trying to close a connection to the server, and I would expect the 
connection to be closed:
{code:java}
InputStream content = 
HttpClientBuilder.create().build().execute(url).getEntity().getContent();
readChunk(content);
content.close(); {code}
Instead, while closing, {{ChunkedInputStream}} tries to read the next chunk 
that may or may not be ever be available, and hangs indefinitely, or until a 
timeout (if one is configured) occurs:
{code:java}
// Optimistically check if the content has been fully read
// when there's no data remaining in the current chunk.
// This is common when self-terminating content (e.g. JSON)
// is parsed from response streams.
if (chunkSize == pos && chunkSize > 0 && read() == -1) {
    return;
} {code}
Note that we are at a chunk boundary, not halfway through a chunk, and there is 
no indication that there are any more chunks available to read.

I would therefore expect {{ChunkedInputStream}} to simply close the socket and 
not try to read anything more from it, since we are trying to close it.

But perhaps I'm missing something about this. Do you know if this is the 
expected behavior for the API?

> 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