Versión 2.5 del Servidor HTTP Apache

Este documento complementa la mod_rewrite
documentación de referencia. Describe
el uso de la directiva RewriteMap,
y proporciona ejemplos de cada uno de los diversos tipos de RewriteMap.
Introducción
int: Función Interna
txt: Mapas de texto plano
rnd: Texto Plano Aleatorizado
dbm: Archivo Hash DBM
prg: Programa de Reescritura Externo
dbd o fastdbd: Consulta SQL
Resumen
La directiva RewriteMap
define una función externa que puede ser llamada en el contexto de
directivas RewriteRule o
RewriteCond para
realizar reescrituras que son demasiado complicadas, o demasiado especializadas para ser
realizadas solo con expresiones regulares. La fuente de esta búsqueda puede
ser cualquiera de los tipos listados en las secciones siguientes, y enumerados en
la documentación de referencia de RewriteMap.
La sintaxis de la directiva RewriteMap
es la siguiente:
RewriteMap MapName MapType:MapSource
El MapName es un nombre arbitrario que asigna al mapa, y que usará en directivas más adelante. Los argumentos se pasan al mapa a través de la siguiente sintaxis:
${ MapName : LookupKey
}
${ MapName :
LookupKey | DefaultValue }
Cuando se encuentra tal construcción, se consulta el mapa MapName y se busca la clave LookupKey. Si la clave se encuentra, la construcción de función de mapa se sustituye por SubstValue. Si la clave no se encuentra entonces se sustituye por DefaultValue o por la cadena vacía si no se especificó DefaultValue.
Por ejemplo, puede definir un
RewriteMap como:
RewriteMap examplemap "txt:/path/to/file/map.txt"
Entonces podrá usar este mapa en una
RewriteRule de la siguiente manera:
RewriteRule "^/ex/(.*)" "${examplemap:$1}"
Se puede especificar un valor predeterminado en caso de que no se encuentre nada en el mapa:
RewriteRule "^/ex/(.*)" "${examplemap:$1|/not_found.html}"
La directiva RewriteMap no puede usarse
en secciones <Directory> ni en
archivos .htaccess. Debe
declarar el mapa en contexto de servidor o virtualhost. Puede usar el mapa,
una vez creado, en sus directivas RewriteRule y
RewriteCond en esos
ámbitos. Simplemente no puede declararlo en esos ámbitos.
Las secciones siguientes describen los diversos MapTypes que pueden usarse, y dan ejemplos de cada uno.
Cuando se usa un MapType de int, el MapSource es una
de las funciones internas disponibles de RewriteMap.
Los autores de módulos pueden proporcionar
funciones internas adicionales registrándolas con la
API ap_register_rewrite_mapfunc.
Las funciones que se proporcionan por defecto son:
Para usar una de estas funciones, cree un RewriteMap que referencie
la función int, y luego úselo en su RewriteRule:
Redirigir una URI a una versión toda en minúsculas de sí misma
RewriteMap lc int:tolower
RewriteRule "(.*)" "${lc:$1}" [R]
Por favor tenga en cuenta que el ejemplo ofrecido aquí es para
fines ilustrativos únicamente, y no es una recomendación. Si desea
hacer URLs insensibles a mayúsculas/minúsculas, considere usar
mod_speling en su lugar.
Cuando se usa un MapType de txt, el MapSource es una ruta del sistema de archivos a un
archivo de mapeo de texto plano, que contiene un par clave/valor separado por espacios
por línea. Opcionalmente, una línea puede contener un comentario, comenzando con
un carácter '#'.
Un archivo de mapa de reescritura de texto válido tendrá la siguiente sintaxis:
# Línea de comentario
MatchingKey SubstValue
MatchingKey SubstValue # comentario
Cuando se invoca el RewriteMap,
el argumento se busca en el
primer argumento de una línea, y, si se encuentra, se devuelve el valor de
sustitución.
Por ejemplo, podemos usar un archivo de mapa para traducir nombres de productos a IDs de productos para URLs más fáciles de recordar, usando la siguiente receta:
Configuración de Producto a ID
RewriteMap product2id "txt:/etc/apache2/productmap.txt"
RewriteRule "^/product/(.*)" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]
Asumimos aquí que el script prods.php sabe qué
hacer cuando recibe un argumento de id=NOTFOUND cuando
un producto no se encuentra en el mapa de búsqueda.
El archivo /etc/apache2/productmap.txt entonces contiene
lo siguiente:
##
## productmap.txt - Archivo de mapa de Producto a ID
##
television 993
stereo 198
fishingrod 043
basketball 418
telephone 328
Así, cuando se solicita http://example.com/product/television,
se aplica la RewriteRule,
y la solicitud
se mapea internamente a /prods.php?id=993.
.htaccess,
necesitará eliminar la barra inicial del patrón de
reescritura para que coincida con algo:
RewriteRule "^product/(.*)" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]
Las claves buscadas son almacenadas en caché por httpd hasta que el mtime
(tiempo de modificación) del archivo de mapa cambia, o el servidor httpd se
reinicia. Esto asegura un mejor rendimiento en mapas que son llamados
por muchas solicitudes.
Cuando se usa un MapType de rnd, el MapSource es una
ruta del sistema de archivos a un archivo de mapeo de texto plano, cada línea del cual
contiene una clave, y uno o más valores separados por |.
Uno de estos valores se elegirá al azar si la clave
coincide.
Por ejemplo, puede usar el siguiente archivo de mapa y directivas para proporcionar un balanceo de carga aleatorio entre varios servidores backend, a través de un proxy inverso. Las imágenes se envían a uno de los servidores en el grupo 'static', mientras que todo lo demás se envía a uno del grupo 'dynamic'.
##
## map.txt -- mapa de reescritura
##
static www1|www2|www3|www4
dynamic www5|www6
Directivas de configuración
RewriteMap servers "rnd:/path/to/file/map.txt"
RewriteRule "^/(.*\.(png|gif|jpg))" "http://${servers:static}/$1" [NC,P,L]
RewriteRule "^/(.*)" "http://${servers:dynamic}/$1" [P,L]
Así, cuando se solicita una imagen y la primera de estas reglas
coincide, RewriteMap busca la cadena
static en el archivo de mapa, que devuelve uno de los
nombres de host especificados al azar, que luego se usa en el
destino de la RewriteRule.
Si quisiera que uno de los servidores sea más probable de ser elegido (por ejemplo, si uno de los servidores tiene más memoria que los otros, y por lo tanto puede manejar más solicitudes) simplemente listelo más veces en el archivo de mapa.
static www1|www1|www2|www3|www4
Cuando se usa un MapType de dbm, el MapSource es una
ruta del sistema de archivos a un archivo de base de datos DBM que contiene pares clave/valor para
ser usados en el mapeo. Esto funciona exactamente igual que el
mapa txt, pero es mucho más rápido, porque un DBM está indexado,
mientras que un archivo de texto no. Esto permite un acceso más rápido a la
clave deseada.
Opcionalmente puede especificar un tipo particular de dbm:
RewriteMap examplemap "dbm=sdbm:/etc/apache/mapfile.dbm"
El tipo puede ser sdbm, gdbm, ndbm
o db.
Sin embargo, se recomienda que simplemente use la utilidad httxt2dbm que se
proporciona con Apache HTTP Server, ya que usará la biblioteca DBM correcta,
que coincida con la que se usó cuando se compiló httpd mismo.
Para crear un archivo dbm, primero cree un archivo de mapa de texto como se describe
en la sección txt. Luego ejecute
httxt2dbm:
$ httxt2dbm -i mapfile.txt -o mapfile.map
Luego puede referenciar el archivo resultante en su
directiva RewriteMap:
RewriteMap mapname "dbm:/etc/apache/mapfile.map"
Tenga en cuenta que con algunos tipos de dbm, se genera más de un archivo, con
un nombre base común. Por ejemplo, puede tener dos archivos llamados
mapfile.map.dir y mapfile.map.pag. Esto es
normal, y solo necesita usar el nombre base mapfile.map en
su directiva RewriteMap.
Las claves buscadas son almacenadas en caché por httpd hasta que el mtime
(tiempo de modificación) del archivo de mapa cambia, o el servidor httpd se
reinicia. Esto asegura un mejor rendimiento en mapas que son llamados
por muchas solicitudes.
Cuando se usa un MapType de prg, el MapSource es una
ruta del sistema de archivos a un programa ejecutable que proporcionará el
comportamiento de mapeo. Puede ser un archivo binario compilado, o un programa
en un lenguaje interpretado como Python o Perl.
Este programa se inicia una vez, cuando se inicia Apache HTTP Server,
y luego se comunica con el motor de reescritura a través de
STDIN y STDOUT. Para cada búsqueda de función de mapa,
la clave se escribe en el STDIN del programa,
seguida de un carácter de nueva línea. El programa debería leer una línea
de STDIN (hasta e incluyendo la nueva línea), y
escribir su respuesta como una única línea terminada en nueva línea en
STDOUT. Las claves nunca contendrán caracteres de nueva línea;
si se encuentra una clave que contenga una nueva línea, la búsqueda
fallará.
Si no hay un valor de búsqueda correspondiente, el programa de mapa
debería devolver la cadena de cuatro caracteres "NULL" para
indicar esto. Tenga en cuenta que esta comparación no distingue entre mayúsculas y minúsculas, así que
"null", "Null", etc. también se tratan como una búsqueda fallida. Como
consecuencia, no es posible que un programa de mapeo devuelva
la cadena literal "NULL" como valor mapeado.
El STDERR del programa se hereda del
proceso padre de httpd, por lo que cualquier cosa que el programa escriba en
STDERR terminará en el mismo lugar que la propia
salida de errores de httpd (típicamente el ErrorLog).
Los programas de reescritura externos no se inician si están definidos en
un contexto que no tiene RewriteEngine establecido a
on.
Por defecto, los programas de reescritura externos se ejecutan como el
usuario:grupo que inició httpd. Esto puede cambiarse en sistemas UNIX
pasando nombre de usuario y nombre de grupo como tercer argumento a
RewriteMap en el
formato username:groupname.
Esta característica utiliza el mutex rewrite-map,
que es necesario para una comunicación fiable con el programa.
El mecanismo de mutex y el archivo de bloqueo pueden configurarse con la
directiva Mutex.
Aquí se muestra un ejemplo simple que reemplazará todos los guiones con guiones bajos en una URI de solicitud.
Configuración de reescritura
RewriteMap d2u "prg:/www/bin/dash2under.py" apache:apache
RewriteRule "-" "${d2u:%{REQUEST_URI}}"
dash2under.py
#!/usr/bin/env python3
import sys
for line in sys.stdin:
print(line.strip().replace('-', '_'), flush=True)
flush=True a
print(). La E/S con buffer causará que httpd espere la
salida, y por lo tanto se colgará.SIGTERM al programa; si no sale dentro de 3 segundos, se
le envía SIGKILL.Cuando se usa un MapType de dbd o fastdbd,
el MapSource es una sentencia SQL SELECT que toma un solo
argumento y devuelve un solo valor.
mod_dbd necesitará estar configurado para apuntar a
la base de datos correcta para que esta sentencia se ejecute.
Hay dos formas de este MapType.
Usar un MapType de dbd causa que la consulta se
ejecute con cada solicitud de mapa, mientras que usar fastdbd
almacena en caché las búsquedas de base de datos internamente. Así, mientras que
fastdbd es más eficiente, y por lo tanto más rápido, no
reflejará los cambios en la base de datos hasta que el servidor sea
reiniciado.
Si una consulta devuelve más de una fila, se usa una fila aleatoria del conjunto de resultados.
RewriteMap myquery "fastdbd:SELECT destination FROM rewrite WHERE source = %s"
El nombre de la consulta se pasa al controlador de base de datos como una etiqueta para una sentencia SQL preparada, y por lo tanto necesitará seguir cualquier regla (como sensibilidad a mayúsculas/minúsculas) requerida por su base de datos.
La directiva RewriteMap puede
aparecer más de una vez. Para cada función de mapeo use una
directiva RewriteMap para declarar
su archivo de mapa de reescritura.
Aunque no puede declarar un mapa en
contexto per-directorio (archivos .htaccess o
bloques <Directory>) es
posible usar este mapa en contexto per-directorio.