Versión 2.5 del Servidor HTTP Apache

Este documento complementa la mod_rewrite
documentación de referencia. Describe
los conceptos básicos necesarios para el uso de
mod_rewrite. Otros documentos entran en mayor detalle,
pero este documento debería ayudar al principiante a mojarse los pies.
Introducción
Expresiones Regulares
Conceptos Básicos de RewriteRule
Banderas de Reescritura
Condiciones de Reescritura
Mapas de reescritura
Archivos .htaccessEl módulo de Apache mod_rewrite es un módulo muy potente y
sofisticado que proporciona una forma de hacer manipulaciones de URL. Con
él, puede hacer casi todos los tipos de reescritura de URL que pueda necesitar. Es,
sin embargo, algo complejo, y puede ser intimidante para el principiante.
También hay una tendencia a tratar las reglas de reescritura como encantamientos mágicos,
usándolas sin realmente entender lo que hacen.
Este documento intenta dar suficiente contexto para que lo que sigue sea entendido, en lugar de simplemente copiado a ciegas.
Recuerde que muchas tareas comunes de manipulación de URL no requieren la
potencia y complejidad completas de mod_rewrite. Para tareas
simples, consulte mod_alias y la documentación
sobre mapeo de URLs al
sistema de archivos.
Finalmente, antes de continuar, asegúrese de configurar
el nivel de log de mod_rewrite a uno de los niveles de traza usando
la directiva LogLevel. Aunque esto
puede dar una cantidad abrumadora de información, es indispensable para
depurar problemas con la configuración de mod_rewrite, ya que
le dirá exactamente cómo se procesa cada regla.
mod_rewrite usa el vocabulario de Expresiones
Regulares Compatibles con Perl. En este documento, no intentamos
proporcionar una referencia detallada de expresiones regulares. Para eso,
recomendamos las páginas man de PCRE, la
página man de expresiones
regulares de Perl, y Mastering
Regular Expressions, de Jeffrey Friedl (la tercera edición es de
2006, pero la sintaxis de expresiones regulares es esencialmente la misma, y este
sigue siendo la referencia definitiva sobre el tema).
En este documento, intentamos proporcionar suficiente vocabulario de regex
para que pueda comenzar, sin ser abrumador, con la esperanza de que
las RewriteRules sean fórmulas
científicas, en lugar de encantamientos mágicos.
Los siguientes son los bloques de construcción mínimos que necesitará, para
escribir expresiones regulares y RewriteRules. Ciertamente no
representan un vocabulario completo de expresiones regulares, pero son un buen
punto de partida, y deberían ayudarle a leer expresiones regulares básicas, así
como a escribir las suyas propias.
| Carácter | Significado | Ejemplo |
|---|---|---|
. |
Coincide con cualquier carácter individual | c.t coincidirá con cat, cot,
cut, etc |
+ |
Repite la coincidencia anterior una o más veces | a+ coincide con a, aa,
aaa, etc |
* |
Repite la coincidencia anterior cero o más veces | a* coincide con todo lo mismo que a+,
pero también coincidirá con una cadena vacía |
? |
Hace la coincidencia opcional | colou?r coincidirá con color y
colour |
\ |
Escapa el siguiente carácter | \. coincidirá con . (punto) y no con cualquier
carácter individual como se explicó arriba |
^ |
Llamado ancla, coincide con el inicio de la cadena | ^a coincide con una cadena que comienza con a |
$ |
La otra ancla, coincide con el final de la cadena | a$ coincide con una cadena que termina con a |
( ) |
Agrupa varios caracteres en una sola unidad, y captura una coincidencia para uso en una referencia inversa | (ab)+ coincide con ababab - es decir, el
+ se aplica al grupo. Para más sobre referencias inversas vea
más abajo |
[ ] |
Una clase de caracteres - coincide con uno de los caracteres | c[uoa]t coincide con cut, cot o
cat |
[^ ] |
Clase de caracteres negativa - coincide con cualquier carácter no especificado | c[^/]t coincide con cat o c=t pero
no con c/t |
En mod_rewrite el carácter ! puede usarse
antes de una expresión regular para negarla. Es decir, una cadena se
considerará que ha coincidido solo si no coincide con el resto de
la expresión.
Una cosa importante que debe recordarse aquí: Siempre que
use paréntesis en Pattern o en uno de los
CondPattern, se crean referencias inversas internas
que pueden usarse con las cadenas $N y
%N (ver más abajo). Estas están disponibles para crear
el parámetro Substitution de una
RewriteRule o
el parámetro TestString de una
RewriteCond.
Las capturas en los patrones de RewriteRule están (contraintuitivamente) disponibles para
todas las directivas
RewriteCond precedentes,
porque la expresión de RewriteRule
se evalúa antes que las condiciones individuales.
La Figura 1 muestra a qué ubicaciones se transfieren las referencias inversas para expansión, así como ilustra el flujo de la coincidencia de RewriteRule, RewriteCond. En los próximos capítulos, exploraremos cómo usar estas referencias inversas, así que no se preocupe si le parece un poco extraño al principio.

