How can I use wildcards in an Nginx map directive?

I am trying to use Nginx to served cached files produced by a web application, and have spotted a potential problem; that the url-space is wide, and will exceed the Ext3 limit of 32000 subdirectories.

I would like to break up the subdirectories, making, say, a two-level filesystem cache. So, where I am currently caching a file at

/var/cache/www/arbitrary_directory_name/index.html

I would store that instead at something like

/var/cache/www/a/r/arbitrary_directory_name/index.html

My trouble is that I can't get try_files, or even rewrite to make that mapping. My searching on the subject leads me to believe that I need to do something like this (heavily abbreviated):

http {
    map $request_uri $prefix {
        /aa*   a/a;
        /ab*   a/b;
        /ac*   a/c;
        ...
        /zz*   z/z;
    }

    location / {
        try_files /var/cache/www/$prefix/$request_uri/index.html @fallback;

        # or
        # if (-f /var/cache/www/$prefix/$request_uri/index.html) {
        #     rewrite ^(.*)$ /var/cache/www/$prefix/$1/index.html;
        # }
    }
}

But I can't get the /aa* pattern to match the incoming uri. Without the *, it will match an exact uri, but I can't get it to match just the first two characters.

The Nginx documentation suggests that wildcards should be allowed, but I can't see a way to get them to work. Is there a way to do this? Am I missing something simple? Or am I going about this the wrong way?


Solution 1:

I suspect that globs are only supported with the special hostname mode. You need to use regular expressions to achieve this, so your map should look like this:

map $request_uri $prefix {
    ~^/aa(?<suffix>.*)$ /a/a/$suffix;
    ...
}