May 29, 2011

f Comment

In Nginx Rewrite How To Test Multiple "if" Conditions

Amazon How the HECK do I test multiple conditions in "if" statement in Nginx server configuration file? It it AMAZING that Nginx server configuration does NOT support multiple conditions natively, meaning no such thing as the following:

if ($request_method = POST && -f $request_filename) {
...
}

In fact it does NOT even support nested conditions, meaning no such syntax as the following:
if ($request_method = POST) {
  if (-f $request_filename) {
    ...
  }
}
Why?? I am just as confused as you are. The fact that common conditionals like AND and OR are NOT supported is a serious inconvenience to webmasters especially those who are converting from Apache to Nginx. Below we'll see how to get around the issue of Nginx not supporting multiple conditions in "if" block.

Solution
When there's a will there's a way. You can use a hack by setting a variable in each tested-true condition and when the variable reflects that both conditions are true, do what you need to do. Here's an example:
server {
  listen  80;
  server_name  www.mensfashionforless.com;
  rewrite_log on;
  ...
  location / {
    # test whether $document_root/cache$request_uri exists 
    # in the file system
    if (-f $document_root/cache$request_uri) {
      set $test P;
    }
    # test whether there's no URL argument to this request
    # = '' tests whether the value is empty!
    # for more info refer to how to test whether a server variable is empty
    if ($args = ''){
      set $test  "${test}C";
    }
    # if both of the above tests are true, do the rewrite
    if ($test = PC){
      rewrite ^/(.+)$ /cache/$1 last;
      break;
    }
    ...
  }
  ...
}
Incidentally if you are confused by the test-empty-variable syntax refer to how to test whether a server variable is empty. You need to pay extra attention to Nginx's syntax! For example there MUST be a space between if and ( according to the syntax.

The following will fail:
...
if($test = PC){
rewrite ^/(.+)$ /cache/$1 last;
break;
}
...

Nginx's server configuration syntax is very unforgiving. So make sure you check the correctness of syntax before you restart Nginx server. The way to do is it use Nginx's command line tool with "-t" option. Assume it's installed at /usr/sbin/nginx you run the following command:

/usr/sbin/nginx -t -c {location to nginx configuration file or no -c to check the default location}
If you see the following then it means your syntax is correct:

$ /usr/sbin/nginx -t
2011/05/29 11:43:04 [info] 29803#0: the configuration file /etc/nginx/nginx.conf syntax is ok
2011/05/29 11:43:04 [info] 29803#0: the configuration file /etc/nginx/nginx.conf was tested successfully
$

If your nginx config has syntax errors you'll see something like the following:

$ /usr/sbin/nginx -t
2011/05/29 11:52:08 [emerg] 30258#0: unknown directive "abc" in /etc/nginx/nginx.conf:2
2011/05/29 11:52:08 [emerg] 30258#0: the configuration file /etc/nginx/nginx.conf test failed
$

Simply correct the errors and run the command again until you see the success message.

By the way the following command will check your nginx configuration RECURSIVELY! Suppose your nginx.conf contains such statements as the following:

include /etc/nginx/sites-enabled/*;
Now you run "nginx -t" to check syntax, and it'll check syntax of every configuration file located in /etc/nginx/sites-enabled/!

If you have any questions please let me know and I will do my best to help you!
Please leave a comment here!
One Minute Information - by Michael Wen
ADVERTISING WITH US - Direct your advertising requests to Michael