Probando el mod_deflate de Apache
El RFC2616, de 1999, definió el protocolo HTTP 1.1. En el apartado 14.3, el estándar habla de la cabecera para peticiones Accept-Encoding, que le permite al cliente de HTTP (normalmente un navegador) especificarle al servidor que acepta contenido comprimido.
En efecto, si tomamos una traza de red (p.e. con WireShark) de una petición de un navegador (p.e. Iceweasel) a un servidor web, veremos que éste le dice al servidor web que acepta el contenido comprimido por gzip o por deflate (es decir, zlib):
GET / HTTP/1.1 Host: www.example.com User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.8) Gecko/20071004 Iceweasel/2.0.0.8 (Debian-2.0.0.8-1) Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive
En Firefox, podemos usar el parámetro del about:config network.http.accept-encoding para especificar exactamente qué queremos tener para esa entrada de la cabecera, siendo el valor por defecto “gzip,deflate“.
Por su parte, el servidor web Apache 2 es capaz de atender esas peticiones de compresión por medio del módulo mod_deflate.
En Debian, el módulo ya viene en el paquete estándar de apache2:
# dpkg -S deflate.load apache2.2-common: /etc/apache2/mods-available/deflate.load
Sin embargo, no viene activado por defecto. Para habilitarlo, tenemos que crear un enlace en el directorio mods-enabled:
# cd /etc/apache2/mods-enabled/ # ln -s ../mods-available/deflate.load deflate.load
Además, tendremos que elegir las opciones de configuración que más nos puedan interesar. Como la compresión de según qué tipos de ficheros con según qué versiones de navegador puede dar problemas, una solución que nos comprime prácticamente todos los ficheros de texto típicos de una página sin crear mayores problemas es usar la directiva AddOutputFilterByType diciéndole que comprima ficheros HTML, CSS, JavaScript y de texto:
AddOutputFilterByType DEFLATE text/html text/plain text/css application/x-javascript
Tras esto, es conveniente revisar que la sintaxis es correcta con un “apache2ctl configtest” y reinciar el servidor para que se use la nueva configuración sin cortar las conexiones existentes al servidor web con un “apache2ctl graceful“.
Tras aplicar estos cambios, la contestación del servidor web a la petición anterior del navegador será ésta, aceptando la compresión y enviando la página comprimida a continuación:
HTTP/1.1 200 OK Date: Fri, 23 Nov 2007 16:14:42 GMT Server: Apache/2.2.3 (Debian) PHP/5.2.0-8+etch7 X-Powered-By: PHP/5.2.0-8+etch7 Expires: Wed, 11 Jan 1984 05:00:00 GMT Last-Modified: Fri, 23 Nov 2007 16:14:43 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Length: 22266 Keep-Alive: timeout=15, max=99 Connection: Keep-Alive Content-Type: text/html; charset=UTF-8
Si queremos comprobar el buen funcionamiento de este módulo, podemos usar el wget, versátil herramienta que nos permite descargar documentos desde línea de comandos mediante HTTP y FTP.
Por defecto, el wget manda unas cabeceras muy sencillas:
GET / HTTP/1.0 User-Agent: Wget/1.10.2 Accept: */* Host: www.example.com Connection: Keep-Alive
Vemos que usa HTTP 1.0 y no indica ningún Accept-Encoding. Sin embargo, podemos usar la opción de línea de comandos --header para modificar las cabeceras y aceptar compresión.
Así, vemos que el fichero raíz de un servidor web que ocupa 78 KiB:
$ wget http://www.example.com
--18:10:02-- http://www.example.com
=> `index.html'
Resolving www.example.com... 10.12.34.56
Connecting to www.example.com|10.12.34.56|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
[ <=> ] 80,206 40.26K/s
18:10:05 (40.18 KB/s) - `index.html' saved [80206]
únicamente ocupa 22 KiB si se pide comprimido:
$ wget --header="Accept-Encoding: gzip" http://www.example.com
--18:13:51-- http://www.example.com
=> `index.html'
Resolving www.example.com... 10.12.34.56
Connecting to www.example.com|10.12.34.56|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 22,143 (22K) [text/html]
100%[====================================>] 22,143 --.--K/s
18:13:55 (5.19 MB/s) - `index.html' saved [22143/22143]
Sin embargo, si examinamos ese fichero descargado, vemos que no es el fichero HTML que esperábamos, sino un fichero comprimido con gzip:
$ file index.html index.html: gzip compressed data, from Unix
Sería necesario descomprimir el fichero para encontrar que tiene el tamaño y el contenido esperado:
$ mv index.html index.html.gz $ gzip -d index.html.gz $ ll index.html -rw-r--r-- 1 root root 80206 2007-11-23 18:13 index.html $ file index.html index.html: HTML document text
Comprimir las páginas web antes de enviarlas supone una gran ventaja en circunstancias de ancho de banda limitado. Sin embargo, no hay que olvidar que el servidor tiene que estar permanentemente comprimiendo ficheros, lo que puede ocasionar que la CPU no dé abasto. Por tanto, hay que tener muy presente, antes de habilitar esta opción, si en situaciones de carga extraordinaria la limitación de nuestro servidor web está en la carga de CPU o en el ancho de banda disponible.
Finalmente, comentar que en la página www.http-compression.com podemos leer sobre qué navegadores soportan la compresión de las páginas, que son prácticamente todas las versiones modernas de los navegadores comunes: Firefox, Konqueror, Opera e Internet Explorer.
Por cierto, ¿sabías que example.com, example.org y example.net son dominios reservados para usar como ejemplo en la documentación?
:wq








Bytecoders dijo:
Interesante, haciendo las pruebas la página principal del blog pasa de 33,4 K a 8 K estando comprimida en gzip.
La verdad es que en casa el ancho de banda no abunda y la carga que tiene el PC no es mucha, por tanto creo que es un escenario ideal.
Sobre los dominios example no tenía ni idea.
Super Coco dijo:
@Bytecoders Me alegro de que te haya parecido interesante. La verdad es que es precisamente en entornos como el de hospedaje doméstico cuando más interesante puede ser esta configuración.
Iván dijo:
Muy interesante lo que nos cuentas de la compresión. Como dices, para servidores caseros en los que no vamos muy sobrados de ancho de banda puede ser una opción muy útil.
Ahora una pregunta. No se podrían cachear de alguna manera las páginas comprimidas para no tener que estar constantemente comprimiendo el mismo contenido?.
Saludos, Iván.
Super Coco dijo:
@Iván Hablando de contenido dinámico es difícil que Apache lo pueda cachear. Si tratamos con Wordpress sería mejor pensar en algo como el WP-Cache de Ricardo Galli que cachea y permite comprimir a la vez.
Para contenidos estáticos se podría combinar el mod_deflate con el mod_cache para dejar los contenidos cacheados y sin volver a comprimirlos.
Iván dijo:
Yo lo decía porque aunque sea contenido dinámico, realmente un post es siempre estático y lo único que cambia es la parte de los comentarios. Aunque supongo que si se utiliza wp-cache o similares no debería haber demasiados problemas.
Saludos, Iván.
Super Coco dijo:
El WP-Cache permite cachear las entradas de Wordpress, de forma que las páginas dinámicas que no hayan cambiado sean servidas desde un fichero estático. Sin embargo, no permite dejar dichas páginas comprimidas y evitar así que la CPU las tenga que comprimir cada vez.
El artículo Modifying WP-Cache 2.0 to generate and cache gzipped output once and serve it multiple times cuenta cómo modificar el WP-Cache para que las páginas almacenadas en la caché se almacenen ya comprimidas para no tener que comprimirlas cada vez.
El 1 Blog Cache parece que ya lo permite por defecto.
zarta dijo:
Me ha parecido un artículo interesante, y sobretodo el modo de utilizar esta opción en wget (para mis futuras descargas de iso de mis distribuciones preferidas jajaja)
Aparte, voy a aplicar esto en mi pequeño web/wiki/caja de pruebas de casa.
Super Coco dijo:
@zarta ¡Gracias! Me alegro de que te haya gustado.
Robert dijo:
Para activar y desactivar los módulos puedes usar el a2enmod y el a2dismod, que en combinación con el bash_completion te ahorran un par de tecleos
Por ejemplo para el deflate “a2enmod deflate”
También existen a2ensite y a2dissite
Super Coco dijo:
@Robert No los conocía, pero me parecen muy útiles. ¡Muchas gracias por el apunte!