[ https://issues.apache.org/jira/browse/HTTPCORE-600?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Oleg Kalnichevski resolved HTTPCORE-600. ---------------------------------------- Fix Version/s: 5.0-beta9 4.4.13 Resolution: Fixed Fix merged to 4.4.x and master. Oleg > 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 > Fix For: 4.4.13, 5.0-beta9 > > Attachments: asyncbugtest.log, 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-unsubscr...@hc.apache.org For additional commands, e-mail: dev-h...@hc.apache.org