MOD_REWRITE es un potente módulo incluido en Apache que permite realizar un pre-procesamiento de las peticiones llevadas a cabo por los clientes que solicitan determinados recursos del servidor web. Su funcionamiento es sencillo, sin embargo dado que es bastante flexible, puede ser tan complejo como se desee/necesite. Lo que hace este módulo realmente es manipular las URL’s solicitadas por un cliente y realizar una redireccion interna a otro recurso, lo que significa que cuando un cliente ingresa una URL en su navegador, la página/recurso que esta solicitado simplemente es una “marca” para el servidor web que le indicará que debe realizar una redirección interna y servir un contenido determinado. Esto es útil en el sentido de que pueden escribirse URL’s amigables que son más fáciles de entender (y posiblemente de memorizar) para el usuario final. El mecanismo utilizado por este módulo para ejecutar las redirecciones internas es por medio del uso de la directiva RewriteRule y expresiones regulares que aplican sobre la URL solicitada por el cliente, de esta forma cada vez que una URL cumple alguna de las reglas definidas con esta directiva, se activa de forma automática la dirección a un recurso interno que también se define en la directiva anteriormente mencionada.

HABILITANDO MOD_REWRITE EN APACHE

Antes de continuar explicando el funcionamiento este módulo, es importante comprender que todos los módulos disponibles en Apache son también conocidos como DSO (Dynamic Shared Object) y deben ser habilitados de forma manual utilizando la utilidad APXS (Apache Extension Tool) la cual se encuentra ubicada en el directorio <APACHE_INSTALL>/bin La finalidad de esta herramienta es construir e instalar extensiones (módulos DSO) en el servidor web, normalmente los módulos que ya se encuentran preparados para ser construidos e instalados en Apache se encuentran disponibles en el directorio <APACHE_INSTALL>/modules/mappers

En este caso concreto, podrá verse los ficheros mod_rewrite.* que componen el código fuente de MOD_REWRITE.

Ahora bien, para poder instalar este módulo usando APXS es necesario ubicarse en el directorio <APACHE_INSTALL>/modules/mappers y ejecutar

>../../bin/apxs -i -a -c mod_rewrite.c

/usr/share/apr-1.0/build/libtool –silent –mode=compile i486-linux-gnu-gcc -std=gnu99 -prefer-pic -D_REENTRANT -D_GNU_SOURCE -D_LARGEFILE64_SOURCE -pthread -I/opt/WebServerFull/httpd-2.4.2/include -I/usr/include/apr-1.0 -I/usr/include/apr-1.0 -c -o mod_rewrite.lo mod_rewrite.c && touch mod_rewrite.slo

/usr/share/apr-1.0/build/libtool –silent –mode=link i486-linux-gnu-gcc -std=gnu99 -o mod_rewrite.la -rpath /opt/WebServerFull/httpd-2.4.2/modules -module -avoid-version mod_rewrite.lo

/opt/WebServerFull/httpd-2.4.2/build/instdso.sh SH_LIBTOOL=’/usr/share/apr-1.0/build/libtool’ mod_rewrite.la /opt/WebServerFull/httpd-2.4.2/modules

/usr/share/apr-1.0/build/libtool –mode=install install mod_rewrite.la /opt/WebServerFull/httpd-2.4.2/modules/

libtool: install: install .libs/mod_rewrite.so /opt/WebServerFull/httpd-2.4.2/modules/mod_rewrite.so

libtool: install: install .libs/mod_rewrite.lai /opt/WebServerFull/httpd-2.4.2/modules/mod_rewrite.la

libtool: install: install .libs/mod_rewrite.a /opt/WebServerFull/httpd-2.4.2/modules/mod_rewrite.a

libtool: install: chmod 644 /opt/WebServerFull/httpd-2.4.2/modules/mod_rewrite.a

libtool: install: ranlib /opt/WebServerFull/httpd-2.4.2/modules/mod_rewrite.a

libtool: finish: PATH=»/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/apache-maven-3.0.4/bin/:/sbin» ldconfig -n /opt/WebServerFull/httpd-2.4.2/modules

———————————————————————-

Libraries have been installed in:

/opt/WebServerFull/httpd-2.4.2/modules

If you ever happen to want to link against installed libraries

in a given directory, LIBDIR, you must either use libtool, and

specify the full pathname of the library, or use the `-LLIBDIR’

flag during linking and do at least one of the following:

– add LIBDIR to the `LD_LIBRARY_PATH’ environment variable

during execution

– add LIBDIR to the `LD_RUN_PATH’ environment variable

during linking

– use the `-Wl,-rpath -Wl,LIBDIR’ linker flag

