<-
Apache > Servidor HTTP > Documentación > Versión 2.5 > Rewrite

Técnicas avanzadas con mod_rewrite

Idiomas disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

Este documento complementa la mod_rewrite documentación de referencia. Proporciona algunas técnicas avanzadas usando mod_rewrite.

Tenga en cuenta que muchos de estos ejemplos no funcionarán sin cambios en su configuración particular del servidor, por lo que es importante que los entienda, en lugar de simplemente copiar y pegar los ejemplos en su configuración.

Consulte también

top

Fragmentación basada en URL entre múltiples backends

Descripción:

Una técnica común para distribuir la carga del servidor o el espacio de almacenamiento se llama "fragmentación" (sharding). Al usar este método, un servidor front-end usará la URL para "fragmentar" consistentemente usuarios u objetos a servidores backend separados.

Solución:

Se mantiene un mapeo, de usuarios a servidores destino, en archivos de mapa externos. Tienen este aspecto:

user1 physical_host_of_user1
user2 physical_host_of_user2
# ... y así sucesivamente

Colocamos esto en un archivo map.users-to-hosts. El objetivo es mapear;

/u/user1/anypath

a

http://physical_host_of_user1/u/user/anypath

por lo que no es necesario que cada ruta URL sea válida en cada host físico backend. El siguiente conjunto de reglas hace esto por nosotros con la ayuda de los archivos de mapa, asumiendo que server0 es un servidor predeterminado que se usará si un usuario no tiene entrada en el mapa:

RewriteEngine on
RewriteMap    users-to-hosts      "txt:/path/to/map.users-to-hosts"
RewriteRule   "^/u/([^/]+)/?(.*)" "http://${users-to-hosts:$1|server0}/u/$1/$2"

Consulte la documentación de la directiva RewriteMap y el Cómo usar RewriteMap para más discusión de la sintaxis de esta directiva.

top

Regeneración de Contenido sobre la marcha

Descripción:

Deseamos generar contenido dinámicamente, pero almacenarlo estáticamente una vez que se ha generado. Esta regla verificará la existencia del archivo estático, y si no está allí, lo generará. Los archivos estáticos pueden eliminarse periódicamente, si se desea (digamos, mediante cron) y se regenerarán bajo demanda.

Solución:
Esto se hace mediante el siguiente conjunto de reglas:
# This example is valid in per-directory context only
RewriteCond "%{REQUEST_URI}"   !-U
RewriteRule "^(.+)\.html$"     "/regenerate_page.cgi"   [PT,L]

El operador -U determina si la cadena de prueba (en este caso, REQUEST_URI) es una URL válida. Lo hace mediante una sub-solicitud. En el caso de que esta sub-solicitud falle - es decir, el recurso solicitado no existe - esta regla invoca el programa CGI /regenerate_page.cgi, que genera el recurso solicitado y lo guarda en el directorio de documentos, de modo que la próxima vez que se solicite, se pueda servir una copia estática.

De esta manera, documentos que se actualizan con poca frecuencia pueden servirse en forma estática. Si los documentos necesitan actualizarse, pueden eliminarse del directorio de documentos, y se regenerarán la próxima vez que se soliciten.

top

Balanceo de Carga

Descripción:

Deseamos distribuir aleatoriamente la carga entre varios servidores usando mod_rewrite.

Solución:

Usaremos RewriteMap y una lista de servidores para lograr esto.

RewriteEngine on
RewriteMap  lb       "rnd:/path/to/serverlist.txt"
RewriteRule "^/(.*)" "http://${lb:servers}/$1"     [P,L]

serverlist.txt contendrá una lista de los servidores:

## serverlist.txt

servers one.example.com|two.example.com|three.example.com

Si desea que un servidor particular reciba más carga que los otros, agreguelo más veces a la lista.

Discusión

Apache viene con un módulo de balanceo de carga - mod_proxy_balancer - que es mucho más flexible y con más funcionalidades que cualquier cosa que pueda construir usando mod_rewrite.

top

Directorios de Usuario Estructurados

Descripción:

Algunos sitios con miles de usuarios usan una disposición de directorio personal estructurada, es decir, cada directorio personal está en un subdirectorio que comienza (por ejemplo) con el primer carácter del nombre de usuario. Así, /~larry/anypath es /home/l/larry/public_html/anypath mientras que /~waldo/anypath es /home/w/waldo/public_html/anypath.

Solución:

Usamos el siguiente conjunto de reglas para expandir las URLs de tilde a la disposición anterior.

RewriteEngine on
RewriteRule   "^/~(([a-z])[a-z0-9]+)(.*)"  "/home/$2/$1/public_html$3"
top

Redireccionando Anclas

Descripción:

Por defecto, redirigir a un ancla HTML no funciona, porque mod_rewrite escapa el carácter #, convirtiéndolo en %23. Esto, a su vez, rompe la redirección.

Solución:

Use la bandera [NE] en la RewriteRule. NE significa No Escapar.

Discusión:
Esta técnica por supuesto también funcionará con otros caracteres especiales que mod_rewrite, por defecto, codifica en URL.
top

Reescritura Dependiente del Tiempo

Descripción:

Deseamos usar mod_rewrite para servir contenido diferente basado en la hora del día.

Solución:

Hay muchas variables llamadas TIME_xxx para condiciones de reescritura. En conjunto con los patrones especiales de comparación lexicográfica <STRING, >STRING y =STRING podemos hacer redirecciones dependientes del tiempo:

RewriteEngine on
RewriteCond   "%{TIME_HOUR}%{TIME_MIN}" >0700
RewriteCond   "%{TIME_HOUR}%{TIME_MIN}" <1900
RewriteRule   "^foo\.html$"             "foo.day.html" [L]
RewriteRule   "^foo\.html$"             "foo.night.html"

Esto proporciona el contenido de foo.day.html bajo la URL foo.html de 07:01-18:59 y en el tiempo restante el contenido de foo.night.html.

mod_cache, proxies intermedios y navegadores pueden cada uno almacenar en caché las respuestas y causar que cualquiera de las páginas se muestre fuera de la ventana de tiempo configurada. Se puede usar mod_expires para controlar este efecto. Por supuesto, es mucho mejor simplemente servir el contenido dinámicamente y personalizarlo basándose en la hora del día.
top

Establecer Variables de Entorno Basadas en Partes de la URL

Descripción:

A veces, queremos mantener algún tipo de estado cuando realizamos una reescritura. Por ejemplo, desea tomar nota de que ha realizado esa reescritura, para poder verificar más tarde si una solicitud llegó a través de esa reescritura. Una forma de hacer esto es estableciendo una variable de entorno.

Solución:

Use la bandera [E] para establecer una variable de entorno.

RewriteEngine on
RewriteRule   "^/horse/(.*)"   "/pony/$1" [E=rewritten:1]

Más adelante en su conjunto de reglas puede verificar esta variable de entorno usando una RewriteCond:

RewriteCond "%{ENV:rewritten}"  =1

Tenga en cuenta que las variables de entorno no sobreviven a una redirección externa. Podría considerar usar la bandera [CO] para establecer una cookie. Para reescrituras en contexto per-directorio y htaccess, donde la sustitución final se procesa como una redirección interna, las variables de entorno de la ronda anterior de reescritura se prefijan con "REDIRECT_".

Idiomas disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn