Versión 2.5 del Servidor HTTP Apache

Este documento discute algunos de los detalles técnicos de mod_rewrite
y la coincidencia de URLs.
Apache HTTP Server maneja las solicitudes en varias fases. En cada una de estas fases, uno o más módulos pueden ser llamados para manejar esa porción del ciclo de vida de la solicitud. Las fases incluyen cosas como traducción de URL a nombre de archivo, autenticación, autorización, contenido, y registro. (Esta no es una lista exhaustiva.)
mod_rewrite actúa en dos de estas fases (o "hooks", como se les
suele llamar) para influir en cómo las URLs pueden ser reescritas.
Primero, usa el hook de traducción de URL a nombre de archivo, que ocurre
después de que la solicitud HTTP ha sido leída, pero antes de que cualquier autorización
comience. Segundo, usa el hook de Fixup, que es después de las
fases de autorización, y después de que los archivos de configuración per-directorio
(archivos .htaccess) han sido leídos, pero antes de que el
manejador de contenido sea llamado.
Después de que una solicitud llega y se ha determinado un servidor o
host virtual correspondiente, el motor de reescritura comienza a
procesar cualquier directiva de mod_rewrite que aparezca en la
configuración per-servidor. (es decir, en el archivo de configuración principal del servidor
y secciones <Virtualhost>.)
Esto sucede en la fase de traducción de URL a nombre de archivo.
Unos pasos más tarde, una vez que se han encontrado los directorios de datos finales,
se aplican las directivas de configuración per-directorio (archivos .htaccess
y bloques <Directory>). Esto
sucede en la fase de Fixup.
En cada uno de estos casos, mod_rewrite reescribe el
REQUEST_URI ya sea a una nueva URL, o a un nombre de archivo.
En contexto per-directorio (es decir, dentro de archivos .htaccess
y bloques Directory), estas reglas se están aplicando
después de que una URL ya ha sido traducida a un nombre de archivo. Debido a
esto, la ruta URL contra la que mod_rewrite inicialmente compara las directivas
RewriteRule
es la ruta completa del sistema de archivos al nombre de archivo traducido con la ruta del
directorio actual (incluyendo una barra final) eliminada del frente.
Para ilustrar: Si las reglas están en /var/www/foo/.htaccess y se está procesando una solicitud para /foo/bar/baz, una expresión como ^bar/baz$ coincidiría.
Si se hace una sustitución en contexto per-directorio, se emite una nueva
sub-solicitud interna con la nueva URL, que reinicia el procesamiento de las
fases de la solicitud. Si la sustitución es una ruta relativa, la directiva RewriteBase
determina el prefijo de ruta URL que se antepone a la sustitución.
En contexto per-directorio, se debe tener cuidado de
crear reglas que eventualmente (en alguna "ronda" futura de procesamiento de reescritura
per-directorio) no realicen una sustitución para evitar bucles.
(Vea RewriteLooping
para más discusión de este problema.)
Debido a esta manipulación adicional de la URL en contexto per-directorio, necesitará tener cuidado de crear sus reglas de reescritura de manera diferente en ese contexto. En particular, recuerde que la ruta de directorio principal se eliminará de la URL que sus reglas de reescritura verán. Considere los ejemplos siguientes para más clarificación.
| Ubicación de la regla | Regla |
|---|---|
| Sección VirtualHost | RewriteRule "^/images/(.+)\.jpg" "/images/$1.gif" |
| Archivo .htaccess en la raíz del documento | RewriteRule "^images/(.+)\.jpg" "images/$1.gif" |
| Archivo .htaccess en el directorio images | RewriteRule "^(.+)\.jpg" "$1.gif" |
Para aún más información sobre cómo mod_rewrite manipula URLs en
diferentes contextos, debería consultar las entradas del log realizadas durante
la reescritura.
Ahora cuando mod_rewrite se activa en estas dos fases de la API, lee
los conjuntos de reglas configurados desde su estructura de
configuración (que a su vez fue creada al inicio para
contexto per-servidor o durante el recorrido de directorios del
núcleo de Apache para contexto per-directorio). Entonces el motor de reescritura
de URLs se inicia con el conjunto de reglas contenido (una o más
reglas junto con sus condiciones). La operación del
motor de reescritura de URLs es exactamente la misma para ambos
contextos de configuración. Solo el procesamiento del resultado final es
diferente.
El orden de las reglas en el conjunto de reglas es importante porque el
motor de reescritura las procesa en un orden especial (y no muy
obvio). La regla es esta: El motor de reescritura recorre
el conjunto de reglas regla por regla (directivas
RewriteRule) y
cuando una regla particular coincide, opcionalmente recorre
las condiciones correspondientes existentes (directivas RewriteCond).
Por razones históricas las condiciones se dan
primero, y por lo tanto el flujo de control es un poco
enrevesado. Vea la Figura 1 para más detalles.

Figura 1:El flujo de control a través del conjunto de reglas de reescritura
Primero la URL se compara contra el
Pattern de cada regla. Si falla, mod_rewrite
inmediatamente deja de procesar esta regla, y continúa con la
siguiente regla. Si el Pattern coincide, mod_rewrite busca
las condiciones de regla correspondientes (directivas RewriteCond,
que aparecen inmediatamente encima de la RewriteRule en la configuración).
Si no hay ninguna, sustituye la URL con un nuevo valor, que se
construye a partir de la cadena Substitution, y continúa
con su bucle de reglas. Pero si existen condiciones, inicia un
bucle interno para procesarlas en el orden en que están
listadas. Para las condiciones, la lógica es diferente: no comparamos
un patrón contra la URL actual. En su lugar, primero creamos una
cadena TestString expandiendo variables,
referencias inversas, búsquedas en mapas, etc. y luego intentamos
comparar CondPattern contra ella. Si el patrón
no coincide, el conjunto completo de condiciones y la
regla correspondiente fallan. Si el patrón coincide, entonces se
procesa la siguiente condición hasta que no haya más condiciones
disponibles. Si todas las condiciones coinciden, el procesamiento continúa
con la sustitución de la URL con
Substitution.