sábado, 2 de enero de 2010

Personalización del listado de directorios de Apache

mod_autoindex


Aunque para entornos de producción nunca es buena idea dejar disponible para el público el listado de directorios, para algunas tareas es una funcionalidad que viene bien. Por ejemplo, para un repositorio de paquetes para una distribución Linux. Y la pregunta que surge al ver cómo quedan esos listados tan elaborados es saber cómo se pueden hacer fácilmente.

La respuesta viene de la de mano del módulo autoindex para Apache. Pero antes de entrar en detalle en este módulo, recordemos cómo evitar la generación de estos listados automáticos en la configuración de Apache.

Nota: Todas las referencias a la configuración y funcionamiento de Apache se han hecho sobre la versión 2.2.14 para Win32, excepto las que se indiquen explícitamente.

Desactivación de los listados automáticos

Dentro de las directivas Location y Directory, la directiva Options se encarga de configurar las opciones disponibles para esa determinada ubicación. El modificador Indexes es el encargado de activar al módulo autoindex, por lo que para evitar esta funcionalidad, deberemos configurarlo más o menos así:
<Location />
Options -Indexes

</Location>

Otra opción más radical es comentar la línea de carga del módulo en el fichero httpd.conf. Pero si elegimos esta opción, deberemos revisar el resto de la configuración para quitar la opción Indexes de cualquier directiva Options en la que aparezca. En caso contrario, al reiniciar el servicio, Apache informará que se ha producido un error y no arrancará.

Creación de la configuración para autoindex


Si nos fijamos en el fichero de configuración global de Apache, la siguiente línea se encuentra comentada por defecto:
# Fancy directory listings
#Include conf/extra/httpd-autoindex.conf

Por lo que si tenemos activado el listado automático, veremos que el resultado es de lo más espartano.

Ejemplo de listado de directorio sin la configuración de mod_autoindex

En lugar de hacer modificaciones sobre el fichero httpd-autoindex.conf, vamos a crear uno nuevo, llamado custom_autoindex.conf, que situaremos en el mismo directorio donde se encuentre el archivo httpd.conf. De esta forma, sólo con incluir esta línea al final del fichero httpd.conf, se cargarán nuestras modificaciones:
# Añadir al final del fichero httpd.conf
Include conf/custom_autoindex.conf

Personalización de las directivas


En el manual oficial de Apache, se encuentran explicadas cada una de las directivas disponibles para el módulo autoindex. En el presente artículo sólo se muestran algunas de ellas, por lo que si alguien necesita alguna funcionalidad más de las aquí presentadas, recomiendo la lectura de la documentación oficial.
IndexOptions

Los modificadores de esta directiva se pueden agrupar todos dentro de la misma línea o bien se pueden ir agregando uno por línea, para que el fichero quede más claro y legible y para que sea más fácil jugar (comentar/descomentar) las diferentes opciones.

La primera opción en nombrar es, precisamente, la que permite activar otras opciones más avanzadas de los listados de directorios. Se llama FancyIndexing y, si está desactivada, el listado de archivos se presenta en forma de lista simple (tal y como se puede ver en la imagen del primer ejemplo).

La siguiente que vamos a presentar es FoldersFirst y, como su nombre indica, independientemente del orden que escoja el usuario (las columnas nombre, última modificación, tamaño, etc), siempre aparecerán primero los directorios y después los ficheros.

Otra opción relacionada con la ordenación es IgnoreCase. Si está activada, mayúsculas y minúsculas no importarán a la hora de ordenar los archivos.

Adicionalmente, también vamos a añadir la opción VersionSort para que, en el caso de mostrar varios ficheros con mismo nombre pero versión diferente, se ordenen perfectamente de acuerdo a la versión y no al orden ASCII: la versión 1.12 iría después de la 1.9, por ejemplo.

IconsAreLinks permite que los iconos asociados a cada fichero también sean un enlace a dicho archivo. Como las imágenes suelen ser zonas muy apetecibles para el ratón, dejaremos esta opción activada.

Para nuestro ejemplo, vamos a activar la opción SuppressDescription, para no mostrar la descripción de los tipos de archivo en el listado. Aunque en un entorno real, es una funcionalidad que puede ser interesante si se listan tipos de fichero poco usuales.

Para tener más control sobre la salida HTML generada por mod_autoindex, vamos a activar las opciones SuppressRules, SuppressHTMLPreamble y XHTML. De esta forma, obligamos a que el módulo saque el contenido del listado en formato XHTML (y no en HTML 3.2) y que se ocupe sólamente de generar dicho listado. El resto de la página la generaremos nosotros más adelante.

