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
Accept-Ranges:bytes
Cache-Control:max-age=1209600, s-maxage=120960
Connection:keep-alive
Content-Length:122871
Content-Type:application/javascript
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
Server:nginx/1.2.8
No accel = works
Cache-Control:max-age=1209600, s-maxage=120960
Connection:keep-alive
Content-Encoding:gzip
Content-Length:122871
Content-Type:application/javascript
Date:Mon, 24 Jun 2013 13:45:08 GMT
Expires:Mon, 08 Jul 2013 13:45:08 GMT
HTTP1/0 200 Ok:
Pragma:cache
Server:nginx/1.2.8
X-Powered-By:PHP/5.4.9
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);
exit(0);
}
else{
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;
}
fclose($fileHandle);
}
exit(0);
}
I've tried setting proxy_pass_header Content-Encoding;
but apparently it has no effect.
It appears there are two solutions:
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; }
Enable the gzip_static module.