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;
}
精彩评论