3

I think starting with a small snippet would be wisest:

    location ^~ /test/ {
            proxy_pass              http://frontend;
            proxy_http_version      1.1;
            proxy_set_header        Connection "";
            proxy_set_header        Host $host;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_set_header        X-Real-Port $server_port;
            if ( $remote_addr ~* "123.123.123.123" ) {
                    proxy_cache            cache_base;
                    proxy_cache_valid      720m;
            }
    }

So, in essence what we want to do is setup proxy caching based on a coniditonal IF statement.

The above does not work, as proxy_cache is not valid inside IF.

Does anyone know how to proxy cache based on a regexp match on one of the many nginx internal variables?

Note:

We want to basically disable / enable proxy_caching based on $remote_addr regexp. Not specify different proxy_cache values.

Thanks.

anonymous-one
  • 1,018
  • 7
  • 27
  • 43

2 Answers2

6

It seems that what you really want is to combine a geo variable with proxy_cache_bypass and proxy_no_cache:

geo $skip_cache {
  default 1;
  123.123.123.123/32 0;
  1.2.3.4/32 0;
  10.0.0.0/8 0;
}

server {
  location ^~ /test/ {
    proxy_pass              http://frontend;
    proxy_http_version      1.1;
    proxy_set_header        Connection "";
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Real-Port $server_port;
    proxy_cache            cache_base;
    proxy_cache_valid      720m;

    # When $skip_cache is 1, the cache will be bypassed, and
    # the response won't be eligible for caching.
    proxy_cache_bypass     $skip_cache;
    proxy_no_cache         $skip_cache;
  }
}
kolbyjack
  • 8,039
  • 2
  • 36
  • 29
1

'If' is generally a bad practive in nginx configuration. You can use map module to make things work. see http://nginx.org/en/docs/http/ngx_http_map_module.html http://wiki.nginx.org/HttpMapModule

map $remote_addr $matched_ip_location { 
123.123.123.123 @cache; 
default         @default; 
} 
... 
location ^~ /test/ {
 ... 
rewrite ^ $matched_ip_location
}
location @cache {
    ...
    proxy_cache            cache_base;
    proxy_cache_valid      720m;
}
location @default {
   ...
}
DukeLion
  • 3,259
  • 1
  • 18
  • 19
  • ok i understand the concept of nginx 'maps'. but once i have a custom variable set (eg: $matched_ip), dont i have to do a if statement somewhere anyways? and if so, how do i wrap either a whole location block in an if OR just my proxy_cache block? – anonymous-one May 16 '12 at 11:42
  • You just use your mapped value as directive parameter without any wrappers. Nginx config is not imperative - it's more declarative/functional-like. Give me more details, and I can provide you an example config. – DukeLion May 16 '12 at 11:44
  • 1
    for example: `map $remote_addr $matched_ip_server { 123.123.123.123 cache_server; default default_server; } ... location ^~ /test/ { ... proxy_cache $matched_ip_server }` – DukeLion May 16 '12 at 11:49
  • ahhh! i understand... i should have mentioned this in the initial question... we want to DISABLE proxy_cache for servers that do not match a given condition. – anonymous-one May 16 '12 at 11:50
  • i supposed we could set up another "proxy_cache_path" in /dev/null... – anonymous-one May 16 '12 at 11:52
  • Hmm.. you can try to rewrite to named location using map variable as location name. http://wiki.nginx.org/HttpMapModule – DukeLion May 16 '12 at 11:55
  • Thank you kindly for all the help. Just as i saw your answer pop up I tested a similar setup and, yep, it worked :) – anonymous-one May 16 '12 at 12:02