【问题标题】:How i can translate uppercase to lowercase letters in a rewrite rule in nginx web server?我如何在 nginx Web 服务器的重写规则中将大写字母转换为小写字母?
【发布时间】:2011-04-09 14:57:03
【问题描述】:

我需要翻译地址:

www.example.com/TEST in ---> www.example.com/test

【问题讨论】:

    标签: nginx rewrite uppercase lowercase


    【解决方案1】:

    是的,您将需要 perl。如果您使用的是 Ubuntu,而不是 apt-get install nginx-full,请使用 apt-get install nginx-extras,它将具有嵌入式 perl 模块。 然后,在您的配置文件中:

      http {
      ...
        # Include the perl module
        perl_modules perl/lib;
        ...
        # Define this function
        perl_set $uri_lowercase 'sub {
          my $r = shift;
          my $uri = $r->uri;
          $uri = lc($uri);
          return $uri;
        }';
        ...
        server {
        ...
          # As your first location entry, tell nginx to rewrite your uri,
          # if the path contains uppercase characters
          location ~ [A-Z] {
            rewrite ^(.*)$ $scheme://$host$uri_lowercase;
          }
        ...
    

    【讨论】:

    • 效果很好,虽然我的查询参数确实被剥夺了。
    • 这对我有用。在 ubuntu 上,我需要 apt-get install nginx-extras。还有location ~ [A-Z] {... 代码我放在一个特定的 nginx conf 文件中(对于有多个站点的服务器)
    • 还为实际使用它们的人提供了一个要点。 gist.github.com/KalobTaulien/eb5851ee42343aac614ab6e6cfe90245 基本上是相同的代码,但是我在上面的评论中解释的方式——对新手更友好一点
    • 这太棒了,我正在寻找其他东西,这非常适合。向您致敬,先生!
    【解决方案2】:
    location /dupa/ {
        set_by_lua $request_uri_low "return ngx.arg[1]:lower()" $request_uri;
        rewrite ^ https://$host$request_uri_low;
    }
    

    【讨论】:

    • 您可能希望使用 301 而不是 302 用于 SEO 目的,例如:rewrite ^ https://$host$request_uri_low permanent;
    • ...和return: return 301 $request_url_low.
    【解决方案3】:

    我设法使用嵌入式 perl 实现了目标:

    location ~ [A-Z] {
      perl 'sub { my $r = shift; $r->internal_redirect(lc($r->uri)); }';
    }
    

    【讨论】:

    • 它可能会解决发布的问题,但“忽略大小写”和“小写”是两个完全不同的东西。
    • 如果您不想重写地址并在地址字段中的任何情况下回答真实页面,则此方式兼容。感谢您提供解决问题的其他方法。
    【解决方案4】:
    location ~*^/test/ {
      return 301 http://www.example.com/test;
    }
    

    位置可以由前缀字符串或正则表达式定义。正则表达式由前面的“~*”修饰符(用于不区分大小写的匹配)或“~”修饰符(用于区分大小写的匹配)指定。

    来源:http://nginx.org/en/docs/http/ngx_http_core_module.html#location

    【讨论】:

      【解决方案5】:

      根据 Adam 的回答,我最终使用了 lua,因为它在我的服务器上可用。

      set_by_lua $request_uri_low "return ngx.arg[1]:lower()" $request_uri;
      if ($request_uri_low != $request_uri) {
         set $redirect_to_lower 1;
      }
      if (!-f $request_uri) {
          set $redirect_to_lower "${redirect_to_lower}1";
      }
      if ($redirect_to_lower = 11) {
          rewrite . https://$host$request_uri_low permanent;
      }
      

      【讨论】:

      • 小心这个答案。如果是邪恶的:nginx.com/resources/wiki/start/topics/depth/ifisevil
      • @MacroMan 只有在location 上下文中使用它才可能是不安全的,并且取决于此配置片段后面的内容。在大多数情况下,这应该是完全安全的。
      【解决方案6】:

      我想指出,大多数 Perl 答案都容易受到 CRLF 注入。

      你不应该在 HTTP 重定向中使用 nginx 的 $uri 变量。 $uri 变量需要规范化(more info),包括:

      • 对 URL 编码的字符进行解码
      • 删除 ?和查询字符串
      • 连续的 / 字符被单个 / 替换

      URL解码是CRLF注入漏洞的原因。如果您在重定向中使用了 $uri 变量,则以下示例 url 将在重定向中添加恶意标头。

      https://example.org/%0ASet-Cookie:MaliciousHeader:Injected

      %0A 被解码为 \n\r 并且 nginx 将在标题中添加以下行:

      Location: https://example.org
      set-cookie: maliciousheader:injected
      

      安全的 Perl 重定向需要替换所有换行符。

      perl_set $uri_lowercase 'sub {
          my $r = shift;
          my $uri = $r->uri;
          $uri =~ s/\R//; # replace all newline characters
          $uri = lc($uri);
          return $uri;
      }';
      

      【讨论】:

        猜你喜欢
        • 2020-09-11
        • 1970-01-01
        • 2013-02-04
        • 2015-08-07
        • 2015-07-28
        • 1970-01-01
        • 1970-01-01
        • 2013-07-26
        • 1970-01-01
        相关资源
        最近更新 更多