4 votos

try_files nginx procesado dos veces y no si establece la suplencia del error

Tengo un bloque de ubicación de instalación para la captura de todas las solicitudes de archivo y enviarlos a PHP-FPM:

location  / {
    try_files  $uri /routing.php?$args;
    fastcgi_pass   unix:/opt/local/var/run/php54/php-fpm-www.sock;
    include       /documents/projects/intahwebz/intahwebz/conf/fastcgi.conf;
}

Esto funciona correctamente y se pasa la solicitud a PHP-FPM a la exacta existentes archivo php que se ha solicitado o con routing.php establecido como la secuencia de comandos para ejecutar.

He intentado añadir una página de error, por lo que si el archivo de enrutamiento nunca fue eliminado o no disponible, la página de error se mostrarán en lugar de Nginx la página de error predeterminada:

location  / {
    try_files $uri /routing.php?$args /50x_static.html;
    fastcgi_pass   unix:/opt/local/var/run/php54/php-fpm-www.sock;
    include       /documents/projects/intahwebz/intahwebz/conf/fastcgi.conf;
}

Esto detiene el routing.php de archivo de que se sirve, y el 50x_static.html la página se muestra en su lugar. Las solicitudes existentes en un archivo PHP todavía funcionan decir, ir a la URL /dynamic.php

Me doy cuenta de que el último parámetro en un try_files comando es un poco mágico:

En el caso de que no se encuentra el archivo, un interno de la redirección a la última parámetro se invoca. Tenga en cuenta que sólo el último parámetro hace un redirect interno, antiguos establece el URI interna puntero. El el último parámetro es el retroceso y el URI debe existir, o de una error interno serán resucitados.

Mientras que la investigación de por qué el error_page había roto la config, me di cuenta de que para la config que funciona (sin el error estático de la página), Nginx no parece ser coincidencia de la solicitud dos veces de acuerdo a la Nginx reescritura de registro cuando se trata de obtener la URL de la root "/":

"^/proxy/(\d+)/(\w+)/(.+)\.(gif|png|jpg|jpeg|GIF|PNG|JPG|JPEG)$" does not match "/", client: 127.0.0.1, server: basereality.com, request: "GET / HTTP/1.1", host: "basereality.test"
"^/proxy/(\d+)/(.+)\.(gif|png|jpg|jpeg|GIF|PNG|JPG|JPEG)$" does not match "/", client: 127.0.0.1, server: basereality.com, request: "GET / HTTP/1.1", host: "basereality.test"
"^/staticImage/(\w+)/(.+)\.([^\.]*)$" does not match "/", client: 127.0.0.1, server: basereality.com, request: "GET / HTTP/1.1", host: "basereality.test"
"^/proxy/(\d+)/(\w+)/(.+)\.(gif|png|jpg|jpeg|GIF|PNG|JPG|JPEG)$" does not match "/routing.php", client: 127.0.0.1, server: basereality.com, request: "GET / HTTP/1.1", host: "basereality.test"
"^/proxy/(\d+)/(.+)\.(gif|png|jpg|jpeg|GIF|PNG|JPG|JPEG)$" does not match "/routing.php", client: 127.0.0.1, server: basereality.com, request: "GET / HTTP/1.1", host: "basereality.test"
"^/staticImage/(\w+)/(.+)\.([^\.]*)$" does not match "/routing.php", client: 127.0.0.1, server: basereality.com, request: "GET / HTTP/1.1", host: "basereality.test"

es decir, la petición llega como /, try_files no servía el archivo y lo vuelve a escribir la solicitud de / a /routing.php y, a continuación, vuelve a procesar la solicitud.

¿Por qué tratar de archivos que no sirve a la routing.php archivo en el primer paso? Existe y es accesible, de lo contrario no sería servido en la segunda ronda.

EDITAR

Eliminado sin relación config.

3voto

Sergey Vlasov Puntos 3888

La documentación que se cita explícitamente dice que "un redirect interno para el último parámetro se invoca". El redirect interno se maneja de la misma forma que la solicitud inicial procede del cliente - esto incluye el procesamiento de la rewrite declaraciones en el nivel de servidor, que aparece en el registro. Sin embargo, si cualquier otra try_files parámetro excepto el último que coincide con un archivo existente, la solicitud se controla el uso de la location configuración donde el try_files declaración se encuentra, y no habrá una segunda coincidencia.

Como para sus reglas, intenta simplemente omitiendo $args en try_files?

location  / {
    try_files $uri /routing.php /50x_static.html;
    fastcgi_pass   unix:/opt/local/var/run/php54/php-fpm-www.sock;
    include       /documents/projects/intahwebz/intahwebz/conf/fastcgi.conf;
}

Tenga en cuenta que $uri no contiene $args ; los parámetros de la consulta todavía será pasado a la FastCGI backend a través de la QUERY_STRING parámetro, que es de suponer que en su conjunto fastcgi.conf:

fastcgi_param QUERY_STRING    $query_string;

Y si no $uri ni /routing.php están presentes en los archivos, la solicitud será redirigido a /50x_static.html y manejados de acuerdo a la location = /50x_static.html sección en su configuración (pero una segunda iteración de la reescritura de los intentos de realizarse, debido a que sus reglas de reescritura se colocan en el nivel de servidor).

Uno muy sospechoso detalle de su configuración es que se pasa todos los archivos a través de PHP, independientemente de la extensión de archivo - esto es muy inusual, y puede causar problemas de seguridad debido a la ejecución de código PHP en un archivo donde no se esperaba.

0voto

Danack Puntos 429

Sergey había que corregir; añadiendo $args a un try_files comando detiene el archivo se emparejan y se lo envía Nginx ronda en otro bucle de procesamiento, lo cual es extraño, ya que es lo que el Nginx ejemplo, dice que hacer.

Si sigue el ejemplo exactamente con:

try_files $uri $uri/ /index.php?q=$uri&$args;

Si $uri y $uri/ no existen, Nginx pasar a la magia último parámetro. Ni siquiera tratar de coincidir con el archivo y en su lugar vuelve a procesar la solicitud de establecimiento de la nueva ruta a /index.php y $args ahora q=$uri&$args.

Por otro lado, si usted tiene otro valor en try_files después de index.php por ejemplo,

try_files $uri $uri/ /index.php?q=$uri&$args /50x_static.html;

Nginx busca un archivo llamado /index.php?q=$uri&$args y obviamente no existe, y por lo que se mueve dentro de la /50x_static.html y vuelve a procesar.

Porque $uri se reescribe cuando Nginx vuelve a procesar la solicitud, para evitar esto se necesita algunos cambios sutiles. Si configuras tu config para ser como este:

set $originalURI  $uri;
try_files $uri $uri/ /index.php  /50x_static.html;
fastcgi_param  QUERY_STRING  q=$originalURI&$query_string;

El archivo Nginx busca es /index.php cual es el nombre correcto, por lo que nginx detener el procesamiento de allí. Tenemos que copiar el $uri variable como try_files modifica y por lo tanto sería sólo /index.php si sólo se utilizó después de la try_files.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: