Super Tux

Lo hice y lo entendí

El blog de Vicente Navarro Jover
23 Nov

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

19 Nov

Solucionando el error “attempt to access beyond end of device” con reglas de udev, hal y/o un parche del kernel

Recientemente actualicé mi Debian Lenny/Testing como suelo hacer de vez en cuando. No sé exactamente qué paquetes se actualizarían pero empezó a ocurrir algo que no me gustaba: Tres veces durante el arranque se me llenaba la pantalla de cientos de mensajes como el siguiente:

attempt to access beyond end of device
sdb: rw=0, want=3636361172, limit=398297088
attempt to access beyond end of device
sdb: rw=0, want=3636361176, limit=398297088

Y uno de los problemas que me generaban estos errores es que me llenaban el buffer circular de mensajes del kernel y no podía ver los mensajes de arranque del kernel con dmesg.

Yo tengo dos discos Maxtor SATA iguales en RAID 0 usando los servicios de la placa con el chipset NVidia NForce 4. El RAID se activa automáticamente durante el arranque gracias a que el initrd ejecuta el comando dmraid durante el arranque (ya salió esto en Hibernación en Linux con TuxOnIce. Notas sobre los initrd y sobre cpio.). Tras ejecutar el dmraid, unos nuevos ficheros de dispositivo que representan al disco lógico formado por los dos discos físicos son creados en /dev/mapper/ :

# ll /dev/mapper/
total 0
drwxr-xr-x  2 root root     180 2007-11-18 22:03 ./
drwxr-xr-x 14 root root    5880 2007-11-18 21:04 ../
crw-rw----  1 root root  10, 63 2007-11-18 22:03 control
brw-rw----  1 root disk 254,  0 2007-11-18 22:03 nvidia_bdehcbaa
brw-rw----  1 root disk 254,  1 2007-11-18 22:03 nvidia_bdehcbaa1
brw-rw----  1 root disk 254,  2 2007-11-18 22:03 nvidia_bdehcbaa2
brw-rw----  1 root disk 254,  3 2007-11-18 21:03 nvidia_bdehcbaa3
brw-rw----  1 root disk 254,  4 2007-11-18 22:03 nvidia_bdehcbaa5
brw-rw----  1 root disk 254,  5 2007-11-18 22:03 nvidia_bdehcbaa6

Los ficheros de dispositivo de los discos físicos (en mi caso /dev/sdb y /dev/sdc) no tienen ninguna utilidad desde ese momento.

Sigue leyendo »

17 Nov

Notas sobre la función wptexturize de Wordpress, sobre los navegadores que convierten el código HTML a UTF-8 y sobre Unicode/UTF-8

Si nos fijamos en la cabecera del código XHTML de este blog, veremos que está codificado en UTF-8:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

Con la vistas puesta en un asunto que tal vez trate en una futura entrada, estaba haciendo unas pruebas de guardar el código desde el navegador a un fichero .html y he descubierto algunas cosas interesantes…

La función wptexturize de Wordpress

En primer lugar, que Wordpress tiene una función/filtro llamado wptexturize (en wp-includes/formatting.php) que nos arregla el aspecto de algunos signos de puntuación. Por ejemplo, si al editar la entrada escribimos:

"prueba"

la función wptexturize, al crear la página final, lo sustituiría por

&#8220;prueba&#8221;

que es equivalente a

&ldquo;prueba&rdquo;

y que, renderizado por el navegador, queda con fancy quotes (comillas de apertura y cierre diferenciadas):

“prueba”

En What is Texturize? encontramos más ejemplos, y si queremos saber exactamente qué y cómo lo hace, podemos consultar el código de la función. También hay que tener en cuenta que hay fuentes que sacan las fancy quotes exactamente igual que las estándar, así que es posible que según la fuente usada no lo notemos.

Algunos navegadores guardan el código HTML codificado