El fichero custom_autoindex.conf, con todo lo visto hasta ahora, comenzaría así:
IndexOptions FancyIndexing
IndexOptions FoldersFirst
IndexOptions IgnoreCase
IndexOptions VersionSort
IndexOptions IconsAreLinks
IndexOptions SuppressDescription
IndexOptions SuppressRules
IndexOptions SuppressHTMLPreamble
IndexOptions XHTML

Directorio de iconos

Los iconos por defecto que vienen distribuidos con Apache, aunque funcionales, se han quedado algo antiguos en cuanto a diseño. Por esa razón, vamos a cambiarlos por los que vienen en la colección hidroxygen.

Para ello, vamos a poner en un mismo directorio todos los iconos de esta colección de tamaño 32x32 píxeles. Conviene recordar que cualquier cambio en la asociación de ficheros, requiere reiniciar Apache.

La configuración de este directorio, quedaría así:
Alias /icons/ "D:/Apache2/conf/hidroxygen/"

<Directory "D:/Apache2/conf/hidroxygen">
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>

Asociación de tipos de archivos

Hay varias directivas relacionadas con la asociación:

  • AddIconByEncoding: sirve para asociar un icono a una codificación MIME.

  • AddIconByType: asocia un icono a un tipo MIME.

  • AddIcon: asocia un icono a una extensión.


Para nuestro ejemplo, este sería el código:
AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip

