Lo hice y lo entendí

El blog de Vicente Navarro
09 dic

Configurar una Hauppauge WinTV-HVR-3000 en Linux

Hace unos meses contaba en Configuración de una Hauppauge WinTV-HVR-1100 en Linux cómo configurar una Hauuppauge WinTV-HVR-1100. En aquella entrada mencionaba que la WinTV-HVR-3000 es similar a la HVR1100 pero soportando adicionalmente DVB-S, por lo que es capaz de sintonizar el trío TV analógica/TDT/Satélite.

Por haber nombrado a la HVR3000 comenzaron a llegar bastantes visitantes que buscaban cómo configurarla en Linux. Dos de ellos, Alberto y Sergio, comenzaron a tratar el tema en los comentarios y posteriormente se les unió X04n 2.0 que con las pistas previas dio con la solución definitiva, que documentó de forma excelente. Yo no tengo una HVR3000, por lo que no puedo probar personalmente si realmente funciona, pero como creo que sí, he pensado que no está de más dedicarle una entrada.

El problema de la HVR3000 es que, aunque aparece en el Documentation/video4linux/CARDLIST.cx88 de las fuentes de un kernel 2.6.22.10:

 53 -> Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T  [0070:1404,0070:1400,0070:1401,0070:1402]

y está definida en el fichero drivers/media/video/cx88/cx88-cards.c:

        [CX88_BOARD_HAUPPAUGE_HVR3000] = {
                /* FIXME: Add dvb & radio support */
                .name           = "Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T",
                .tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
                .radio_type     = UNSET,
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
                .tda9887_conf   = TDA9887_PRESENT,
                .input          = {{
                        .type   = CX88_VMUX_TELEVISION,
                        .vmux   = 0,
                        .gpio0  = 0x84bf,
                },{
                        .type   = CX88_VMUX_COMPOSITE1,
                        .vmux   = 1,
                        .gpio0  = 0x84bf,
                },{
                        .type   = CX88_VMUX_SVIDEO,
                        .vmux   = 2,
                        .gpio0  = 0x84bf,
                }},
                .mpeg           = CX88_MPEG_DVB,
        },

vemos la nota “/* FIXME: Add dvb & radio support */“, indicando que aún no hay soporte de la mayor parte de funciones de la tarjeta.

El desarrollador del proyecto V4L Steve Toth (por la dirección de correo parece que es empleado de Hauppauge) estuvo trabajando hasta Octubre de 2006 en el soporte de esta tarjeta: hvr3000 development repository. En la lista de distribución de DVB de linuxtv.org, Steve contó que sus drivers son, de momento, una proof of concept ([linux-dvb] Hauppauge WinTV HVR 3000 Questions):

they are not ready for merging into the mainline and are proof of
concept patches to handle multiple DVB frontends on a single shared
transport bus. They worked fairly reliably last I tried, although they
need to cleanup and sanity checks before any merge could occur.

Pero claro, por aquellas fechas el último kernel disponible era el 2.6.18 y desafortunadamente estos drivers no funcionan en kernels posteriores ([linux-dvb] HVR-3000: fixed by downgrading kernel, any ~stoth/hvr3000 patches for >2.6.18 kernels?):

> Does anyone know if any *working* patches exist to get Steve Toth’s HVR-3000
> driver (currently in hg under ~stoth/hvr3000) working on newer kernels? I got
> it to compile fairly well, it just didn’t do much after it was compiled…

The best bet is to compile steven’s branch (~stoth/hvr3000) with vanilla
kernel 2.6.18. Changes introduced in this branch include support for
multiple exclusive frontends on a single bus, it’s somehow experimental
and it will need several changes prior to include in the main branch.

Analog works ok, DVB-T ok, DVB-S working with some troubles with diseq.

En un mensaje a la lista más reciente (Jul/07) nos enteramos de que la inclusión de drivers para esta tarjeta está a la espera de la inclusión de multi-protocol code en el V4L. ¿Tal vez porque tiene que soportar a la vez DVB-T y DVB-S como decía Steve (“handle multiple DVB frontends on a single shared transport bus“)? ([linux-dvb] [Fwd: Re: OHauppauge WinTV HVR-3000 or 4000]):

