Tomcat Get请求的巨坑
轉載自 ?Java程序員注意:Tomcat Get請求的巨坑!
Tomcat8.5,當Get請求中包含了未經編碼的中文字符時,會報以下錯誤,請求未到應用程序在Tomcat層就被攔截了。
Tomcat報錯:
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
返回400錯誤:
Transfer-Encoding--->[chunked]?
null--->[HTTP/1.1 400 Bad Request]?
Server--->[Apache-Coyote/1.1] C
onnection--->[close]?
Date--->[Wed, 07 Feb 2018 03:19:04 GMT]
根據錯誤找到了Tomcat最新的源碼:
org/apache/coyote/http11/LocalStrings.properties
iib.invalidRequestTarget=Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986org/apache/coyote/http11/Http11InputBuffer.java
boolean parseRequestLine(boolean keptAlive) throws IOException {...} else if (HttpParser.isNotRequestTarget(chr)) {throw new IllegalArgumentException(sm.getString("iib.invalidRequestTarget"));}...}java/org/apache/tomcat/util/http/parser/HttpParser.java
public static boolean isNotRequestTarget(int c) {// Fast for valid request target characters, slower for some incorrect// onestry {return IS_NOT_REQUEST_TARGET[c];} catch (ArrayIndexOutOfBoundsException ex) {return true;} }查源碼發現在Tomcat7.0.73就已經添加了RFC 3986這個規范。
RFC 3986文檔對Url的編解碼問題做出了詳細的建議,指出了哪些字符需要被編碼才不會引起Url語義的轉變,以及對為什么這些字符需要編碼做出了相應的解釋。
RFC 3986文檔規定,Url中只允許包含英文字母(a-zA-Z)、數字(0-9)、-_.~4個特殊字符以及所有保留字符(! * ' ( ) ; : @ & = + $ , / ? # [ ])。
還有一些字符當直接放在Url中的時候,可能會引起解析程序的歧義,這些字符被視為不安全字符。
-
空格:Url在傳輸的過程,或者用戶在排版的過程,或者文本處理程序在處理Url的過程,都有可能引入無關緊要的空格,或者將那些有意義的空格給去掉。
-
引號以及<>:引號和尖括號通常用于在普通文本中起到分隔Url的作用
-
#:通常用于表示書簽或者錨點
-
%:百分號本身用作對不安全字符進行編碼時使用的特殊字符,因此本身需要編碼
-
{}|\^[]`~:某一些網關或者傳輸代理會篡改這些字符
對于此問題,有以下幾種解決方案。
1、切換版本到7.0.73以下,這個不實際。
2、修改Tomcat源碼,這個也不實際。
3、前端請求對URL編碼。
4、修改Get方法為Post方法。
5、因{}是不安全字符,默認被 tomcat攔截。如果需要在URL中傳輸json數據,在catalina.properties中添加支持。
tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
總結
如果Get請求在合作方,而合作方不愿意修改代碼,那1、2種方法可以嘗試。如果Get請求在自己,可以嘗試3、4種方法。僅需要在URL上傳輸json數據,使用第5種方法即可。
總結
以上是生活随笔為你收集整理的Tomcat Get请求的巨坑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蒜汁怎么调好吃 蒜汁如何调好吃
- 下一篇: 斗罗大陆唐昊结局 结局内容介绍