Tomcat升级后请求头中host未指定端口请求返回400解决方法

公司项目由于业务需要,将tomcat6升级为tomcat9后,记一次踩坑过程。

问题描述:

服务启动后,使用postman等工具发送POST请求可正常响应,下级服务器拼接请求发送后返回400错误码。


解决方案:

 

进入Tomcat/conf文件夹,修改server.xml内Connector标签,添加allowHostHeaderMismatch="True",即可解决。

<Connector port="80" allowHostHeaderMismatch="true"/>


排查过程:

首先排除了底层协议拼接错误,因为在原有版本的服务器上是可以正常通讯,只在新版tomcat上返回400,而使用postman又可以正常通讯,所以我认为是tomcat9中对请求头的解析进行了修改。

b'''POST http://127.0.0.1:80/***/*** HTTP/1.1
Accept: image/gif, */*
Referer: http://127.0.0.1/index.html
Accept-Language: zh-cn
Content-Type: multipart/form-data
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Host: 127.0.0.1
Content-Length: 3
Proxy-Connection: Keep-Alive
Pragma: no-cache

123'''

以上是原有请求头。后面经过逐步对比,发现是host未指定端口,在host后面指定端口,就可以正常请求,但是因为业务特殊,下级服务器更换程序成本较高,所以理想情况下是更改tomcat配置。


排查过程:

首先是下载了tomcat9的源码,按照网上的配置进行启动后,一步一步debug,发现在

org.apache.coyote.http11.Http11Processor

类中有如下处理:

if (http11) {
    // Missing host header is illegal but handled above
    if (hostValueMB != null) {
        // Any host in the request line must be consistent with
        // the Host header
        if (!hostValueMB.getByteChunk().equals(
                uriB, uriBCStart + pos, slashPos - pos)) {
            if (protocol.getAllowHostHeaderMismatch()) {
                // The requirements of RFC 2616 are being
                // applied. If the host header and the request
                // line do not agree, the request line takes
                // precedence
                hostValueMB = headers.setValue("host");
                hostValueMB.setBytes(uriB, uriBCStart + pos, slashPos - pos);
            } else {
                // The requirements of RFC 7230 are being
                // applied. If the host header and the request
                // line do not agree, trigger a 400 response.
                badRequest("http11processor.request.inconsistentHosts");
            }
        }
    }
} 

getAllowHostHeaderMismatch()方法就是是否检查请求头。

为了印证猜想,在Tomcat的conf文件夹内,添加了allowHostHeaderMismatch

后来在查看tomcat更新日志后发现有提到这个更新说明。

  • Add: Enable strict validation of the provided host name and port for all connectors. Requests with invalid host names and/or ports will be rejected with a 400 response. (markt)
  • Fix: Implement the requirements of RFC 7230 (and RFC 2616) that HTTP/1.1 requests must include a Host header and any request that does not must be rejected with a 400 response. (markt)
  • Fix: Implement the requirements of RFC 7230 that any HTTP/1.1 request that specifies a host in the request line, must specify the same host in the Host header and that any such request that does not, must be rejected with a 400 response. This check is optional and disabled by default. It may be enabled with the allowHostHeaderMismatch attribute of the Connector. (markt)
  • Fix: Implement the requirements of RFC 7230 that any HTTP/1.1 request that contains multiple Host headers is rejected with a 400 response. (markt)
  • Add: 62273: Implement configuration options to work-around specification non-compliant user agents (including all the major browsers) that do not correctly %nn encode URI paths and query strings as required by RFC 7230 and RFC 3986. (markt)

总结:

类似问题,一定要先去官方的更新日志找找。如果一开始先去看了日志,省去不少功夫!!!血与泪的教训!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值