[
https://issues.apache.org/jira/browse/HTTPCORE-526?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Stefano Fornari updated HTTPCORE-526:
-------------------------------------
Affects Version/s: 4.4.9
Environment: Linux HOSTENAME 4.13.0-39-generic #44~16.04.1-Ubuntu SMP
Thu Apr 5 16:43:10 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Description:
Hello, I recently switched for a project from httpcore-4.3.3 to httpcore-4.4.9
and ran into a nasty problem. The project is fundamentally a web server and the
problem I encountered in the switch is that connections started to be reset
quite frequently and the web app stopped to work. Not all content were flushed
to the wire.
I therefore investigated the problem and checked the differences between the
two versions and I think I found a bug in the new implementation of
BHttpConnectionBase. The old shutdown method looked like:
{quote}@Override
public void shutdown() throws IOException {
final Socket socket = this.socketHolder.getAndSet(null);
if (socket != null) {
socket.close();
}
}
{quote}
The new one:
{quote}@Override
public void shutdown() throws IOException {
final Socket socket = this.socketHolder.getAndSet(null);
if (socket != null) {
// force abortive close (RST)
try {
socket.setSoLinger(true, 0);
} catch (final IOException ex) {
} finally {
socket.close();
}
}
}
{quote}
In researching the meaning of setSoLinger() I found the following description:
*Linger set to {{true}} and linger time==0*** *No more receives or sends can be
issued on the socket. The socket send and receive buffers are both discarded.
This means that if the OS has data internally for the socket this data is not
sent and not received by the other end. The {{close()}} method returns
immediately and clears the send buffer in background.*
*Linger set to {{true}} and linger time!=0*** *No more receives or sends can be
issued on the socket. Data in socket send buffer is sent and data in the
receive buffer is discarded. If the linger time expires an exception will
occur. The {{close()}} method will block for a maximum of linger seconds or
until data has been sent and acknowledged at the TCP level.*
linger == true && linger time == 0 would explain the issue I am experiencing,
because the underlying SO buffer may not be flushed before closing the stream
(I am on linux).
Simply changing the code to:
{quote}socket.setSoLinger(true, 1);
{quote}
solves the problem.
Please do not ask me to create a simple test case, it would require too much on
my side not being fully familiar with the code base. You can refer to
[https://github.com/stefanofornari/https] for reference and I am available to
help as much as I can.
Summary: Bug in c.shutdown() (was: Bug in
BHttpConnectionBase.shutdown())
> Bug in c.shutdown()
> -------------------
>
> Key: HTTPCORE-526
> URL: https://issues.apache.org/jira/browse/HTTPCORE-526
> Project: HttpComponents HttpCore
> Issue Type: Bug
> Affects Versions: 4.4.9
> Environment: Linux HOSTENAME 4.13.0-39-generic #44~16.04.1-Ubuntu SMP
> Thu Apr 5 16:43:10 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
> Reporter: Stefano Fornari
> Priority: Major
>
> Hello, I recently switched for a project from httpcore-4.3.3 to
> httpcore-4.4.9 and ran into a nasty problem. The project is fundamentally a
> web server and the problem I encountered in the switch is that connections
> started to be reset quite frequently and the web app stopped to work. Not all
> content were flushed to the wire.
> I therefore investigated the problem and checked the differences between the
> two versions and I think I found a bug in the new implementation of
> BHttpConnectionBase. The old shutdown method looked like:
> {quote}@Override
> public void shutdown() throws IOException {
> final Socket socket = this.socketHolder.getAndSet(null);
> if (socket != null) {
> socket.close();
> }
> }
> {quote}
> The new one:
> {quote}@Override
> public void shutdown() throws IOException {
> final Socket socket = this.socketHolder.getAndSet(null);
> if (socket != null) {
> // force abortive close (RST)
> try {
> socket.setSoLinger(true, 0);
> } catch (final IOException ex) {
> } finally {
> socket.close();
> }
> }
> }
> {quote}
> In researching the meaning of setSoLinger() I found the following description:
> *Linger set to {{true}} and linger time==0*** *No more receives or sends can
> be issued on the socket. The socket send and receive buffers are both
> discarded. This means that if the OS has data internally for the socket this
> data is not sent and not received by the other end. The {{close()}} method
> returns immediately and clears the send buffer in background.*
> *Linger set to {{true}} and linger time!=0*** *No more receives or sends can
> be issued on the socket. Data in socket send buffer is sent and data in the
> receive buffer is discarded. If the linger time expires an exception will
> occur. The {{close()}} method will block for a maximum of linger seconds or
> until data has been sent and acknowledged at the TCP level.*
> linger == true && linger time == 0 would explain the issue I am experiencing,
> because the underlying SO buffer may not be flushed before closing the stream
> (I am on linux).
> Simply changing the code to:
> {quote}socket.setSoLinger(true, 1);
> {quote}
> solves the problem.
> Please do not ask me to create a simple test case, it would require too much
> on my side not being fully familiar with the code base. You can refer to
> [https://github.com/stefanofornari/https] for reference and I am available to
> help as much as I can.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]