Tomcat 9 Http/2 "Ошибка чтения запроса, игнорируется"

Я использую 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.coyoteDepp.decode(HpackDecoder.java:111) в org.apache.coyote.http2.Http2Parser.readHeaderPayload(Http2Parser.java:418) в org.apache.coyote.http2.Http2Parser.readHeadersFrame: or2jp2 (org) athtp apache.coyote.http2.Http2Parser.readFrame(Http2Parser.java:97) в org.apache.coyote.http2.Http2Parser.readFrame(Http2Parser.java:69) в org.apache.coyote.httpttp2 Java:313) в org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54) в org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) в org.apache.stracty $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.j): 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)

Таким образом, соединение открыто только для трех запросов, после чего сервер закрывает соединение при этом исключении.

PS: я использую httpclient-5(бета) для установления постоянного соединения с моим клиентом. Если 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>";

Если у кого-нибудь есть идеи по поводу этого исключения, пожалуйста, помогите

ТИА

1 ответ

Как обсуждено в комментариях

HPACK - это алгоритм сжатия заголовка HTTP, используемый в HTTP/2. Таким образом, сообщения об ошибках указывают на проблему с вашими заголовками 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

Поэтому проверьте все ваши заголовки (включая ваш путь) на наличие некорректных запросов.

В вашем случае это был плохо закодированный запрос Param в нашем:path: header.

Другие вопросы по тегам