java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
at org.apache.coyote.http11.InternalInputBuffer.parseRequestLine(InternalInputBuffer.java:189)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1000)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
原因
Coyote中最后一条:
Add additional checks for valid characters to the HTTP request line parsing so invalid request lines are rejected sooner. (markt)
代码
org.apache.tomcat.util.http.parser.HttpParser#IS_NOT_REQUEST_TARGET[]
中定义了一堆not request target
if(IS_CONTROL[i] || i > 127 || i == 32 || i == 34 || i == 35 || i == 60 || i == 62 || i == 92 || i == 94 || i == 96 || i == 123 || i == 124 || i == 125) {
IS_NOT_REQUEST_TARGET[i] = true;
}
转换过来就是以下字符(对应10进制ASCII看):
- 键盘上那些控制键:(
<32或者=127
) - 非英文字符(
>127
) -
空格
(32
) -
双引号
(34
) -
#
(35
) -
<
(60
) -
>
(62
) -
反斜杠
(92
) -
^
(94
) -
TAB上面那个键,我也不晓得嫩个读
(96
) -
{
(123
) -
}
(124
) -
|
(125
)
解决(两种方案)
- 请求前自行转义
- 更换tomcat为较低版本(不过tomcat的这次更改是依据RFC7230 and RFC 3986,在往后的版本,不会移除该特性),同样的问题应该也存在于
>= 8.0.39
和>= 9.0.0.M12
(从Changelog上看的,未验证哈)