Wextensible

Introducción

A veces hay necesidad de modificar la ubicación de los documentos. Inicialmente tenía mi glosario XHTML+CSS en la carpeta /xhtml-css. Pero por motivos de organización de carpetas he de trasladarlo a /temas/xhtml-css. Para que eso no afecte a los usuarios de nuestra web hay que usar las redirección 301 del servidor. En este caso se trata de hacer unas pruebas en mi servidor localhost Apache y exponer la experiencia en este tema. Podemos encontrar el manual en línea Apache.org 2.2, donde buscaremos las referencias necesarias.

Podemos hacer una redirección en ese servidor actuando sobre la configuración del mismo de, al menos, dos formas:

  1. Teniendo acceso al archivo de configuración httpd.conf que suele ubicarse en la carpeta conf de instalación del Apache.
  2. Si no tenemos ese acceso, podemos usar un archivo .htaccess para declarar configuraciones en nuestra dominio, como es el caso de los dominios virtuales en servidores compartidos.

En este caso vamos a suponer que usamos un .htaccess para nuestras redirecciones. Este archivo lo colocamos en la carpeta raíz, o en su caso si ya está usando uno, simplemente hay que añadir las directivas Las configuraciones del servidor Apache se les suele llamar directivas de redirección necesarias.

En la documentación de Apache podemos encontrar a su vez dos formas al menos para hacer una redirección:

  1. Usando la directiva RewriteRule del módulo mod_rewrite.
  2. Usando la directiva RedirectMatch del módulo mod_alias.

En resumen estos módulos contienen directivas que gestionan las peticiones que se hacen al servidor para controlar, o mejor dicho, redireeccionar las respuestas. El segundo módulo mod_alias tiene como finalidad las tareas más sencillas, mientras que si se pretende un control más complejo ha de usarse el primer módulo mod_rewrite. En los siguientes temas comentaremos la forma de hacer una redirección usando la directiva RewriteRule y RedirectMatch. A continuación comentaremos algunas consideraciones sobre las directivas de Apache y el archivo .htaccess y algo sobre el coste en recursos de tiempo y proceso de una redirección.

Consideraciones sobre el archivo .htaccess

Si estamos en un alojamiento compartido quizás no tengamos acceso al archivo de configuración del Apache httpd.conf. En ese caso podemos usar archivos .htaccess, llamados archivos de configuración distribuidos (distributed configuration files). Pero para poder insertar estos archivos necesitamos que la directiva AllowOverride tenga el valor distinto de None, el valor que inicialmente viene puesto por defecto en el httpd.conf. Especificamente debe tener el valor FileInfo o bien el valor All que permite sobreescribir todas las directivas. Y esto a su vez debe ser configurado en el httpd.conf (o en extra/httpd-vhosts.conf si son dominios virtuales):

<Directory ".../Apache server/htdocs">
    ...
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    #AllowOverride None
    AllowOverride All
    ...
</Directory>

Recordemos algo sobre las directivas en Apache. Por ejemplo, para la directiva RedirectMatch tenemos esta imagen capturada del sitio Apache.org:

RedirectMatch de Apache

Aparte de la sintáxis de la directiva, es importante fijarse en el contexto donde puede usarse. Si indica .htaccess ya sabemos que podemos usarla en estos archivos. Pero además la entrada Override con el valor FileInfo nos indica que debe haber en la directiva AllowOverride para que RedirectMatch pueda usarse en un .htaccess. Es decir, hemos de tener AllowOverride FileInfo o AllowOverride All para poder usar RedirectMatch en los archivos .htaccess. Por ejemplo si ponemos en el http.conf

<Directory ".../Apache server/htdocs">
    ...
    AllowOverride Options
    ...
</Directory>

con objeto de tener el siguiente .htaccess en la carpeta raíz, donde se incluye la redirección RedirectMatch y también la directiva Options -Indexes para impedir que se listen los archivos de las carpetas--:

Options -Indexes
RedirectMatch 301 ^/xhtml-css/(.*)$ /temas/xhtml-css/$1

Entonces cuando accedamos a la carpeta raíz, es decir, cuando solicitemos cualquier documento de localhost, obtendremos un error de servidor, algo como "500 Internal Server Error". Cada vez que nos aparece un error en Apache podemos consultar el archivo error.log. Haciendo una petición cualquiera a nuestro localhost veremos que se registra en error.log lo siguiente (acortamos la ruta real con "..." y ponemos en varias líneas para mayor comodidad):

[Sun May 08 10:55:01 2011] [alert] [client 127.0.0.1] 
    C:/.../Apache server/htdocs/home/sitio/.htaccess: 
    RedirectMatch not allowed here

Nos dice el error que RedirectMatch no está permitido en el .htaccess que está en la carpeta raíz. Por lo tanto vamos a la documentación de Apache (la imagen capturada de arriba) y vemos que necesitamos FileInfo para AllowOverride (o bien All).

Si AllowOverride tiene el valor None y aunque existan archivos .htaccess, el servidor no generará ningún error dado que simplemente ignorará esos archivos.