The HVR-3000 is “supported” by a branch created by Steven Toth. It’s
not seen any updates in a while, and currently (as far as I know)
doesn’t compile with kernels after 2.6.18. It’s working ok for me here
though. I think the reason for no updates / lack of inclusion in
mainline dvb is that he is waiting for some sort of multi-protocol code
to be implemented into the mainline dvb code.

La Hauppauge WinTV-HVR-4000 es una tarjeta que además de soportar TV analógica, DVB-T y DVB-S como la HVR3000, soporta DVB-S2 (emisiones por satélite en alta definición) y TDT en alta definición (a España aún no ha llegado). Pues bien, en la lista de distribución hablan a menudo también de la HVR4000 relacionándola con la HVR3000 porque el soporte de ambas parece que va relacionado. En ese contexto, me temo que es totalmente desalentador para los propietarios de una HVR3000 oir de boca de Steve hace menos de un mes (11/11/07) que mejor olvidar la HVR3000 y comprar una HVR4000 en eBay ([linux-dvb] Future of HVR3000?):

James A R Brown wrote:
> I guess this email is more for Steve and Manu.
>
> It is very pleasing to see the work going on for the HVR4000 and pushing
> the multiproto tree back into the main tree.
>
> Infact its a breath of fresh air as I have sadly watched the HVR3000
> branch be stripped to DVB-T and merged in without the DVB-S Support and
> was actually wondering if the card would be simply passed over by
> LinuxTV. It probably almost has by the HVR4000, but then again HVR3000
> is becoming a cheap card in the UK. (1/2 price of HVR4000)
>
> So my question is, once HVR4000 and multiproto are back in the main
> tree, are there any plans to also merge in the HVR3000 tree with
> multiproto support or should I stick them on ebay and look to the HVR4000?

Use ebay.

- Steve

Sigue leyendo »

08 dic

Probando la netconsole de Linux

Trabajando en la entrada Configurar Linux para permitir el acceso remoto por módem a la consola y por RAS/PPP, descubrí en el fichero Documentation/kernel-parameters.txt de las fuentes del kernel el fichero Documentation/networking/netconsole.txt que cuenta cómo configurar el kernel para poder monitorizar sus mensajes remotamente a través de una red Ethernet y usando paquetes UDP. No se puede hacer exactamente desde el primer momento del arranque como hacíamos con la consola serie, claro, sino que es únicamente a partir del punto en el que los drivers de la tarjeta de red sean cargados. Esto es porque mientras que el puerto serie es único y se puede configurar de forma muy sencilla desde el primer momento, las tarjetas de red posibles se cuentan por cientos.

It can be used either built-in or as a module. As a built-in,
netconsole initializes immediately after NIC cards and will bring up
the specified interface as soon as possible. While this doesn't allow
capture of early kernel panics, it does capture most of the boot
process.

No confundamos la netconsole de Linux con la “LAN Console” de los grandes sistemas UNIX, que es simplemente un chip independiente del sistema que redirige la salida de la consola serie típica a un pequeño servidor de telnet, por ejemplo, y que nos permite interactuar con la consola por la red pero exactamente igual que si estuviéramos conectados con cualquier tipo de terminal serie. La netconsole de Linux es más bien un netlogging o un “kernel-level network logging via UDP packets” tal y como se referían a ella cuando sacaron el primer parche que lo permitía: [patch] netconsole – log kernel messages over the network. 2.4.10.

La forma de usarla es:

It takes a string configuration parameter "netconsole" in the
following format:

 netconsole=[src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr]

   where
        src-port      source for UDP packets (defaults to 6665)
        src-ip        source IP to use (interface address)
        dev           network interface (eth0)
        tgt-port      port for logging agent (6666)
        tgt-ip        IP address for logging agent
        tgt-macaddr   ethernet MAC address for logging agent (broadcast)

Examples:

 linux netconsole=4444@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc

  or

 insmod netconsole netconsole=@/,@10.0.0.2/

