7.2.2.2.6. Sentencia condicional

nginx dispone de la sentencia if, que permite fijar directias dependiendo de una condición. Sin embargo,

Advertencia

la documentación oficial advierte de que usar if dentro de location es imprevisible y recomienda encarecidamente no hacerlo. Dentro de location sólo nos asegura que funcionará correctamente cuando se hace un return o una reescritura (rewrite) con last.

La sintaxis del bloque es la siguiente:

if (condicion) {
   # Directivas
}

Para escribir la condición ha de tenerse en cuenta que:

  • Una variable se evalúa a falso si es la cadena vacía o vale 0.

  • Los operadores de comparación son:

    • = para igualdad.

    • != para desigualdad.

    • ~ y ~* para comparar con un patrón de expresiones regulares. El segundo no atiende a mayúsculas o minúsculas. Además, pueden definirse capturas y usarlas luego.

    • -f y !-f comprueban la existencia o inexistencia de un fichero.

    • -d y !-d comprueban la existencia o inexistencia de un directorio.

    • -e y !-e comprueban la existencia o inexistencia de un fichero o directorio.

    • -x y !-x comprueban si existe o no el ejecutable.

Ejemplo:

if ($invalid_referer) {
   return 404;
}

Obsérvese que la condición es simple: no existe la concatenación de condiciones con or ni and. Lo primero es fácil de emular escribiendo secuencialmente los if:

if (condicion1) {
   # Directiva
}

if (condicion2) {
   # Misma directiva
}

En cambio ejecutar una directiva cuando se cumplen ambas condiciones no es tan evidente, ya que requiere algo de imaginación. Por ejemplo, supongamos que tenemos mezclados en un mismo bloque server los sitios seguro e inseguro y queremos el tráfico del sitio inseguro al seguro cuando se cumplen dos circunstancias[1]:

  1. La petición fue insegura.

  2. El usuario está identificado en la aplicación web, lo cual se sabe porque el navegador envía para acreditarlo una cookie al servidor con un nombre característico.

Podemos hacer lo siguiente[2]:

if ($https != "on") {
   set $test "http";
}

# Dependiendo de la aplicación web la cookie se podrá identificar
# con un nombre u otro (este ejemplo es para wordpress)
if ($http_cookie ~* _logged_ ) {
   set $test "${test}+logged";
}

if ($test = "http+logged") {
   return 303 https://$host$request_uri$is_args$args;
}

Notas al pie