Merge pull request #1129 from mempool/wiz/nginx-redirects-for-localized-urls

Improve nginx caching and use redirects for i18n
This commit is contained in:
wiz 2022-01-12 16:44:11 +00:00 committed by GitHub
commit ea2a2310a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 111 additions and 45 deletions

View file

@ -1,8 +1,9 @@
map $http_accept_language $header_lang { map $http_accept_language $header_lang {
default en-US; default '';
~*^en-US en-US; ~*^en-US '';
~*^en en-US; ~*^en '';
~*^ar ar; ~*^ar ar;
~*^ca ca;
~*^cs cs; ~*^cs cs;
~*^de de; ~*^de de;
~*^es es; ~*^es es;
@ -11,16 +12,21 @@ map $http_accept_language $header_lang {
~*^ko ko; ~*^ko ko;
~*^hi hi; ~*^hi hi;
~*^it it; ~*^it it;
~*^he he;
~*^ka ka; ~*^ka ka;
~*^hu hu; ~*^hu hu;
~*^mk mk;
~*^nl nl; ~*^nl nl;
~*^ja ja; ~*^ja ja;
~*^nb nb; ~*^nb nb;
~*^pl pl; ~*^pl pl;
~*^pt pt; ~*^pt pt;
~*^ro ro;
~*^ru ru;
~*^sl sl; ~*^sl sl;
~*^fi fi; ~*^fi fi;
~*^sv sv; ~*^sv sv;
~*^th th;
~*^tr tr; ~*^tr tr;
~*^uk uk; ~*^uk uk;
~*^vi vi; ~*^vi vi;
@ -28,30 +34,35 @@ map $http_accept_language $header_lang {
} }
map $cookie_lang $lang { map $cookie_lang $lang {
default $header_lang; default $header_lang;
~*^en-US en-US; ~*^en-US '';
~*^en en-US; ~*^en '';
~*^ar ar; ~*^ar ar;
~*^ca ca;
~*^cs cs; ~*^cs cs;
~*^de de; ~*^de de;
~*^es es; ~*^es es;
~*^fa fa; ~*^fa fa;
~*^fr fr; ~*^fr fr;
~*^ko ko;
~*^hi hi; ~*^hi hi;
~*^it it; ~*^it it;
~*^he he;
~*^ka ka; ~*^ka ka;
~*^hu hu; ~*^hu hu;
~*^ja ja; ~*^mk mk;
~*^ko ko;
~*^nb nb;
~*^nl nl; ~*^nl nl;
~*^ja ja;
~*^nb nb;
~*^pl pl; ~*^pl pl;
~*^pt pt; ~*^pt pt;
~*^ro ro;
~*^ru ru;
~*^sl sl; ~*^sl sl;
~*^fi fi; ~*^fi fi;
~*^sv sv; ~*^sv sv;
~*^th th;
~*^tr tr; ~*^tr tr;
~*^uk uk; ~*^uk uk;
~*^vi vi; ~*^vi vi;
~*^zh zh; ~*^zh zh;
} }

View file

@ -0,0 +1,11 @@
location /api/v1/contributors/images {
proxy_pass https://mempool.space;
proxy_cache services;
proxy_cache_valid 200 1d;
expires 7d;
add_header Cache-Control "public, no-transform";
proxy_hide_header onion-location;
proxy_hide_header strict-transport-security;
proxy_hide_header content-security-policy;
proxy_hide_header x-frame-options;
}

View file

@ -1,18 +1,15 @@
location /api/v1/ws { location /api/v1/statistics {
proxy_pass $mempoolBackend; try_files /dev/null @mempool-api-v1-cache;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
} }
location /api/v1 { location /api/v1 {
try_files /dev/null @mempool-api-v1; try_files /dev/null @mempool-api-v1-nocache;
} }
location /api/ { location /api/ {
rewrite ^/api/(.*) /$1 break; rewrite ^/api/(.*) /$1 break;
try_files /dev/null @electrs-api; try_files /dev/null @electrs-api-nocache;
} }
location @mempool-api-v1 { location @mempool-api-v1-cache {
proxy_pass $mempoolBackend; proxy_pass $mempoolBackend;
proxy_http_version 1.1; proxy_http_version 1.1;
@ -21,13 +18,35 @@ location @mempool-api-v1 {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade; proxy_cache_bypass $http_upgrade;
proxy_redirect off; proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off;
proxy_cache_valid any 10s;
expires 10s;
} }
location @electrs-api { location @mempool-api-v1-nocache {
proxy_pass $mempoolBackend;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
proxy_buffering off;
expires -1;
}
location @electrs-api-nocache {
proxy_pass $electrsBackend; proxy_pass $electrsBackend;
proxy_http_version 1.1; proxy_http_version 1.1;
@ -36,8 +55,9 @@ location @electrs-api {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade; proxy_cache_bypass $http_upgrade;
proxy_redirect off; proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off;
} }

View file

@ -1,5 +1,6 @@
include mempool/production/nginx/server-common.conf; include mempool/production/nginx/server-common.conf;
include mempool/production/nginx/location-api-v1-contributors.conf; include mempool/production/nginx/location-api-v1-contributors.conf;
include mempool/production/nginx/location-api-v1-contributors-images.conf;
include mempool/production/nginx/location-api-v1-donations.conf; include mempool/production/nginx/location-api-v1-donations.conf;
include mempool/production/nginx/location-api-v1-donations-images.conf; include mempool/production/nginx/location-api-v1-donations-images.conf;

View file

@ -35,32 +35,47 @@ add_header X-Frame-Options $frameOptions;
add_header Content-Security-Policy $contentSecurityPolicy; add_header Content-Security-Policy $contentSecurityPolicy;
# enable browser and proxy caching # enable browser and proxy caching
add_header Cache-Control "public, no-transform"; add_header Pragma "public";
add_header Cache-Control "public";
# vary cache if user changes language preference # vary cache if user changes language preference
add_header Vary Accept-Language; add_header Vary Accept-Language;
add_header Vary Cookie; add_header Vary Cookie;
# fallback for all URLs i.e. /address/foo /tx/foo /block/000 # see order of nginx location rules
location / { # https://stackoverflow.com/questions/5238377/nginx-location-priority
try_files /$lang/$uri /$lang/$uri/ $uri $uri/ /en-US/$uri @index-redirect;
# for exact / requests, redirect based on $lang
location = / {
if ($lang != '') {
return 302 $scheme://$host/$lang$uri;
}
try_files /en-US/index.html =404;
expires 10m; expires 10m;
} }
location /resources {
try_files /$lang/$uri /$lang/$uri/ $uri $uri/ /en-US/$uri @index-redirect;
expires 1h;
}
location @index-redirect {
rewrite (.*) /$lang/index.html;
}
# location block using regex are matched in order
# used to rewrite resources from /<lang>/ to /en-US/ # used to rewrite resources from /<lang>/ to /en-US/
location ~ ^/(ar|bg|bs|ca|cs|da|de|et|el|es|eo|eu|fa|fr|gl|ko|hr|id|it|he|ka|lv|lt|hu|mk|ms|nl|ja|ka|no|nb|nn|pl|pt|pt-BR|ro|ru|sk|sl|sr|sh|fi|sv|th|tr|uk|vi|zh)/resources/ { location ~ ^/[a-z][a-z]/resources/(.*) {
rewrite ^/[a-zA-Z-]*/resources/(.*) /en-US/resources/$1; try_files $uri /en-US/resources/$1 =404;
expires 1w;
} }
# used for cookie override # used for cookie override
location ~ ^/(ar|bg|bs|ca|cs|da|de|et|el|es|eo|eu|fa|fr|gl|ko|hr|id|it|he|ka|lv|lt|hu|mk|ms|nl|ja|ka|no|nb|nn|pl|pt|pt-BR|ro|ru|sk|sl|sr|sh|fi|sv|th|tr|uk|vi|zh)/ { location ~ ^/([a-z][a-z])$ {
try_files $uri $uri/ /$1/index.html =404; try_files $uri /$1/index.html /en-US/index.html =404;
expires 10m;
}
location ~ ^/([a-z][a-z])/ {
try_files $uri /$1/index.html /en-US/index.html =404;
expires 10m;
}
# fallback to serving resources from en-US
location /resources {
try_files $uri /en-US/$uri /en-US/index.html;
expires 1w;
}
# fallback for all URLs i.e. /address/foo /tx/foo /block/000
location / {
try_files /$lang/$uri $uri /en-US/$uri /en-US/index.html =404;
expires 10m;
} }

View file

@ -1,7 +1,8 @@
include mempool/production/nginx/server-common.conf; include mempool/production/nginx/server-common.conf;
include mempool/production/nginx/location-api-v1-contributors.conf; include mempool/production/nginx/location-api-v1-contributors.conf;
include mempool/production/nginx/location-api-v1-donations-images.conf; include mempool/production/nginx/location-api-v1-contributors-images.conf;
include mempool/production/nginx/location-api-v1-donations.conf; include mempool/production/nginx/location-api-v1-donations.conf;
include mempool/production/nginx/location-api-v1-donations-images.conf;
include mempool/production/nginx/location-api.conf; include mempool/production/nginx/location-api.conf;
include mempool/production/nginx/location-liquid-api.conf; include mempool/production/nginx/location-liquid-api.conf;
include mempool/production/nginx/location-liquidtestnet-api.conf; include mempool/production/nginx/location-liquidtestnet-api.conf;

View file

@ -1,6 +1,7 @@
include mempool/production/nginx/server-common.conf; include mempool/production/nginx/server-common.conf;
include mempool/production/nginx/location-redirects.conf; include mempool/production/nginx/location-redirects.conf;
include mempool/production/nginx/location-api-v1-contributors.conf; include mempool/production/nginx/location-api-v1-contributors.conf;
include mempool/production/nginx/location-api-v1-contributors-images.conf;
include mempool/production/nginx/location-api-v1-donations.conf; include mempool/production/nginx/location-api-v1-donations.conf;
include mempool/production/nginx/location-api-v1-donations-images.conf; include mempool/production/nginx/location-api-v1-donations-images.conf;
include mempool/production/nginx/location-api.conf; include mempool/production/nginx/location-api.conf;

View file

@ -1,4 +1,4 @@
#!/usr/bin/env zsh #!/usr/local/bin/zsh
PROTO=https PROTO=https
HOSTNAME=mempool.ninja HOSTNAME=mempool.ninja
URL_BASE=${PROTO}://${HOSTNAME} URL_BASE=${PROTO}://${HOSTNAME}
@ -20,17 +20,23 @@ echo "Starting tests to ${URL_BASE}"
echo "Test locale for / with no header or cookie" echo "Test locale for / with no header or cookie"
curl -s ${URL_BASE}/ | grep '<html lang' | tr -d '\r\n' | curltest '<html lang="en-US">' curl -s ${URL_BASE}/ | grep '<html lang' | tr -d '\r\n' | curltest '<html lang="en-US">'
echo "Test locale for / with 'ja' lang header and no cookie" echo "Test locale for /ja with no header or cookie"
curl -s -H 'Accept-Language: ja' ${URL_BASE}/ | grep '<html lang' | tr -d '\r\n' | curltest '<html lang="ja">' curl -s ${URL_BASE}/ja | grep '<html lang' | tr -d '\r\n' | curltest '<html lang="ja">'
#echo "Test locale for /ja with 'ja' lang header and 'en' lang cookie"
#curl -s -H 'Accept-Language: ja' --cookie 'lang=en' ${URL_BASE}/ja | grep '<html lang' | tr -d '\r\n' | curltest '<html lang="en-US">'
echo "Test redirect for / with 'ja' lang header and no cookie"
curl -i -s -H 'Accept-Language: ja' ${URL_BASE}/ | grep '^location:' | tr -d '\r\n' | curltest "location: ${URL_BASE}/ja/"
echo "Test locale for / with 'ja' lang header and 'en' lang cookie" echo "Test locale for / with 'ja' lang header and 'en' lang cookie"
curl -s -H 'Accept-Language: ja' --cookie 'lang=en' ${URL_BASE}/ | grep '<html lang' | tr -d '\r\n' | curltest '<html lang="en-US">' curl -s -H 'Accept-Language: ja' --cookie 'lang=en' ${URL_BASE}/ | grep '<html lang' | tr -d '\r\n' | curltest '<html lang="en-US">'
echo "Test locale for / with 'ja' lang header and 'sv' lang cookie" echo "Test redirect for / with 'ja' lang header and 'sv' lang cookie"
curl -s -H 'Accept-Language: ja' --cookie 'lang=sv' ${URL_BASE}/ | grep '<html lang' | tr -d '\r\n' | curltest '<html lang="sv">' curl -i -s -H 'Accept-Language: ja' --cookie 'lang=sv' ${URL_BASE}/ | grep '^location:' | tr -d '\r\n' | curltest "location: ${URL_BASE}/sv/"
echo "Test locale for / with 'ja' lang header and 'foo' lang cookie" echo "Test redirect for / with 'ja' lang header and 'foo' lang cookie"
curl -s -H 'Accept-Language: ja' --cookie 'lang=foo' ${URL_BASE}/ | grep '<html lang' | tr -d '\r\n' | curltest '<html lang="ja">' curl -i -s -H 'Accept-Language: ja' --cookie 'lang=foo' ${URL_BASE}/ | grep '^location:' | tr -d '\r\n' | curltest "location: ${URL_BASE}/ja/"
echo "Test rewrite for /resources/pools.json with no header and no cookie" echo "Test rewrite for /resources/pools.json with no header and no cookie"
curl -s -i ${URL_BASE}/resources/pools.json | grep -i content-type | tr -d '\r\n' | curltest 'content-type: application/json' curl -s -i ${URL_BASE}/resources/pools.json | grep -i content-type | tr -d '\r\n' | curltest 'content-type: application/json'