Joao Silva created HTTPCORE-768:
-----------------------------------
Summary: 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.3-beta1, 5.2.3, 5.1.4, 5.0.4
Reporter: Joao Silva
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: [email protected]
For additional commands, e-mail: [email protected]