.. _ngx-if: Sentencia condicional ===================== :program:`nginx` dispone de la sentencia `if `_, que permite fijar directias dependiendo de una condición. Sin embargo, .. warning:: 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: .. code-block:: nginx 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: .. code-block:: nginx 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``: .. code-block:: nginx if (condicion1) { # Directiva } if (condicion2) { # Misma directiva } .. _nginx-and: 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 :ref:`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\ [#]_: #. La petición fue insegura. #. 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\ [#]_: .. code-block:: nginx 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; } .. rubric:: Notas al pie .. [#] Tal circunstancia puede ocurrir si el navegador almacenó la cookie y tras arrancar el navegador nos conectamos al sitio no seguro. .. [#] En realidad, en este caso particular, nos podemos ahorrar el primer ``if``: .. code-block:: nginx if ($http_cookie ~* _logged_ ) { set $test "${https}+logged"; } if ($test = "+logged") { return 303 https://$host$request_uri$is_args$args; }