如何在nginx web服务器中将大写字母转换为小写字母?

nfeuvbwi  于 2023-05-28  发布在  Nginx
关注(0)|答案(8)|浏览(262)

我需要翻译地址:
www.example.com/TEST in ---> www.example.com/test

hm2xizp9

hm2xizp91#

是的,你将需要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;
      }
    ...
vvppvyoh

vvppvyoh2#

location /dupa/ {
    set_by_lua $request_uri_low "return ngx.arg[1]:lower()" $request_uri;
    rewrite ^ https://$host$request_uri_low;
}
sycxhyv7

sycxhyv73#

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

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

bq9c1y664#

location ~*^/test/ {
  return 301 http://www.example.com/test;
}

位置可以由前缀字符串或正则表达式定义。正则表达式使用前面的**"~*”修饰符(用于不区分大小写的匹配)**或“~”修饰符(用于区分大小写的匹配)指定。
来源:http://nginx.org/en/docs/http/ngx_http_core_module.html#location

gopyfrb3

gopyfrb35#

基于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;
}
zz2j4svz

zz2j4svz6#

我想指出的是,大多数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;
}';
bxfogqkk

bxfogqkk7#

使用LUA模块重定向。

load_module /usr/lib/nginx/modules/ndk_http_module.so;
load_module /usr/lib/nginx/modules/ngx_http_lua_module.so;

set_by_lua $uri_lowercase "return string.lower(ngx.var.uri)";
location ~[A-Z] {
  return 301 $scheme://$http_host$uri_lowercase$is_args$args;
}
nhjlsmyf

nhjlsmyf8#

我在互联网上看到了这个代码,它确实有效。但是,它使用nginx服务器接收的主机名。在Kubernetes基础设施的情况下,这可能与客户端使用的内容不同,因此重定向不仅会失败,还会给予有关集群命名方案的私有信息。
这段代码对我来说很管用,而且稍微快一点,因为它使用了内部重定向

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

它可以在nginx配置文件中使用,如下所示:

user        nginx; # Not important for this answer, use any user you want
                   # but nginx is a sensible default.

# Load the Perl module
load_module /usr/lib/nginx/modules/ngx_http_perl_module.so;

...

http {
    server {
        # Given any location that contains an upper-case letter
        location ~ [A-Z] {
            # Lowercase it and redirect internally
            perl 'sub {
                my $r = shift;
                my $uri = $r->uri;
                $uri =~ s/\R//; # replace all newline characters
                $uri = lc($uri);
                $r -> internal_redirect($uri)
            }';
        }

        # This can be any set of rules, below is a simple one that hosts
        # static content. It will receive the lower-cased location and
        # serve it.
        location / {
            root  /usr/share/nginx/html;
            index index.html;
        }
    }
}

我的Dockerfile以这一行开始,不需要额外的包:

FROM nginx:1.23.4-perl

在这个例子中,你需要将你的静态站点复制到/usr/share/nginx/html,例如:

COPY nginx.conf /etc/nginx/nginx.conf
COPY src/ /usr/share/nginx/html

相关问题