Tomcat 9 Http / 2“读取请求时出错,已忽略”

时间:2018-06-27 13:36:12

标签: tomcat http2 tomcat9 apache-httpclient-5.x

我正在使用tomcat 9.0.5(jdk-9.0.4 + 11)来处理我的请求,这些请求还启用了Http / 2以进行持久连接,并且我的客户端也使用相同版本的Java,因此我需要打开一个持久化从客户端连接到服务器并无限期地重用。我可以从客户端成功连接到服务器并发送请求(带有requestBody的帖子),但是在3个请求(恰好3个)之后,服务器将抛出异常,如下所示,

  

org.apache.coyote.AbstractProtocol $ ConnectionHandler.process错误   读取请求,在以下位置忽略了java.lang.NullPointerException   org.apache.coyote.http2.HpackDecoder.handleIndex(HpackDecoder.java:270)     在org.apache.coyote.http2.HpackDecoder.decode(HpackDecoder.java:111)     在   org.apache.coyote.http2.Http2Parser.readHeaderPayload(Http2Parser.java:418)     在   org.apache.coyote.http2.Http2Parser.readHeadersFrame(Http2Parser.java:252)     在org.apache.coyote.http2.Http2Parser.readFrame(Http2Parser.java:97)     在org.apache.coyote.http2.Http2Parser.readFrame(Http2Parser.java:69)     在   org.apache.coyote.http2.Http2UpgradeHandler.upgradeDispatch(Http2UpgradeHandler.java:313)     在   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:754)     在   org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1376)     在   org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)     在   java.base / java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)     在   java.base / java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:641)     在   org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61)     在java.base / java.lang.Thread.run(Thread.java:844)

因此,仅针对三个请求打开连接,然后服务器在出现此异常后关闭连接。

p.s:我正在使用httpclient-5(beta)从客户端建立持久连接。 如果queryParam / requestBody是静态内容,则连接保持持久。但是,如果queryParam / requestBody具有一些动态内容(例如时间戳),则连接会因上述错误而关闭,我不知道帖子主体中的数据与tcp连接之间的关系

我无法发布请求正文,因为它违反了政策,因此我会在屏蔽所有请求参数后发布该帖子,我的请求将如下所示

String postBody = "<?xml version=\"1.0\" standalone=\"no\"?>\n" + 
                "<XX xxx=\"1000000005011\" xxx=\"true\" xxx=\"false\" xxx=\"0\" xxx=\"P|TA|D|J|M\" xxx=\"\" xxx=\"\" xxx=\"false\" xxx=\"false\" xxx=\"1\" xxx=\"true\" xxx=\"false\" xxx=\"xxx\" xxx=\"8265\"  xxx=\"true\" avgDnsTime=\"null\" xxx=\"false\" xxx=\"EVAL_USER\" xxx=\"1000000000011\" xxx=\"2\" xxx=\"true\" xxx=\"http://localhost:8080/app/xxx\" xxx=\"true\" xxx=\"false\" xxx=\"av_xxx\" ut=\"1528453675150\" xxx=\"URL\" xxx=\"70\" time=\""+(System.currentTimeMillis()+"")+"\" xxx=\"1440\" xxx=\"48\" xxx=\"1\" xxx=\"1\" postUrl=\"xxx.com:8443\">\n" + 
                "<XXX xxx=\"\" xxx=\"\" xxx=\"false\" xxx=\"\" xxx=\"1000000005011\" xxx=\"60\" xxx=\"\" xxx=\"127.0.0.1\" xxx=\"\" xxx=\"false\" xxx=\"\" xxx=\"default\" xxx=\"\" xxx=\"\" xxx=\"\" xxx=\"false\" xxx=\"false\" xxx=\"false\" xxx=\"http://www.example.com\" xxx=\"\" xxx=\"\" xxx=\"false\" m=\"G\" xxx=\"0\" xxx=\"\" xxx=\"\" t=\"30\" xxx=\"English\"><XD></XD><XH xxx=\"\" xxx=\"_sep_\" xxx=\"\"/><XI xxx=\"\" xxx=\"\"/>\n" + 
                "</XXX>\n" + 
                "</XX>";

如果有人对此异常有任何想法,请提供帮助

TIA

1 个答案:

答案 0 :(得分:1)

如评论中所述

HPACK是HTTP / 2中使用的HTTP标头压缩算法。因此,错误消息表明您的HTTP标头存在问题。

HTTP / 1对于格式错误的HTTP标头非常宽容,但是HTTP / 2更加严格。多余的换行符,引号,多余的冒号...等。都会引起问题。

此外,在HTTP / 2下,所有请求方法和参数都被视为HTTP标头。

所以,这在HTTP / 1中:

GET /page.html HTTP/1.1
Header1: Header1Value
Header2: Header2Value

在HTTP / 2中成为:

:method: GET
:path: /page.html
Header1: Header1Value
Header2: Header2Value

因此,请检查所有标头(包括路径)中是否存在格式错误的请求。

在您的情况下,这是我们的:path:标头中的编码错误的查询参数。