Tomcat 9: строка заголовка не соответствует RFC 7230 - PullRequest
2 голосов
/ 28 октября 2019

У меня есть приложение, которое работало на Tomcat 8.5.38. Теперь я решил обновить до Tomcat 9.0.27, и возникает проблема с запросом GET и RFC 7230, Протокол передачи гипертекста (HTTP / 1.1): синтаксис и маршрутизация сообщений .

Запрос:

/api/vehicle/power_off?vehicleId=1428714&dtStart=2019-10-21 08:00:00&dtEnd=2019-10-21 08:30:00

Он отлично работал как из браузера (любого - IE, Opera, Chrome, FF), так и из другого клиента (система 1C ERP).

После обновления версиииз браузера все равно работает отлично, а из 1С - нет. Tomcat показывает ошибку:

28-Oct-2019 17:29:26.201 INFO [http-nio-8080-exec-3] org.apache.coyote.http11.Http11Processor.service Error parsing HTTP request header
 Note: further occurrences of HTTP request parsing errors will be logged at DEBUG level.
    java.lang.IllegalArgumentException: The HTTP header line [get /api/vehicle/power_off?deviceId=1428714&dtStart=2019-10-21%2008:00:00&dtEnd=2019-10-21%2008:30:00 HTTP/1.1: ] does not conform to RFC 7230 and has been ignored.
        at org.apache.coyote.http11.Http11InputBuffer.skipLine(Http11InputBuffer.java:962)
        at org.apache.coyote.http11.Http11InputBuffer.parseHeader(Http11InputBuffer.java:825)
        at org.apache.coyote.http11.Http11InputBuffer.parseHeaders(Http11InputBuffer.java:564)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:309)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

Та же ошибка на моей машине разработчика (MacOS + Tomcat 9.0.24) и производственном сервере (Ubuntu 16.04 + Tomcat 9.0.27).

Причинанаходится в двоеточии в параметрах datetime. Когда я удаляю двоеточия из строки запроса (оставьте только «2019-10-21 080000»), запрос работает как ожидалось (с ошибкой «дата и время не могут быть проанализированы ...»). Также, когда я вручную изменяю двоеточия на «% 3A», запрос работает и возвращает нормальный результат.

Затем я добавляю параметр relaxedQueryChars в Tomcat Connector с двоеточием (хотя двоеточие разрешено символом):

relaxedQueryChars=':[]|{}^\`"<>'

и все равно не получается.

В чем разница между версиями Tomcat 8 и 9, что мой запрос работает в 8, а в 9 - нет? Что я могу сделать в Tomcat, чтобы этот запрос работал? Изменение запросов на стороне клиента - очень сложная задача ...

1 Ответ

1 голос
/ 28 октября 2019

В чем разница между 8 и 9 версиями Tomcat, что мой запрос работает в 8, а в 9 нет?

Я думаю, что разница в том, что Tomcat 9.x ужесточилсячто должно быть разрешено быть незакодированным в URL, поэтому с технической точки зрения нет проблем с Tomcat 9.x;проблема связана с более ранними выпусками Tomcat, и браузеры не строго следуют спецификациям.

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

Я добавляю параметр relaxedQueryChars в коннектор Tomcat с двоеточием (хотя двоеточие разрешено символом) ... и он по-прежнему не работает.

С документация Tomcat 9.0 для relaxedQueryChars:

Спецификация HTTP / 1.1 требует, чтобы определенные символы кодировались в% nn при использовании в строках запроса URI. К сожалению, многие пользовательские агенты, включая все основные браузеры, не соответствуют этой спецификации и используют эти символы в незашифрованном виде. Чтобы предотвратить отклонение таких запросов Tomcat, этот атрибут может использоваться для указания дополнительных разрешенных символов. Если не указано, дополнительные символы не будут разрешены. Значение может быть любой комбинацией следующих символов: "<> [\] ^` {|}. Любые другие символы, присутствующие в значении, будут игнорироваться.

Примечаниепоследние два предложения. Символ двоеточия не упоминается, поэтому он " будет игнорироваться ".

Могу ли я что-нибудь сделать в Tomcat, чтобы этот запрос работал?

Я так не думаю, но настоящая проблема в том, что вы не кодируете двоеточия в своих параметрах, и вы уже упоминали, что это решает проблему. См. Этот SO-ответ и, в частности, последнее предложение:

There are reserved characters, that have a reserved meanings, those are delimiters — :/?#[]@ — and subdelimiters — !$&'()*+,;=

There is also a set of characters called unreserved characters — alphanumerics and -._~ — which are not to be encoded.

That means, that anything that doesn't belong to unreserved characters set is supposed to be %-encoded, when they do not have special meaning (e.g. when passed as a part of GET parameter).

Двоеточие - это зарезервированный символ со специальным значением, и поэтому оно должно быть закодировано в ваших параметрах.

Примечания:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...