All,

Hopefully I can explain this clearly...

The short question is that my client is sometimes not getting the 0-length 
chunk at the end of the response from Tomcat, so my connections don't get 
reused.

My Tomcat server is version 7.0.81.  JDK is 1.8.0_144.  I have a Jersey client, 
version 2.25, connecting to it from another Tomcat server.  I noticed that 
inbound connections to the server are not getting reused properly.  I think the 
reason has to do with the fact that Tomcat is using chunked output but is not 
sending the 0-length chunk that signals the end of the response, even though 
the response is completed/successful.

My Tomcat server has 3 connectors: one plain HTTP, one SSL, and one SSL + 
mutual authentication (2-way SSL.)  With plain HTTP, I always get the 0-length 
chunk.  I verified this both with the remote debugger and TCPMon.  With the 
other two connectors, I don't get the 0-length chunk with the Jersey client, 
though I do see it with some other clients.  I can't use TCPMon with SSL, but 
with the same breakpoints as with non-SSL I see that there is no 0-length chunk.

Setting a breakpoint on ChunkedInputStream line 326 on the client side and 
printing the chunk sizes, I get this output for 2 responses over plain HTTP:

chunk size: 8192
chunk size: 1312
chunk size: 0
chunk size: 8192
chunk size: 1312
chunk size: 0

And for SSL:

chunk size: 8192
chunk size: 1312
chunk size: 8192
chunk size: 1312

When there is no 0-length chunk, the processRaw() method exits on line 304.  
When there is, it exits on line 457.

In all scenarios, the client uses HTTP/1.1 and sends the Connection: keep-alive 
header.  Adding "%{Connection}i %{Connection}o" to my access valve gives me 
this in the log:

keep-alive -

When I run tests from a load generator directly against the server, the 
chunking occurs and the connections get reused as expected.

Here is my plain HTTP connector:

<Connector port="7150"
                protocol="HTTP/1.1"
                connectionTimeout="3000"
                enableLookups="false"
                acceptCount="150"
                redirectPort="8443"
                maxThreads="80"
                maxKeepAliveRequests="100"
                />

Here is one of my SSL connectors:

<Connector port="7154"
        protocol="HTTP/1.1"
        SSLEnabled="true"
        maxThreads="160"
        maxKeepAliveRequests="100"
        keepAliveTimeout="10000"
        scheme="https"
        secure="true"
        clientAuth="true"
        sslProtocol="TLS"
        sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"
        keystoreFile="${keystoreFile}"
        keystorePass="${keystorePassword}"
        keyAlias="banana"
        truststoreFile="${truststoreFile}"
        truststorePass="${truststorePassword}"
        allowUnsafeLegacyRenegotiation="false"
        ciphers="blah blah blah"
/>

Any ideas?

Thanks

John



Reply via email to