Figura 1: El flujo de referencias inversas a través de una regla.
En este ejemplo, una solicitud para /test/1234 sería transformada en /admin.foo?page=test&id=1234&host=admin.example.com.
Una RewriteRule consiste
en tres argumentos separados por espacios. Los argumentos son
El Pattern es una expresión regular. Se compara inicialmente (para la primera regla de reescritura o hasta que ocurra una sustitución) contra la ruta URL de la solicitud entrante (la parte después del nombre de host pero antes de cualquier signo de interrogación que indique el inicio de una cadena de consulta) o, en contexto per-directorio, contra la ruta de la solicitud relativa al directorio para el cual se define la regla. Una vez que ha ocurrido una sustitución, las reglas siguientes se comparan contra el valor sustituido.

Figura 2: Sintaxis de la directiva RewriteRule.
La Substitution puede ser una de tres cosas:
RewriteRule "^/games" "/usr/local/games/web/puzzles.html"
Esto mapea una solicitud a una ubicación arbitraria en su sistema de archivos, de forma
similar a la directiva Alias.
RewriteRule "^/games$" "/puzzles.html"
Si DocumentRoot está configurado
como /usr/local/apache2/htdocs, entonces esta directiva
mapearía solicitudes para http://example.com/games a la
ruta /usr/local/apache2/htdocs/puzzles.html.
RewriteRule "^/product/view$" "http://site2.example.com/seeproduct.html" [R]
Esto le dice al cliente que haga una nueva solicitud a la URL especificada.
/usr/) existe en el sistema de archivos, mientras que en el caso de 2, no existe. (es decir, no hay /bar/ como directorio de nivel raíz en el sistema de archivos.)La Substitution también puede contener referencias inversas a partes de la ruta URL entrante coincidida por el Pattern. Considere lo siguiente:
RewriteRule "^/product/(.*)/view$" "/var/web/productdb/$1"
La variable $1 será reemplazada por cualquier texto
que haya coincidido con la expresión dentro de los paréntesis en
el Pattern. Por ejemplo, una solicitud
para http://example.com/product/r14df/view será mapeada
a la ruta /var/web/productdb/r14df.
Si hay más de una expresión entre paréntesis, están
disponibles en orden en las
variables $1, $2, $3, y así
sucesivamente.
El comportamiento de una RewriteRule puede ser modificado por la
aplicación de una o más banderas al final de la regla. Por ejemplo, el
comportamiento de coincidencia de una regla puede hacerse insensible a mayúsculas/minúsculas mediante la
aplicación de la bandera [NC]:
RewriteRule "^puppy.html" "smalldog.html" [NC]
Para más detalles sobre las banderas disponibles, sus significados, y ejemplos, consulte el documento de Banderas de Reescritura.
Una o más directivas RewriteCond
pueden usarse para restringir los tipos de solicitudes que estarán
sujetas a la
RewriteRule siguiente. El
primer argumento es una variable que describe una característica de la
solicitud, el segundo argumento es una expresión
regular que debe coincidir con la variable, y un tercer argumento opcional
es una lista de banderas que modifican cómo se evalúa la coincidencia.

Figura 3: Sintaxis de la directiva RewriteCond
Por ejemplo, para enviar todas las solicitudes desde un rango de IP particular a un servidor diferente, podría usar:
RewriteCond "%{REMOTE_ADDR}" "^10\.2\."
RewriteRule "(.*)" "http://intranet.example.com$1"
Cuando se especifica más de
una RewriteCond,
todas deben coincidir para que la
RewriteRule se aplique.
Por ejemplo, para denegar solicitudes que contengan la palabra "hack" en
su cadena de consulta, a menos que también contengan una cookie que contenga
la palabra "go", podría usar:
RewriteCond "%{QUERY_STRING}" "hack"
RewriteCond "%{HTTP_COOKIE}" !go
RewriteRule "." "-" [F]
Note que el signo de exclamación especifica una coincidencia negativa, por lo que la regla solo se aplica si la cookie no contiene "go".
Las coincidencias en las expresiones regulares contenidas en
las RewriteConds pueden
usarse como parte de la Substitution en
la RewriteRule usando las
variables %1, %2, etc. Por ejemplo, esto
dirigirá la solicitud a un directorio diferente dependiendo del
nombre de host usado para acceder al sitio:
RewriteCond "%{HTTP_HOST}" "(.*)"
RewriteRule "^/(.*)" "/sites/%1/$1"
Si la solicitud fue para http://example.com/foo/bar,
entonces %1 contendrá example.com
y $1 contendrá foo/bar.
La directiva RewriteMap
proporciona una forma de llamar a una función externa, por así decirlo, para hacer su
reescritura por usted. Esto se discute con mayor detalle en la documentación complementaria de RewriteMap.
La reescritura se configura típicamente en la configuración principal del servidor
(fuera de cualquier sección <Directory>) o
dentro de contenedores <VirtualHost>.
Esta es la forma más fácil de hacer reescritura y es
recomendada. Sin embargo, es posible hacer reescritura
dentro de secciones <Directory>
o archivos .htaccess
a costa de algo de complejidad adicional. Esta técnica
se llama reescrituras per-directorio.
La principal diferencia con las reescrituras per-servidor es que el prefijo de ruta
del directorio que contiene el archivo .htaccess se
elimina antes de la coincidencia en
la RewriteRule. Además, se debería usar RewriteBase para asegurar que la solicitud se mapee correctamente.