[ 
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]

Reply via email to