java - gzip 编码响应的奇怪问题

标签 java http server gzip nanohttpd

好吧,所以我正在运行我自己的 NanoHttpd 分支(一个极简主义的 Java Web 服务器,尽管该分支相当复杂),并且我必须在其之上实现 gzip 压缩。

它工作得很好,但事实证明,Linux mint 17.1 上的 firefox 33.0 根本不会执行 gzipped js 文件,尽管它们加载得很好,标题看起来也不错等。在带有 chrome 的同一台电脑上,这种情况不会发生,或者我尝试过的任何其他浏览器,但仍然是我必须修复的问题。

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

这是负责 gzip 压缩的代码:

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: 尝试在打开/关闭 gzip 时使用 TemperData 检查响应和 header 。 唯一的区别是,当gzipping开启时,响应头中有Content-Encoding: gzip,这并不是很奇怪。除此之外,100% 相同的回复。

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

最佳答案

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

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

关于java - gzip 编码响应的奇怪问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32583281/

相关文章:

c - 读取客户端响应导致服务器崩溃

java - 如何修复测试后打开报告然后截图的问题

java - 我怎样才能停止 jMonkeyEngine 游戏?

java - 数组中的 2 个值到我的 DataFrame 中的 2 列

c# - web api 2.0过滤器实现customFilter的最佳选择

java - 是否可以在 HttpServer.createContext 的处理程序方法中获取完整的 http 请求?

java - 检测变量变化

http - 如何通过 HTTP get 在 Java 中发送数据?

http - 如何在没有网络延迟的情况下计算 HTTP 请求处理时间?

swift - 获取错误域=NSURLErrorDomain代码=-1004 "Could not connect to the server."UserInfo={NSUnderlyingError=0x7fcb0e1de350