tomcat 8.5--RFC7230 RFC3986 -- org.apache.coyote.http11.Http11Processor.service 解析 HTTP 请求 header 错误

报错报文:

19-Dec-2021 23:55:56.790 信息 [http-nio-8080-exec-8] org.apache.coyote.http11.Http11Processor.service 解析 HTTP 请求 header 错误
 Note: further occurrences of HTTP request 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.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:483)
		at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:502)
		at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
		at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:818)
		at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1623)
		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:748)

请求URL:

  • http://localhost:8080/app-api/exportHistory/getTxt?Auth=bdffdf6da5ff4d65a62d983285c0fb66&id=[20211215114722316533282]

请求方式:

  • GET

可能原因:

原因解决检查
请求header参数过长修改maxHttpHeaderSize字段排除
不能解析header中的汉字增加URIEncoding=“UTF-8”排除
浏览器强转成https协议清除浏览器缓存排除
springboot内置tomcat版本与部署时tomcat版本冲突去除tomcat启动依赖排除
header含不可解析的字符符号properties及xml中修改配置确认

  • 请求header参数过长,缓冲区大小不够

    Tomcat的header缓冲区大小不够,需要在server.xml中增加maxHttpHeaderSize字段,具体设置在service.xml文件中设置maxHttpHeaderSize=“你想要的大小”

<Connector port="8080" protocol="HTTP/1.1"
			   maxHttpHeaderSize="10240000"
               connectionTimeout="20000" 
               redirectPort="8443"/>

  • 不能解析header中的汉字

    需要在server.xml中增加 URIEncoding="UTF-8"配置

<Connector port="8080" protocol="HTTP/1.1"
			   maxHttpHeaderSize="10240000"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8"/>

  • 浏览器强转成https协议

    chrome浏览器清空缓存
    在这里插入图片描述

  • springboot内置tomcat版本与部署时tomcat版本冲突

    如果要将最终的打包形式改为war的话,还需要对pom.xml文件进行修改,因为spring-boot-starter-web中包含内嵌的tomcat容器,所以直接部署在外部容器会冲突报错。解决方案如下:

    1. 去除内嵌的spring-boot-starter-tomcat依赖
    2. 增加tomcat-embed-jasper依赖(scope必须是provided)
      Markdown将文本转换为 HTML。

    因为SpringBootServletInitializer需要依赖
    javax.servlet,而tomcat-embed-jasper下面的tomcat-embed-core中就有这个javax.servlet,如果没用provided,最终打好的war里面会有servlet-api这个jar,这样就会跟tomcat本身的冲突了

pom 依赖修改:

	<dependency>
			<groupId>net.riking</groupId>
			<artifactId>web-html-core</artifactId>
			<version>2.4.0</version>
			<exclusions>
				<exclusion>
					<artifactId>spring-boot-starter-tomcat</artifactId>
						<groupId>org.springframework.boot</groupId>
				</exclusion>
			</exclusions>
	</dependency>
	<!--添加provided -->
	<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
			<scope>provided</scope>
	</dependency>

  • header含不可解析的字符符号
  1. 在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 只能配置|、{、} 允许这三个字符,对于其他的(例如" < > [ \ ] ^ ` { | } .),在请求时,仍然拦截,如果使用了|{}之外的其他字符那怎么办呢?那就还需要如下配置:

  2. 在conf/server.xml中的节点中,添加2个属性:

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

    这2个属性,可以接收任意特殊字符的组合,根据需要可以自行增减。

    server.xml:

    <Connector port="8080" protocol="HTTP/1.1" maxHttpHeaderSize="10240000"
               connectionTimeout="20000" 
               redirectPort="8443" URIEncoding="UTF-8"
    		   relaxedPathChars="|{}[]," relaxedQueryChars="|{}[],"/>
    

    catalina.properties:

    tomcat.util.buf.StringCache.byte.enabled=true
    #tomcat.util.buf.StringCache.char.enabled=true
    #tomcat.util.buf.StringCache.trainThreshold=500000
    #tomcat.util.buf.StringCache.cacheSize=5000
    #This system property is deprecated. Use the relaxedPathChars relaxedQueryChars
    #attributes of the Connector instead. These attributes permit a wider range of
    #characters to be configured as valid.
    #Allow for changes to HTTP request validation
    #WARNING: Using this option may expose the server to CVE-2016-6816
    #tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}[]
    #tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}?&
    tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
    org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值