Nginx - 编码(规范化)URI 的一部分

Nginx - encoding (normalizing) part of URI

我有 nginx location 指令,其目的是 "remove" 来自 proxy_pass 指令的 URI 的本地化前缀。

例如,使 URI http://example.com/en/lalala use proxy_pass http://example.com/lalala

location ~ '^/(?<locale>[\w]{2})(/(?<rest>.*))?$' {
        ...
        proxy_pass http://example/$rest;
        ...
}

这样 rest 变量在传递给 proxy_pass directeve 时将被解码。这似乎是预期的 behavior.

问题是当我的 URI 包含从客户端

传递的编码 space %20
http://example.com/lala%20lala

nginx 将 URI 解码为

http://example.com/lala lala

我可以在我的 error.log 中看到它。

问题是 - 是否可以使用编码的 rest 变量,因为它是从客户端传递过来的? 如果我做的事情完全错误,请提出正确的方法。

谢谢。

是的,这种行为是预期的,尽管文档也说:

如果指定 proxy_pass 时不带 URI,请求 URI 将以与处理原始请求时客户端发送的相同形式传递给服务器,或者在处理时传递完整的规范化请求 URI处理更改后的 URI:

location /some/path/ {
    proxy_pass http://127.0.0.1;
}

Nginx 工程师也这么说:https://serverfault.com/questions/459369/disabling-url-decoding-in-nginx-proxy

但是,如果您将 $request_uri 附加到 proxy_pass(并且事先去除区域设置,它可能会被 Nginx 工程师用作 said):

set $modified_uri $request_uri;

if ($modified_uri ~ "^/([\w]{2})(/.*)") {
set $modified_uri ;
}

proxy_pass http://example$modified_uri;

我在使用 Confluence 和 nginx 背后的其他 Atlassian 应用程序时取得了一些成功,其中 ( ) < > [ ] 等特殊字符导致了问题。

location /path {
  # [... other proxy options ...]

  # set proxy path with regex
  if ($request_uri ~* "/path(/.*)") { 
    proxy_pass http://server:port/path;
    break;
  }

  # fallback (probably not needed)
  proxy_pass http://server:port/path;
}

set 指令可以解决问题。它保持编码完整或更确切地说编码解码字符串。

location ~ '^/(?<locale>[\w]{2})(/(?<rest>.*))?$' {
        ...
        set $encoded_rest $rest
        proxy_pass http://example/$encoded_rest;
        ...
}