Built-in netconsole starts immediately after the TCP stack is
initialized and attempts to bring up the supplied dev at the supplied
address.

The remote host can run either 'netcat -u -l -p <port>' or syslogd.

En el kernel por defecto de Debian el netconsole viene como módulo, no integrado en el kernel:

# grep -i netconsole /boot/config-2.6.18-5-686
CONFIG_NETCONSOLE=m

Sigue leyendo »

08 dic

Configurar el syslogd para que acepte mensajes de sistemas remotos

Ya he comendao alguna vez que el router que uso para conectar a Internet es un Zyxel 660HW-61. Este router permite enviar sus mensajes al syslog de una máquina UNIX remota:

Zyxel syslog

El puerto de red asignado al syslog es el 514/UDP:

# grep syslog /etc/services
syslog          514/udp

Sin embargo, el proceso syslogd de Debian no se conecta a ese puerto porque no escucha mensajes de la red por defecto. Si queremos que lo haga, tenemos que editar el fichero /etc/default/syslogd, que en la configuración estándar no contiene ninguna opción:

# For remote UDP logging use SYSLOGD="-r"
#
SYSLOGD=""

Si queremos que escuche de la red, hemos de especificar la opción -r:

# For remote UDP logging use SYSLOGD="-r"
#
SYSLOGD="-r"

que sirve precisamente para esto:

       -r     This option will enable the facility to receive message from the
              network using an internet domain socket with the syslog  service
              (see  services(5)).   The default is to not receive any messages
              from the network.

y reiniciar el proceso con “/etc/init.d/sysklogd restart“. Tras esto, podremos comprobar que el demonio funciona con la opción deseada

# ps -ef | grep syslog
root      4547     1  0 17:35 ?        00:00:00 /sbin/syslogd -r

y que el proceso está escuchando en el puerto 514/UDP:

# netstat -a | grep syslog
udp        0      0 *:syslog                *:*

Puesto que los mensajes del Zyxel van a llegar por la facility local2, podemos querer establecer un fichero de log específico para él en el /etc/syslog.conf (para que se relea después de modificarlo, haremos un “/etc/init.d/sysklogd reload“):

local2.* /var/log/zyxel.log

Si quisiéramos que fuera un sistema Linux (por ejemplo, una Debian) el que mandara ciertos mensajes a un syslog remoto, podríamos hacerlo simplemente poniendo en el syslog.conf una línea como:

local3.* @sistemaremoto.dominio

Tras releer la configuración, con una sencilla prueba con el comando logger:

logger -p local3.info "Mensaje de prueba"

veremos que, efectivamente, el mensaje aparece en el sistema remoto en varios logs configurados para recibir mensajes de la prioridad formada por la pareja facility/level que hemos especificado:

# grep "Mensaje de prueba" /var/log/*
/var/log/messages:Dec  8 18:18:15 ordenador logger: Mensaje de prueba
/var/log/syslog:Dec  8 18:18:15 ordenador logger: Mensaje de prueba

Recordemos que las facilities son:

  • auth, security 1
  • authpriv
  • cron
  • daemon
  • ftp
  • kern
  • lpr
  • mail
  • mark (sólo para uso interno)
  • news
  • sys-log
  • user
  • uucp
  • local0 → local7

y los levels:

  • debug
  • info
  • notice
  • warning, warn 1
  • error, err 1
  • crit
  • alert
  • emerg, panic 1

1. En los casos en que aparecen dos etiquetas juntas, la segunda es equivalente a la primera y está obsoleta.

Si tomamos una traza de red vemos que el protocolo (BSD syslog Protocol) es extraordinariamente sencillo (RFC 3164):

wireshark syslog trace

Podemos ver que la prioridad es un byte que contiene la facility (5bits) y el level (3bits).

Con un simple netcat también podemos mandar mensajes a un syslogd remoto que esté escuchando la red, aunque no pongamos la cabecera con la prioridad y la fecha del evento:

# echo "Nuevo mensaje de prueba con el netcat" | netcat -q 0 -u 192.168.1.20 514

