Ich habe lange nichts mehr geschrieben, also lassen Sie uns das Ende des Freitags mit einfachen, aber nicht immer offensichtlichen Suchen in Nginx verwässern .
Dieser Webserver verfügt über eine wunderbare Kartenanweisung , mit der Sie Konfigurationen erheblich vereinfachen und verkürzen können. Das Wesentliche der Direktive ist, dass Sie damit eine neue Variable erstellen können, deren Wert von den Werten einer oder mehrerer der ursprünglichen Variablen abhängt. Die Direktive wird noch mächtiger, wenn reguläre Ausdrücke verwendet werden, aber gleichzeitig wird ein wichtiger Punkt vergessen. Auszug aus dem Handbuch:
Da die Variablen nur zum Zeitpunkt der Verwendung ausgewertet werden, verursacht selbst eine große Anzahl von Map- Variablendeklarationen selbst keinen zusätzlichen Aufwand für die Abfrageverarbeitung.
Und hier ist es nicht nur wichtig, dass "Map keine zusätzlichen Kosten für die Bearbeitung von Anfragen verursacht", sondern auch, dass "Variablen nur zum Zeitpunkt der Verwendung berechnet werden".
Wie Sie wissen, ist die Nginx- Konfiguration meist deklarativ. Dies gilt auch für die Map- Direktive . Trotz der Tatsache, dass sie sich im http- Kontext befindet , wird sie erst ausgewertet, wenn die Anforderung verarbeitet wurde. Das heißt, wenn die resultierende Variable im Kontextserver , Speicherort, if usw. verwendet wird. Wir "ersetzen" nicht das fertige Ergebnis der Berechnung, sondern nur die "Formel", nach der dieses Ergebnis zum richtigen Zeitpunkt berechnet wird. Es gibt keine Probleme in dieser Konfigurations-Kasuistik, bis wir reguläre Ausdrücke verwenden. Nämlich reguläre Ausdrücke mit Auswahl. Genauer gesagt, reguläre Ausdrücke mit unbenannten Auswahlen. Es ist einfacher, mit einem Beispiel zu zeigen.
example.com 3- , - ru.example.com, en.example.com, de.example.com .., ru.example.org, en.example.org, de.example.org .. :
map $host $redirect_host {
default "example.org";
"~^(\S+)\.example\.com$" $1.example.org;
}
server {
listen *:80;
server_name .example.com;
location / {
rewrite ^(.*)$ https://$redirect_host$1 permanent;
}
, ru.example.com map , , location $redirect_host ru.example.org, :
$ GET -Sd ru.example.com GET http://ru.example.com 301 Moved Permanently GET https://ru.example.orgru
, ru.example.orgru. - , " " rewrite .
- regexp map , , :
map $host $redirect_host {
default "example.org";
"~^(\S+)\.example\.com$" $1.example.org;
}
server {
listen *:80;
server_name .example.com;
location / {
return 301 https://$redirect_host$request_uri;
}
}
, ( ).
map:
map $host $redirect_host {
default "example.org";
"~^(?<domainlevel3>\S+)\.example\.com$" $domainlevel3.example.org;
}
server {
listen *:80;
server_name .example.com;
location / {
rewrite ^(.*)$ https://$redirect_host$1 permanent;
}
}
:
$ GET -Sd ru.example.com GET http://ru.example.com 301 Moved Permanently GET https://ru.example.orgru
da unsere unbenannte Zuordnung $ 1 das Ergebnis von $ domainlevel3 erhält . Das heißt, Sie müssen in beiden regulären Ausdrücken benannte Auswahlen verwenden:
map $host $redirect_host {
default "example.org";
"~^(?<domainlevel3>\S+)\.example\.com$" $domainlevel3.example.org;
}
server {
listen *:80;
server_name .example.com;
location / {
rewrite ^(?<requri>.*)$ https://$redirect_host$requri permanent;
}
}
Und jetzt funktioniert alles wie erwartet:
$ GET -Sd ru.example.com GET http://ru.example.com 301 Moved Permanently GET https://ru.example.org/