解決SpringBoot 報錯 Error parsing HTTP request header


一、SpringBoot 項目,使用自帶tomcat

1、問題描述

接收 application/x-www-form-urlencoded Post

參數 data={"data":[{"id_dev":"CSB000001","state":"online","on_ts":1526004805}, {"id_dev":"CSB000001","state":"online","on_ts":1526004805,"off_ts":1526004810}]}

報錯:

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

 

 

2、原因分析

導致上述問題是因為tomcat自8.5.x系列的:8.5.12 之后版本、8.0.x系列的:8.0.42 之后版本、7.0.x系列的:7.0.76 之后版本對URL參數做了比較規范的限制,必須遵循RFC 7230 and RFC 3986規范,對於非保留字字符(json格式的請求參數)必須做轉義操作,否則會拋出Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986錯誤信息。就是嚴格按照 RFC 3986規范進行訪問解析,而 RFC 3986規范定義了Url中只允許包含英文字母(a-zA-Z)、數字(0-9)、-_.~4個特殊字符以及所有保留字符(RFC3986中指定了以下字符為保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。

 

3、解決方法

1)降低tomcat版本,不推薦

2)在SpringBoot工程中增加一個tomcat 配置,配置文件代碼如下

@Configuration
public class TomcatConfigurer {

    @Bean
    public TomcatServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.addConnectorCustomizers((Connector connector) -> {
            connector.setProperty("relaxedPathChars", "\"<>[\\]^`{|}");
            connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}");
        });
        return factory;
    }

}

 

參考:https://www.jianshu.com/p/75eec24321e7

 

二、SpringBoot 項目,部署獨立tomcat

1、同樣問題

2、解決方法

參考:https://developer.aliyun.com/article/641394

在conf/catalina.properties中最后添加2行:

tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

該方式,在所有Tomcat版本均適用。

解析:在執行請求時,碰到該沒問題的,大多是在URL中傳輸Json等。尤其是用瀏覽器地址輸入的URL死活不能包含有任何特殊字符。否則會返回400 狀態碼。

首先:不推薦降低tomcat版本,這等於掩耳盜鈴,絕對得不償失。
Tomcat在 7.0.73, 8.0.39, 8.5.7 版本后,在http解析時做了嚴格限制。
RFC3986文檔規定,請求的Url中只允許包含英文字母(a-zA-Z)、數字(0-9)、-_.~4個特殊字符以及所有保留字符。

如果要使用這些特殊字符,並不是絕對不可以。Tomcat做了限制的同時,也提供了相關配置。給出的解決方案第一行requestTargetAllow,指定了允許的特殊字符,在等號后面配|{}就行了。

如果你需要使用這三個字符,配置到此就OK了。重啟tomcat,rebuild工程再啟動,就能正常使用了。

不幸的是, requestTargetAllow 只能配置|、{、} 允許這三個字符,對於其他的(例如" < > [ \ ] ^ ` { | } .),在請求時,仍然攔截,如果使用了|{}之外的其他字符那怎么辦呢?那就還需要如下配置。

在conf/server.xml中的<Connector>節點中,添加2個屬性:

relaxedPathChars="|{}[],"
relaxedQueryChars="|{}[],"

這2個屬性,可以接收任意特殊字符的組合,根據需要可以自行增減。

參考文檔:https://tomcat.apache.org/tomcat-8.5-doc/config/systemprops.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM