4

How can gzip be turned off for a particular location and all its sub-directories? My main site is at http://mydomain.com and I want to turn gzip off for both http://mydomain.com/foo and http://mydomain.com/foo/bar. gzip is turned on in nginx.conf.

I tried turning off gzip as shown below, but the Response Headers in Chrome's dev tools shows that Content-Encoding:gzip.

How should gzip/output buffering be disabled properly?

Attempt:

server {
    listen   80;
    server_name www.mydomain.com mydomain.com;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    root /var/www/mydomain/public;

    index index.php index.html;

    location / {
        gzip on;
        try_files $uri $uri/ /index.php?$args ;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_read_timeout 300;
    }

    location /foo/ {
        gzip off;
        try_files $uri $uri/ /index.php?$args ;
    }

}

UPDATE

I turned off gzip in nginx.conf and tried using named locations. However gzip is now always off, and gzip on; in the location / block does not seem to turn gzip back on. Any ideas?

server {
    listen   80;
    server_name www.mydomain.com mydomain.com;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    root /var/www/mydomain/public;

    index index.php index.html;

    location / {
        try_files $uri $uri/ @php;
    }

    location /foo/ {
        try_files $uri $uri/ @php_nogzip;
    }

    location @php {
        gzip on;
        try_files $uri $uri/ /index.php?$args ;
    }

    location @php_nogzip {
        gzip off;
        try_files $uri $uri/ /index.php?$args ;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_read_timeout 300;
    }

}
Nyxynyx
  • 1,459
  • 11
  • 39
  • 49

3 Answers3

3

I'd suppose that URLs you're requesting are being handled with try_files inside location ^~ /foo/ and due to absence of those files, they're internally re-directed to another location handler not having gzip off inherited.

Try using "named location" in /foo location, and then define that "named" location @fooNoGzip with gzip off inside and fascgi_pass stuff.

poige
  • 9,448
  • 2
  • 25
  • 52
  • Thanks, I tried your suggested and updated the original post with the new conf, but now gzip if always turned off. Can you take a look? :) – Nyxynyx Oct 16 '12 at 17:11
  • @Nyxynyx, solved? – poige Nov 02 '12 at 19:20
  • This helped me. gzip was the right solution. – anup Feb 22 '17 at 13:41
  • This helped me. Turning off gzip was the right solution. However the down side is that it applied to all *.php. So, text/html for all php processed pages are not compressed. We do have CDN over Varnish which will cache pages for lower TTL and that does the Gzip at last mile. – anup Feb 22 '17 at 13:48
2

Just for the sake of some necro-romancy: the updated nginx configuration of the OP wasn't working because it's handled ultimately by \.php$ location block.

The proper solution would be removing it and making the named locations as the ones forwarding requests to FastCGI (PHP-FPM):

server {
    listen   80;
    server_name www.mydomain.com mydomain.com;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    root /var/www/mydomain/public;

    index index.php index.html;

    location / {
        try_files $uri $uri/ @php;
    }

    location /foo/ {
        try_files $uri $uri/ @php_nogzip;
    }

    location @php {
        gzip on;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_read_timeout 300;
    }

    location @php_nogzip {
        gzip off;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_read_timeout 300;
    }
}
Danila Vershinin
  • 5,286
  • 5
  • 17
  • 21
-1

As each location is independent, setting gzip off on @php_nogzip will not apply to the location ~ \.php$, it still use the nginx/server default. That is why you see gzip off, because that is the default. Only files delivered by the try_files in the @php_nogzip will be compressed.

The only way i see is to use the map. In the http block use:

map $uri   $gz {
   default  "on";
    ~/foo/  "off";
}

Then in the server:

   location ~ \.php$ {
        gzip $gz; 
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_read_timeout 300;
    }
higuita
  • 1,173
  • 9
  • 13
  • This will never work. The `gzip` configuration directive only allows to be set in configuration directly and is not evaluated from a string variable produced by `map`. – Danila Vershinin Aug 09 '19 at 19:35
  • @DanilaVershinin i never tested this, but if gzip do not accept variables and you need this, i would suggest open a bug in nginx, they are always adding support for more variable settings and this one looks like it would be useful for some people – higuita Aug 12 '19 at 11:12
  • I was merely communicating the fact that the `gzip` directive does not support variable expansion so your solution wouldn't work. I don't have such a requirement, and it's trivial to solve by adding proper locations, so I highly doubt nginx will ever will or need to add variable support for this directive, considering all the extra code required and maintaining it. E.g. exra code it is in my ngx_dynamic etag module's [change](https://github.com/dvershinin/ngx_dynamic_etag/commit/cb4b2847cb789084926520e1e97d7573011bf5f7) to support variable expansion for a similar `on/off` switch. – Danila Vershinin Aug 12 '19 at 18:41