y en el /var/log/syslog remoto encontramos el mensaje:

Dec  8 18:39:15 ordenador Nuevo mensaje de prueba con el netcat

:wq

08 dic

Monitorizando los mensajes del sistema en la consola y en las X

Si queremos tener una ventana mostrándonos en todo momento los mensajes del sistema, el xconsole es la aplicación que necesitamos:

xconsole

En los escritorios moderno, es fácil configurar la ventana para mantener el xconsole en primer plano.

Aunque la documentación de xconsole diga que accede a /dev/console, en muchas distribuciones (Make xconsole work), para evitar multitud de problemas que ocasiona engancharlo al /dev/console relacionados con la no posibilidad de teclear en las ventanas (sólo con hacer un “xconsole -file /dev/console“, se puede comprobar inmediatamente), normalmente las distribuciones crean una named pipe en /dev/xconsole:

# ll /dev/xconsole
prw-r----- 1 root adm 0 2007-12-08 12:27 /dev/xconsole|

en la que el syslogd escribe, como vemos en el /etc/syslog.conf de Debian:

# The named pipe /dev/xconsole is for the `xconsole' utility.  To use it,
# you must invoke `xconsole' with the `-file' option:
#
#    $ xconsole -file /dev/xconsole [...]
#
# NOTE: adjust the list below, or you'll go crazy if you have a reasonably
#      busy site..
#
daemon.*;mail.*;\
        news.err;\
        *.=debug;*.=info;\
        *.=notice;*.=warn       |/dev/xconsole

Si queremos que algún usuario distinto de root pueda usar el xconsole, habrá que asignarlo al grupo adm (al menos en Debian), pero parece más conveniente simplemente crear un acceso directo usando kdesu o gksu para que nos pregunte el password de root antes de ejecutar el xconsole:

kdesu

Para limpiar los mensajes actuales de la ventana del xconsole, podemos hacer un CONTROL+C sobre ella, como descubrimos en el fichero /etc/X11/app-defaults/XConsole:

*text.baseTranslations:         #override\
        Ctrl<KeyPress>C:        Clear() \n\
        <KeyPress>Clear:        Clear()

Si queremos una especie de equivalente al xconsole en la consola de texto, el syslog.conf estándar de Debian ya nos ofrece una configuración perfectamente válida. Descomentando estas las líneas que envían varias áreas de syslog al /dev/tty8 podremos verlos simplemente pulsando ALT+8 o ALT+CONTROL+8 si estamos en las X:

#
# I like to have messages displayed on the console, but only on a virtual
# console I usually leave idle.
#
daemon,mail.*;\
        news.=crit;news.=err;news.=notice;\
        *.=debug;*.=info;\
        *.=notice;*.=warn       /dev/tty8

Tras los cambios al syslog.conf, podemos hacer un /etc/init.d/sysklogd reload para que el cambio tenga efecto.

Hay que tener en cuenta que cualquiera con acceso físico a la máquina (incluso sin usuario válido) podrá ver estos mensajes que pueden llevar información sensible, de forma que hay que usarlo con mucha precaución. Por eso está deshabilitado por defecto.

:wq

06 dic

Configurar Linux para permitir el acceso remoto por módem a la consola y por RAS/PPP

En los PCs, la entrada estándar siempre ha sido el teclado, y la salida estándar, el monitor a través de la tarjeta de vídeo. Sin embargo, en los grandes sistemas UNIX, la entrada/salida estándar ha sido tradicionalmente a través de un terminal o un módem serie. Incluso en workstations UNIX enfocadas a CAD con monitor y teclado, siempre ha existido la posibilidad de gestionar la máquina desde el arranque por el puerto serie. En ocasiones, los fabricantes han redirigido esa conexión serie a un servidor de telnet para tener una “LAN Console” y en otras, a un servidor web, para tener una “Web Console”, pero en definitiva, los que hacen es facilitarnos el acceso a lo que sigue siendo internamente una consola serie estándar.

