1. 程式人生 > >Invalid character found in the request target. The valid characters are defined in RFC 3986

Invalid character found in the request target. The valid characters are defined in RFC 3986

問題描述

請求引數含有特殊字元時後臺報這個錯誤:

資訊: Error parsing HTTP request header
 Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
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.InternalAprInputBuffer.parseRequestLine(InternalAprInputBuffer.java:235)
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.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2517)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2506)
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)

查了資料原因是 Tomcat在 7.0.73, 8.0.39, 8.5.7 版本後,添加了對於http頭的驗證。

安全定義

安全字元

  • 英文字母 : a-zA-Z
  • 數字 : 0-9
  • 特殊字元 : -_.~
  • 保留字元 : !*'();:@&=+$,/?#[]

不安全字元

  • 空格 : Url在傳輸的過程,或者使用者在排版的過程,或者文字處理程式在處理Url的過程,都有可能引入無關緊要的空格,或者將那些有意義的空格給去掉
  • "(雙引號) 以及 <>(尖括號) : 引號和尖括號通常用於在普通文字中起到分隔Url的作用
  • # : 通常用於表示書籤或者錨點
  • % : 百分號本身用作 對 不安全字元進行轉碼 的特殊字元 , 所以必須要轉碼
  • {}|^[]`~ : 某一些閘道器或者傳輸代理會篡改這些字元
  • 中文 : 中文作為一個特殊編碼 , 對tomcat來說 ,也是不識別的.所以必須轉碼

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;
            }
  • 鍵盤上那些控制鍵:(<32或者=127)
  • 非英文字元(>127)
  • 空格(32)
  • 雙引號(34)
  • #(35)
  • <(60)
  • >(62)
  • 反斜槓(92)
  • ^(94)
  • ` : TAB上面那個鍵(96)
  • {(123)
  • }(124)
  • |(125)

三種解決方案

方案一:

更換低版本的Tomcat來規避這種問題。

使用 7.0.73 之前的版本

方案二:

在conf/catalina.properties中最後新增一行:

org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

或者,把要安全使用的放到配置後面

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

方案三:

  • get 請求,引數轉碼
  • post請求,放到body中

引數轉碼

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

個人問題

升級Tomcat到8.5 後 , 出現這個問題. 經查證, 是Request url 中 , 出現了中文.

將引數encode後,問題解決!

參考

[異常:Invalid character found in the request target. The valid characters are defined in RFC 3986 : 作者:碼上筆記]https://blog.csdn.net/ak57193856/article/details/77892749