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.

How do I only redirect too sub1.example.com when hitting $request_filename ~ /sub1 on example.com. For example if I'm on sub1.example.com, hitting /sub1 wont redirect me back too sub1.example.com but rather the actual page sub1.example.com/sub1?

My NGINX config:

server
{
    server_name .example.com;
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;
    root /var/www/html/example;
    index index.php;

    location ~ \.php$ {
        if (-f $request_filename) {
            fastcgi_pass    127.0.0.1:9000;
        }
        fastcgi_index   index.php;
        fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include         fastcgi_params;
    }

    location / {
        if ($request_filename ~ /sub1) {
            rewrite ^ http://sub1.example.com/? permanent;
        }
        if ($request_filename ~ /sub2) {
            rewrite ^ http://sub2.example.com/? permanent;
        }
        if (!-f $request_filename) {
            rewrite ^(.*)$ /index.php last;
        }
    }
}

How do I use the location clause for only root domain?

Update @ Marcel:

server
{
    server_name .example.com;
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;
    root /var/www/html/example;
    index index.php;
    location ~ \.php$ {
        if (-f $request_filename) {
            fastcgi_pass    127.0.0.1:9000;
        }
        fastcgi_index   index.php;
        fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include         fastcgi_params;
    }

    location = /sub1 {
       if($host = "example.com") {
           rewrite ^ http://sub1.example.com permanent;
       }
    }
    location = /sub2 {
       if($host = "example.com") {
           rewrite ^ http://sub2.example.com permanent;
       }
    }
    location / {
       if (!-f $request_filename) {
           rewrite ^(.*)$ /index.php last;
       }
    }
}
share|improve this question
    
still no luck? no progress on this matter? –  Marcel Apr 8 '13 at 19:26
    
@Marcel Afraid not. Using your latest configuration I am still running into the case where "a request to http://sub1.example.com/sub1 still redirects the user to http://sub1.example.com". –  Dan Kanze Apr 10 '13 at 0:55
add comment

2 Answers

Nginx treats location directives in a certain manner, depending on which directives you have. This link points out nginx behaviour:

A location can either be defined by a prefix string, or by a regular expression.
Regular expressions are specified by prepending them with the “~*” modifier (for case-insensitive matching), or with the “~” modifier (for case-sensitive matching).

To find a location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the most specific one is searched.
Then regular expressions are checked, in the order of their appearance in a configuration file. A search of regular expressions terminates on the first match, and the corresponding configuration is used.

If no match with a regular expression is found then a configuration of the most specific prefix location is used."

location / is a wildcard location that will match every request.

This is what your locations should be:

location ~ \.php$ {
    if (-f $request_filename) {
        fastcgi_pass    127.0.0.1:9000;
    }
    fastcgi_index   index.php;
    fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include         fastcgi_params;
}
location = /sub1 {
   if($host = "example.com") {
       rewrite ^ http://sub1.example.com permanent;
   }
}
location = /sub2 {
   if($host = "example.com") {
       rewrite ^ http://sub2.example.com permanent;
   }
}
location / {
   if (!-f $request_filename) {
       rewrite ^(.*)$ /index.php last;
   }
}
share|improve this answer
    
Thankyou for your answer however it doesn't seem to be working as intended. I'm still redirected back too each subdomain index for those location directives. Are you able to reproduce? –  Dan Kanze Apr 5 '13 at 20:53
    
You're saying that a request to http://sub1.example.com/sub1 still redirects the user to http://sub1.example.com using only the location directives I've pointed out? –  Marcel Apr 5 '13 at 21:51
    
Correct, yes. I've updated my post to what my updated config is currently. –  Dan Kanze Apr 5 '13 at 22:27
    
@Marcel You have a syntax error. location = is used for literal matching, ^ and $ are meta-characters of regular expressions and missplaced. My edit should fix this. You should also consider replacing regular expressions by literal matches wherever possible (would probably improve performance). –  Lukas Apr 7 '13 at 5:39
    
The nginx wiki also advises the use of try_files over ìf (regarding the location / block): If is evil. This is a minor issue, however, since rewrite can safely be used inside if. –  Lukas Apr 7 '13 at 5:47
add comment

Don't use If inside Location block. much better to declare several sections server {} in config with different server_name.

Instead if (-f $request_filename) { use try_files directive.

share|improve this answer
add comment

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.