【问题标题】:Duplicate headers in response / browsers failing intermittently响应中的重复标头/浏览器间歇性失败
【发布时间】:2016-04-19 13:09:14
【问题描述】:

这个问题似乎是几天前开始的,没有任何代码更改,我的本地 tomcat 服务器会停止响应。

我的主要过滤器断点没有被命中,只有一些资源被加载。

那些确实失败的,似乎有重复的响应头:

Accept-Ranges:bytes
Accept-Ranges:bytes
Content-Disposition:inline;filename="online-framework.js"
Content-Disposition:inline;filename="online-framework.js"
Content-Encoding:gzip
Content-Encoding:gzip
Content-Range:bytes 0-42062/42063
Content-Range:bytes 0-42062/42063
Content-Type:application/javascript
Content-Type:application/javascript
Date:Tue, 19 Apr 2016 13:01:18 GMT
ETag:online-framework.js_42063_1461060446000
ETag:online-framework.js_42063_1461060446000
Expires:Tue, 26 Apr 2016 13:01:19 GMT
Expires:Tue, 26 Apr 2016 13:01:19 GMT
Last-Modified:Tue, 19 Apr 2016 10:07:26 GMT
Last-Modified:Tue, 19 Apr 2016 10:07:26 GMT
Server:Apache-Coyote/1.1
Server:Apache-Coyote/1.1
Transfer-Encoding:chunked
Transfer-Encoding:chunked
Vary:Accept-Encoding
Vary:Accept-Encoding

chrome 因错误而停止:Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING,这是有道理的。

tomcat 连接器没有被修改,并且包含一个 gzip 响应。我尝试了什么:

  • 线程转储 - 没有明显的阻塞代码
  • wireshark - 不知道它是否足够好,无法找出问题所在
  • 已禁用防病毒软件
  • 没有代理运行

页面似乎永远加载。这是踢球者,它是随机发生的,它会在一小时内开始工作,但下一小时不会。

我唯一能想到的是某些领域的事情可能已经改变,没有运行 Windows 更新,并且 3 或 4 台其他电脑做同样的事情,而其他 2 台没有(相同的版本)

我不知道下一步该往哪里看?有什么想法吗?

