tomcat运行项目java.lang.IllegalArgumentException

tomcat运行项目java.lang.IllegalArgumentException

  1. 错误类型java.lang.IllegalArgumentException
  2. 错误原因:HTTP请求头中的某一行不符合 RFC 7230 标准。
  3. 具体问题行
    深色版本
    cookie:ifvip=false; preUrl=http%3A%2F%2F182.106.142.58%3A8092%2FEPG%2Fstart_back.html; 0xd50x8b0x8b0x01lastId=ljdg
    • 该行中包含非法字符(如 0xd50x8b0x8b0x01),导致解析失败。
  4. 影响:请求被拒绝,可能导致客户端无法正常访问服务。

问题原因分析

  1. 非法字符

    • HTTP Header 的值必须符合 RFC 7230 的语法规则。Header 值只能包含可见的 ASCII 字符(32-126),以及空格和制表符。
    • 日志中的 0xd50x8b0x8b0x01 是非 ASCII 字符,违反了标准。
  2. Cookie 格式问题

    • Cookie 的值也可能包含非法字符或未正确编码。
    • 例如,preUrl 的值虽然进行了 URL 编码,但可能在某些情况下被篡改或损坏。
  3. 客户端问题

    • 可能是客户端(浏览器、爬虫或其他工具)发送了不规范的请求头。
    • 也可能是中间代理服务器对请求头进行了修改。
  4. 服务器配置问题

    • Tomcat 默认会严格验证 HTTP 请求头是否符合 RFC 7230。
    • 如果请求头中存在非法字符,Tomcat 会直接拒绝请求。

推荐解决方案

1. 修复客户端问题

这是最根本的解决方法。检查并修复客户端代码,确保发送的 Cookie 值符合标准:

  • 避免非法字符
    • 确保 Cookie 值只包含合法的 ASCII 字符。
    • 如果需要传递特殊数据(如二进制数据),可以使用 Base64 编码或其他合法编码方式。
  • 示例修复
    • 将 0xd50x8b0x8b0x01 替换为合法的字符串,例如 Base64 编码后的值:
      javascript

      深色版本
      // 示例:将二进制数据转换为 Base64
      const binaryData = new Uint8Array([0xd5, 0x8b, 0x8b, 0x01]);
      const base64String = btoa(String.fromCharCode(...binaryData));
      console.log(base64String); // 输出类似 "1YuL"
    • 在客户端设置 Cookie 时,使用合法的值:
      javascript

      深色版本
      document.cookie = "lastId=" + encodeURIComponent(base64String);

2. 配置 Tomcat 放宽限制

如果无法控制客户端行为,可以通过以下方法放宽 Tomcat 对非法字符的限制:

  • 启用 relaxedHttpHeaders 参数
    • Tomcat 提供了一个专门用于放宽 HTTP Header 验证的参数:relaxedHttpHeaders
    • 在 server.xml 文件中添加以下配置:
      xml

      深色版本
      <Connector port="8080" protocol="HTTP/1.1"
                 connectionTimeout="20000"
                 redirectPort="8443"
                 relaxedHttpHeaders="true" />
    • 作用:启用后,Tomcat 将忽略 HTTP Header 中的非法字符,不再拒绝请求。
    • 注意:此参数可能会引入安全风险,请谨慎使用。

3. 使用反向代理过滤非法请求

如果无法修改客户端或服务器配置,可以使用反向代理(如 Nginx 或 Apache)对非法请求进行过滤:

  • Nginx 配置示例
    • 添加规则拦截包含非法字符的请求:
      nginx

      深色版本
      if ($http_cookie ~* "0xd50x8b0x8b0x01") {
          return 403;
      }
    • 或者直接移除非法字符:
      nginx

      深色版本
      proxy_set_header Cookie $http_cookie;
      set $clean_cookie $http_cookie;
      if ($clean_cookie ~* "(0xd50x8b0x8b0x01)") {
          set $clean_cookie "";
      }
      proxy_set_header Cookie $clean_cookie;

4. 启用 DEBUG 日志进一步排查

  • 如果问题仍然存在,可以通过启用 DEBUG 日志来捕获更多细节:
    • 修改 logging.properties 文件,将日志级别调整为 DEBUG:
      properties

      深色版本
      org.apache.coyote.http11.level = FINE
    • 查看日志以定位其他可能的问题。

总结

针对您的报错,最合适的解决方案如下:

  1. 优先修复客户端:确保 Cookie 值符合标准,避免非法字符。
  2. 启用 relaxedHttpHeaders:如果无法控制客户端,可以在 Tomcat 中启用该参数以放宽限制。
  3. 使用反向代理过滤:如果不能修改服务器配置,可以通过 Nginx 或其他代理工具拦截或清理非法请求。

如果您确认无法修复客户端问题,建议在 Tomcat 中启用 relaxedHttpHeaders 参数:

xml

深色版本
<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           relaxedHttpHeaders="true" />

这样可以快速解决问题,但请务必加强日志监控,防止潜在的安全风险。

报错示例

08-Apr-2025 10:01:33.873 INFO [http-nio-8080-exec-67] org.apache.coyote.http11.Http11Processor.service Error parsing HTTP request header
 Note: further occurrences of HTTP request parsing errors will be logged at DEBUG level.
	java.lang.IllegalArgumentException: The HTTP header line [cookie:ifvip=false; preUrl=http%3A%2F%2F182.106.142.58%3A8092%2FEPG%2Fstart_back.html; 0xd50x8b0x8b0x01lastId=ljdg] does not conform to RFC 7230. The request has been rejected.
		at org.apache.coyote.http11.Http11InputBuffer.skipLine(Http11InputBuffer.java:1088)
		at org.apache.coyote.http11.Http11InputBuffer.parseHeader(Http11InputBuffer.java:991)
		at org.apache.coyote.http11.Http11InputBuffer.parseHeaders(Http11InputBuffer.java:593)
		at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:292)
		at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
		at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:937)
		at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
		at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
		at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
		at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
		at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
		at java.lang.Thread.run(Thread.java:750)

 

温馨提示: 本文最后更新于2025-04-08 11:14:54,某些文章具有时效性,若有错误或已失效,请在下方 留言
© 版权声明
THE END
喜欢就支持一下吧
点赞8赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容