La segunda cosa que he descubierto es que cuando guardas una página codificada en UTF-8 que tienes abierta en Firefox o en Internet Explorer, los códigos HTML como &ldquo; o &rdquo; (podemos consultar todos los códigos HTML en Character entity references in HTML 4) son sustituidos por sus secuencia de bytes correspondiente para formar el código UTF-8 que corresponde. Konqueror no lo hace así y deja los códigos tal y como van en la página.

Por ejemplo, supongamos que creamos un fichero HTML con el siguiente código:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Prueba</title>
</head>
<body>
Una palabra &ldquo;entrecomillada&rdquo; como ejemplo.
</body>
</html>

Sigue leyendo »

17 Nov

SMB connection failed: Insufficient server memory to perform the requested function.

Si al ir a montar un directorio compartido por Windows usando Samba te encuentras con este error:

# mount -t smbfs -o username=supercoco //pcconwindows/compartido /mnt/smb/
Password:
8070: tree connect failed: ERRDOS - ERRnomem (Insufficient server memory to perform the requested function.)
SMB connection failed

no le eches la culpa al Samba (como hizo un usuario de Ubuntu Feisty). Se trata de un problema conocido de Windows (Error message: “Not enough server storage is available to process this command”) y se puede solucionar fácilmente aumentando el parámetro IRPStackSize en el registro (Description of the IRPStackSize parameter in Windows 2000, in Windows XP, and in Windows Server 2003).

El IRPStackSize es:

The IRPStackSize parameter specifies the number of stack locations in I/O request packets (IRPs).

y ahí lo dejamos, porque no me atrevo a tratar de interpretar qué significa eso exactamente.

Su valor por defecto es de 15 (decimal) y el rango de valores permitido es de 11 (0xb hexadecimal) a 50 (0×32 hexadecimal) y se puede modificar en la siguiente rama del registro de Windows:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters

Pero es muy posible que la primera vez no exista, por lo que tenemos que crear una nueva entrada DWORD para IRPStackSize e introducir el valor deseado. Yo he probado con 50 y, tras reiniciar (esto no lo dice el documento de Microsoft), el error ha desaparecido.

La pista sobre este problema me la ha dado un post a la lista de distribución de Samba ¡del 2002!: [Samba] Samba & W2K shares: ERRnomem: Insufficient server memory to perform the requested function

Finalmente, usar valores de 33 a 38 puede causar problemas: Event ID 2021 is logged even though lots of non-paged pool memory is available in Windows Server 2003.

:wq

07 Nov

Hojas de estilo CSS para imprimir

Hace unos días patata dijo en un comentario que le gustan tanto algunos de los artículos de este blog que se los imprime, pero que le quedan muy mal y que si podría poner alguna hoja de estilo para imprimir. A cambio, yo no puedo hacer menos que agradecer tales halagos atendiendo su petición, ya que, por otro lado, es algo muy fácil de hacer, siempre y cuando el HTML esté muy estructurado y no se mezcle contenido con estilo, algo que muchas veces se tiende a hacer, especialmente si se usan herramientas automatizadas de creación de páginas web. Yo procuro evitarlo, aunque reconozco que en ocasiones muy determinadas y concretas lo hago.

El HTML está para el contenido y el CSS para el estilo. Idealmente, el HTML no debería de tener ninguna referencia a colores, fuentes, tamaños, alineamiento del texto, etc. Eso nos permite cambiarle muy fácilmente la hoja de estilo y tener otra página de aspecto radicalmente distinto pero con el mismo contenido. Alguna vez le querido explicar esto a alguien y me ha resultado muy fácil hacerlo apoyándome en CSS Zen Garden: The Beauty in CSS Design, una página en la que partiendo del mismo contenido, multitud de autores le dan un aspecto radical y sorprendentemente distinto únicamente cambiando el CSS, la hoja de estilo.

Para especificar una hoja de estilo diferente para impresión, deberíamos de tener en la cabecera del documento HTML (entre <head> y </head>) una entrada de CSS para el diseño en pantalla (media="screen") y otra para el diseño para imprimir (media="print"):

