Bug 60232 - HTTP/2 connector stuck when parsing big http header
Summary: HTTP/2 connector stuck when parsing big http header
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 8.5.5
Hardware: PC All
: P2 normal (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-10-10 14:27 UTC by barney2k7
Modified: 2016-10-20 10:10 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description barney2k7 2016-10-10 14:27:46 UTC
HTTP/2 connector of tomcat 8.5.5 is getting stuck (endless busy loop) when parsing a big (e.g. 30kb) http header.

Steps to reproduce using apache-tomcat-8.5.5-windows-x86.zip on windows 7 (64) and jre 1.8.0_102 (32):
1.) configure a https connector including http2 upgrade, e.g.
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true">
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="key.key"
                         certificateFile="cert.crt"
                         />
        </SSLHostConfig>
    </Connector>

2.) Point Firefox to https://localhost:8443/, verify HTTP/2 is used using Network View in Developer Tools
3.) For the verified request, use 'Edit and Resend' to add a big http header, e.g.
X-Big-Header: <put 30kb of text here>
and send that request
4.) The request never returns, and Windows Task Manager shows that tomcat's java vm now fully uses one core
5.) Stacktrace of the stuck thread looks like this:

Name: https-openssl-apr-8443-exec-6
State: RUNNABLE
Total blocked: 0  Total waited: 1

Stack trace: 
org.apache.coyote.http2.HPackHuffman.decode(HPackHuffman.java:383)
org.apache.coyote.http2.HpackDecoder.readHuffmanString(HpackDecoder.java:215)
org.apache.coyote.http2.HpackDecoder.readHpackString(HpackDecoder.java:204)
org.apache.coyote.http2.HpackDecoder.readHeaderName(HpackDecoder.java:188)
org.apache.coyote.http2.HpackDecoder.decode(HpackDecoder.java:116)
org.apache.coyote.http2.Http2Parser.readHeaderBlock(Http2Parser.java:404)
org.apache.coyote.http2.Http2Parser.readHeadersFrame(Http2Parser.java:246)
org.apache.coyote.http2.Http2Parser.readFrame(Http2Parser.java:96)
org.apache.coyote.http2.Http2Parser.readFrame(Http2Parser.java:68)
org.apache.coyote.http2.Http2UpgradeHandler.upgradeDispatch(Http2UpgradeHandler.java:314)
org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2241)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
   - locked org.apache.tomcat.util.net.AprEndpoint$AprSocketWrapper@cd6eb
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:745)


In case you're wondering what the use-case for such big headers is: they actually occur when using SPNEGO/Kerberos. The 'Negotiate'-Header can easily be dozens of KB long.
Comment 1 barney2k7 2016-10-13 07:07:38 UTC
This issue still exists in tomcat 8.5.6, even though there seem to have been some bugfixes (e.g. bug  60173 ) in the affected area
Comment 2 Mark Thomas 2016-10-20 10:10:30 UTC
Thanks for the report. This has been fixed in trunk for 9.0.0.M12 onwards and 8.5.x for 8.5.7 onwards.