Je n'ai rien écrit depuis longtemps, alors diluons la fin de vendredi avec des recherches simples, mais pas toujours évidentes, dans Nginx .
Ce serveur Web a une merveilleuse directive de carte qui vous permet de simplifier et de raccourcir considérablement les configurations. L'essence de la directive est qu'elle vous permet de créer une nouvelle variable dont la valeur dépend des valeurs d'une ou plusieurs des variables d'origine. La directive devient encore plus puissante lors de l'utilisation d'expressions régulières, mais en même temps, on oublie un point important. Extrait du manuel:
Étant donné que les variables ne sont évaluées qu'au moment de l'utilisation, même un grand nombre de déclarations de variables de mappage n'entraîne aucune surcharge de traitement de requête supplémentaire.
Et ici, il est important non seulement que "la carte n'entraîne pas de frais supplémentaires pour le traitement des demandes", mais aussi que "les variables ne soient calculées qu'au moment de l'utilisation".
Comme vous le savez, la configuration Nginx est principalement déclarative. Cela s'applique également à la directive map et, bien qu'elle se trouve dans le contexte http , elle n'est pas évaluée tant que la demande n'est pas traitée. Autrement dit, lors de l'utilisation de la variable résultante dans le serveur de contextes , l'emplacement, si , etc. nous «substituons» non pas le résultat final du calcul, mais seulement la «formule» par laquelle ce résultat sera calculé au bon moment. Il n'y a aucun problème dans cette casuistique de configuration jusqu'à ce que nous utilisions des expressions régulières. À savoir des expressions régulières avec des sélections. Plus précisément, des expressions régulières avec des sélections sans nom. Il est plus facile de montrer avec un exemple.
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
puisque notre allocation sans nom $ 1 obtiendra le résultat de nommé $ domainlevel3 . Autrement dit, vous devez utiliser des sélections nommées dans les deux expressions régulières:
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;
}
}
Et maintenant, tout fonctionne comme prévu:
$ GET -Sd ru.example.com GET http://ru.example.com 301 Moved Permanently GET https://ru.example.org/