<link rel="stylesheet" href="style.css" type="text/css" media="screen" />

<link rel="stylesheet" href="print.css" type="text/css" media="print" />

Podemos consultar los tipos de media que podemos usar en el estándar CSS 2.1, capítulo Media Types. Vemos que también existe el media handheld para especificar hojas de estilos adecuadas para PDAs y teléfonos móviles.

Para la hoja de estilo de impresión de este blog, yo he decidido intervenir lo mínimo posible. Únicamente escondo todos los elementos que no deberían aparecer en la página impresa: los comentarios, el formulario para introducir comentarios, las cajas laterales, los enlaces de navegación (entrada anterior, entrada siguiente), etc. e intervengo mínimamente en un par de aspectos más.

Sigue leyendo »

02 Nov

¡Ya se pueden revisar los comentarios!

Hace unos días Ringmaster se lamentaba en un comentario (que ya corregí con sus indicaciones) de no tener una función de “Vista Previa” en los comentarios para revisar el contenido y el formato de sus trabajados comentarios antes de enviarlo definitivamente.

La verdad es que muchos de los blogs que suelo visitar están en Blogger y una de las cosas que siempre me ha dado envidia ha sido la función de preview o Vista Previa.

Hasta ahora había sido muy reacio a instalar plugins de Wordpress, entre otras cosas para no atarme a ninguno y que no me dejaran libertad para migrar a futuras versiones de Wordpress con las que pudieran no ser compatibles. Además, algunos meten datos propios en la base de datos que después a ver cómo los borras si quieres dejar de usarlo. Sin embargo, esto era algo absolutamente necesario. Por un lado, por Ringmaster y otros visitantes como él, que con los comentarios tan detallados que nos regalan de vez cuando, es lo mínimo que se merecen, que los puedan escribir y revisar en condiciones. Pero por otro lado, es que hay veces que los comentarios llevan una ortografía desastrosa y quiero pensar que en muchos casos son errores que si existiera la posibilidad de revisarlos, sus autores querrían corregirlos.

Que yo pueda instalar un plugin para Wordpress o no, en condiciones normales no hubiera merecido una entrada. Sin embargo, la lamentable ortografía, gramática y expresión al más puro estilo hoygan de ciertos comentarios llega a dañar la vista. Y eso sí se merece una reflexión. Y no es sólo aquí, por supuesto. En este humilde blog en realidad se nota bastante poco. Pero a poco que te das un paseo por la blogosfera española, si te consideras un poco respetuoso de la lengua de Cervantes, te puedes quedar absolutamente alucinado con lo que te encuentras. ¿Es de verdad ese el nivel educativo que tenemos en España? ¿Y lo es también el de los países de Sudamérica, que no parece precisamente mejor?

Podría poner y señalar ejemplos concretos, pero no lo voy a hacer, porque se dice el pecado, y no el pecador y lo último que se merecería un amable lector que pasa por aquí y decide dejar un comentario, es que se le ridiculizara.

Y que no se me entienda mal, por favor: prefiero mil veces que un lector deje un comentario, esté escrito como esté, que que no deje ninguno. Yo soy el primero que puedo tener errores por despiste o por ignorancia. La primera vez que una noticia mía salió publicada en la portada de Barrapunto hice el ridículo más espantoso posible poniendo “hoy a salido” en vez de “hoy ha salido“. Sin embargo, hasta donde puedo, trato de ser meticuloso con la ortografía y la gramática.

Por otra parte, también es muy fácil que ocurra que alguien cometa una pequeña equivocación y al releer se dé cuenta de un error que desearía que no estuviera ahí. Esto me ha ocurrido a mí en ocasiones en blogs Wordpress que no tienen Vista Previa. Es en estos casos en los que más falta hace una función como esta.

