Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have my Nginx server setup allow requests to be served with the X-Accel-Redirect header. This works fine for images, but I'm trying to get it to work for Javascript files that are already gzip'ed on the disk and it appears Nginx is stripping off the Content-Encoding header. This makes the browser not unzip the content when it receives it, which obviously makes it not work.

How can I serve pre-gzipped content through X-Accel-Redirect ?

The headers seen are:

With Accel = doesn't work

Cache-Control:max-age=1209600, s-maxage=120960
Date:Mon, 24 Jun 2013 13:44:36 GMT
Expires:Mon, 08 Jul 2013 13:44:36 GMT
Last-Modified:Mon, 24 Jun 2013 13:38:20 GMT

No accel = works

Cache-Control:max-age=1209600, s-maxage=120960
Date:Mon, 24 Jun 2013 13:45:08 GMT
Expires:Mon, 08 Jul 2013 13:45:08 GMT
HTTP1/0 200 Ok:

In case it's relevant the code that is serving the content is:

public static function  proxyFile($fileNameToServe, $mimeType, $alreadyGzip = false){
        $seconds_to_cache = 3600 * 24 * 7 * 2; 

        $filesize = filesize($fileNameToServe);
        header('Content-Length: '.$filesize);

        if ($alreadyGzip) {
            header('Content-Encoding: gzip');

        if(defined('X-ACCEL-REDIRECT') == true && constant('X-ACCEL-REDIRECT') == true){
            $filenameToProxy = str_replace(PATH_TO_ROOT."var/cache", '/protected_files', $fileNameToServe );
            sendProxyHeaders($mimeType, $seconds_to_cache);
            header("X-Accel-Redirect: ".$filenameToProxy);
            sendProxyHeaders($mimeType, $seconds_to_cache);
            $fileHandle = fopen($fileNameToServe, 'r');

            if($fileHandle == false){
                throw new \Exception("Failed to open file [$fileNameToServe] for serving.");

            while (!feof($fileHandle)) {
                $contents = fread($fileHandle, 8192);
                echo $contents;



I've tried setting proxy_pass_header Content-Encoding; but apparently it has no effect.

share|improve this question
Can't you just use try_files? – Michael Hampton Jun 24 '13 at 15:28
No, the file is actually several Javascript files that are bundled together and then minified on the fly. – Danack Jun 24 '13 at 15:38
up vote 0 down vote accepted

It appears there are two solutions:

  1. Tell Nginx to pass the Content-Encoding header by add_header Content-Encoding $upstream_http_content_encoding;, and turn gzip off for the x-accel-redirect location, to prevent the content being gzipped twice.

    location ^~ /protected_files { gzip off; internal; alias /home/intahwebz/var/cache; add_header Content-Encoding $upstream_http_content_encoding; }

  2. Enable the gzip_static module.

Before serving a file from disk to a gzip-enabled client, this module will look for a precompressed file in the same location that ends in ".gz". The purpose is to avoid compressing the same file each time it is requested.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.