In source code [1], the "forceRead" section (from Line 265 to 273, as of today) does not reset "forceRead" to false after a forced read. This causes improper forced reading in follow-up loops even though there are still data in the socketChannel left over from last unwrap. As a result, it causes timeout in the WsWebSocketContainer.processResponse() method, and prevents websocket hand-shaking from completion. [1] http://svn.apache.org/repos/asf/tomcat/trunk/java/org/apache/tomcat/websocket/AsyncChannelWrapperSecure.java
Note the same issue applies to other versions as well.
Thanks for the report. This has been fixed in 9.0.x for 9.0.0.M4 onwards, 8.0.x for 8.0.33 onwards and 7.0.x for 7.0.69 onwards.