30

I need to translate the address:

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

ErikE
  • 43,574
  • 19
  • 137
  • 181
Peak
  • 301
  • 1
  • 3
  • 5

5 Answers5

18

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;
      }
    ...
Thiago Ganzarolli
  • 1,111
  • 12
  • 17
  • Works well, although my query params do get stripped. – Jonathan Mar 06 '17 at 15:02
  • This worked for me. On ubuntu I needed to `apt-get install nginx-extras`. And the `location ~ [A-Z] {...` code I put inside a specific nginx conf file (for servers that have multiple sites on them) – Kalob Taulien Nov 22 '18 at 19:34
  • 1
    Also made a gist for anyone who actually uses those. https://gist.github.com/KalobTaulien/eb5851ee42343aac614ab6e6cfe90245 It's basically the same code, but the way I explained in the comment above — a little more newbie friendly – Kalob Taulien Nov 22 '18 at 19:43
  • This is brilliant, I was looking for something else and this fits perfectly. Kudos to you sir! – Travis D Feb 09 '21 at 15:02
9
location /dupa/ {
    set_by_lua $request_uri_low "return ngx.arg[1]:lower()" $request_uri;
    rewrite ^ https://$host$request_uri_low;
}
Adam Dobrawy
  • 947
  • 11
  • 12
9

i managed to achieve the goal using embedded perl:

location ~ [A-Z] {
  perl 'sub { my $r = shift; $r->internal_redirect(lc($r->uri)); }';
}
Dennis Krupenik
  • 656
  • 5
  • 18
  • It may solve the posted issue, but "ignoring case" AND "lowering case" are two completely different things. – alejandrob Feb 07 '20 at 21:55
  • This way compatible if you want to not rewrite address and answer true page with any case in address field. Thaks for additional way to resolve the issue. – PRIHLOP Feb 12 '21 at 13:28
3
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

3

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;
}
Timon de Groot
  • 4,658
  • 4
  • 19
  • 36
  • 2
    Be careful with this answer. If is evil: https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/ – MacroMan Feb 26 '18 at 11:14
  • @MacroMan It can be unsafe only if used in the `location` context and depends on what is following this configuration fragment. For the most cases this one should be completely safe. – Ivan Shatsky Nov 07 '20 at 17:58