在 nginx 映射中使用带有特殊字符的 URL

在 nginx 映射中使用带有特殊字符的 URL

使用 nginx 和映射时,可以使用映射文件重写多个 URL。问题是当 URL 包含特殊字符时。我一直在绞尽脑汁试图解决这个问题,希望这个问题/解决方案可以让其他人免于白发苍苍。

让我们设定一下场景。

运行标准 nginx 的 Linux 服务器 (Debian/Ubuntu)。指向此服务器的 DNS 可解析为服务器配置。包含传入和传出 URL 的重复条目的 Map(可解析)

地图设置包含以下内容:

map $host$request_uri $rewrite_uri {
    include /<path to file filename>;
}

地图文件本身每行包含一个条目,以分号结尾。

example.com/Böhme https://anotherexample.org/SomeWeirdPath/Böhme;

此映射工作的服务器配置

server {
    listen 443 ssl http2;
    ssl_certificate /<absolute path to crt file>;
    ssl_certificate_key /<absolute path to key file>;
    server_name example.com;
    proxy_set_header X-Forwarded-For $remote_addr;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_dhparam <absolute path to Diffie Hellman key>;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
    server_tokens off;
    if ($rewrite_uri) {
            rewrite ^ $rewrite_uri redirect;
    }
    rewrite ^ <default URL> redirect;
}

我简化了此服务器配置的配置,以便我们可以专注于地图设置。配置假定域将使用 SSL 并且证书有效。仅当 $host$request_uri 位于具有 $rewrite_uri 的列表中时,才会执行 if 语句,否则将执行最后一个重写。

问题

我该如何转换 $request_uri 以便 nginx 正确理解它?映射文件包含 UTF8 格式的值,但 nginx 似乎想要 URL 编码的 $request_uri 和十六进制格式。

$request_uri 与 mapfile 中的一样

example.com/Böhme

$request_uri 根据浏览器进行 URL 编码

example.com/B%C3%B6hme

$request_uri 因为我认为 nginx 需要它

example.com/B\xC3\xB6hme

我似乎找不到具有此功能的系统包,但我想我开始在这里重新发明轮子。

我需要:

创建一个函数,按照 URL 编码列表如何在 shell 中解码 URL 编码的字符串?

function urldecode() { local i="${*//+/ }"; echo -e "${i//%/\\x}"; }

然后按照使用八进制转储在命令行上将字符串转换为十六进制,因此在内存中创建了具有正确值的映射存储桶如果詳細說明測試。

这开始让人感觉像是火箭科学,我无法相信以前没有其他人解决过这个问题,我似乎找不到解决方案。

相关内容