Nginx wildcard/regex in location path

nginxregexwildcard

The Nginx config I have throws 404 for .php like:

## Any other attempt to access PHP files returns a 404.
location ~* ^.+\.php$ {
    return 404;
}

However I have some index.php file in subfolder that I want to run. The current config is like:

location = /sitename/subpage/index.php {
    fastcgi_pass phpcgi; #where phpcgi is defined to serve the php files
}

location = /sitename/subpage2/index.php {
    fastcgi_pass phpcgi; 
}

location = /sitename/subpage3/index.php {
    fastcgi_pass phpcgi; 
}

it works perfectly, but the issue is duplicate locations and if there are lots of subpages then the config becomes huge.

I tried the wildcard like * and some regex, which says the nginx test passed but doesn't load the page i.e. 404. What I tried are:

location = /sitename/*/index.php {
    fastcgi_pass phpcgi;
}

location ~* ^/sitename/[a-z]/index.php$ {
    fastcgi_pass phpcgi;
}

Is there any way I can have some pathname in the location as regex or wildcard?

Best Answer

The = modifier in location block is an exact match, without any wildcards, prefix matching or regular expressions. That's why it doesn't work.

On your regex attempt, [a-z] matches a single character between a and z. That's why it doesn't work for you.

You need to have your locations set up like the following. Note the order of location statements. nginx picks the first matching regex condition.

location ~ ^/sitename/[0-9a-z]+/index.php$ {
    fastcgi_pass phpcgi;
}

location ~ \.php$ {
    return 404;
}

I use case sensitive matching here (~ modifier instead of ~*). In the first case, I match the first part of path, then one or more number of alphabetic / number characters and then index.php. You can modify the match range, but remember the + for "one or more" repetitions.

The second one matches any URI ending with .php. You don't need the extra characters in your version because of the way regular expressions work.