Details
-
Bug
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
5.0-beta8
-
None
-
macOS Mojave, Debian Jessie
Description
On 5.0, an asynchronous server handling an HTTP1 request never calls SSLIOSession.close(). The attached sample server program exhibits the problem. To test:
- Set a breakpoint in SSLIOSession.close().
- Make some requests.
The expectation is for the breakpoint to be triggered when the connection ends. The observed behavior is that the breakpoint is never reached.
The sample program uses Conscrypt (org.conscrypt:conscrypt-openjdk-uber:2.2.1) but the root problem occurs with any JSSE provider including the default. There is an additional bad side effect with Conscrypt, however, which is that the program spins in the selection loop and consumes excessive CPU.
When AbstractHttp1StreamDuplexer.requestShutdown() sets OP_WRITE, this code in onOutput() should call SSLIOSession.close():
This doesn't happen because SSLIOSession.isAppOutputReady() returns false here:
which happens because status is CLOSING and sslEngine.getHandshakeStatus() returns NEED_WRAP. So onOutput() is not called after requestShutdown() and OP_WRITE remains set. On Conscrypt, selection on OP_WRITE keeps succeeding which causes the spin.
I tried hacking SSLIOSession.isAppOutputReady():
— a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/SSLIOSession.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/SSLIOSession.java
@@ -523,8 +523,9 @@ public boolean isAppOutputReady() throws IOException {
this.session.getLock().lock();
try
finally
{ this.session.getLock().unlock(); }This is probably not the appropriate fix, but it does call SSLIOSession.close() and does not spin with Conscrypt so something that achieves that should work.
Attachments
Attachments
Issue Links
- links to