You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by "Oleg Kalnichevski (JIRA)" <ji...@apache.org> on 2018/05/08 09:07:00 UTC

[jira] [Resolved] (HTTPCORE-526) Bug in BHttpConnectionBase.shutdown()

     [ https://issues.apache.org/jira/browse/HTTPCORE-526?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Oleg Kalnichevski resolved HTTPCORE-526.
----------------------------------------
    Resolution: Information Provided

> Bug in BHttpConnectionBase.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: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org