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

时间:2015-07-07 10:56:03

标签: nginx

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

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

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

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

问题是我的URI包含从客户端传递的编码空间%20

http://example.com/lala%20lala

nginx将URI解码为

http://example.com/lala lala

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

问题是 - 是否有可能以某种方式使用编码的rest变量,因为它是从客户端传递的? 如果我做错了什么,请以正确的方式提出建议。

谢谢。

3 个答案:

答案 0 :(得分:7)

是的,虽然文档也说:

,但预计会出现这种情况

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

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 $1;
}

proxy_pass http://example$modified_uri;

答案 1 :(得分:4)

我使用以下内容与Confluence以及nginx后面的其他Atlassian应用程序取得了一些成功,其中特殊字符如()&lt; &GT; []造成了问题。

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

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

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

答案 2 :(得分:1)

set指令可以解决问题。它可以使编码完整无缺,甚至可以编码解码后的字符串。

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