Rewrite image request to sub-directory structure in Nginx

Given a location like this:

location ~ ^/user-content/img/) {
  root /srv/foo/bar/uploads/;
  autoindex off;
  access_log off;
  expires 30d;
}

Is it possible using nginx to have a request for

/user-content/img/3AF1D3A69CE92ADAED8B0D25C2411595C7C798A5.png

To be actually served from directory /srv/foo/bar/uploads/3A/F1/D3 which would involve taking the first two characters from the request filename and use them as first subfolder, then using characters 3-4 for the next deeper folder and finally append characters 5-6 for the last subfolder?


You can try (not tested)

location /user-content/img/ {
    rewrite "^/user-content/img/(\w{2})(\w{2})(\w{2})(.*)" /$1/$2/$3/$1$2$3$4 break;
    root /srv/foo/bar/uploads;
    autoindex off;
    access_log off;
    expires 30d;
}

Update

Just give it a test. Can confirm that this approach works too. As OP noted, regex with curly braces should be quoted in nginx config.


This approach should work:

location ~ "^/user-content/img/([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})(.*)$" {
    root /srv/foo/bar/uploads;
    try_files /$1/$2/$3/$1$2$3$4 =404;
    autoindex off;
    access_log off;
    expires 30d;
}

In the location line, we capture parts of the filename to four different variables using regular expressions, first three parts being the directory and fourth part being the rest of the filename.

Variables are used in the try_files directive to create the path to the image name.