74

How do I set a location condition in Nginx that responds to anything that isn't equal to the listed locations?

I tried:

location !~/(dir1|file2\.php) { rewrite ^/(.*) http://example.com/$1 permanent; } 

But it doesn't trigger the redirect. It simply handles the requested URI using the rules in the rest of the server configuration.

3
  • I don't get it. For example user goes to /aabbcc and where are you going to redirect him? Commented Apr 30, 2013 at 15:32
  • See stackoverflow.com/questions/16159108/… Commented Nov 26, 2014 at 10:50
  • 2
    this is also can be applied to location directive location ~ ^/(?!(dir1|file2\.php)) {} Commented Dec 14, 2014 at 11:11

3 Answers 3

95

According to nginx documentation

there is no syntax for NOT matching a regular expression. Instead, match the target regular expression and assign an empty block, then use location / to match anything else

So you could define something like

location ~ (dir1|file2\.php) { # empty } location / { rewrite ^/(.*) http://example.com/$1 permanent; } 
Sign up to request clarification or add additional context in comments.

5 Comments

Worth noting: I needed this to conditionally redirect a hostname and had some more locations next to the redirecting one. The redirect wasn't working. Turns out I had to add a break; directive as per stackoverflow.com/a/14049884
Unfortunately this does not work when you want to proxy_pass requests in first location because proxy_pass doesn't support regexps
I get that the doc says there is no syntax for NOT matching however ~ ^/(?!(text or pattern not to match)) is valid regex and more importantly works.
There is a syntax for not matching. And there is a operator that not produces a match with a given subregex
i want rule, if someone enter "/api/123" it should return 403, everything except "/api/" shoud return 403
93

i was looking for the same. and found this solution.

Use negative regex assertion:

location ~ ^/(?!(favicon\.ico|resources|robots\.txt)) { .... # your stuff } 

Source Negated Regular Expressions in location

Explanation of Regex :

If URL does not match any of the following path

example.com/favicon.ico example.com/resources example.com/robots.txt 

Then it will go inside that location block and will process it.

8 Comments

This working well. Example: location ~ (/konference(?!/20)) catch /konference,/konference/images/ NOT catch /konference/2015, /konferece/2015/images tested on Nginx 1.10.2
How to extract variable if needed? I want to know what is the slug so I can pass it to a proxy pass.
@ApoorvNag i dont know, try creating new question. thanks
really useful. EG catch any php file except index location ~ /public/(?!index.php$)+.*\.php$ { rewrite ^/(.*)$ /public/index.php?url=$1; }
@AMB Can you provide an explanation of the regex? I didn't get it even after reading the source link.
|
2

As of 22-JAN-2023, nginx documentation states that !~ and !~* are valid operators, although it doesn't mention since which version they're available. See the documentation reference

1 Comment

Negative operators are only available for if statements. Not for location detectives.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.