Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Please consider the following directory structure in my root:

/resources/css
/resources/js
/resources/templates
/resources/images

I want to serve static content from the above directories but I also want to allow a rewrite like this to work:

rewrite ^/([a-z]+)(.*)$    /index.php?p1=$1&p2=$2;

For example myurl.com/register/... is rewritten to myurl.com/index.php?p1=register&p2=...

But that rule also rewrites /resources/, so how do I exclude /resources from the rewrite? Or do I need another rewrite? Nothing I've tried seems to work so obviously I'm not understanding something.

share|improve this question
1  
Can you please fix the typo in your rewrite above? –  Michael Hampton Oct 3 '12 at 13:19

3 Answers 3

up vote 3 down vote accepted

The config below is what I found that works, since the location statements are all the same precedence they are checked in order.

This helped me understand the precedence of location blocks:

location =  <path>  (longest match wins)
location ^~ <path>  (longest match wins)
location ~  <path>  (first defined match wins)
location    <path>  (longest match wins)

Here is the config:

// match all css/js/images in resource path

location ~ ^/resources {
        root   /mypath/myurl.com;
        try_files $uri =404;
        break;
}

// allow myurl.com/register etc:

location ~  ^/([a-z]+)/(.*)$ {
        root   /mypath/myurl.com;
        rewrite ^/([a-z]+)(.*)$    /index.php?p1=$1&p2=$2;
}

// everything else:

location ~ / {
    root   /mypath/myurl.com;
    index  index.php;
}

Comments welcome!

share|improve this answer

You can use this example:

if ($http_user_agent ~ MSIE) {
  rewrite  ^(.*)$  /msie/$1  break;
}

if ($http_cookie ~* "id=([^;] +)(?:;|$)" ) {
  set  $id  $1;
}

if ($request_method = POST ) {
  return 405;
}

if ($slow) {
  limit_rate  10k;
}

if ($invalid_referer) {
  return   403;
}

if ($args ~ post=140){
  rewrite ^ http://example.com/ permanent;
}

For more information, visit: http://wiki.nginx.org/HttpRewriteModule

share|improve this answer

You could just add another location handler for that URI that matches on files that exist - or breaks if they don't.

location ~* /resources/(css|js|templates|images) {
  if (!-f $request_filename) {
    break;
  }
  root   /path/to/resources;
}

rewrite ^/([a-z]+)(.*)$    /index.php?p1=$1&p2=$2;
share|improve this answer
    
That looks reasoanable to me but does not seem to work, it's still trying to rewrite the resources directory. –  amanda Sep 19 '12 at 21:36
    
Its the right code. So the next question is whether the file you are trying to access is readable by the web-server - and that you have entered your Nginx config in the right order as above. Paste your full Nginx config to confirm. –  Sonassi Sep 19 '12 at 22:20
    
The files were accessible and the code was copy/pasted from above and edited properly. I found after researching that using (if) is not recommended by nginx, please see: nginx docs, so I did not try using this code further. Thanks for your input! –  amanda Sep 20 '12 at 16:00
    
if is fine as long as you aren't using it to conditionally set variables; you are safe to use break in an if without any issue. This is the right method, short of using try_files. Post your full Nginx config - as at the moment, the code is out of context and your placement of it is probably the cause. –  Sonassi Sep 20 '12 at 16:16
    
I posted the working solution that does not use if. –  amanda Sep 20 '12 at 16:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.