Când utilizați nginx și hărți, este posibil să rescrieți mai multe adrese URL cu un fișier de hartă. Ceea ce este problematic este atunci când URL-ul conține caractere speciale. Mi-am rupt capul încercând să înțeleg acest lucru corect și sper că această întrebare/soluție ar putea salva pe alții să devină părul gri.
Să stabilim scenariul.
Un server Linux (Debian/Ubuntu) care rulează standard nginx.
DNS care indică acest server care se rezolvă la o configurație de server.
O hartă care nu conține intrări duplicat cu adrese URL de intrare și de ieșire (rezolvabile)
Configurarea hărții va conține următoarele:
harta $host$request_uri $rewrite_uri {
include /<calea către numele fișierului>;
}
fișierul hartă în sine conține o intrare pe linie terminată cu punct și virgulă.
example.com/Böhme https://anotherexample.org/SomeWeirdPath/Böhme;
Configurația serverului pentru această mapare să funcționeze
Server {
asculta 443 ssl http2;
ssl_certificate /<calea absolută către fișierul crt>;
ssl_certificate_key /<calea absolută către fișierul cheie>;
nume_server example.com;
proxy_set_header X-Forwarded-For $remote_addr;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_dhparam <calea absolută către cheia Diffie Hellman>;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
server_tokens dezactivat;
if ($rewrite_uri) {
rescrie ^ $rewrite_uri redirecționare;
}
rescrie ^ <adresa URL implicită> redirecționare;
}
Am simplificat configurația acestui server, astfel încât să ne putem concentra asupra setărilor hărții.Configurația presupune că domeniul va folosi SSL și că certificatul este valid. Instrucțiunea if se va executa numai dacă $host$request_uri este în lista cu $rewrite_uri, altfel ultima rescrire va fi executată.
Intrebarea
Cum transform $request_uri, astfel încât nginx să-l înțeleagă corect? Fișierul de hartă conține valoarea în UTF8, dar se pare că nginx vrea URL-ul $request_uri codificat și în hexazecimal.
$request_uri ca în fișierul mapfile
exemplu.com/Böhme
$request_uri URLEncoded conform browserului
exemplu.com/B%C3%B6hme
$request_uri așa cum cred că nginx vrea
exemplu.com/B\xC3\xB6hme
Se pare că nu găsesc un pachet de sistem care să aibă această caracteristică, dar cred că încep să reinventez roata aici.
as avea nevoie sa:
creați o funcție care va codifica adresa URL a listei,
conform Cum se decodifică șirul codificat URL în shell?
function urldecode() { local i="${*//+/ }"; echo -e „${i//%/\x}”; }
și apoi utilizați Octal dump conform Convertiți șirul în hexazecimal pe linia de comandă, astfel încât grupul de hărți este creat în memorie cu valorile corecte pentru dacă test de declarație.
Începe să pară știință rachetă și nu-mi vine să cred că nimeni altcineva nu a rezolvat această problemă până acum, pur și simplu nu pot găsi o soluție.