try_files doesn't use variables from regex and map
I'm trying to conditionally serve .webp images to supported clients. The images are stored like image.jpg
and image.jpg.webp
in the same folder.
I can't get try_files to do what I think it should to. When I use $1$webp_suffix
as the location it fails and also does not try the second location.
In nginx.conf I set $webp_suffix
like so:
http {
map $http_accept $webp_suffix {
default "";
"~*webp" ".webp";
}
include /opt/local/etc/nginx/vhosts/*;
}
But when I try to use the suffix in my virtual host I get an error 404.
server {
listen 443 ssl;
server_name my.example.com;
# allow /data/ and /data/343/ as public URL
location ~ ^/data/[0-9/]*(.*)$ {
expires 365d;
add_header Cache-Control "public, no-transform";
# Serve webp images when available and supported
location ~ ^/data/[0-9/]*(.+\.(png|jpg))$ {
add_header Vary Accept;
alias /local/path/httpdocs/data/;
try_files $1$webp_suffix $1 =404;
}
alias /Users/r/Sites/cms/httpdocs/data;
try_files /$1 =404;
}
}
Everything works when I remove $1$webp_suffix
, so the paths and such seem correct.
The problem is $1
. It gets overwritten each time Nginx evaluates a regular expression. The expression $1$webp_suffix
causes Nginx to evaluate the regular expression in the map
statement, which simultaneously causes $1
to become an empty string.
Use a named capture in the location
statements.
For example:
location ~ ^/data/[0-9/]*(?<filename>.*)$ {
expires 365d;
add_header Cache-Control "public, no-transform";
# Serve webp images when available and supported
location ~ \.(png|jpg)$ {
add_header Vary Accept;
root /local/path/httpdocs/data/;
try_files /$filename$webp_suffix /$filename =404;
}
root /Users/r/Sites/cms/httpdocs/data;
try_files /$filename =404;
}
Also, you should be using root
instead of alias
.