Acerca del uso de expresiones regulares en el mapa nginx

No he escrito nada durante mucho tiempo, así que diluyamos el final del viernes con búsquedas simples, pero no siempre obvias, en Nginx .





Este servidor web tiene una maravillosa directiva de mapas que le permite simplificar y acortar las configuraciones en gran medida. La esencia de la directiva es que le permite crear una nueva variable, cuyo valor depende de los valores de una o más de las variables originales. La directiva se vuelve aún más poderosa cuando se usan expresiones regulares, pero al mismo tiempo se olvida un punto importante. Extracto del manual:





Dado que las variables solo se evalúan en el momento de su uso, incluso una gran cantidad de declaraciones de variables de mapa en sí mismas no conllevan ninguna sobrecarga adicional de procesamiento de consultas.





Y aquí es importante no solo que "el mapa no conlleve ningún coste adicional para la tramitación de las solicitudes", sino también que "las variables se calculan únicamente en el momento de su uso".





Como sabe, la configuración de Nginx es principalmente declarativa. Esto también se aplica a la directiva map y, a pesar de que está ubicada en el contexto http , no se evalúa hasta que se procesa la solicitud. Es decir, cuando se usa la variable resultante en el servidor de contextos , ubicación, si , etc. "sustituimos" no el resultado final del cálculo, sino sólo la "fórmula" mediante la cual este resultado se calculará en el momento adecuado. No hay problemas en esta casuística de configuración hasta que usamos expresiones regulares. Expresiones regulares con selecciones. Más precisamente, expresiones regulares con selecciones sin nombre. Es más fácil de mostrar con un ejemplo.





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
      
      



ya que nuestra asignación sin nombre $ 1 obtendrá el resultado de $ domainlevel3 con nombre . Es decir, debe usar selecciones con nombre en ambas expresiones regulares:





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;
    }
}
      
      



Y ahora todo funciona como se esperaba:





$ GET -Sd ru.example.com
GET http://ru.example.com
301 Moved Permanently
GET https://ru.example.org/
      
      






All Articles