开发者

How i can translate uppercase to lowercase letters in a rewrite rule in nginx web server?

I need to translate the address:

www.example.com/TEST in ---> www.exam开发者_JAVA百科ple.com/test


Yes, you are going to need perl.

If you are using Ubuntu, instead of apt-get install nginx-full, use apt-get install nginx-extras, which will have the embedded perl module.

Then, in your configuration file:

  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;
      }
    ...


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


i managed to achieve the goal using embedded perl:

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


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

A location can either be defined by a prefix string, or by a regular expression. Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching), or the “~” modifier (for case-sensitive matching).

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


Based on Adam's answer, I ended up using lua, as it's available on my server.

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


I would like to point out that most of Perl answers are vulnerable to CRLF injection.

You should never use nginx's $uri variable in a HTTP redirection. $uri variable is subject to normalization (more info), including:

  • URL encoded characters are decoded
  • Removal of the ? and query string
  • Consecutive / characters are replace by a single /

URL decoding is the reason of CRLF injection vulnerability. The following example url would add a malicious header into your redirect, if you used $uri variable in the redirection.

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

%0A is decoded to \n\r and nginx will add into headers the following lines:

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

The secure Perl redirection requires to replace all newline characters.

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


Redirect with LUA module.

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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