Bug 1200276 - NIO2: Creating concurrent requests (non keep alive) to HTTPS results in Exceptions shown in debug log
Summary: NIO2: Creating concurrent requests (non keep alive) to HTTPS results in Excep...
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: JBoss Enterprise Application Platform 6
Classification: JBoss
Component: Web
Version: 6.4.0
Hardware: Unspecified
OS: Unspecified
unspecified
medium
Target Milestone: CR2
: EAP 6.4.1
Assignee: Rémy Maucherat
QA Contact: Radim Hatlapatka
URL:
Whiteboard:
Depends On:
Blocks: 1188828 eap641-payload
TreeView+ depends on / blocked
 
Reported: 2015-03-10 08:05 UTC by Radim Hatlapatka
Modified: 2017-01-17 10:02 UTC (History)
4 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2015-03-30 13:29:24 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
Simple war with static content (1.18 KB, application/zip)
2015-03-10 08:05 UTC, Radim Hatlapatka
no flags Details
Example config file (16.76 KB, application/xml)
2015-03-10 08:06 UTC, Radim Hatlapatka
no flags Details
Server certificate (749 bytes, text/x-vhdl)
2015-03-10 08:07 UTC, Radim Hatlapatka
no flags Details
Server key (2.19 KB, application/octet-stream)
2015-03-10 08:07 UTC, Radim Hatlapatka
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Red Hat Bugzilla 1200283 0 unspecified CLOSED NIO2: Creating concurrent requests with keep-alive header to HTTPS results to timeout of second requests from the same c... 2021-02-22 00:41:40 UTC
Red Hat Bugzilla 1225403 0 unspecified CLOSED Multiple concurrent requests (non keep-alive) via HTTPS with server using NIO2 connector results in Exceptions written i... 2021-02-22 00:41:40 UTC

Internal Links: 1200283 1225403

Description Radim Hatlapatka 2015-03-10 08:05:11 UTC
Created attachment 999759 [details]
Simple war with static content

Description of problem:
When having defined https with NIO2 connector [1] and doing multiple requests in parallel it results in Exceptions being written in debug log [2]. The exception is usually ClosedChannelException [3] or IOException [4].

Version-Release number of selected component (if applicable):
EAP 6.4.0.ER3


How reproducible: always


Steps to Reproduce:
1. Unzip EAP distro
2. Deploy attached test.war (contains some static files with different byte length)
3. Load certificate and keystore to $JBOSS_HOME/standalone
4. Configure https and set protocol to NIO2 ([1] or see attached config)
5. Enable debug logging for "org.apache" ([2] or see attached config)
6. Do concurrent requests via ApacheBench (ab -n 3 -c 2 -Z DHE-RSA-AES256-SHA -v 3  https://127.0.0.1:8443/test/f256)


Actual results:
Requests are processed and exception is shown in debug (all exceptions which occur on the channel are logged as debug)

Expected results:
Requests are processed without the exception being thrown


Additional info:
This behaviour was detected only with enabled ssl (https).


[1]
 <connector name="https" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https" socket-binding="https" enabled="true">
                <ssl name="http-perf" key-alias="jboss" password="jbossas" certificate-key-file="${jboss.server.base.dir}/server.keystore" cipher-suite="ALL" protocol="TLSv1" verify-client="none" certificate-file="${jboss.server.base.dir}/server.crt"/>
            </connector>

[2]
To enable debug logging for org.apache:

<logger category="org.apache">
      <level name="DEBUG"/>
</logger>


[3]
14:21:16,832 DEBUG [org.apache.coyote.http11] (http-/127.0.0.1:8443-70) JBWEB003064: Error during blocking read: java.nio.channels.ClosedChannelException
    at org.apache.tomcat.util.net.jsse.SecureNioChannel.readBytes(SecureNioChannel.java:130) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.apache.coyote.http11.InternalNioInputBuffer.fill0(InternalNioInputBuffer.java:515) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.apache.coyote.http11.InternalNioInputBuffer.fill(InternalNioInputBuffer.java:469) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.apache.coyote.http11.InternalNioInputBuffer.parseRequestLine(InternalNioInputBuffer.java:285) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:290) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:911) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.apache.tomcat.util.net.NioEndpoint$ChannelProcessor.run(NioEndpoint.java:936) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_75]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_75]
    at org.apache.tomcat.util.net.NioEndpoint$DefaultThreadFactory$1$1.run(NioEndpoint.java:1249) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_75]


[4] This is one of IO Exceptions I am seeing in log:

