【问题标题】:Analyze HTTP-header before body is transmitted in apache tomcat在apache tomcat中传输body之前分析HTTP-header
【发布时间】:2015-11-23 05:31:02
【问题描述】:

是否可以在传输正文之前分析 HTTP-(POST)-Request 的标头?

如果客户端尝试通过 HTTP-POST 上传的文件太大而无法由服务器处理,我想向客户端发送错误消息。为了改善用户体验(和安全流量),我希望在他上传整个文件之前通过分析 content-length-header 来发送错误响应。

我想过像这样实现一个javax.servlet.filter

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
   if (request.getContentLength() > MAX_DOCUMENT_SIZE) {
          ObjectMapper jsonMapper = new ObjectMapper();
          Map<String, Object> jsonMap = new HashMap<>();
          jsonMap.put("messageCode", 1234);
          jsonMap.put("messageDescription", "error message");

          response.reset();
          response.setStatus(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);
          jsonMapper.writeValue(response.getWriter(), jsonMap);
          return;
       }
    }

    chain.doFilter(request, response);
}

但我不确定 tomcat 是否能够在传输漏洞请求之前分析标头。

编辑:卷曲

> CONNECT myserver.com:443 HTTP/1.1
> Host: myserver.com:443
> Proxy-Connection: Keep-Alive
> user-agent: my-test
>
< HTTP/1.0 200 Connection established
<
* Proxy replied OK to CONNECT request
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
* Server certificate: myserver.com
> POST /uploads HTTP/1.1
> Host: myserver
> Accept: */*
> user-agent: my-test
> Content-Length: 51951089
> Content-Type: application/x-www-form-urlencoded
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
< HTTP/1.1 404 Not Found
< Date: Tue, 01 Sep 2015 09:49:01 GMT
* Server WEB is not blacklisted
< Server: WEB
< X-XSS-Protection: 1; mode=block
< X-DNS-Prefetch-Control: off
< X-Content-Type-Options: nosniff
< X-Frame-Options: sameorigin
< Strict-Transport-Security: max-age=15768000 ; includeSubDomains
< Cache-Control: private
< Expires: Thu, 01 Jan 1970 01:00:00 GMT
< Content-Type: text/plain;charset=utf-8
< Content-Length: 0
< Vary: Accept-Encoding
< Connection: close
<

【问题讨论】:

  • 你一定要试试
  • 是的,它应该可以工作。记得设置Connection: close作为响应。

标签: java tomcat servlets servlet-filters


【解决方案1】:

是的,这是可能的,我实际上是在 Tomcat 6 中这样做的。我没有尝试过 Filter,而是 Tomcat 特定的 Valve。如果此解决方案可用作 Vavle,请随时将其移植到 Filter

让 Tomcat 调用您的阀门。您的演示代码看起来就像它应该看起来的样子,请确保您发送400(或更好的413)以表明输入不合适。您也可以关闭连接。现在到了非常重要的部分:要完成这项工作,客户端必须向POSTPUT 请求,另外客户端必须 发送Expect: 100-continue 标头。服务器将分析所有传入的标头并向客户端发出请求不合适的信号。这样,客户端将在发送其有效负载之前收到400(或更好的413)(请求将被中止)。您将只交换标题并节省资源。但请注意,您的客户必须正确实施Expect: 100-continue。 .NET 客户端没有。我强烈建议您使用curl 验证您的阀门是否正常工作,因为它可以正确完成工作。如果您想查看此接线头,没问题。

警告:如果客户端以块的形式流式传输其有效负载,您的内容长度限制将不起作用。

【讨论】:

  • 我工作了,但是我遇到了一个奇怪的现象:当通过curl发送一个大文件时,它被拒绝了413虽然内容长度标题没有超过我定义的限制。
  • 请运行 curl--verbose 并显示日志。我还建议在您的阀门中添加一些log.debug(),带有远程地址和端口,以及标题。这将有助于找到您的问题。
  • 好的,我发现内容长度问题是某种 curl 错误。但是,仍然有一些奇怪的行为:结果不是预期的 413,而是 404。Tomcat 的 access.log 显示,GET /apache-error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var HTTP/1.1" 404 被调用。有什么想法吗?
  • @woezelmann 你能分享access.log 部分和curl 详细日志吗?
  • 我编辑了我的帖子。 access.log 只显示上面评论中的那一行。
【解决方案2】:

您编写一个 java 脚本函数并将其绑定到 input type="file" files[0].size 上的 onchange 事件,将给出文件的大小。因此您可以检查它是否可上传。

谢谢

【讨论】:

  • 抱歉,我忘了说它是一个 REST-API。我无法控制客户端代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
  • 2018-12-06
  • 1970-01-01
  • 1970-01-01
  • 2014-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多