Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the difference between Last and break flag

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/01 Report--

What is the difference between Last and break flag? for this question, this article introduces the corresponding analysis and solution in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible way.

Rewrite (URL rewrite) instructions can appear under server {} or under location {}, there is a difference between them! For rewrite instructions that appear under server {}, they are executed before the location matches Of course, the execution of the rewrite instruction under location {} is after the location match, but because rewrite causes the URI of the HTTP request to change, the URI after the rewrite under location {} needs to re-match the location, just like a new HTTP request. (note that the maximum number of such circular matches caused by the rewrite in location {} is no more than 10 times, otherwise nginx will report a 500 error). Generally speaking, if there is rewrite under both server {} and location {}, server {} is still executed first, and then location matching is performed. If there is a rewrite instruction within the matched location {}, then continue to execute rewrite. At the same time, because the rewrite in location {} has changed the URI, the rewritten result URI needs to be re-matched with location as a new request (which should also include re-executing rewrite under server {}).

The difference between Last and break flag

The official document describes the difference between last flag and break flag as "last-completes processing of rewrite directives, after which searches for corresponding URI and location" and "break-completes processing of rewrite directives", both of which mean "do not allow subsequent rewrite instructions to be executed", but the difference has not been unfolded.

Here I use experiments to tell you the difference. Preparation for the experiment:

1. Install nginx; (if you don't know anything about installation and location, please refer to: http://eyesmore.iteye.com/blog/1141660)

2. Create four files under the html subdirectory of the nginx installation directory, which are called aaa.html, bbb.html, ccc.html and ddd.html, with their respective file names (for example, aaa html file can be written in the aaa.html file).

3. The initialization of Nginx configuration file is:

The log of the error_log logs/error.log info; # URL rewriting module is written to this file

Server {

Listen 9090

Server_name localhost

Root html

Rewrite_log on; # turn on the log switch of the URL rewrite module to write to error_log

Location / aaa.html {

Rewrite "^ / aaa\ .html $" / bbb.html

Rewrite "^ / bbb\ .html $" / ddd.html

}

Location / bbb.html {

Rewrite "^ / bbb\ .html $" / ccc.html

}

}

There are two points to note in the above configuration: 1. Turn on the log switch of the rewrite module so that rewrite can perform log writing to error_log (Note: the level at which rewrite logs are written to error_log is notice, so pay attention to the error_log log level, where info is used) 2. Two location are defined, which are / aaa.html and / bbb.html, but in / aaa.html, rewrite / aaa.html to / bbb.html, then / bbb.html to / ddd.html; in / bbb.html, rewrite / bbb.html to / ccc.html.

[test 1] when there are no last and break tags: request aaa.html

[root@web108 ~] # curl http://localhost:9090/aaa.html

Ddd html file

[root@web108 ~] #

The log content of Error_log:

22:13:23 on 2011-08-07 [notice] 9066: 0: * 85 "^ / aaa\ .html $" matches "/ aaa.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

22:13:23 on 2011-08-07 [notice] 9066 rewritten data: * 85 rewritten data: "/ bbb.html", args: "", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

22:13:23 on 2011-08-07 [notice] 9066: 0: * 85 "^ / bbb\ .html $" matches "/ bbb.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

22:13:23 on 2011-08-07 [notice] 9066 rewritten data: * 85 rewritten data: "/ ddd.html", args: "", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

22:13:23 on 2011-08-07 [info] 9066 closed keepalive connection: * 85 client 127.0.0.1 closed keepalive connection

The log of the URL rewriting module tells us that for a HTTP request "GET / aaa.html", the rewriting process is as follows: first / aaa.html is rewritten as / bbb.html Then rewritten data: / bbb.html, continue to execute the following rewrite instructions, and then be rewritten as / ddd.html, and then rewrittern data: / ddd.html will not be rewritten (in fact, / ddd.html needs to rematch location again at this time, but the log is not reflected, which will be reflected in the next test 2), so output the contents of / ddd.html.

[test 2] when using last tags: request aaa.html

Modify the above location / aaa.html {} to:

Location / aaa.html {

Rewrite "^ / aaa\ .html $" / bbb.html last

Rewrite "^ / bbb\ .html $" / ddd.html

}

Test results:

[root@web108 ~] # curl http://localhost:9090/aaa.html

Ccc html file

[root@web108 ~] #

Error_log log:

22:24:31 on 2011-08-07 [notice] 18569500: * 86 "^ / aaa\ .html $" matches "/ aaa.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

22:24:31 on 2011-08-07 [notice] 1856940: * 86 rewritten data: "/ bbb.html", args: "", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

22:24:31 on 2011-08-07 [notice] 18569500: * 86 "^ / bbb\ .html $" matches "/ bbb.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

22:24:31 on 2011-08-07 [notice] 1856940: * 86 rewritten data: "/ ccc.html", args: "", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

22:24:31 on 2011-08-07 [info] 18569 closed keepalive connection: * 86 client 127.0.0.1 closed keepalive connection

I wonder if the reader will be surprised to see the result "ccc html file" displayed by GET / aaa.html: "Why the result is not bbb html file". The whole process is explained below: first / aaa.html matches location / aaa.html {}, so execute rewrite "^ / aaa\ .html $" / bbb.html last, rewrite / aaa.html as / bbb.html, and the subsequent rewrite instruction (referring to rewrite "^ / bbb\ .html $" / ddd.html) will not be executed because of the use of last flag. It seems that "bbb html file" should be output at this time, but let's take a look at the nginx official explanation: "last-completes processing of rewrite directives, after which searches for corresponding URI and location" means that the last no longer matches the following rewrite instructions, but then you need to rematch the location for the rewritten URI. Let's look at the official "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. "so, when you rematch, you match the new location / bbb.html {}, execute" rewrite "^ / bbb\ .html $" / ccc.html ", and the final content is" ccc html file ".

[test 3] when using break tags: request aaa.html

Modify the above location / aaa.html {} to use the break tag:

Location / aaa.html {

Rewrite "^ / aaa\ .html $" / bbb.html break

Rewrite "^ / bbb\ .html $" / ddd.html

}

Test results:

[root@web108 ~] # curl http://localhost:9090/aaa.html

Bbb html file

[root@web108 ~] #

Log results:

22:37:49 on 2011-08-07 [notice] 21069 / 0: * 89 "^ / aaa\ .html $" matches "/ aaa.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

22:37:49 on 2011-08-07 [notice] 21069: * 89 rewritten data: "/ bbb.html", args: "", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

22:37:49 on 2011-08-07 [info] 21069 closed keepalive connection: * 89 client 127.0.0.1 closed keepalive connection

I think this result does not need to be explained, and fully reflects the difference between break and last: "last-completes processing of rewrite directives, after which searches for corresponding URI and location" and "break-completes processing of rewrite directives". Both Break and last can prevent subsequent rewrite instructions from being executed, but if last is used under location, location will be rematched for the rewritten URI, but break will not rematch location. To put it simply, break terminates more thoroughly than last (for the convenience of memory, we can understand the re-matching URI location as "the next iteration of the URI matching location loop statement". In high-level programming, break is generally used to exit the loop, so break not only terminates and continues to execute rewrite, but also exits the loop iteration in which URI rematches location).

The second example of Nginx's iteration on Rewrite

Configuration:

Error_log logs/error.log info

Server {

Listen 9090

Server_name localhost

Root html

Rewrite_log on

Rewrite "^ / aaa\ .html $" / bbb.html

Location / ccc.html {

Rewrite "^ / ccc\ .html $" / eee.html

}

Location / bbb.html {

Rewrite "^ / bbb\ .html $" / ccc.html

Rewrite "^ / ccc\ .html $" / ddd.html

}

}

Results:

[root@web108 ~] # curl http://localhost:9090/aaa.html

Ddd html file

[root@web108 ~] #

Log:

10:05:41 on 2011-08-08 [notice] 31592 / 0: * 90 "^ / aaa\ .html $" matches "/ aaa.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

2011-08-08 10:05:41 [notice] 31592: * 90 rewritten data: "/ bbb.html", args: "", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:05:41 on 2011-08-08 [notice] 31592 / 0: * 90 "^ / bbb\ .html $" matches "/ bbb.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

2011-08-08 10:05:41 [notice] 31592: * 90 rewritten data: "/ ccc.html", args: "", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:05:41 on 2011-08-08 [notice] 31592 / 0: * 90 "^ / ccc\ .html $" matches "/ ccc.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

2011-08-08 10:05:41 [notice] 31592: * 90 rewritten data: "/ ddd.html", args: "", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:05:41 on 2011-08-08 [notice] 31592 / 0: * 90 "^ / aaa\ .html $" does not match "/ ddd.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:05:41 on 2011-08-08 [info] 31592 closed keepalive connection: * 90 client 127.0.0.1 closed keepalive connection

Explanation:

GET / aaa.html request, first execute the server-level rewrite instruction, which is rewritten as / bbb.html, then match to location / bbb.html {}, and then execute the location-level rewrite instruction, first rewritten as / ccc.html, then rewritten as / ddd.html Because URI is rewritten by the rewrite instruction at the location level, it is necessary to rematch the location, which means that the rewritten URI is treated as a new request, which reexecutes the rewrite at the server level, and then rematches the location. The log "2011-08-08 10:05:41 [notice] 31592pm 0: * 90" ^ / aaa\ .html $"does not match" / ddd.html ", client: 127.0.0.1, server: localhost, request:" GET / aaa.html HTTP/1.1 ", host:" localhost:9090 "" reflects the process of rematching location.

Example 2

Configuration:

Error_log logs/error.log info

Server {

Listen 9090

Server_name localhost

Root html

Rewrite_log on

Rewrite "^ / aaa\ .html $" / bbb.html

Rewrite "^ / ccc\ .html $" / ddd.html

Location / bbb.html {

Rewrite "^ / bbb\ .html $" / ccc.html

}

Location / ddd.html {

Rewrite "^ / ddd\ .html $" / eee.html

}

}

Results:

[root@web108 ~] # curl http://localhost:9090/aaa.html

Eee html file

[root@web108 ~] #

Log:

10:21:00 on 2011-08-08 [notice] 2218: 0: * 91 "^ / aaa\ .html $" matches "/ aaa.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:21:00 on 2011-08-08 [notice] 2218 rewritten data: * 91 rewritten data: "/ bbb.html", args: "", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:21:00 on 2011-08-08 [notice] 2218: 0: * 91 "^ / ccc\ .html $" does not match "/ bbb.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:21:00 on 2011-08-08 [notice] 2218: 0: * 91 "^ / bbb\ .html $" matches "/ bbb.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:21:00 on 2011-08-08 [notice] 2218 rewritten data: * 91 rewritten data: "/ ccc.html", args: "", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:21:00 on 2011-08-08 [notice] 2218: 0: * 91 "^ / aaa\ .html $" does not match "/ ccc.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:21:00 on 2011-08-08 [notice] 2218: 0: * 91 "^ / ccc\ .html $" matches "/ ccc.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:21:00 on 2011-08-08 [notice] 2218 rewritten data: * 91 rewritten data: "/ ddd.html", args: "", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:21:00 on 2011-08-08 [notice] 2218: 0: * 91 "^ / ddd\ .html $" matches "/ ddd.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:21:00 on 2011-08-08 [notice] 2218 rewritten data: * 91 rewritten data: "/ eee.html", args: "", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:21:00 on 2011-08-08 [notice] 2218: 0: * 91 "^ / aaa\ .html $" does not match "/ eee.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:21:00 on 2011-08-08 [notice] 2218: 0: * 91 "^ / ccc\ .html $" does not match "/ eee.html", client: 127.0.0.1, server: localhost, request: "GET / aaa.html HTTP/1.1", host: "localhost:9090"

10:21:00 on 2011-08-08 [info] 2218 closed keepalive connection: * 91 client 127.0.0.1 closed keepalive connection

Explanation:

The first iteration of location matching

GET / aaa.html, first perform a server-level rewrite, "rewrite" ^ / aaa\ .html $"/ bbb.html" rewrites / aaa.html as / bbb.html, but / bbb.html does not match "rewrite" ^ / ccc\ .html $"/ ddd.html", and finally retains / bbb.html Next, match location / bbb.html {}, execute the location-level rewrite instruction, and rewrite / bbb.html as / ccc.html. Since URI is rewritten by location-level rewrite, location matching needs to be iterated again.

The second iteration of location matching

For the result of the first iteration / ccc.html, the first step is still to execute the server-level rewrite instruction. "rewrite" ^ / aaa\ .html $"/ bbb.html;" does not match / ccc.html, but "rewrite" ^ / ccc\ .html $"/ ddd.html;" rewrites / ccc.html as / ddd.html After the server-level rewrite is executed, it is followed by location matching, / ddd.html matching to location / ddd.html {}, execution of location-level rewrite instructions, and rewriting / ddd.html to / eee.html. Also because URI is rewritten by rewrite instructions at the location level, location matching needs to be iterated again.

The third iterative location matching

For the result of the second iteration / eee.html, first still execute the server-level rewrite instruction, "rewrite" ^ / aaa\ .html $"/ bbb.html;" and "rewrite" ^ / ccc\ .html $"/ ddd.html;", but none of them match / eee.html, followed by / eee.html location match, no, the final result is / eee.html, return to the "eee html file" page.

Finally, if you modify the above configuration to the editing order of server-level rewrite and location:

Server {

Listen 9090

Server_name localhost

Root html

Rewrite_log on

Location / bbb.html {

Rewrite "^ / bbb\ .html $" / ccc.html

}

Location / ddd.html {

Rewrite "^ / ddd\ .html $" / eee.html

}

Rewrite "^ / aaa\ .html $" / bbb.html

Rewrite "^ / ccc\ .html $" / ddd.html

}

The result is unaffected, that is, the location matching iteration always performs server-level rewrite, then location matching, and then location-level rewrite. If the URI is rewritten by location-level rewrite instructions, the next iteration is required. However, the total number of iterations is no more than 10, otherwise nginx reports 500 errors.

Simple pseudocode describes the rewrite execution process:

Boolean match_finish = false

Int match_count = 0

While (! match_finish & & match_count < 10) {

Match_count + +

(1) execute server-level rewrite instructions in editing order

(2) match location according to the rewritten URI

(3)

String uri_before_location = uri

Execute location-level rewrite instructions in editing order

String uri_after_location = rewrite (uri)

If (uri_before_location! = uri_after_location) {

Match_finish = false

} else {

Match_finish = true

}

If (location rewrite has last flag) {

Continue;// means not to execute the following rewrite and go straight to the next iteration.

}

If (location rewrite has break flag) {

Break;// means not to execute the following rewrite and to exit the loop iteration

}

}

If (match_count

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report