【问题讨论】:

    标签: java tomcat gzip content-encoding http-content-range


    【解决方案1】:

    好的,伙计们,在这里回答我自己的问题,但我已经找到了解决方案。

    我使用的是由@BalusC 编写的自定义file servlet;问题就在其中

    这是我的发现:

    • 同时使用Content-Encoding: gzipContent-Range 时会出现此问题
    • 产生的错误是:ERR_INCOMPLETE_CHUNKED_ENCODING
    • 我首先决定禁用这个过滤器,让 tomcat 的DefaultServlet 处理它...问题消失了
    • 作为一名程序员,我必须知道为什么。
    • 我还是没有确切的原因,但我认为是因为gzip不能用长度准确表示

    Content-Range 的规范还指出:

    Content-Range 实体标头与 部分实体主体 一起发送,以指定应在完整实体主体中应用部分主体的位置。范围单位在 3.12 节中定义。

    在代码中,即使是完整的响应,它也会被发送:

    if (ranges.isEmpty() || ranges.get(0) == full) {
        // Return full file.
        Range r = full;
        response.setContentType(contentType);
        response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);
    
        if (content) {
            // .....
    

    我删除了那条线,一切又开始工作了!我真的很希望有人能参与进来,并可能给出更好的解释。

    这是失败文件的chrome://net-internals/ 输出:

    t = 3740 [st = 38] -HTTP_STREAM_REQUEST t= 3740 [st= 38] +HTTP_TRANSACTION_SEND_REQUEST [dt=0] t = 3740 [st = 38] HTTP_TRANSACTION_SEND_REQUEST_HEADERS --> GET /Core/resources/scripts/scriptaculous/dragdrop.js?t=1461139610 HTTP/1.1 主机:本地主机:8080 连接:保持活动 Pragma:无缓存 缓存控制:无缓存 接受: */* 用户代理:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36 DNT: 1 参考:http://localhost:8080/Core/Dashboard?componentID=VCmq3c 接受编码:gzip、deflate、sdch 接受语言:en-US,en;q=0.8,af;q=0.6 Cookie:[306 字节被剥离] t = 3740 [st = 38] -HTTP_TRANSACTION_SEND_REQUEST t= 3740 [st= 38] +HTTP_TRANSACTION_READ_HEADERS [dt=4] t= 3740 [st= 38] HTTP_STREAM_PARSER_READ_HEADERS [dt=4] t = 3744 [st = 42] HTTP_TRANSACTION_READ_RESPONSE_HEADERS --> HTTP/1.1 200 OK 服务器:Apache-Coyote/1.1 内容处置:内联;文件名="dragdrop.js" 接受范围:字节 ETag:dragdrop.js_19250_1461136271305 最后修改时间:2016 年 4 月 20 日星期三 07:11:11 GMT 过期:2016 年 4 月 27 日星期三 08:06:51 GMT 内容范围:字节 0-19249/19250 内容类型:应用程序/javascript 传输编码:分块 变化:接受编码 日期:格林威治标准时间 2016 年 4 月 20 日星期三 08:06:50 t = 3744 [st = 42] -HTTP_TRANSACTION_READ_HEADERS t= 3744 [st= 42] HTTP_CACHE_WRITE_INFO [dt=56] t= 3800 [st= 98] HTTP_CACHE_WRITE_DATA [dt=0] t= 3800 [st= 98] HTTP_CACHE_WRITE_INFO [dt=1] t = 3801 [st = 99] URL_REQUEST_DELEGATE [dt = 0] t = 3801 [st = 99] -URL_REQUEST_START_JOB t = 3801 [st = 99] URL_REQUEST_DELEGATE [dt = 0] t= 3801 [st= 99] HTTP_TRANSACTION_READ_BODY [dt=0] t= 3801 [st= 99] HTTP_CACHE_WRITE_DATA [dt=1] t = 3802 [st = 100] URL_REQUEST_JOB_BYTES_READ --> 字节数 = 3683 t= 3802 [st= 100] HTTP_TRANSACTION_READ_BODY [dt=0] t= 3802 [st= 100] HTTP_CACHE_WRITE_DATA [dt=0] t = 3802 [st = 100] URL_REQUEST_JOB_BYTES_READ --> 字节数 = 13982 t= 3802 [st= 100] HTTP_TRANSACTION_READ_BODY [dt=20365] --> net_error = -355 (ERR_INCOMPLETE_CHUNKED_ENCODING) t=24167 [st=20465] 失败 --> net_error = -355 (ERR_INCOMPLETE_CHUNKED_ENCODING) t=24168 [st=20466] -REQUEST_ALIVE --> net_error = -355 (ERR_INCOMPLETE_CHUNKED_ENCODING)

    最后,这里有一些对我很有帮助的链接,似乎 spring 去年也遇到了同样的问题。

    我仍然无法弄清楚为什么这在运行多年后随机启动,并且真的感谢任何输入。

    【讨论】:

    • 不错的发现。我怀疑是 Chrome 错误。其他浏览器或旧版 Chrome 是否也会出现这种情况?尽管如此,Content-Range 在代表完整范围时确实不属于那里,但它应该是无害的,因为它是内容长度领先的Content-Length。顺便说一句,旧的 FileServlet 已被重新设计为 showcase.omnifaces.org/servlets/FileServlet,从中剥离了 Gzip 响应并拆分为 showcase.omnifaces.org/filters/GzipResponseFilter 它们在您的情况下运行良好吗?
    • @BalusC,非常感谢您的意见!它发生在 Firefox 和 Chrome 中,这让我很困惑。我已经看到了新改版的FileServlet,看起来很棒,我将花一些时间来实现它们,看看当它们相互结合使用时问题是否仍然存在:)
    • 好的,为了安全起见,我从博客和 OmniFaces 中删除了完整文件中不必要的 Content-Range。顺便说一下,GzipResponseFilter 已经从 gzipping 中跳过带有 Content-Range 标头的响应。旧的FileServlet 应该也做了同样的事情。
    • 理论上,它不应该是必要的。因此,我怀疑客户端(或代理)端出了点问题。
    • 仅供参考:根据github.com/omnifaces/omnifaces/issues/269,此解决方法已得到进一步改进
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2019-04-18
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多