Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firefox fails to decompress gzip files

I have .gz files stored on AWS s3.

Using the s3 REST-API, I'm generating authenticated links that point to individual files. I'm also setting the content-header options such that browsers requesting these urls will decompress and download the gzipped files as attachments.

The generated s3 url looks like so:

https://MY_BUCKET.s3.amazonaws.com/PATH_TO/file.ext.gz
  ?AWSAccessKeyId=MY_KEY
  &Expires=DATE_TIME
  &Signature=MY_SIGNATURE
  &response-content-disposition=attachment%3B%20filename%3D%22file.ext%22
  &response-content-encoding=gzip
  &response-content-type=application%2Foctet-stream
  &x-amz-security-token=MY_TOKEN

The links behave as expected in: (All on OSX) Chrome (42.0.2311), Safari (8.0.6), Opera (29.0),

but NOT Firefox (38.0.1)

Firefox downloads and renames the file correctly but fails to decompress the gzipped file.

The response headers of a GET request to the authenticated urls look like so:

Accept-Ranges:bytes
Content-Disposition:attachment; filename="file.ext"
Content-Encoding:gzip
Content-Length:928
Content-Type:application/octet-stream
Date:SOME_DATE_TIME
ETag:"MY_ETAG"
Last-Modified:SOME_OTHER_DATE_TIME
Server:AmazonS3
x-amz-expiration:expiry-date="ANOTHER_DATE_TIME"
x-amz-id-2:MY_AMZ_ID
x-amz-request-id:MY_AMZ_REQUEST_ID
x-amz-server-side-encryption:AES256

Does Firefox look for different headers and/or header values to indicate decompression?

like image 778
cjhin Avatar asked May 17 '15 22:05

cjhin


People also ask

Do browsers automatically decompress gzip?

If the gzip compression is enabled on the web server, that is, not in the application logic, then the browser will uncompress automatically.

Does browser support gzip?

gzip is commonly supported by web servers and modern browsers, meaning that servers can automatically compress files with gzip before sending them, and browsers can uncompress files upon receiving them.


2 Answers

The solution appears to be removing .gz from the end of the filename.

It's a common misconfiguration to set Content-Encoding: gzip on .gz files when you intend for the end user to download -- and end up with -- a .gz file; e.g. downloading a .tar.gz of source package.

This isn't what you are doing... It's the opposite, essentially... but I suspect you're seeing a symptom of an attempt to address that issue.

In fact, the configuration I described should only be the case when you gzipped an already-gzipped file (which, of course, you shouldn't do)... but it was entrenched for a long time by (iirc) default Apache web server configurations. Old bug reports seem to suggest that the Firefox developers had a hard time grasping what should be done with Content-Encoding: gzip, particularly with regard to downloads. They were a bit obsessed, it seems, with the thought that the browser should not undo the content encoding when saving to disk, since saving to disk wasn't the same as "rendering" the downloaded content. That, to me, is nonsense, a too-literal interpretation of an RFC.

I suspect what you see is a legacy of that old issue.

Contrary to your conception, it's quite correct to store a file with Content-Encoding: gzip without a .gz extension... arguably, in fact, it's more correct to store such content without a .gz extension, because the .gz implies (at least to Firefox, apparently) that the downloading user should want the compressed content downloaded and saved in the compressed form.

like image 117
Michael - sqlbot Avatar answered Oct 07 '22 12:10

Michael - sqlbot


1. Background to compressed content

Michael's changing of the file extension solves the problem is because the important step is to change the Content-Type header to reflect the underlying content within the compressed file, rather than that of the compressed file itself.

In many webservers, the mime types are detected based on file extension - for example, you may have a mime type of application/gzip corresponding to .gz file extensions (on a default Debian install of nginx, this can be found within /etc/nginx/mime.types). Your server will then set headers as Content-Type: application/gzip for the files matching this mime type.

If your browser receives a Content-Type header suggesting binary compressed content is on it's way rather than the text within the compressed file, it will assume it's not for human consumption and may not display it. Mine (Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0) didn't.

2. Header adjustment

  1. Set a Content-Encoding: 'gzip' header
  2. Set Content-Type: 'text/plain' header for files you want displayed in plain text

The browser (if gzip compression is supported), should decompress and display the content for the client.

3. Real world example

/usr/share/doc contains text documentation, many of which have also been gzip compressed.

By adding the following to the nginx server {} block, you can enable transparent decompression on the client:

# local documentation access
location /doc {
    alias /usr/share/doc;
    autoindex on; # allow dir listings
    allow 127.0.0.1; deny all; # anyone outside is forbidden

    # display .gz content in text on the browser
    location ~ \.gz {
        default_type text/plain;
        add_header Content-Encoding: 'gzip';
    }

}
like image 42
Mark Avatar answered Oct 07 '22 13:10

Mark