En definitiva, esta directiva AllowOverride la modificará el administrador del servidor pues como dijimos antes, sólo puede ser incluida dentro de una directiva Directory. Y ésta a su vez sólo puede usarse en los contextos server config o virtual host, es decir, en el archivo http.conf o bien en el extra/httpd-vhosts.conf (ver más sobre cómo configurar un alojamiento compartido en Apache Server).

Una vez que tengamos la posibilidad de sobreescribir directivas en un archivo .htaccess, simplemente creamos un archivo de texto con ese nombre y ponemos las directivas para sobreescribir los tipos. Estos archivos de configuración se sitúan en las carpetas afectando a las peticiones que se hagan a la misma y a sus contenidos en las carpetas hijas. Es lo que en la documentación Apache denomina configuración por directorio.

Hay otra configuración previa necesaria para que un .htaccess con redirecciones funcione. Veámos una nota que aparece en la página RewriteRule de la documentación Apache:

Note: Enabling rewrites in per-directory context: To enable the rewriting engine for per-directory configuration files, you need to set RewriteEngine On in these files and Options FollowSymLinks must be enabled. If your administrator has disabled override of FollowSymLinks for a user's directory, then you cannot use the rewriting engine. This restriction is needed for security reasons.

Podemos traducirlo más o menos como sigue:
Nota: Activar reescritura en el contexto por directorio: Par activar los procesos de reescritura en los ficheros de configuración por directorio (los .htaccess), necesitará RewriteEngine On en el .htaccess y también Options FollowSymLinks. Si el administrador ha desactivado la sobreescritura de FollowSymLinks para su directorio de usuario, entonces no podrá usar los procesos de reescritura. Esta restricción suelen hacerla (los administradores) por razones de seguridad.

Por lo tanto un .htaccess con la redirección para un ejemplo con RewriteRule (que veremos en el siguiente tema) quedaría así (incluyendo -Indexes para evitar listar el contenido de una carpeta):

Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteRule ^xhtml-css/(.*)$ /temas/xhtml-css/$1 [R=301,L]

Por un lado hemos de poner RewriteEngine On para usar RewriteRule. Por otro lado, si el administrador nos permite sobreescribir la directiva FollowSymLinks, entonces la incluimos en nuestro .htaccess anteponiéndole el "+". Esto quiere decir que si en una carpeta previa se incluyó un Options -FollowSymLinks es que se desactivó esa directiva para esa carpeta y todas las que cuelgan de ella. Por lo tanto si el .htaccess está en alguna entre ellas, al poner el signo "+" la estamos activando nuevamente, pero seguirá desactivada para el resto de carpetas hermanas de esta.

Aún no tengo del todo claro lo de FollowSymLinks, pues tiene que ver en la forma que UNIX trabaja con los vínculos o enlaces simbólicos. Puede ver algo más en la documentación de Apache.org documentos por fuera de la raíz y también en optimización del rendimiento de Apache, donde se observa que es aconsejable usar FollowSymLinks para mejorar la repuesta del servidor y desactivarlos en aquellas carpetas donde busquemos mayor seguridad. De todas formas en los alojamientos compartidos se suele tener esta directiva activada, pero en todo caso no está de más incluirla en el .htaccess de la carpeta raíz si vamos a usar redirecciones.

Lo que no debemos olvidar es que los archivos .htaccess consumen recursos de tiempo en el servidor, aparte de otros riesgos de seguridad que también habrá que tenerse en cuenta. En cuanto al coste de recursos, si por ejemplo solicitamos el documento /abc/def/ghi/jkl.html, el servidor deberá mirar si en la carpeta final hay un .htaccess, pero también tendrá que hacerlo en las carpetas que ascienden hasta la raíz, pues cualquiera de ellas puede contener directivas que afecten al documento jkl.html. Y esto lo hace siempre que la directiva AllowOverride esté activada (valor distinto de None) independientemente de si hay o no archivos .htaccess.

Por lo tanto si el servidor tiene la directiva anterior activada, como suele ser el caso de los alojamientos compartidos, esto no lo podemos evitar. Pero si cada vez que encuentre uno de estos archivos ha de procesarlo para comprobar si ha de aplicar alguna directiva a ese documento, entonces el consumo de tiempo es mayor, incluso si esos .htaccess que se va encontrando no afectan al documento que está más abajo en el árbol de carpetas. Por lo tanto deben usarse sólo cuando no podamos modificar la configuración en los archivos del servidor, los que están en la carpeta conf o extra/httpd-vhosts.conf.

Las herramientas de desarrollo de los navegadores: analizando el retardo de las redirecciones

Desde hace algún tiempo casi todos los navegadores van incorporando herramientas de desarrollo que, aunque aún no las conozco bien, son evidentemente de mucha utilidad. En este caso hemos usado Google Chrome para mostrar un ejemplo que se expone en el tema sobre redirecciones con RedirectMatch. Se trata de redireccionar desde /xhtml-css/formulario.html a /temas/xhtml-css/formulario.html.

