如何控制NGINX“位置”指令匹配顺序?

发布于 12-20 02:08 字数 1267 浏览 3 评论 0原文

我正在尝试优化我的“位置”指令,但无法找到确定是否尝试特定位置匹配的好方法。在位置块内使用 echo 在这里没有帮助。

NGINX ngx_http_core_module 文档 有点令人困惑。

要使用正则表达式,必须使用前缀:

  1. ~ 对于区分大小写的匹配

  2. ~* 对于不区分大小写的匹配

如何执行匹配:

  1. 带有与查询匹配的 = 前缀的指令确切地。如果找到,搜索将停止。

  2. 所有剩余的指令都带有常规字符串。如果此匹配使用 ^~ 前缀,则搜索停止。

  3. 正则表达式,按照它们在配置文件中定义的顺序排列。

  4. 如果 #3 产生匹配,则使用该结果。否则,使用 #2 中的匹配。

这里的数字 2 表示“常规字符串”,但随后表示它可以与 ^~ 前缀一起使用。 ~ 不是暗示正则表达式吗?如果不是,它如何确定什么是正则表达式?

具体来说,我想要以下内容:

  1. 直接提供文字 /assets 之外的任何内容。停止搜索。

  2. 通过 fast-CGI STOP SEARCH 提供任何匹配 RegExp \.php$|/$ 的内容。

  3. 直接通过文字 /

    直接通过文字提供其他所有内容

这样,就只有一个 /对从资产外部提供的非动态文件的匹配尝试。

我有:

location ^~ /assets {}      # search-terminating literal? or regex?
location ~ \.php$|/$ {}
location / {}               # is this match always attempted?

从文档来看,实际顺序似乎是 1-3-2,始终运行文字 / 匹配。是的,这种优化不会对实际性能产生任何影响,但我只是想澄清一些歧义。

I'm trying to optimize my 'location' directives and cannot find a good way of determining if a specific location match is even attempted. Using echo inside the location block doesn't help here.

The NGINX ngx_http_core_module documentation is somewhat confusing.

To use regular expressions, you must use a prefix:

  1. ~ For case sensitive matching

  2. ~* For case insensitive matching

How the match is performed:

  1. Directives with the = prefix that match the query exactly. If found, searching stops.

  2. All remaining directives with conventional strings. If this match used the ^~ prefix, searching stops.

  3. Regular expressions, in the order they are defined in the configuration file.

  4. If #3 yielded a match, that result is used. Otherwise, the match from #2 is used.

Number 2 here says "conventional strings" but then says it can be used with the ^~ prefix. Doesn't ~ imply a RegExp? If not, how does it determine what is an isn't a RegExp?

Specifically, I want the following:

  1. Serve anything out of literal /assets directly. STOP SEARCH.

  2. Serve anything matching RegExp \.php$|/$ via fast-CGI STOP SEARCH.

  3. Serve everything else directly via literal /

This way, there is only a / match attempt for non-dynamic files served from outside of assets.

I have:

location ^~ /assets {}      # search-terminating literal? or regex?
location ~ \.php$|/$ {}
location / {}               # is this match always attempted?

From the document, it looks as though the actual order would be 1-3-2, always running the literal / match. Yes, this optimization won't make any difference for real performance, but I just want to clear up some ambiguity.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

山色无中2024-12-27 02:08:21

来自维基:

location  = / {
  # matches the query / only.
  [ configuration A ] 
}
location  / {
  # matches any query, since all queries begin with /, but regular
  # expressions and any longer conventional blocks will be
  # matched first.
  [ configuration B ] 
}

所以,这将首先匹配:
location ~ \.php$ {}

即使资产是在

php 块内的 location / {} 之外提供的,您也希望在传递到 fastcgi 之前防止恶意上传:

if ($uri ~* "^/uploads/") {
  return 404;
}

正如您所看到的,nginx 的工作方式与您的预期略有不同。

From the wiki:

location  = / {
  # matches the query / only.
  [ configuration A ] 
}
location  / {
  # matches any query, since all queries begin with /, but regular
  # expressions and any longer conventional blocks will be
  # matched first.
  [ configuration B ] 
}

So, this will be matched first:
location ~ \.php$ {}

Even though assets are served out of location / {}

Inside the php block you also want to secure against malicious uploads before passing to fastcgi:

if ($uri ~* "^/uploads/") {
  return 404;
}

As you can see nginx works a little bit differently than you might expect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文