Por todo ello, tengo el gusto de anunciar que he incorporado el plugin WP Ajax Edit Comments a este blog. El autor del plugin ha creado un vídeo que muestra perfectamente cómo se usa, pero es muy sencillo. Durante 10 minutos (así lo he configurado) después de enviar el comentario, es posible hacer click sobre el comentario o sobre el nick del usuario y modificarlo. Además, aparece un mensaje avisando de que es posible editar la entrada y un contador de tiempo mostrando el tiempo que falta de los 10 minutos.

Creo que está muy bien y no ensucia mucho la base de datos. Sólo mete algunas entradas en wp_postmeta para poder seguir los comentarios que se pueden editar:

mysql> select meta_value from wp_postmeta where meta_value like 'wpAjax%';
+--------------------------------------------------------------------------------------------------------+
| meta_value                                                                                             |
+--------------------------------------------------------------------------------------------------------+
| wpAjax75bfb832b13b8233462531bb34f12bbeb48f6d51a9066cb3470dcbac6960069c364e0d1dbe06c510f0c3735b9dea964e |
| wpAjax4740ec477fad9cff90b0a8dc1b7c99003cb06da3684bded96018c7f23b7d8096c1fad451916120e01d277a27775ac371 |
+--------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

Pero como dichas entradas se pueden eliminar muy fácilmente desde la GUI de Wordpress, no tienen mayor importancia. Si no tuviéramos la GUI a mano, podríamos hacerlo así:

delete from wp_postmetadata where left(meta_value, 6) = 'wpAjax';

Otro plugin que he probado y he estado a punto de instalar es el Live Comment Preview. Es muy sencillo. Es sólo un fichero .php que consigue mostrarnos debajo del cuadro de introducción del comentario una previsualización de cómo quedará el comentario al mismo tiempo que lo vamos escribiendo. También muy aconsejable para aquellos que no quieran complicarse mucho la vida.

Si quieres probar el plugin, ya sabes: ¡Deja un comentario!

Actualización 21/11/07:

El WP Ajax Edit Comments también guarda su configuración en la tabla wp_options. Para ver los valores almacenados podemos hacer:

mysql> select * from wp_options where option_name="WPAjaxEditComments";

Y para eliminarlos si queremos desinstalar el plugin:

mysql> delete from wp_options where option_name="WPAjaxEditComments";
01 Nov

Hibernación en Linux con TuxOnIce. Notas sobre los initrd y sobre cpio.

Llevaba tiempo queriendo dedicarle tiempo a ver cómo está actualmente el panorama de la hibernación a disco en Linux. Ya lo había estado probando hace varios años, en tiempos del kernel 2.4, y la verdad es que estaba en pañales.

Yo sabía que existía el proyecto Suspend2, recientemente renombrado a TuxOnIce, y que parece ser que está dando muy buenos resultados. Pero fue cuando en la lista de novedades del kernel 2.6.20 leí que ya se incluían en el kernel grandes mejoras en la infraestructura necesaria para soportar la hibernación, que me decidí a retomar el tema.

Según leo en el artículo Suspend2 de la Wikipedia, parece que hay un tira y afloja entre los desarrolladores sobre si la parte que implementa Suspend2 debe de ir en el kernel o en el espacio de usuario. De momento, aún necesita parchear el kernel.

En cualquier caso, no hay que hacer muchas cosas para poder probar el TuxOnIce en una distribución que aún no lo soporte por defecto, y casi todas ellas vienen documentadas en el capítulo 2 del Software Suspend HOWTO. Resumiendo, hay que:

  1. Verificar que tenemos bastante espacio en la swap para almacenar todo el contenido de la memoria. Si no lo hay, se puede usar compresión o un fichero dedicado a esto.
  2. Parchear el kernel, compilarlo, instalarlo y arrancar con él.
  3. Hacer un pequeño cambio en los scripts del initrd.
  4. Añadir una opción de arranque al GRUB/LILO.
  5. Ejecutar el script hibernate.

Sigue leyendo »

Tema LHYLE08, creado por Vicente Navarro a partir del tema Fluid Index de 2yi