Los PCs no están bien preparados para tener como única posibilidad de entrada/salida un terminal serie. Al menos no durante el arranque y para configurar la BIOS. Una vez que el sistema operativo o el GRUB toma el control ya sí que podemos usar el puerto serie para gestionar el ordenador. Pero es precisamente en circunstancias muy dramáticas cuando nos puede interesar especialmente controlar el arranque remotamente. Por eso hay fabricantes de servidores x86 cuyos sistemas permiten redirigir la salida de la BIOS a un puerto serie, como por ejemplo la HP BIOS Serial Console. Para ampliar información sobre servidores con esta posibilidad, podemos leer sobre IPMI y sobre Out-of-band management o Lights-out management. En la web en japonés sobre la tarjeta Lights-Out 100 de HP podemos ver capturas de una BIOS por el puerto serie.

En cualquier caso, en PCs normales no tenemos esta posibilidad. El primer momento en el que podemos comenzar a redirigir la salida estándar es en el GRUB. El segundo momento es al arrancar el kernel de Linux. El tercero es cuando el sistema operativo ya está totalmente arriba.

Veamos cómo acceder a la consola por el puerto serie una vez que el sistema está arriba y luego veremos qué dificultades presentan los otros casos.

Sigue leyendo »

02 dic

Comprimir y cachear las páginas generadas por WordPress

Las dos entradas anteriores:

trataban de conseguir optimizar el ancho de banda de nuestro servidor web comprimiendo el documento para que ocupara menos y de cómo lograr que el mismo contenido no se tenga que comprimir una y otra vez malgastando inútilmente ciclos de CPU. Sin embargo, aquella teoría estaba orientada a páginas estáticas… ¿Cómo podemos hacer lo mismo para contenido creado dinámicamente como es el generado por WordPress? ¿Es aplicable?

El contenido generado por WordPress se puede enviar comprimido a través de varios mecanismos. Por un lado, podemos simplemente señalar la opción “WordPress debería comprimir las entradas (gzip) si los navegadores lo requieren” del panel de “Opciones de lectura” de WordPress. Por otro, podemos habilitar la opción zlib.output_compression del php.ini (en /etc/php5/apache2/php.ini en Debian):

; Transparent output compression using the zlib library
; Valid values for this option are 'off', 'on', or a specific buffer size
; to be used for compression (default is 4KB)
; Note: Resulting chunk size may vary due to nature of compression. PHP
;       outputs chunks that are few hundreds bytes each as a result of
;       compression. If you prefer a larger chunk size for better
;       performance, enable output_buffering in addition.
; Note: You need to use zlib.output_handler instead of the standard
;       output_handler, or otherwise the output will be corrupted.
zlib.output_compression = On

Y por supuesto, podemos usar el mod_deflate, que nos comprime la salida generada por WordPress sin problemas si lo tenemos configurado para que nos comprima los ficheros text/html:

AddOutputFilterByType DEFLATE text/html

Es recomendable no usar más de un método de compresión porque pueden chocar entre ellos.

Sin embargo, todos estos métodos necesitan estar comprimiendo una y otra vez las mismas páginas. ¿Podríamos usar el mod_cache con alguno de estos métodos de compresión como hacíamos con contenidos estáticos y el mod_deflate? Pues desafortunadamente la respuesta es un no.

Si tomamos una traza de red para ver qué cabeceras devuelve una petición enviada a un servidor de WordPress:

HTTP/1.1 200 OK
Date: Sun, 02 Dec 2007 10:05:43 GMT
Server: Apache/2.2.3 (Debian) PHP/5.2.0-8+etch7
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Last-Modified: Sun, 02 Dec 2007 10:05:44 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
Keep-Alive: timeout=15, max=97
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

vemos que entre otras cosas, una respuesta con “Cache-Control: no-cache” no es cacheada por defecto en ningún caso, tal y como leemos en la Apache HTTP Server Version 2.2: Caching Guide:

Likewise, if the response includes the “no-store” option in a “Cache-Control:” header, it will not be stored unless the CacheStoreNoStore has been used.

