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 2019/09/12 17:52:00 UTC

[jira] [Assigned] (HTTPCORE-600) SocketTimeoutException when remote server closes connection after payload has been delivered

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

Oleg Kalnichevski reassigned HTTPCORE-600:
------------------------------------------

    Assignee: Oleg Kalnichevski

> SocketTimeoutException when remote server closes connection after payload has been delivered
> --------------------------------------------------------------------------------------------
>
>                 Key: HTTPCORE-600
>                 URL: https://issues.apache.org/jira/browse/HTTPCORE-600
>             Project: HttpComponents HttpCore
>          Issue Type: Bug
>          Components: HttpCore NIO
>    Affects Versions: 4.4.10, 4.4.11, 4.4.12
>            Reporter: Brian B
>            Assignee: Oleg Kalnichevski
>            Priority: Major
>         Attachments: asyncbugtest.zip
>
>
> Initially I created this under CXF (CXF-8113), but I think the consensus is it is an NIO issue.  The description from that Jira edited to remove CXF-specific changes:
> When using the Asynchronous Client HTTP Transport to handle soap web services, we get a SocketTimeout exception when a remote server closes the connection after the payload has been delivered.
> The problem occurs when the client receives a TLS {{close_notify}} _after_ the payload has been received.  The payload must be larger than the allocated byte buffer receiving the decrypted payload (~16K in the default case). This results in decrypted data being available in the {{httpcore-nio}} library, but not immediately consumed. 
> When these conditions are met, the following section of code is invoked:
>  {{org.apache.cxf.transport.http.asyncclient.SharedInputBuffer#_consumeContent_:{color:#0747a6}111{color}}}:
> {code:java}
> if (!this.buffer.hasRemaining() && this.ioctrl != null && !this.endOfStream) {
>     this.ioctrl.suspendInput();
> }
> {code}
> The suspension of input when combined with the connection close and the following change introduced in {{httpcore-nio}} 4.4.10 (and it's revised 4.4.11 version here) truly removes the {{READ}} {{EventMask}} from the underlying {{IOSessionImpl}}:
>  {{org.apache.http.nio.reactor.ssl.SSLIOSession#_updateEventMask_:{color:#0747a6}402{color}}}
> {code:java}
> if (this.endOfStream && (this.appBufferStatus == null || !this.appBufferStatus.hasBufferedInput())) {
>     newMask = newMask & ~EventMask.READ;
> }
> {code}
> Once this happens, requests for input by {{SharedInputBuffer#_waitForData(int)_}} enter the {{_updateEventMask_}} method as expected, but the new {{httpcore-nio}} code above prevents the read operation from being reenabled despite the remainder of the decrypted payload being available in the {{SSLIOSession}} {{inPlain}} buffer.  The call ultimately fails with a {{SocketTimeoutException}}.
> I created a unit test to demonstrate the failure and attached it to the JIRA.  Given the complexity of the code and multiple buffers at play, I have not been able to come up with a fix beyond modifying the {{SSLIOSession}} code above to account for the buffered decrypted content.  It seems in all cases where {{appBufferStatus.hasBufferedInput()}} is queried, {{inPlain.hasData()}} is also queried, with the exception of the {{updateEventMask}} code above.
> Please let me know if there's anything else you need from me.
>  



--
This message was sent by Atlassian Jira
(v8.3.2#803003)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org