14:24:01,962 DEBUG [org.apache.tomcat.util] (http-/127.0.0.1:8443-93) JBWEB003023: Channel processing failed: javax.net.ssl.SSLException: java.util.concurrent.ExecutionException: java.io.IOException: Broken pipe
    at org.apache.tomcat.util.net.jsse.SecureNioChannel.handshake(SecureNioChannel.java:636) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.apache.tomcat.util.net.jsse.NioJSSESocketChannelFactory.handshake(NioJSSESocketChannelFactory.java:227) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.apache.tomcat.util.net.NioEndpoint$HandshakeHandler.run(NioEndpoint.java:635) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_75]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_75]
    at org.apache.tomcat.util.net.NioEndpoint$DefaultThreadFactory$1$1.run(NioEndpoint.java:1249) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_75]
Caused by: java.util.concurrent.ExecutionException: java.io.IOException: Broken pipe
    at sun.nio.ch.CompletedFuture.get(CompletedFuture.java:69) [rt.jar:1.7.0_75]
    at org.apache.tomcat.util.net.jsse.SecureNioChannel.doHandshake(SecureNioChannel.java:754) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    at org.apache.tomcat.util.net.jsse.SecureNioChannel.handshake(SecureNioChannel.java:634) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
    ... 6 more
Caused by: java.io.IOException: Broken pipe
    at sun.nio.ch.FileDispatcherImpl.write0(Native Method) [rt.jar:1.7.0_75]
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) [rt.jar:1.7.0_75]
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93) [rt.jar:1.7.0_75]
    at sun.nio.ch.IOUtil.write(IOUtil.java:51) [rt.jar:1.7.0_75]
    at sun.nio.ch.UnixAsynchronousSocketChannelImpl.implWrite(UnixAsynchronousSocketChannelImpl.java:691) [rt.jar:1.7.0_75]
    at sun.nio.ch.AsynchronousSocketChannelImpl.write(AsynchronousSocketChannelImpl.java:381) [rt.jar:1.7.0_75]
    at sun.nio.ch.AsynchronousSocketChannelImpl.write(AsynchronousSocketChannelImpl.java:386) [rt.jar:1.7.0_75]
    ... 8 more

Comment 1 Radim Hatlapatka 2015-03-10 08:06:39 UTC
Created attachment 999761 [details]
Example config file

Comment 2 Radim Hatlapatka 2015-03-10 08:07:08 UTC
Created attachment 999762 [details]
Server certificate

Comment 3 Radim Hatlapatka 2015-03-10 08:07:46 UTC
Created attachment 999763 [details]
Server key

Comment 7 Rémy Maucherat 2015-03-11 15:24:13 UTC
Since this looked 100% SSL related, I tried porting the Tomcat changes to handle incomplete writes, and this does seem to fix the issues for me.

Comment 8 Rémy Maucherat 2015-03-12 09:18:23 UTC
So is it possible to test with the change I committed ?

Comment 9 Radim Hatlapatka 2015-03-12 10:22:19 UTC
I have tried it with the committed change [1] and I am getting still the same behaviour, I am still seeing [2] in debug log. Could it be somehow related to "Connection: close" header send by ApacheBench client for non keep alive connections?


[1]
https://source.jboss.org/changelog/JBossWeb?cs=2597

[2]
11:20:33,412 DEBUG [org.apache.tomcat.util] (http-/127.0.0.1:8443-9) JBWEB003023: Channel processing failed: javax.net.ssl.SSLException: java.util.concurrent.ExecutionException: java.io.IOException: Broken pipe
	at org.apache.tomcat.util.net.jsse.SecureNioChannel.handshake(SecureNioChannel.java:642) [jbossweb-7.5.7.Final.jar:7.5.7.Final]
	at org.apache.tomcat.util.net.jsse.NioJSSESocketChannelFactory.handshake(NioJSSESocketChannelFactory.java:227) [jbossweb-7.5.7.Final.jar:7.5.7.Final]
	at org.apache.tomcat.util.net.NioEndpoint$HandshakeHandler.run(NioEndpoint.java:635) [jbossweb-7.5.7.Final.jar:7.5.7.Final]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_75]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_75]
	at org.apache.tomcat.util.net.NioEndpoint$DefaultThreadFactory$1$1.run(NioEndpoint.java:1249) [jbossweb-7.5.7.Final.jar:7.5.7.Final]
	at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_75]
Caused by: java.util.concurrent.ExecutionException: java.io.IOException: Broken pipe
	at sun.nio.ch.CompletedFuture.get(CompletedFuture.java:69) [rt.jar:1.7.0_75]
	at org.apache.tomcat.util.net.jsse.SecureNioChannel.doHandshake(SecureNioChannel.java:760) [jbossweb-7.5.7.Final.jar:7.5.7.Final]
	at org.apache.tomcat.util.net.jsse.SecureNioChannel.handshake(SecureNioChannel.java:640) [jbossweb-7.5.7.Final.jar:7.5.7.Final]
	... 6 more
