zoukankan      html  css  js  c++  java
  • 解决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

  • 相关阅读:
    Redis宣言
    软件工程
    分布式编程
    编程泛型
    tcp/ip高效编程总结
    IP协议详解
    gevent程序员指南
    网站架构
    这些话,是乔布斯给世间留下的真正伟大礼物
    Flink/Spark 如何实现动态更新作业配置
  • 原文地址:https://www.cnblogs.com/qiujz/p/13679539.html
Copyright © 2011-2022 走看看