【问题标题】:The last & break mechanism in nginx rewritenginx rewrite 中的 last & break 机制
【发布时间】:2017-05-23 19:25:22
【问题描述】:

我现在正在为我的项目处理 nginx 重写,但有些事情超出了我的预期,请与您分享,看看是否有任何合理的建议。

下面的nginx服务器设置列表:

location /download/ {
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3;
    rewrite ^(/download/.*)/movie/(.*)\..*$ $1/avi/$2.mp3 break;
    rewrite ^(/download/.*)/avvvv/(.*)\..*$ $1/rmvb/$2.mp3;
}

从上面的部分可以看到,我只添加了一个下载位置和三个重写规则。我在nginx中打开调试日志并启动它来加载这个设置。

现在我们在浏览器中输入 url:localhost/download/123/movie/UBW.avi。从日志中我们可以看到规则被命中,日志如下:

2017/05/22 15:27:27 [notice] 1904#12520: *85 "^(/download/.*)/media/(.*)\..*$" does not match "/download/123/movie/UBW.avi", client: 127.0.0.1, server: localhost, request: "GET /download/123/movie/UBW.avi HTTP/1.1", host: "localhost"
2017/05/22 15:27:27 [notice] 1904#12520: *85 "^(/download/.*)/movie/(.*)\..*$" matches "/download/123/movie/UBW.avi", client: 127.0.0.1, server: localhost, request: "GET /download/123/movie/UBW.avi HTTP/1.1", host: "localhost"
2017/05/22 15:27:27 [notice] 1904#12520: *85 rewritten data: "/download/123/avi/UBW.mp3", args: "", client: 127.0.0.1, server: localhost, request: "GET /download/123/movie/UBW.avi HTTP/1.1", host: "localhost"
2017/05/22 15:27:27 [error] 1904#12520: *85 CreateFile() "D:\Soft\nginx-1.13.0/html/download/123/avi/UBW.mp3" failed (3: The system cannot find the path specified), client: 127.0.0.1, server: localhost, request: "GET /download/123/movie/UBW.avi HTTP/1.1", host: "localhost"

从上面的信息中,我们可以看到第二条规则被命中,并且由于“break”关键字而分节。这种行为在我们的预料之中。

但是我改变了下面的部分并表现出与上面相同的行为:

location /download/ {
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3;
    rewrite ^(/download/.*)/movie/(.*)\..*$ $1/avi/$2.mp3 last;
    rewrite ^(/download/.*)/avvvv/(.*)\..*$ $1/rmvb/$2.mp3;
}

下面的日志:

2017/05/22 15:33:45 [notice] 11244#11544: *92 "^(/download/.*)/media/(.*)\..*$" does not match "/download/123/movie/UBW.avi", client: 127.0.0.1, server: localhost, request: "GET /download/123/movie/UBW.avi HTTP/1.1", host: "localhost"
2017/05/22 15:33:45 [notice] 11244#11544: *92 "^(/download/.*)/movie/(.*)\..*$" matches "/download/123/movie/UBW.avi", client: 127.0.0.1, server: localhost, request: "GET /download/123/movie/UBW.avi HTTP/1.1", host: "localhost"
2017/05/22 15:33:45 [notice] 11244#11544: *92 rewritten data: "/download/123/avi/UBW.mp3", args: "", client: 127.0.0.1, server: localhost, request: "GET /download/123/movie/UBW.avi HTTP/1.1", host: "localhost"
2017/05/22 15:33:45 [notice] 11244#11544: *92 "^(/download/.*)/media/(.*)\..*$" does not match "/download/123/avi/UBW.mp3", client: 127.0.0.1, server: localhost, request: "GET /download/123/movie/UBW.avi HTTP/1.1", host: "localhost"
2017/05/22 15:33:45 [notice] 11244#11544: *92 "^(/download/.*)/movie/(.*)\..*$" does not match "/download/123/avi/UBW.mp3", client: 127.0.0.1, server: localhost, request: "GET /download/123/movie/UBW.avi HTTP/1.1", host: "localhost"
2017/05/22 15:33:45 [notice] 11244#11544: *92 "^(/download/.*)/avvvv/(.*)\..*$" does not match "/download/123/avi/UBW.mp3", client: 127.0.0.1, server: localhost, request: "GET /download/123/movie/UBW.avi HTTP/1.1", host: "localhost"
2017/05/22 15:33:45 [error] 11244#11544: *92 CreateFile() "D:\Soft\nginx-1.13.0/html/download/123/avi/UBW.mp3" failed (3: The system cannot find the path specified), client: 127.0.0.1, server: localhost, request: "GET /download/123/movie/UBW.avi HTTP/1.1", host: "localhost"

从日志的第二行,我们可以看到规则被命中了,但是随后nginx为下载部分开始了一个新的循环,奇怪的是,它没有命中规则,为什么?

另外,如果我们使用 last 关键字,那么 nginx 会尝试循环该部分多少次,默认是两次,对吗?

【问题讨论】:

  • @MattiaDinosaur thx,我浏览了上面的网址,答案是我以前知道的,但我的问题与它不一样。
  • 你的问题是什么?如果你的问题是为什么最后一个指令之后,它不符合规则,我可以回答原因。
  • @MattiaDinosaur,是的,请。
  • 重写的 URI 缺少文本 /movie/,那么您为什么希望它匹配第二条规则?

标签: nginx url-rewriting break


【解决方案1】:

ngx_http_rewrite_module 模块用于更改请求 URI 使用 PCRE正则表达式

记住,当你重写 uri 时,uri 会改变。

对于last

当 rewrite 模块遇到 last 时,它停止处理当前集合 并且重写的请求被传递再次以找到合适的 位置(以及新的重写规则集)。

在你的配置中

location /download/ {
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3;  //a
    rewrite ^(/download/.*)/movie/(.*)\..*$ $1/avi/$2.mp3 last; //b
    rewrite ^(/download/.*)/avvvv/(.*)\..*$ $1/rmvb/$2.mp3;    //c
}

你的网址localhost/download/123/movie/UBW.avi

您的请求 uri 是 /download/123/movie/UBW.avi


第一关

/download/123/movie/UBW.avi匹配b,所以uri重写为/download/123/avi/UBW.mp3,第一遍完成。


第二遍

然后,在第二遍中,uri 是

/download/123/avi/UBW.mp3

所以它不匹配a b c,最后,它会在日志中抛出错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-16
    • 2012-03-27
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 2013-11-06
    相关资源
    最近更新 更多