Con nginx y el módulo de Perl embebido es posible reescribir/redirigir todas las visitas a URL en minúsculas añadiendo algo como esto a la configuración:
http {
...
perl_modules perl/lib;
perl_set $uri_lowercase 'sub {
my $r = shift;
my $uri = $r->uri;
$uri = lc($uri);
return $uri;
}';
...
}
server {
...
location / {
if ( $uri != $uri_lowercase ) {
rewrite . http://$host$uri_lowercase;
}
# or just:
# rewrite . $uri_lowercase;
}
...
}
La primera opción (con el if y el http://$host) genera una redirección HTTP a la URL en minúscula si la URL que pide el cliente no está ya toda en minúscula. Me gusta más esta técnica ya que de alguna forma normaliza todas las URL a una forma canónica en minúsculas. La segunda opción (sin el if ni el http://) simplemente acepta cualquier URL y la reescribe internamente a minúsculas. Si previamente se renombran todos los ficheros y directorios a minúsculas se consigue un efecto “case insensitive” similar al de Windows.
Quiero dar las gracias al siguiente post de la lista de usuarios de nginx en el que me he inspiarado ;D para conseguir hacer esto. En efecto, la documentación y ejemplos del módulo de Perl de nginx son muy escasos. :-(
http://forum.nginx.org/read.php?2,39425,39944
De todas formas esta solución tiene dos problemas:
- Hace falta el módulo de Perl que según los propios desarrolladores es experimental y puede tener memory leaks.
- Aunque la redirección se hace en el location que esté el rewrite, el cálculo de la URL en minúscula al estar en la sección “http” de la configuración se hace para todas las peticiones que lleguen al servidor, haya que cambiarles la URL o no. Es decir, si tienes un servidor virtual con 10 dominios y sólo en una parte de uno de ellos es necesario reescribir las URL, aunque sólo se redirija el tráfico en ese caso, la URL en minúscula se calcula para todas las peticiones de todos los dominios.
Supongo que si en lugar de definir la variable en minúscula se escribiera una función Perl si que se podría restringir a un location determinado, tengo que mirarlo con más detenimiento aunque con la poca documentación que hay de esto la cosa está chunga. Otra opción es escribir un módulo en C que lo haga.
¿Y por qué querría alguien reescribir todas las URL a minúsculas? En el trabajo estamos migrando una aplicación Tomcat vieja desarrollada y que hasta ahora corría en un servidor Windows a Linux, y parece ser que los desarrolladores originales no prestaron nada de atención al tema de las mayúsculas y minúsculas en los nombres de ficheros y directorios, enlazando a veces bien los ficheros según mayúsculas y minúsculas pero otras veces no. Esto en Windows no es un problema, pero en Linux si que lo es. Así que lo que hemos hecho ha sido renombrarlo todo a minúsculas y configurar esta redirección a minúsculas en los servidores nginx que tenemos delante de la granja de Tomcats. Aún así todavía quedan algunos casos problemáticos aislados que han tenido que ser tratados uno a uno, como includes en los JSP a ficheros en mayúsculas (estos casos no “salen” al nginx si no que los trata internamente Tomcat, con lo que la redirección no se aplica), pero el grueso de los accesos a imágenes, videos, páginas HTML estáticas, etc. mal enlazados se ha solucionado de un plumazo sin tener que tocar el código.