gzip编码响应的奇怪问题

时间:2015-09-15 10:07:45

标签: java http server gzip nanohttpd

好的,所以我正在运行我自己的NanoHttpd分支(一个极简主义的Java Web服务器,虽然分叉很复杂),我不得不在它上面实现gzip压缩。

它运行良好,但事实证明,Linux 17m上的firefox 33.0根本不会执行gzipped js文件,虽然它们加载得很好,标题看起来还不行等。这不会发生在同一台带镀铬的电脑上,或者我尝试过的任何其他浏览器,但仍然是我必须修复的东西。

此外,如果我禁用gzipping,js资源执行得很好。我也尝试删除Connection:keep-alive,但这没有任何效果。

这是负责gzipping的代码:

private void sendAsFixedLength(OutputStream outputStream) throws IOException {
        int pending = data != null ? data.available() : 0; // This is to support partial sends, see serveFile()
        headerLines.add("Content-Length: "+pending+"\r\n");
        boolean acceptEncoding = shouldAcceptEnc();

        if(acceptEncoding){
            headerLines.add("Content-Encoding: gzip\r\n");
        }
        headerLines.add("\r\n");

        dumpHeaderLines(outputStream);//writes header to outputStream

        if(acceptEncoding)
            outputStream = new java.util.zip.GZIPOutputStream(outputStream);


        if (requestMethod != Method.HEAD && data != null) {
            int BUFFER_SIZE = 16 * 1024;
            byte[] buff = new byte[BUFFER_SIZE];
            while (pending > 0) {
                int read = data.read(buff, 0, ((pending > BUFFER_SIZE) ? BUFFER_SIZE : pending));
                if (read <= 0) {
                    break;
                }
                outputStream.write(buff, 0, read);

                pending -= read;
            }
        }
        outputStream.flush();
        outputStream.close();
    }

Fwiw,我复制此示例的示例没有关闭outputStream,但没有这样做,gzip压缩资源根本没有加载,而非gzip压缩资源仍然加载正常。所以我猜这部分是以某种方式关闭的。

编辑:firefox不会给出任何错误,它只是不会超出脚本,例如:

的index.html:

<html><head><script src="foo.js"></script></head></html>

foo.js:

alert("foo");

尽管资源已加载,但是没有做任何事情。控制台没有警告,没有任何警告。禁用gzip和其他浏览器时工作正常。

编辑2: 如果我直接请求foo.js,它加载就好了。

编辑3: 尝试检查响应&amp;在打开/关闭gzipping时使用TemperData的标头。 唯一的区别是当打开gzipping时,响应头中有Content-Encoding:gzip,这不是很令人惊讶。除此之外,100%的回应相等。

编辑4: 事实证明,从标题中删除内容长度使其再次起作用......不确定副作用,但至少这会更好地指出它。

1 个答案:

答案 0 :(得分:1)

我认为您的问题的原因是您在压缩数据之前编写Content-Length标题,这导致浏览器的信息不连贯。我想这取决于浏览器实现,它以一种或另一种方式处理这种情况,似乎Firefox以严格的方式做到了。

如果您不知道压缩数据的大小(这是可以理解的),您最好避免编写Content-Length标题,这不是强制性的。