AddIconByType (IMG,/icons/image.png) image/*
AddIconByType (SND,/icons/sound.png) audio/*
AddIconByType (VID,/icons/video.png) video/*

AddIcon /icons/binary.png .bin .exe
AddIcon /icons/tar.png .tar
AddIcon /icons/zip.png .Z .z .tgz .gz .zip
AddIcon /icons/pdf.png .ps .ai .eps .pdf .dvi
AddIcon /icons/www.png .html .shtml .htm
AddIcon /icons/txt.png .txt
AddIcon /icons/text-x-csrc.png .c .h
AddIcon /icons/application-x-php.png .php
AddIcon /icons/application-x-perl.png .pl
AddIcon /icons/application-x-python.png .py
AddIcon /icons/text-x-script.png .conf .sh .shar .csh .ksh .tcl .cgi
AddIcon /icons/tex.png .tex
AddIcon /icons/rar.png .rar
AddIcon /icons/rpm.png .rpm
AddIcon /icons/text-css.png .css

AddIcon /icons/violet-go-up.png ..
AddIcon /icons/gnome-blog.png README
AddIcon /icons/oxyviolet-folder.png ^^DIRECTORY^^

Las últimas 3 líneas son especiales porque sirven para asociar al directorio anterior (..), los archivos README y los directorios, respectivamente.

La lista de asociación se puede hacer tan larga y específica como se quiera o necesite. Como podemos ver, puede ser genérica (usando AddIconByEncoding y AddIconByType) o más particular (con AddIcon y la lista de extensiones).

Hay una directiva más, DefaultIcon, que sirve para mostrar un icono por defecto para los tipos de archivo que no hayamos declarado explícitamente:
DefaultIcon /icons/unknown.png

Salida XHTML

Antes hemos dicho que del módulo autoindex sólo queríamos que generara los listados de archivos, porque el resto de la salida la personalizaríamos nosotros.

La directiva HeaderName sirve para indicar el fichero que se antepondrá al listado de mod_autoindex. Y la directiva ReadmeName, para indicar el archivo que se añadirá al final de listado generado. De esta forma, y con ayuda de la opción SuppressHTMLPreamble, tendremos control total sobre el HTML que enviaremos al navegador desde el servidor web.

Si se quisieran diferentes contenidos de cabecera y pie para cada directorio a mostrar, es posible hacerlo indicando una ruta relativa a los ficheros en estas directivas. Sin embargo, para este ejemplo, vamos a usar una ruta absoluta, que debe estar (esta sí) dentro del directorio de publicación de Apache.
ReadmeName "/autoindex/footer.shtml"
HeaderName "/autoindex/header.shtml"

IndexIgnore

Para acabar con la configuración de este ejemplo, conviene nombrar la directiva IndexIgnore. Sirve para ocultar del listado automático ciertos archivos. Por ejemplo, para evitar que se muestren las copias de seguridad (ficheros acabados en ~ en los sistemas Linux), los propios archivos usados para cabecera y pie de los listados, etcétera.
IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t *.shtml

Contenido de los archivos HeaderName y ReadmeName


El contenido de estos ficheros debe generar HTML, por lo que o bien puede estar en HTML puro o puede estar programado en algún lenguaje interpretado como SSI, PHP, Python o Perl, por ejemplo. Esta opción es interesante para poder mostrar contenido variable y poder tener unos ficheros de cabecera globales. Dicho contenido variable nos lo proporciona el propio servidor a través de sus variables de entorno.

En nuestro ejemplo, vamos a hacer la programación en SSI, puesto que sólo vamos a mostrar algunas de estas variables de Apache. Para activar la interpretación de las instrucciones SSI en el directorio donde hemos puesto los archivos .shtml, debemos añadir a la configuración:
<Location "/autoindex">
Options +Includes
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
</Location>


En entornos Linux, los archivos .shtml deben tener el atributo de ejecución (además del de lectura para el usuario que ejecute Apache) para que puedan ser ejecutados por el servidor web.

Ejemplo completo



Como resultado de la configuración aplicada en este artículo, el contenido del directorio que hemos mostrado antes, ahora luciría de esta forma:

Ejemplo de listado de directorio empleando mod_autoindex

El contenido completo del fichero custom_autoindex.conf:
IndexOptions FancyIndexing
IndexOptions FoldersFirst
IndexOptions IgnoreCase
IndexOptions VersionSort
IndexOptions IconsAreLinks
IndexOptions SuppressDescription
IndexOptions SuppressRules
IndexOptions SuppressHTMLPreamble
IndexOptions XHTML

Alias /icons/ "D:/Apache2/conf/hidroxygen/"

<Directory "D:/Apache2/conf/hidroxygen">
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>

AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip

AddIconByType (IMG,/icons/image.png) image/*
AddIconByType (SND,/icons/sound.png) audio/*
AddIconByType (VID,/icons/video.png) video/*

AddIcon /icons/binary.png .bin .exe
AddIcon /icons/tar.png .tar
AddIcon /icons/zip.png .Z .z .tgz .gz .zip
AddIcon /icons/pdf.png .ps .ai .eps .pdf .dvi
AddIcon /icons/www.png .html .shtml .htm
AddIcon /icons/txt.png .txt
AddIcon /icons/text-x-csrc.png .c .h
AddIcon /icons/application-x-php.png .php
AddIcon /icons/application-x-perl.png .pl
AddIcon /icons/application-x-python.png .py
AddIcon /icons/text-x-script.png .conf .sh .shar .csh .ksh .tcl .cgi
AddIcon /icons/tex.png .tex
AddIcon /icons/rar.png .rar
AddIcon /icons/rpm.png .rpm
AddIcon /icons/text-css.png .css

AddIcon /icons/violet-go-up.png ..
AddIcon /icons/gnome-blog.png README
AddIcon /icons/oxyviolet-folder.png ^^DIRECTORY^^

DefaultIcon /icons/unknown.png

ReadmeName "/autoindex/footer.shtml"
HeaderName "/autoindex/header.shtml"

IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t *.shtml

<Location "/autoindex">
Options +Includes
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
</Location>

Contenido del fichero header.shtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title><!--#echo var="SERVER_NAME" --><!--#echo var="REQUEST_URI" --></title>
<link rel="stylesheet" type="text/css" href="/autoindex/style.css" media="screen" />
</head>
<body>
<div id="header">
<h1><!--#echo var="SERVER_NAME" --><!--#echo var="REQUEST_URI" --></h1>
</div>
<div id="content">

Contenido de footer.shtml:
</div>
<div id="footer">
<address>Copyright © jact 2010</address>
<address><!--#echo var="SERVER_SOFTWARE" --> on <!--#echo var="SERVER_NAME" --></address>
</div>
</body>
</html>

Hoja de estilos (style.css):
body {
background: #F6F6F6;
font-family: "Trebuchet MS", sans-serif;
margin: 1.5em;
}

#header {
border-bottom: 1px solid #000;
}

#content pre {
font-family: "Lucida Console", monospace;
font-size: 120%;
}

#footer {
border-top: 1px solid #000;
padding-top: 1em;
}

a img {
border: none;
}

address {
font-style: normal;
font-size: 90%;
}

Referencias


1 comentario:

Anónimo dijo...

Hola, como puedo ver el listado de directorio de una pagina web con el navegador

kuko4321@hotmail.com