Network Chrome

Lo que vemos es algo así como el histórico de esa petición. En primer lugar el navegador hace una petición GET del documento formulario.html ubicado en la carpeta /xhtml-css. Obtiene como respuesta un código 301 de "movido permanentemente". Veáse que el tamaño de lo recibido es sólo de 256 Bytes, pues sólo se recibe la cabecera 301 y un documento de código de estado. Esta fase dura 16 ms.

Es evidente que estos tiempos son los que se registran en localhost y por tanto nada tienen que ver con las pruebas que puede hacerse al servidor real donde tengo este sitio. Son valores mucho más bajos pues la comunicación no sale del ordenador. Pero puede ser representativo a efectos de buscar una comparación y entender que hay un coste en tiempo en una redirección 301.

Como el código recibido es un 301, el navegador vuelve a solicitar la URL que se recibe en el campo Location de la cabecera (se explicará en los siguientes temas). Ahora solicita con un GET el mismo documento pero en la carpeta redirigida /temas/xhtml-css. En este caso se recibe el documento, que realmente es grande, unos 173KB y tarda esos 362 ms en recibirlos.

Vemos además que el resto de recursos los toma de la caché, pues anteriormente ya había abierto esos recursos con ese navegador. El tiempo total hasta que se cargan todos los contenidos, incluso el DOM es de 667 ms. Se indica al final de la herramienta:

Tiempo total Network Chrome

Los documentos contenidos en la carpeta /xhtml-css fueron los primeros que hice cuando empecé a aprender esta materia. Por lo tanto desconocía detalles como los tiempos de carga. Ahora comprendo que ese documento tenía que haberlo dividido en 4 o 5 documentos para que tuvieran un peso alrededor de los 30KB-50KB (sin contar con los recursos vinculados).

Es obvio que las redirecciones tienen un coste. En este caso son 16 ms más que hemos de añadir al proceso. Por lo tanto deberían evitarse las redirecciones, pero cuando no queda más remedio hay que usarlas. En todo caso si el objetivo es reducir tiempos de carga, hay otras soluciones que, aunque por ahora no contemplo hacerlas, si aprovecho el momento para indicarlas ya que estamos hablando de la herramienta de desarrollo del Chrome. En el resumen de la carga del documento formulario.html vemos que el navegador procesó 16 solicitudes pero el tamaño de la transferencia fue de los sólo 173 KB que ocupa el documento. Esto es porque el resto de recursos los extrajo de su caché (como se observa en la imagen from cache). Pero si un usuario entra por primera vez en el sitio no tendrá nada en su caché, por lo que los tiempos serán mayores.

Por lo tanto más que tener en cuenta el tamaño del documento parece que también hay que fijarse en el tamaño y la forma de gestionar esos recursos anexos. Este navegador Google Chrome tiene también la herramienta Audits (cuyo icono puede ver en la imagen capturada más arriba) que nos ayudaría a mejorar esos tiempos de carga. Pero esa es otra historia que espero aprender en otro momento.

Por cuánto tiempo hay que mantener una redirección 301

Si la redirección 301 tiene por objeto que los usuarios puedan seguir accediendo a las paginas redireccionadas aunque usen enlaces con la dirección anterior, cabe preguntarse por cuánto tiempo hay que mantener una redirección. La pregunta es una clara consecuencia de haber comprendido que una redirección tiene un coste de tiempo y recursos. Si podemos evitarlo no hay necesidad de mantenerlo más que el tiempo necesario.

Vemos que con esta redirección 301 no importará que aparezcan indexadas en Google, por ejemplo, las viejas páginas. Porque aunque ya no existan en el sitio, el redireccionamiento las llevará al nuevo. Y por cada nueva consulta de Google, irá actualizando las nuevas rutas. Supongo que será una cuestión de tiempo, aunque también ayudará si se remite un sitemap con todas las páginas del sitio (además del robots.txt que es para bloquear contenidos). Este archivo debería ser un XML, pero Google también admite un archivo de texto sitemap.txt con una lista de rutas separada por salto de línea, como queda patente en la página creación de sitemaps de Google. Hay herramientas para construirse este XML, pero me gustaría primero saber cuál es su estructura, por lo que por ahora actualizaré el sitemap.txt que ya tengo con las nuevas rutas.

También he usado Webmaster de Google para eliminar contenido indexado. Fueron unos documentos de ejemplos que me olvidé de bloquearlos en robots.txt. La cosa fue bien y en poco tiempo (días), ya no aparecían en Google. Pero ahora el asunto es diferente: no interesa eliminar las antiguas URL mientras el buscador no indexe las nuevas. Por lo tanto pienso que para el caso de la redirección que estoy haciendo no procede eliminar esas páginas del índice. En los buscadores como Google uno puede hacer una simple consulta site:www.wextensible.com que nos dará todas las páginas que tiene indexadas en el sitio. Así podemos hacer un seguimiento sobre los cambios que está haciendo el buscador en el índice de documentos.