The last post explained the server and location matching rules for the most common nginx functions, which are the basis for nginx’s implementation of controlled access and reverse proxy. Nginx is a good way to get started with matching rules, but these are often not enough to meet the actual requirements of the scenario, such as request URL rewriting, redirection, etc., which require the request path modification operation, matching rules can not be completed by the actual requirements. This requires mastering another popular nginx feature, rewrite, which will be rewritten below.
Rewrite the rules
The rewrite function is all about rewriting and redirecting urls using nginx-supplied global variables or self-set variables, combined with regular expressions and flag bits. Rewrite can only be used in server{}, location{}, if{}, and only on strings other than arguments passed after domain names, such as baidu.com/a/we/index… /a/we/index.php Grammar:
rewrite regex replacement [flag];
If relative domain names or parameter strings are in play, you can use global variable matching, or you can use proxy_pass reverse proxy.
Rewrite can change the path of a resource in the same domain, whereas location can control access or reverse proxy for a type of path, proxy_pass to other machines. Rewrite will also be written in location in many cases, in this order:
- Execute the rewrite directive for the server block
- Perform a Location match
- Execute the rewrite directive in the selected location
If one of the urIs is overridden, the loop repeats 1-3 until the actual file is found. If this loop is repeated more than 10 times, 500 Internal Server Error is returned.
2.1 Flag Indicates the flag bit
last
: Stops the current executionngx_http_rewrite_module
, but will continue through the request to match the corresponding server or location;break
: Stops the current executionngx_http_rewrite_module
The request is completed.redirect
: Returns 302 temporary redirect, and the address bar displays the redirect addresspermanent
: Returns 301 permanent redirect, and the address bar displays the redirected address
301 and 302 cannot simply return a status code. They must also have a redirected URL. This is why the return directive cannot return 301,302.
There are a few points to emphasize about the above flags:
last
withbreak
Rewriting the URL does not change the address of the address bar
Nginx rewrites the request URL, but the address bar does not change significantly. This is different from Redirect and Permanent.
last
withbreak
Different processing strategies
Both terminate the instruction set of the current ngx_HTTP_rewrite_module, but last immediately initiates a new round of matching requests while Break does not.
redirect
andpermanent
Terminates subsequent nginx instructions
When nginx encounters flag in rewrite as both, subsequent directives will not execute.
server { listen 8080; location = /test { break; return 200 $request_uri; Proxy_pass http://127.0.0.1:8080/other; } location / { return 200 $request_uri; }}
Copy the code
$request_URI = proxy_pass = proxy_pass = proxy_pass = proxy_pass = proxy_pass = proxy_pass This is because:
The return directive belongs to the ngx_HTTP_proxy_module module and is terminated by break; The rewrite module, which is the ngx_HTTP_proxy_module directive, cannot be broken by break.
2.2 If directives and global variables
If (condition){if(condition){… }, judge the given condition. If true, the rewrite directive in braces will be executed, and the if condition (conditon) can be anything like the following:
- When the expression is just a variable, it is false if the value is null or if any string begins with 0
- Used when comparing variables and content directly
=
or! =
~
Regular expression matching,~ *
Case insensitive matching,! ~
Case sensitive mismatch
The -f and! -f determines whether the -d and! Files exist. -d is used to check whether directories -e and! Exist. -e is used to check whether files or directories exist. -x and! -x determines whether the file is executable
Such as:
if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; // Rewrite requests to /msid/ if ($http_cookie ~* "id=([^;]). (+)? :; |$)") { set $id $1; If ($request_method = POST) {return 405; } // If the submit Method is POST, the status 405 (Method not allowed) is returned. If ($slow) {limit_rate 10k; } // Speed limit, $slow can be set to if (! -f $request_filename){ break; Proxy_pass http://127.0.0.1; } // Reverse proxy to localhost if the requested filename does not exist. If ($args ~ post=140){rewrite ^ http://example.com/ permanent; } // If the query string contains "post=140", Permanent redirect to example.com location ~ * \. (GIF | JPG | PNG | SWF | FLV) ${valid_referers none blocked www.jefflei.com www.leizhenfang.com; if ($invalid_referer) { return 404; } // Anti-theft chain}
Copy the code
The global variable
Here are global variables that can be used for if judgments:
$args
This variable is equal to the argument in the request line, as in $query_string$content_length
: Content-Length field in the request header.$content_type
: Content-Type field in the request header.$document_root
: The value specified in the root directive for the current request.$host
: Requests the host header field, otherwise the server name.$http_user_agent
: Indicates client agent information$http_cookie
: Indicates client cookie information$limit_rate
: This variable can limit the connection rate.$request_method
: Action requested by the client, usually GET or POST.$remote_addr
: IP address of the client.$remote_port
: Indicates the port of the client.$remote_user
: User name that has been authenticated by Auth Basic Module.$request_filename
: The file path of the current request, generated by the root or alias directive and the URI request.$scheme
: HTTP method (such as HTTP, HTTPS).$server_protocol
: The protocol used for the request, usually HTTP/1.0 or HTTP/1.1.$server_addr
: Server address, which can be determined after a system call.$server_name
: Server name.$server_port
: Port number for the request to reach the server.$request_uri
: Contains the original URI of the request parameters, excluding the host name, e.g. “/foo/bar.php? Arg = baz “.$uri
: The current URI with no request parameters. $URI does not contain a host name, such as /foo/bar.html.$document_uri
: same as $uri.
Such as:
Example: http://localhost:88/test1/test2/test.php $host: $server_port localhost: 88 $request_uri: http://localhost:88/test1/test2/test.php $document_uri: / test1 / test2 / test. The PHP $document_root: $request_filename: / var/WWW/HTML/var/WWW/HTML/test1 / test2 / test. The PHP
Copy the code
2.3 Common Res
.
: Matches any character except newline?
: Repeat 0 or 1 times+
: Repeat 1 or more times*
: Repeat 0 or more times\d
: Matching number^
: Matches the beginning of the string$
: Matches the end of the string{n}
: Repeat n times{n,}
: Repeat n or more times[c]
: Matches a single character c[a-z]
: Matches any lowercase letter from A to Z
The matching content between the parentheses () can be referenced later by $1, which represents the content in the previous second (). A confusing part of the re is escaping special characters.
2.4 rewrite instance
Case 1:
Log_format imagelog '[$time_local] '$image_file' '$image_type' '$body_bytes_sent' '$status; Rewrite_log on; server { root /home/www; Error_log logs/ rewrite-.log notice; # note here in 'single quotation marks, avoid {} rewrite' ^ / images/([a-z] {2})/([a - z0-9] {5})/(. *) \. (PNG | JPG | GIF) $'/data? file=$3.$4; Set $image_file $3; set $image_file $3; set $image_type $4; } location /data {# specify the log format for the image type and size access_log logs/images.log mian; root /data/images; # Apply the previously defined variables. Try_files /$arg_file /image404.html; try_files /$arg_file /image404.html; } location = /image404.html {# return 404 "image not found\n"; }}
Copy the code
To form such as/images/ef/uh7b3 / test. The PNG’s request, rewritten to/data? /data/images/test. PNG file exists, if it exists, it will respond properly. If it does not exist, rewrite tryfiles to image404 location. Returns a 404 status code.
Example 2:
rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4? width=$2&height=$3? last;
Copy the code
For file requests like /images/bla_500x400.jpg, override to address /resizer/bla.jpg? Width =500&height=400 and continue trying to match location.
Example 3: See SSL page encryption.
2.5. Rewrite needs attention
Rewrite regex replacement [flag]; rewrite regex replacement [flag].
The rewrite directive matches the request URI with the specified regex or, if successful, with replacement. Note the contents of the replacement string here:
1. If replacement starts with http://, https://, or $scheme, nginx is told that this is a redirect (flag is a redirect by default), nginx stops processing the subsequent content and redirects it back to the client.
Location / {# request will be temporarily redirected to http://www.baidu.com/$1 when matching regular expression /test/(.*) # flag defaults to redirect /test/(.*). https://www.baidu.com/$1; The return of 200 'ok'; # no chance to execute}
Copy the code
2. Anything that does not start with replacement is a simple URL rewrite
Rewrite /test/(.*) will rewrite /test/(.*) in sequence. www.baidu.com/$1; The return of 200 'ok'; Rewrite is executed sequentially.
Copy the code
Redirect port: redirect port: redirect port: redirect port: redirect port
Nginx {listen 8000; location /test1/ { rewrite /test1/index.html http://server1.com/demo/test1 redirect; } location /test2/ { rewrite /test2/index.html /demo/test2 redirect; Proxy_pass http://192.168.1.3:8000; }}
Copy the code
When accessing server.com/test1/index… , will hit/test1 location rules, the corresponding content has been failed to server1.com, found that redirect response after the head of the location of the field values to server1.com: 8000 / demo/test1, with 8000 ports, we are not configured, the performance of the more bizarre?
Visit server.com/test2/index… , hit/test2 location rules, the same access to fail, but access to redirect response header after the location field values to server.com: 8000 / demo/test2, its with server.com server_name and 8000 ports, more strange?
See the above phenomenon, confused; Nginx server_name_in_redirect and port_in_redirect directives:
In the absolute path, Server_name_in_redirect and port_IN_redirect directives specify whether the server_name and LISTEN ports in the server block are used as redirect. The full URL for redirection is determined by $scheme and server_name_in_redirect and port_in_redirect.
In absolute paths, server_name_IN_redirect is disabled by default, while port_IN_redirect is enabled by default. For absolute paths with $scheme redirection, nginx gets the specified server_name and port from replacement for the redirection:
First, if a port is not specified in replacement with the request protocol HTTP (s), nginx defaults to the listen port of the current server as the redirection port. This is the above visit server.com/test1/index… When redirected to server.com: 8000 / demo/test2 will carry 8000 reasons.
Second, if replacement does not include the request protocol HTTP (s) and is an absolute address relative to the local server, as in server.com/test2/index… , server_name_in_redirect at this time due to disable it will ask the host to as server_name, take the current server listen port as port redirection, eventually redirect to server.com: 8000 / demo/test2.
You may ask, visit server.com/test2/index… Why not redirected to http://192.168.1.3:8000/demo/test2? This is because the rewrite redirect flag will stop subsequent directives from executing, so subsequent proxy_pass directives will not execute.
reference
- www.nginx.cn/216.html
- www.ttlsa.com/nginx/nginx…
- Segmentfault.com/a/119000000…