Java Tomcat 8 无法使用“|”处理获取请求 在查询参数中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41053653/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:07:19  来源:igfitidea点击:

Tomcat 8 is not able to handle get request with '|' in query parameters?

javatomcattomcat8tomcat8.5

提问by ashishjmeshram

I am using Tomcat 8. In one case I need to handle external request coming from external source where the request has a parameters where it is separated by |.

我正在使用 Tomcat 8。在一种情况下,我需要处理来自外部源的外部请求,其中请求有一个参数,它由|.

Request is looks like this:

请求是这样的:

http://localhost:8080/app/handleResponse?msg=name|id|

http://localhost:8080/app/handleResponse?msg=name|id|

In this case I am getting following error.

在这种情况下,我收到以下错误。

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.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:467)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:667)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:789)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

EDIT 1

编辑 1

It works with Apache Tomcat 8.0.30 but not with Tomcat 8.5

它适用于 Apache Tomcat 8.0.30 但不适用于 Tomcat 8.5

采纳答案by Piotr Lewandowski

This behavior is introduced in all major Tomcat releases:

所有主要的 Tomcat 版本都引入了此行为:

  • Tomcat 7.0.73, 8.0.39, 8.5.7
  • Tomcat的7.0.738.0.398.5.7

To fix, do one of the following:

要修复,请执行以下操作之一:

  • set relaxedQueryCharsto allow this character (recommended, see Lincoln's answer)
  • set requestTargetAllowoption (deprecated in Tomcat 8.5) (see Jérémie's answer).
  • you can downgrade to one of older versions (not recommended - security)


Based on changelog, those changes could affect this behavior:

根据changelog,这些更改可能会影响此行为:

Tomcat 8.5.3:

雄猫 8.5.3:

Ensure that requests with HTTP method names that are not tokens (as required by RFC 7231) are rejected with a 400 response

确保 HTTP 方法名称不是令牌的请求(根据 RFC 7231 的要求)被拒绝并返回 400 响应

Tomcat 8.5.7:

雄猫 8.5.7:

Add additional checks for valid characters to the HTTP request line parsing so invalid request lines are rejected sooner.

向 HTTP 请求行解析添加对有效字符的额外检查,以便更快地拒绝无效请求行。



The best option (following the standard)- you want to encode your URL on client:

最好的选择(遵循标准)- 你想在客户端对你的 URL 进行编码:

encodeURI("http://localhost:8080/app/handleResponse?msg=name|id|")
> http://localhost:8080/app/handleResponse?msg=name%7Cid%7C

or just query string:

或者只是查询字符串:

encodeURIComponent("msg=name|id|")
> msg%3Dname%7Cid%7C

It will secure you from other problematic characters (list of invalid URI characters).

它将保护您免受其他有问题的字符(无效 URI 字符列表)的影响。

回答by Dan Armstrong

Escape it. The pipe symbol is one that has been handled differently over time and between browsers. For instance, Chrome and Firefox convert a URL with pipe differently when copy/paste them. However, the most compatible, and necessary with Tomcat 8.5 it seems, is to escape it:

逃离它。管道符号是一种随着时间的推移和浏览器之间的不同处理方式。例如,Chrome 和 Firefox 在复制/粘贴 URL 时以不同的方式转换带有管道的 URL。然而,似乎与 Tomcat 8.5 最兼容和最必要的是逃避它:

http://localhost:8080/app/handleResponse?msg=name%7Cid%7C

http://localhost:8080/app/handleResponse?msg=name%7Cid%7C

回答by Jérémie Lesage

Since Tomcat 7.0.76, 8.0.42, 8.5.12you can define property requestTargetAllowto allow forbiden characters.

从 Tomcat 7.0.768.0.428.5.12开始,您可以定义属性requestTargetAllow以允许禁止字符。

Add this line in your catalina.properties

将此行添加到您的 catalina.properties

tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}

回答by Omid Nazerizadeh

The URI is encoded as UTF-8, but Tomcat is decoding them as ISO-8859-1. You need to edit the connector settings in the server.xml and add the URIEncoding="UTF-8" attribute.

URI 编码为 UTF-8,但 Tomcat 将它们解码为 ISO-8859-1。您需要编辑 server.xml 中的连接器设置并添加 URIEncoding="UTF-8" 属性。

or edit this parameter on your application.properties

或在您的 application.properties 上编辑此参数

server.tomcat.uri-encoding=utf-8

server.tomcat.uri-encoding=utf-8

回答by Lincoln

The parameter tomcat.util.http.parser.HttpParser.requestTargetAllowis deprecated since Tomcat 8.5: tomcat official doc.

该参数tomcat.util.http.parser.HttpParser.requestTargetAllow自 Tomcat 8.5 起已弃用:tomcat 官方文档

You can use relaxedQueryChars / relaxedPathCharsin the connectors definition to allow these chars: tomcat official doc.

您可以relaxedQueryChars / relaxedPathChars在连接器定义中使用以允许这些字符:tomcat 官方文档

回答by rama krishna chinna reddy

Issue: Tomcat (7.0.88) is throwing below exception which leads to 400 – Bad Request.

问题:Tomcat (7.0.88) 抛出以下异常,导致 400 – Bad Request。

java.lang.IllegalArgumentException: Invalid character found in the request target. 
The valid characters are defined in RFC 7230 and RFC 3986.

This issue is occurring most of the tomcat versions from 7.0.88 onwards.

从 7.0.88 开始,大多数 tomcat 版本都会出现此问题。

Solution: (Suggested by Apache team):

解决方案:(Apache 团队推荐):

Tomcat increased their security and no longer allows raw square brackets in the query string. In the request we have [,] (Square brackets) so the request is not processed by the server.

Tomcat 提高了它们的安全性,不再允许在查询字符串中使用原始方括号。在请求中,我们有 [,](方括号),因此服务器不会处理请求。

Add relaxedQueryCharsattribute under tag under server.xml (%TOMCAT_HOME%/conf):

relaxedQueryChars在 server.xml (%TOMCAT_HOME%/conf) 下的标签下添加属性:

<Connector port="80" 
           protocol="HTTP/1.1"
           maxThreads="150"
           connectionTimeout="20000"
           redirectPort="443"
           compression="on"
           compressionMinSize="2048"
           noCompressionUserAgents="gozilla, traviata"
           compressableMimeType="text/html,text/xml"
                                     relaxedQueryChars="[,]"
             />

If application needs more special characters that are not supported by tomcat by default, then add those special characters in relaxedQueryCharsattribute, comma-separated as above.

如果应用程序需要更多tomcat默认不支持的特殊字符,则在relaxedQueryChars属性中添加这些特殊字符,如上逗号分隔。