Brian B created CXF-8113: ---------------------------- Summary: SocketTimeoutException when remote server closes connection after payload has been delivered Key: CXF-8113 URL: https://issues.apache.org/jira/browse/CXF-8113 Project: CXF Issue Type: Bug Affects Versions: 3.3.1 Reporter: Brian B Attachments: asyncbugtest.zip
Similar to CXF-7831, 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. >From my research, I'm honestly not sure if this is a CXF issue or an >{{httpcore-nio}} issue. The fix in CXF-7831 to CXF's {{SharedInputBuffer}}, >and the fact that I do not directly consume httpcore-nio led me here first. 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 SocketException. 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 - but I'm assuming that change was added for a reason and did not investigate the side effects of the modification. Please let me know if there's anything else you need from me. -- This message was sent by Atlassian Jira (v8.3.2#803003)