Mapping old to new URLs with external file - configuration invalid

I'm moving an old website to a new nginx based host. To preserve the URL (which completely changed) I have a file that lists the mapping. I want to use it with map module.

Inside /etc/nginx/nginx.conf http{ ... } I refer to PERL and the lowercase function:

#Include PERL and have a function for lowercasing the incoming URL
perl_modules perl/lib;

    # function to lowercase incoming strings like the URL
    perl_set $uri_lowercase 'sub {
        my $r = shift;
        my $uri = $r->uri;
        $uri = lc($uri);
        return $uri;
    }';

My site configuration, which is in the file /etc/nginx/sites-enabled/notessensei (Thx Alexey to point that out) looks like:

server {
    listen www.notessensei.com:80;
    root /home/stw/www;
    index index.html;
    server_name www.notessensei.com notessensei.com;

    location / {
        map $uri_lowercase $new {
            include /home/stw/www/blognginx.map;
        }

        if ($new) {
                rewrite ^ $new redirect;
        }
    }

    error_page 404 /blog/404.html;

}

The mapping file blognginx.map looks like this:

/blog/d6plinks/shwl-6bv35s /blog/2005/04/garbage-in-.html;
/blog/d6plinks/shwl-6c6ggp /blog/2005/05/just-me.html;
/blog/d6plinks/shwl-6c6gh4 /blog/2005/05/it-is-quotmake-your-own-caption-quot-time.html;
/blog/d6plinks/shwl-6c997j /blog/2005/05/big-business-wwjd.html;
/blog/d6plinks/shwl-6ca5qb /blog/2005/05/domino-on-solaris-anyone.html;
/blog/d6plinks/shwl-6ce65j /blog/2005/05/going-places-vietnam.html;
/blog/d6plinks/shwl-6ce6c9 /blog/2006/02/umsys-as-old-as-unix-sort-of.html;

for about 1300 lines. When I do a service nginx configtest I get a fail. When I don't use the include statement I get an OK. Now I have 2 questions:

  1. Is there a way to get a more verbose error, one that tells me what is wrong and where?
  2. What is wrong? Do I need to change the content of the include file? Do I need to move the section?

Help is very much appreciated.


Solution 1:

map directive must be immediate child http block.

syntax: map string $variable { ... }

default: —

context: http

In your case, you must place it beside server block, because you custom config file is included right inside http block in nginx.conf.

map $uri_lowercase $new {
  include /home/stw/www/blognginx.map;
}

server {
  ...
}

Solution 2:

I figured it out, thx to Alexey's pointers. There was a 4 fold problem:

  • the map statement wasn't at the right place, Alexey pointed that out
  • the file had some errors inside (missing space in a few lines)
  • the map sized were too small (see solution below)
  • the service nginx configtest tells less than nginx -t, again Alexey pointed me there

Now my /etc/nginx/nginx.conf has 2 additional lines in the http {} section:

## Increase bucket for big redirects
map_hash_bucket_size 256;
map_hash_max_size 4092;

and the /etc/nginx/sites-enabled/notessensei file looks like this:

map $uri_lowercase $new {
    include /home/stw/www/blognginx.map;
}

server {
    listen www.notessensei.com:80;
    root /home/stw/www;
    index index.html index.htm;
    server_name www.notessensei.com notessensei.com;

    location / {
        if ($new) {
                return 301 $new;
        }
    }

    error_page 404 /blog/404.html;

}

If you want to see it in action, pick any blog entry from wissel.net and apply the uri part to notessensei.com - works like a charm with > 1200 entries.