Sin embargo, el contenido de WordPress, aunque se genera dinámicamente, es bastante estático. Una entrada se escribe y a menos que se generen nuevos comentarios o el autor corrija algo, va a permanecer inalterable durante mucho tiempo. Debería de ser fácilmente cacheable… y en realidad así lo es gracias a distintos plugins.

Sigue leyendo »

02 dic

Usando el mod_cache de Apache para que el mod_deflate no incremente la carga del servidor

En la entrada anterior, Probando el mod_deflate de Apache, vimos cómo conseguir que el Apache comprima los contenidos antes de mandarlos.

Sin embargo, parece un despropósito que el servidor web tenga que estar comprimiendo una y otra vez los mismos contenidos. Supone estar forzando al procesador a usar ciclos que pueden sernos necesarios para otra tarea en algo que debería de poder evitarse. Afortunadamente, gracias al módulo mod_cache, podemos conseguir evitar esta sobrecarga inútil para el servidor.

En realidad, este módulo tiene su máxima utilidad para configurar Apache como servidor Proxy o como Proxy Inverso (mediante el mod_proxy), ya que gracias a la caché, podemos evitar que Apache vuelva a pedir el mismo contenido al servidor final repetidas veces. Para un servidor normal, no parece que una caché pueda proporcionarnos una gran mejora de rendimiento, incluso aunque cacheemos en memoria. Sin embargo, si lo combinamos con el mod_deflate, sí que podemos conseguir que los documentos servidos se almacenen ya comprimidos en la caché ahorrándonos así un elevado e inútil uso de la CPU causado por la compresión repetidas veces de lo mismo.

El documento de referencia para conocer cómo Apache cachea a través del mod_cache es el Apache HTTP Server Version 2.2: Caching Guide, y proporciona sus servicios a través de otros tres módulos que dependen de él: mod_disk_cache, mod_mem_cache, mod_file_cache.

El mod_file_cache es el menos flexible de los tres. Sirve para cachear ficheros concretos en disco o memoria, pero si modificamos alguno de dichos ficheros sólo podremos conseguir que Apache sirva la versión actualizada con un reinicio del gestor:

So whenever one of the mapped files changes on the filesystem you have to restart the server. To reiterate that point: if the files are modified in place without restarting the server you may end up serving requests that are completely bogus. You should update files by unlinking the old copy and putting a new copy in place. Most tools such as rdist and mv do this.

El mod_mem_cache nos permite cachear los ficheros en memoria. Sin embargo, lo que teóricamente podría suponer un a gran mejora de rendimiento del servidor, puede quedarse en mucho menos por dos motivos (In-Memory Caching):

  • Por un lado, forzar a Apache a usar una gran cantidad de memoria para cachear los ficheros del sistema puede causar que el sistema se vaya quedando corto de memoria para otras tareas llegando a swapear y causando que el rendimiento caiga en picado.
  • Por otro lado, los sistemas operativos modernos hacen un excelente trabajo cacheando ficheros que se usan frecuentemente, especialmente si hay memoria de sobra. Además, saben perfectamente cuándo el fichero se ha modificado y hay que renovarlo en la caché y saben cuando hay que dejar de cachear porque el sistema se va quedando corto de memoria. ¿Realmente necesitamos que Apache cachée esos mismos ficheros?

El mod_disk_cache va almacenando en un directorio los documentos que se van solicitando, así como sus cabeceras. Si el mod_deflate está activo y hay unos clientes que aceptan compresión y otros que no, se cacheará el documento comprimido y sin comprimir. Por supuesto, no debemos olvidar que la caché del sistema operativo está actuando, así que estos ficheros de caché, si hay memoria suficiente, también serán cacheados en memoria por el kernel.

Por tanto, el mecanismo de caché para almacenar el contenido comprimido que parece más conveniente en muchas situaciones es el del mod_disk_cache y en él nos vamos a centrar en lo sucesivo.

Sigue leyendo »

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 »

 Anterior 1 2 3 ... 8 9 10 11 12 ... 16 17 18 Siguiente
Tema LHYLE09, creado por Vicente Navarro