HttpRewriteModule
Contents |
[edit] Synopsis
This module makes it possible to change URI using regular expressions (PCRE), and to redirect and select configuration depending on variables.
If the directives of this module are given at the server level, then they are carried out before the location of the request is determined. If in that selected location there are further rewrite directives, then they also are carried out. If the URI changed as a result of the execution of directives inside location, then location is again determined for the new URI.
This cycle can be repeated up to 10 times, after which Nginx returns a 500 error.
[edit] Directives
[edit] break
Syntax: | break |
Default: | |
Context: |
server location if |
Reference: | break |
Completes the current set of rules. Continue processing within the current location block but do not process any more rewrite directives.
Example:
if ($slow) { limit_rate 10k; break; }
[edit] if
Syntax: | if ( condition ) { ... } |
Default: | |
Context: |
server location |
Reference: | if |
note: Before using if please see the if is evil page and consider using try_files instead.
Checks the truth of a condition. If the condition evaluates to true, then the code indicated in the curly braces is carried out and the request is processed in accordance with the configuration within the following block. The configuration inside the if
directive is inherited from the previous level.
The condition can be:
- the name of a variable; false values are: empty string (
""
, or any string starting with "0"; - a comparison of a variable using the
=
and!=
operators; - pattern matching with regular expressions:
-
~
performs a case-sensitive match -
~*
performs a case-insensitive match (firefox
matchesFireFox
) -
!~
and!~*
mean the opposite, "doesn't match"
-
- checking for the existence of a file using the
-f
or!-f
operators; - checking for the existence of a directory using
-d
or!-d
; - checking for the existence of a file, directory or symbolic link using
-e
or!-e
; - checking whether a file is executable using
-x
or!-x
.
Parts of the regular expressions can be in parentheses, whose value can then later be accessed in the $1
to $9
variables. See Extracting matches.
Examples of use:
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; }
The value of the built-in variable $invalid_referer
is given by the directive valid_referers.
[edit] return
Syntax: |
return code [ text ] return code URL return URL |
Default: | |
Context: |
server location if |
Reference: | return |
This directive concludes execution of the rules and returns the status code indicated to client. It is possible to use the following values: 200, 204, 400, 402-406, 408, 410, 411, 413, 416 and 500-504. Furthermore, nonstandard code 444 closes the connection without sending any headers.
[edit] rewrite
Syntax: | rewrite regex replacement [ flag ] |
Default: | |
Context: |
server location if |
Reference: | rewrite |
This directive changes URI in accordance with the regular expression and the replacement string. Directives are carried out in order of appearance in the configuration file.
Flags make it possible to end the execution of rewrite directives.
If the replacement string begins with http://
then the client will be redirected, and any further rewrite directives are terminated.
Flags can be any of the following:
- last - completes processing of current rewrite directives and restarts the process (including rewriting) with a search for a match on the URI from all available locations.
- break - completes processing of current rewrite directives and non-rewrite processing continues within the current location block only.
- redirect - returns temporary redirect with code 302; it is used if the substituting line begins with
http://
- permanent - returns permanent redirect with code 301
- Note that outside location blocks, last and break are effectively the same.
Example:
But if we place these directives in location /download/
, then it is necessary to replace flag "last" by "break", otherwise Nginx will hit the 10 cycle limit and return error 500:
If in the line of replacement arguments are indicated, then the rest of the request arguments are appended to them. To avoid having them appended, place a question mark as the last character:
Note: for curly braces( { and } ), as they are used both in regexes and for block control, to avoid conflicts, regexes with curly braces are to be enclosed with double quotes (or single quotes). For example, to rewrite URLs like:
/photos/123456
to:
/path/to/photos/12/1234/123456.png
use the following (note the quotes enclosing the regex):
rewrite "/photos/([0-9] {2})([0-9] {2})([0-9] {2})" /path/to/photos/$1/$1$2/$1$2$3.png;
If you specify a ?
at the end of a rewrite then Nginx will drop the original $args (arguments). When using $request_uri or $uri&$args you should specify the ?
at the end of the rewrite to avoid Nginx doubling the query string.
Example using $request_uri in a rewrite from www.example.com to example.com
server { server_name www.example.com; rewrite ^ http://example.com$request_uri? permanent; }
Also rewrite operates only on path, not parameters. To rewrite a URL with parameters to another URL, use this instead:
Note that the $args variable is not decoded, unlike URIs during location matching.
Also note that named subexpressions (?<name>)
should be used when accessing variables from a map using regular expressions (patterns begininng with ~
) because the map runs on demand and will override $1
(even when named subexpressions are used in the map).
[edit] rewrite_log
syntax: rewrite_log on | off
default: rewrite_log off
context: http, server, if-in-server, location, if-in-location
variables: no
When enabled, outputs information about rewrites to the error log at notice level.
[edit] set
Syntax: | set variable value |
Default: | |
Context: |
server location if |
Reference: | set |
Directive establishes value for the variable indicated. As the value it is possible to use a text, variables and their combination.
You can use set to define a new variable. Note that you can't set the value of a $http_xxx header variable.
[edit] uninitialized_variable_warn
Syntax: |
uninitialized_variable_warn on | off |
Default: | on |
Context: |
http server location if |
Reference: | uninitialized_variable_warn |
Enables or disables logging of warnings about noninitialized variables.
[edit] Internal implementation
Internally, the rewrite directives are compiled at the time the configuration file is loaded into internal codes, usable during the request by the interpreter.
This interpreter is a simple stack virtual machine. For example, the directive:
will be compiled into this sequence:
variable $forbidden checking to zero recovery 403 completion of entire code variable $slow checking to zero checkings of regular expression copying "/" copying $1 copying "/mp3/" copying $2 copying ".mp3" completion of regular expression completion of entire sequence
Note that there is no code for directive limit_rate, since it does not refer to module ngx_http_rewrite_module. The "if" block exists in the same part of the configuration as the "location" directive.
If $slow is true, then what's inside the "if" block is evaluated, and in this configuration limit_rate it is equal to 10k.
Directive:
It is possible to reduce the sequence, if in the regular expression we include the first slash inside the parentheses:
then the sequence will appear like this:
checking regular expression copying $1 copying "/mp3/" copying $2 copying ".mp3" completion of regular expression completion of entire code