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