Setting cache parameters via if directives

Ryan Malayter malayter at
Tue Feb 1 18:45:58 MSK 2011

On Tue, Feb 1, 2011 at 2:47 AM, agentzh <agentzh at> wrote:
> On Fri, Jan 28, 2011 at 11:55 PM, Ryan Malayter <malayter at> wrote:
>> I do something similar using the conditinal setting of variables
>> inside the if block to set Cache-Control values, perhaps you can use a
>> similar method to set the values of proxy_cache_valid. Since setting
>> variables is one of the few "safe" things to do inside an if block,
>> and most directives can take variables as agurments, it is generally
>> useful.
>> location / {
>>   set $mycc = "private, max-age=0";
>>   if ($foo = "bar") {
>>      set $mycc = "public, max-age=3600"
>>      }
>>  proxy_pass http://backend;
>>  add_header Cache-Control $mycc;
>> }
> I'm amazed to see the config above works for you. I'm not sure if
> you're using some ancient versions of nginx that I know very little
> about (like 0.6.x or 0.5.x or even earlier).
> Consider the following config snippet:
>    location /test {
>        set $a 3;
>        if ($a = 3) {
>            set $a 4;
>        }
>        echo $a;
>    }
> GET /test will give you nothing for nginx 0.7.21 ~ 0.9.4. Don't tell
> me that the ngx_echo module's echo directive is buggy because it's too
> dead simple to get wrong.
> Basically for "modern" versions of nginx, the location "if" block
> creates an anonymous nested location and will trap the execution flow,
> that is, once you get in, you'll never go out of it to reach the
> content phase. And that's one of the reasons why people call nginx's
> "if" an evil monster ;)

It does in fact work in production on nginx 0.7.6x. Below is my actual
configuration (trimmed to the essentials and with a few substitutions
of actual URIs).

location /MyApp {
  proxy_pass http://backendTomcat;
  proxy_set_header Host $host;
  proxy_read_timeout 900;
  proxy_next_upstream error timeout;
  proxy_redirect $scheme://;

  #hide caching related headers from backend
  #the backend is dumb about this but we can't change it
  proxy_hide_header Pragma;
  proxy_hide_header Cache-Control;
  proxy_hide_header Expires;
  #these variables are the new values for caching headers

  set $mycc "private,max-age=0";
  set $myexp "Fri, 01 Jan 1990 00:34:56 GMT";

  #create a variable that includes both scheme and URI so we
  #can redirect in and out of SSL if needed
  set $schemeuri $scheme$uri;

  #add exception for dynamic CSS stylesheet, make it cache for 1 hour
  if ($request_uri ~* uiframework\.Theme) {
    set $mycc "private,max-age=3600";
    set $myexp "";
  if ($schemeuri = "http/MyApp/changePassword") {
    rewrite ^(.*)$  https://$host$1  redirect;

  #add our new headers
  add_header "Cache-Control" $mycc;
  add_header "Expires" $myexp;


More information about the nginx mailing list