[ 
https://issues.apache.org/jira/browse/HTTPCORE-601?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16930087#comment-16930087
 ] 

Oleg Kalnichevski commented on HTTPCORE-601:
--------------------------------------------

[~rhashimoto] In HTTP/1.1 protocol the server endpoints rarely initiate 
connection shutdown unless explicitly requested by the client endpoint with 
{{Connection: close}} request header. Server endpoints execute message 
exchanges and then keep the connection alive for a period of time defined by 
their {{keep-alive}} setting expecting the client endpoints to re-use the same 
connection for subsequent requests. Connections more commonly get closed by the 
client, in which case {{SSLSession#close()}} method may never get called by the 
server explicitly.  

Oleg   

> SSLIOSession.close() is never called for async server handling HTTP1
> --------------------------------------------------------------------
>
>                 Key: HTTPCORE-601
>                 URL: https://issues.apache.org/jira/browse/HTTPCORE-601
>             Project: HttpComponents HttpCore
>          Issue Type: Bug
>          Components: HttpCore NIO
>    Affects Versions: 5.0-beta8
>         Environment: macOS Mojave, Debian Jessie
>            Reporter: Roy Hashimoto
>            Assignee: Oleg Kalnichevski
>            Priority: Major
>         Attachments: ConscryptTest.java
>
>
> 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()}}:
> [https://github.com/apache/httpcomponents-core/blob/44cab548cb4e15d56235aa12eaf0898d028351d0/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java#L366-L373]
> This doesn't happen because {{SSLIOSession.isAppOutputReady()}} returns false 
> here:
> [https://github.com/apache/httpcomponents-core/blob/44cab548cb4e15d56235aa12eaf0898d028351d0/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java#L139]
> 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 {
>              return (this.appEventMask & SelectionKey.OP_WRITE) > 0
> -                    && this.status == ACTIVE
> -                    && this.sslEngine.getHandshakeStatus() == 
> HandshakeStatus.NOT_HANDSHAKING;
> +                    && ((this.status == ACTIVE
> +                         && this.sslEngine.getHandshakeStatus() == 
> HandshakeStatus.NOT_HANDSHAKING)
> +                        || this.status == CLOSING);
>          } 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.



--
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

Reply via email to