Caused by: java.io.IOException: Broken pipe
	at sun.nio.ch.FileDispatcherImpl.write0(Native Method) [rt.jar:1.7.0_75]
	at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) [rt.jar:1.7.0_75]
	at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93) [rt.jar:1.7.0_75]
	at sun.nio.ch.IOUtil.write(IOUtil.java:51) [rt.jar:1.7.0_75]
	at sun.nio.ch.UnixAsynchronousSocketChannelImpl.implWrite(UnixAsynchronousSocketChannelImpl.java:691) [rt.jar:1.7.0_75]
	at sun.nio.ch.AsynchronousSocketChannelImpl.write(AsynchronousSocketChannelImpl.java:381) [rt.jar:1.7.0_75]
	at sun.nio.ch.AsynchronousSocketChannelImpl.write(AsynchronousSocketChannelImpl.java:386) [rt.jar:1.7.0_75]
	... 8 more

Comment 10 Rémy Maucherat 2015-03-12 11:06:10 UTC
I'm not running into any handshake issue, but let's assume there's a problem there.

Can you verify the keepalive variant too by adding -k ? Handshake occurs less often obviously, and I think the rest is probably fine now.

Comment 11 Radim Hatlapatka 2015-03-12 11:51:32 UTC
With keepalive variant it also behaves still the same => via two concurrent clients sending three messages results in only two messages written to access log, third timeouts on ApacheBench side.

I am going to debug it a little bit more and if I find out anything interesting, I will post here my findings.

Comment 12 Rémy Maucherat 2015-03-12 12:09:15 UTC
Ok, something went wrong again during my testing, so problem solved.

Comment 13 Rémy Maucherat 2015-03-12 14:10:13 UTC
According to my testing, hopefully correct now (...), it seems sendfile is causing the issue in this case and can be disabled to fix it. I will continue testing.

Comment 18 Radim Hatlapatka 2015-03-13 14:10:17 UTC
I have tried it with disabled sendfile done in [1] and I no longer see the issues connected to both bugs.


[1]
https://source.jboss.org/changelog/JBossWeb?cs=2598

Comment 26 Radim Hatlapatka 2015-05-18 10:39:37 UTC
Disabled sendfile on NIO2 connector makes all data to be transmitted as whole in both cases (for connection using keep-alive and without it).

=> The main issue is fixed, nevertheless I still see for non keep-alive connections the exception described in comment 9 in debug log. Not sure why I haven't notice during pretesting.

There seems that there are still remaining some incomplete writes resulting in exception being thrown even when all data were already delivered to client (from statistics of apachebench client I see that client received all the data)

Comment 27 Radim Hatlapatka 2015-05-18 10:56:16 UTC
This issue is partially fixed. 

The first and main issue was that not all data were delivered to requestor, which is now fixed. 
The second is that there occurs exception (IO exception or closed channel exception) in debug log of JBoss Web.

The first part is fixed, the second isn't as the exceptions still occur with non-keepalive connection. 

Hypothesis is that there are still attempts to write to the channel which is closed in the meantime resulting in the broken pipe exceptions in the log.

Comment 28 Radim Hatlapatka 2015-05-18 10:58:24 UTC
From the ab client the behaviour seems correct (all requested data are recieved). The exceptions in the debug log needs to be further investigated.

Comment 29 Rémy Maucherat 2015-05-19 07:59:30 UTC
Comment 9 is an exception during handshake, so if it is exclusively this one it is not related to the other issue.

Comment 30 Radim Hatlapatka 2015-05-19 11:19:59 UTC
Yes, the exception I am seeing is the one from comment 9.

Comment 32 Carlo de Wolf 2015-05-27 08:22:19 UTC
As per https://bugzilla.redhat.com/show_bug.cgi?id=1200276#c28 the functionality works and the exception is a 'debug' exception thrown during connection setup.
If we really want to deal with that exception differently we should have a new BZ (which I might just consider a RFE).

Comment 35 Radim Hatlapatka 2015-05-27 10:08:52 UTC
I have created separate BZ#1225403 to track the occurrence of the exception in the debug log during handshaking.

Setting this one as verified as per comment 27 and comment 28 the behaviour is otherwise correct and the exception in log appears as different issue tracked now in separate BZ.

Comment 36 Petr Penicka 2017-01-17 10:01:49 UTC
Retroactively bulk-closing issues from released EAP 6.4 cummulative patches.

Comment 37 Petr Penicka 2017-01-17 10:02:05 UTC
Retroactively bulk-closing issues from released EAP 6.4 cummulative patches.


Note You need to log in before you can comment on or make changes to this bug.