[Apache] Funciones ocultas de mod_rewrite



Answers

si necesita 'bloquear' las redirecciones / reescrituras internas en el .htaccess, eche un vistazo al

RewriteCond %{ENV:REDIRECT_STATUS} ^$

condición, como se discutió aquí .

Question

Parece haber un número decente de hilos mod_rewrite flotando últimamente con un poco de confusión sobre cómo funcionan ciertos aspectos de él. Como resultado, he recopilado algunas notas sobre la funcionalidad común, y tal vez algunos matices molestos.

¿Qué otras características / problemas comunes has encontrado usando mod_rewrite ?




Una mejor comprensión de la bandera [L] está en orden. La bandera [L] es la última, solo tiene que entender qué hará que su solicitud sea enrutada nuevamente a través del motor de análisis de URL. De los documentos ( http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_l ) (énfasis mío):

El indicador [L] hace que mod_rewrite deje de procesar el conjunto de reglas. En la mayoría de los contextos, esto significa que si la regla coincide, no se procesarán más reglas. Esto corresponde al último comando en Perl, o al comando break en C. Use este indicador para indicar que la regla actual debe aplicarse inmediatamente sin considerar otras reglas.

Si está utilizando RewriteRule en los archivos .htaccess o en las secciones <Directory> , es importante conocer cómo se procesan las reglas. La forma simplificada de esto es que una vez que las reglas se han procesado, la solicitud reescrita se devuelve al motor de análisis de URL para hacer lo que se le ocurra. Es posible que a medida que se maneje la solicitud reescrita, el archivo .htaccess o la sección <Directory> puedan encontrarse nuevamente, y por lo tanto, el conjunto de reglas se puede ejecutar nuevamente desde el inicio. Lo más común es que esto suceda si una de las reglas provoca una redirección, ya sea interna o externa, lo que provoca que el proceso de solicitud comience nuevamente.

Entonces, la bandera [L] deja de procesar cualquier otra regla de reescritura para esa pasada a través del conjunto de reglas. Sin embargo, si su regla marcada con [L] modificó la solicitud y se encuentra en el contexto .htaccess o en la sección <Directory> , su solicitud modificada volverá a pasar a través del motor de análisis de URL. Y en el siguiente pase, puede coincidir con una regla diferente esta vez. Si no comprende lo que sucedió, parece que su primera regla de reescritura con la bandera [L] no tuvo ningún efecto.

La mejor forma de evitar esto es utilizar el indicador [END] ( http://httpd.apache.org/docs/current/rewrite/flags.html#flag_end ) en lugar del indicador [L], si realmente desea detenerse. todo el procesamiento posterior de las reglas (y posterior repaso). Sin embargo, el indicador [END] solo está disponible para Apache v2.3.9 +, por lo que si tiene v2.2 o menos, se quedará bloqueado solo con el indicador [L]. En este caso, debe confiar en las declaraciones RewriteCond para evitar la coincidencia de las reglas en pases posteriores del motor de análisis de URL. O bien, debe asegurarse de que sus RewriteRule estén en un contexto (es decir, httpd.conf) que no hará que su solicitud sea re-analizada.




mod_rewrite puede modificar aspectos del manejo de solicitudes sin alterar el URL, por ejemplo, establecer variables de entorno, configurar cookies, etc. Esto es increíblemente útil.

Establecer condicionalmente una variable de entorno:

RewriteCond %{HTTP_COOKIE} myCookie=(a|b) [NC]
RewriteRule .* - [E=MY_ENV_VAR:%b]

Devuelve una respuesta 503: la RewriteRule [R] RewriteRule puede tomar un valor que no sea 3xx y devolver una respuesta que no redirecciona, por ejemplo, para el tiempo de inactividad / mantenimiento administrado:

RewriteRule .* - [R=503,L]

devolverá una respuesta 503 (no una redirección per se).

Además, mod_rewrite puede actuar como una interfaz de gran potencia para mod_proxy, por lo que puede hacer esto en lugar de escribir directivas ProxyPass :

RewriteRule ^/(.*)$ balancer://cluster%{REQUEST_URI} [P,QSA,L]

Opinión: el uso de RewriteRule y RewriteCond para enrutar solicitudes a diferentes aplicaciones o balanceadores de carga en función de prácticamente cualquier aspecto concebible de la solicitud es inmensamente poderoso. El control de las solicitudes en el camino hacia el back-end y la posibilidad de modificar las respuestas en el camino de regreso hacen de mod_rewrite el lugar ideal para centralizar todas las configuraciones relacionadas con el enrutamiento.

Tómese el tiempo para aprender, vale la pena! :)




Otras trampas:

1- A veces es una buena idea desactivar MultiViews

Options -MultiViews

No estoy del todo bien con todas las capacidades de MultiViews, pero sé que estropea mis reglas de mod_rewrite cuando está activo, porque una de sus propiedades es tratar de 'adivinar' una extensión a un archivo que cree que estoy buscando. .

Voy a explicar: supongamos que tienes 2 archivos php en tu directorio web, archivo1.php y archivo2.php y agregas estas condiciones y reglas a tu .htaccess:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ file1.php/$1 

Usted asume que todas las direcciones URL que no coinciden con un archivo o un directorio serán tomadas por file1.php. ¡Sorpresa! Esta regla no se cumple para la URL http://myhost/file2/somepath . En cambio, te llevan dentro de file2.php.

Lo que sucede es que MultiViews adivinó automágicamente que la url que realmente quería era http://myhost/file2.php/somepath y con mucho gusto lo llevó allí.

Ahora, no tienes ni idea de lo que acaba de pasar y en ese momento estás cuestionando todo lo que pensabas que sabías sobre mod_rewrite. Luego comienzas a jugar con las reglas para intentar darle sentido a la lógica detrás de esta nueva situación, pero cuanto más pruebas, menos sentido tiene.

Ok, en resumen, si quieres que mod_rewrite funcione de una manera que se aproxime a la lógica, desactivar MultiViews es un paso en la dirección correcta.

2- habilitar FollowSymlinks

Options +FollowSymLinks 

De ese, realmente no conozco los detalles, pero lo he mencionado muchas veces, así que hazlo.






Links