Seppo420
Seppo420

Reputation: 2241

Weird issues with gzip encoded responses

Ok, so I'm running my own fork of NanoHttpd (a minimalist java web server, the fork is quite complex though), and I had to implement gzip compression on top of it.

It has worked fine, but it just turned out that firefox 33.0 on Linux mint 17.1 will not execute gzipped js files at all, although they load just fine and headers look OK etc. This does not happen on the same pc with chrome, or with any other browser I've tried, but still is something that I must get fixed.

Also, the js resources execute just fine if I disable gzipping. I also tried removing Connection: keep-alive, but that did not have any effect.

Here's the code responsible for 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, the example I copied this from did not close the outputStream, but without doing that the gzipped resources did not load at all, while non-gzipped resources still loaded ok. So I'm guessing that part is off in some way.

EDIT: firefox won't give any errors, it just does not excecute the script, eg:

index.html:

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

foo.js:

alert("foo");

Does not do anything, despite that the resources are loaded OK. No warnings in console, no nothing. Works fine when gzip is disabled and on other browsers.

EDIT 2: If I request foo.js directly, it loads just fine.

EDIT 3: Tried checking the responses & headers with TemperData while having gzipping on/off. The only difference was that when gzipping is turned on, there is Content-Encoding: gzip in the response header, which is not very suprising. Other than that, 100% equal responses.

EDIT 4: Turns out that removing content-length from the header made it work again... Not sure of the side effects tho, but at least this pinpoints it better.

Upvotes: 0

Views: 599

Answers (1)

Little Santi
Little Santi

Reputation: 8793

I think the cause of your problem is that you are writing the Content-Length header before compressing the data, which turns out in an incoherent information to the browser. I guess that depending on the browser implementation, it handles this situation in one or other way, and it seems that Firefox does it the strict way.

If you don't know the size of the compressed data (which is understandable), you'd better avoid writing the Content-Length header, which is not mandatory.

Upvotes: 1

Related Questions