Nginx Rewriting and Returning
nginx(8) allows for requests to be (conditionally) rewritten and returned.
Contents
Logical Control
The if directive allows for rewrite and return directives to be applied conditionally.
A condition can be any of:
A variable name, which evaluates as false if the value is an empty string or "0".
A (literal or variable) comparison using the = and != operators.
- Note that all values are strings, so quoting is optional.
Regular expression matching using the ~ and ~* operators. (The former is case sensistive, the latter is case insensitive.)
Regular expressions can contain capture groups, which then store the captured value in $1 through $9.
Negate a match by prefixing the operator with !; for example !~ and !~*.
If a regular expression includes } or ;, it must be quoted.
File existence with the -f and !-f operators.
Directory existence with the -d and !-d operators.
File/directory/symlink existence with the -e and !-e operators.
Executable file existence the -x and !-x operators.
A variable can be declared with the set directive. The variable name should be prefixed with $.
The break directive causes a request to skip all remaining rewrite, return, and logical control directives.
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
}
if ($slow) {
limit_rate 10k;
break;
}
if ($request_method = POST) {
return 405;
}
Rewrite
The rewrite directive takes a regular expression, a replacement string (which can use variables), and an option.
The regular expressions here follow the same rules as above. Notably:
Regular expressions can contain capture groups, which then store the captured value in $1 through $9.
If a regular expression includes } or ;, it must be quoted.
If a replacement string starts with http://, https://, or $scheme, this is treated as a permanent redirect and immediately returns.
The valid options are:
Option |
Meaning |
last |
Re-scan for locations using the rewritten URI |
break |
Skip all remaining rewrite, return, and logical control directives |
redirect |
Returns a redirect with a 302 code |
permanent |
Returns a permanent redirect with a 301 code |
Removing Path Components
To rewrite a URI, try:
server {
rewrite ^/example(.*)$ $1 last;
}The last option should be replaced with break when used within a location. Otherwise nginx(8) will repeatedly re-enter the location and, after 10 cycles, return an error.
location /example {
rewrite ^/example(.*)$ $1 break;
}
Removing Arguments
If a replacement string includes the new request arguments, the old arguments are appended.
To avoid this, append a ? to the replacement string
rewrite ^/users/(.*)$ /show?user=$1? last;
Return
The return directive takes a code and optionally a URI.
Returning Plain Text
It is also possible to return a literal text message.
location / {
add_header Content-Type text/plain;
return 200 'hello, world!';
}Variables can be used in the text.
Redirecting Requests
To redirect a request, use a 30x code and a new URI.
server {
listen 80;
server_name old.example.com;
return 301 $scheme://new.example.com$request_uri;
}
Rejecting Requests
To reject a request, the nginx(8) convention is to return the non-standard error code 444.
This is often done within a location mapping to a sensitive directory or file
location ~ ^\.ht {
return 444;
}But it can also be used with the if directive shown above.
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;
}
See also
Module ngx_http_rewrite_module documentation