– have your system administrator add LIBDIR to `/etc/ld.so.conf’

See any operating system documentation about shared libraries for

more information, such as the ld(1) and ld.so(8) manual pages.

———————————————————————-

chmod 755 /opt/WebServerFull/httpd-2.4.2/modules/mod_rewrite.so

[activating module `rewrite’ in /opt/WebServerFull/httpd-2.4.2/conf/httpd.conf]

Como puede apreciarse de la salida anterior, el fichero mod_rewrite.so ha sido creado y se ha ubicado en el directorio <APACHE_INSTALL>/modules

Ahora que el módulo se ha creado, es el momento de activarlo en el fichero de configuración del Apache para poder comenzar a utilizar sus directivas disponibles, para ello se deben incluir las siguientes lineas en el fichero de configuración.

LoadModule rewrite_module modules/mod_rewrite.so

Si el servidor web arranca correctamente, indica que el módulo se ha instalado correctamente en el servidor web.

FUNCIONAMIENTO MOD_REWRITE

Ahora que se ha activado el módulo en el servidor web, es el momento de comenzar a usarlo, la forma de hacerlo es igual que con todos los módulos que se han explicado en las publicaciones anteriores, es decir, por medio de las directivas disponibles.

Antes de comenzar a explicar algunas de las directivas que se incluyen en este módulo, es importante entender como funciona internamente. Tal como se ha comentado en la publicación anterior sobre MOD_DEFLATE, en Apache existe un mecanismo de filtros que permite ejecutar rutinas de pre-procesamiento y post-procesamiento de peticiones por parte del usuario, en el caso de este módulo, antes de que una petición por parte del cliente sea procesada, esta es manipulada por el filtro de pre-procesamiento, que se encarga de aplicar las reglas definidas para el módulo y en el caso de que alguna de ellas se cumpla (que como ya se ha dicho, son expresiones regulares) la URL es modificada dinámicamente siguiendo las indicaciones definidas en la regla y finalmente permite que la ejecución continué. Es posible que las redirecciones sean internas o a recursos externos como por ejemplo a otro servidor web o incluso por medio de un proxy (se verá próximamente con el uso del módulo mod_proxy.

Por otro lado, es importante anotar que este módulo aplica a diferentes contextos del servidor web, a nivel de contexto global (configuración global del servidor por medio de fichero de configuración) a nivel de virtual host y finalmente a nivel de directorio (definidos en los ficheros .htaccess). Por defecto la configuración aplicada a nivel de contexto, no es heredada a los virtual host definidos, en el caso de que se desee aplicar los settings de configuración definidos en el contexto global, se debe utilizar la directiva RewriteOptions del siguiente modo

RewriteEngine On
RewriteOptions Inherit

Ahora se explican las principales directivas incluidas en este módulo y posteriormente, ejemplos de como utilizarlas

RewriteBase

Esta directiva permite definir el path relativo base cuando se trata de configuración a nivel de directorio (.htaccess). Su uso es requerido en el caso de que la petición original y la posible sustitución están por debajo del directorio indicado en el DocumentRoot. Por ejemplo:

DocumentRoot /var/www/domain
Alias /app /opt/webapp
<Directory /opt/webapp>
RewriteEngine On
RewriteBase /app/
RewriteRule ^index\.html$  bienvenido.html 
</Directory>

Con el ejemplo anterior, el uso de la directiva RewriteBase era obligatorio, ya que en el caso de que no se indique, cuando el motor intenté manipular una petición dada, buscará en el directorio /var/www/domain/opt/webapp dado que asume que se encuentra por debajo del DocumentRoot como se puede ver, para solucionarlo se ha creado un alias al directorio /opt/webapp llamado /app y se ha definido como base, esto quiere decir que cuando se solicite un recurso como “index.html” el motor de sobre-escritura ya no buscará en el directorio /var/www/domain/opt/webapp sino que en su lugar buscará el recurso bienvenido.html en el directorio /opt/webapp tal como se ha indicado en la directiva RewriteBase

RewriteEngine

Se trata de la directiva principal para este módulo, ya que permite activarlo o desactivarlo para cada contexto de configuración tal como se explico párrafos anteriores. Los únicos posibles valores para esta directiva son on y off

RewriteEngine on

RewriteLog

Con esta directiva, tal como su nombre lo indica, se puede definir un fichero de logs donde se registrarán todos los eventos que se produzcan en el motor de sobre-escritura. Esta directiva solamente puede aparecer una sola vez a nivel de configuración global y solamente es valida para configuración global y virtual hosts.

RewriteLog /file/logs/logfile

RewriteLogLevel

Esta directiva permite definir el nivel de logs que dejará el motor de sobre-escritura, es decir, la cantidad de mensajes que dejará en el fichero de log definido en el directorio RewriteLog. Esta directiva solamente aplica a nivel de configuración global y virtual host. Los posibles valores van desde 0 hasta 9 siendo 0 el nivel más bajo de log (no log) y 9 el más alto (verbose)

RewriteLogLevel 6

RewriteRule

Esta directiva es el corazón del módulo, ya que permite definir reglas concretas para el mecanismo de sobre-escritura. Pueden definirse un número ilimitado de reglas sin embargo el orden en el que se definen es importante ya que se aplican por el motor de sobre-escritura de acuerdo a su orden de aparición, ademas soporta expresiones regulares que se evalúan contra las peticiones que realizan los clientes.

Para comprender mejor esta directiva, es mejor listar algunos ejemplos:

  1. En el directorio definido en DocumentRoot ha creado el siguiente fichero .htaccess
    RewriteEngine on

    RewriteRule ^index.html$ app/index.html

    RewriteRule ^index2.html$ app/index2.html

    En este caso, cuando una petición se realice contra la raíz del sitio, a un recurso que comienza con index.html, se debe realizar una redirección interna al recurso app/index.html, luego existe otra regla que funciona exactamente igual, pero para los recursos index2.html y app/index2.html

  2. Múltiples redirecciones internas y uso de expresiones regulares
    RewriteEngine on

    RewriteRule ^alice.html$ bob.html

    RewriteRule ^indicePrincipal.html$ dir1/dir2/pagina.php

    RewriteRule ^indicePrincipal/([a-zA-Z]+) dir1/dir2/pagina.php?param=$1 [B,CO=cookieName:cookieValue]

    Este ejemplo es mucho más completo y posiblemente será suficiente para comprender como funciona este módulo (a nivel introductorio) las dos primeras reglas simplemente indican que si las páginas alice.html y indicePrincipal.html son invocadas, se debe realizar una redirección interna a cada una de las páginas correspondientes en la regla, la tercera regla es la más interesante, ya que define una expresión regular un poco más compleja que las anteriores y ademas se introducen dos elementos nuevos que son el paso de párametros y las Flags disponibles en Mod_Rewrite.

    1. La expresión ^indicePrincipal/([a-zA-Z]+) indica que en el caso de que la petición al recurso comenzando con indicePrincipal/ y que ademas, después de dicha secuencia de caracteres hay al menos un carácter (independiente de que este en mayúsculas o minúsculas) por ejemplo la petición al recurso <APP>/indicePrincipal/parametro será filtrada por el motor de sobre-escritura y posteriormente será redireccionada a la ruta indicada.
    2. Cuando la expresión anterior se cumpla, internamente se realizará una redirección al recurso <APP>/dir1/dir2/pagina.php?param=$1 el valor de $1 es el primer bloque de expresiones regulares aplicadas en la regla, en este caso concreto es: ([a-zA-Z]+) esta es la forma en la que la manipulación de URL’s funciona para el envío de parámetros por GET
    3. Finalmente, otro elemento interesante en esta regla es lo que viene justo al final ([B,CO=cookieName:cookieValue]) esto es un listado de Flags que son admitidas por Apache, cada Flag tiene un valor especial que indica cual debe ser el comportamiento que debe aplicarse cuando el motor de sobre-escritura ha capturado la regla especificada. En este caso concreto, las Flag B y CO indican que se deben escapar caracteres no alfanumericos antes de aplicar la transformación y que se debe responder con una cookie al cliente)

Para terminar este articulo, se indicará algunas de las flags más interesantes en la directiva RewriteRule:
B: Escaparcaracteres no alfanuméricos antes de aplicar la transformación

cookie|CO: Permite crear y enviar una cookie al cliente.

forbidden|F: Indica que se debe responder con un error HTTP 403.

gone|G: Indica que se debe responder con un error HTTP 410.

last|L: Indica que es la última regla que se debe aplicar por el motor, todas las reglas que vengan definidas por debajo de esta, serán descartadas

next|N: Indica que se debe volver a ejecutar el procedimiento de sobre-escritura desde la primera regla nuevamente

nocase|NC: No realiza distinciones entre mayúsculas y minúsculas
Existen algunas otras Flags que son sumamente interesantes para determinados casos, se aconseja al lector que lea el siguiente documento para ampliar sus conocimientos sobre su uso: http://httpd.apache.org/docs/2.2/rewrite/flags.html