Truco mod_rewrite
Esta es una cosa que nada tiene que ver con el desarrollo de Kraken, pero me he peleado un rato con ella y me gustaría compartirla, para que si me vuelve a pasar recuerde donde buscar o para que a quien le pase sepa como solucionarlo.
La situación es la siguiente: tenemos un dominio, example.com, y queremos crear un subdominio dentro de esa web, por ejemlo, foo.example.com. Como solo tenemos un servidor, hacemos apuntar foo.example.com a example.com y usamos mod_rewrite de Apache para que al entrar a foo.example.com se nos muestre una página distinta, alojada dentro de /www/root/foo.example.com/index.html, donde /www/root es la raíz de nuestro servidor web.
La regla lógica que deberíamos de implementar sería:
RewriteRule ^(.*)$ /foo.example.com/$1
El funcionamiento de este módulo es el siguiente:
- Apache recibe una petición "GET /index.html" con el host foo.example.com
- Comprueba si tiene que reescribir la URL
- Como detecta la RewriteCond y la RewriteRule ve que efectivamente tiene que hacer una reescritura a nivel interno.
- Cada reescritura la considera una nueva petición, ahora "GET /foo.example.com/index.html" con el host foo.example.com
- Como el host sigue siendo el mismo, y la URL pedida sigue encajando dentro de la URL de RewriteRule, lanza una nueva petición
Entonces, cuando accedamos a foo.example.com obtenemos un precioso mensaje de error 500, parecido a mod_rewrite: maximum number of internal redirects reached. Assuming configuration error. Use 'RewriteOptions MaxRedirects' to increase the limit if neccessary.. ¿Cómo solucionamos este problema?
La solución es sencillísima, especialmente si la sabes :P. Basta con añadir una regla de carácter final que frene el bucle de redirecciones:
RewriteRule ^(/foo.example.com|foo.example.com) - [L]
RewriteCond %{HTTP_HOST} ^foo.example.com$
RewriteRule ^(.*)$ /foo.example.com/$1
- RewriteCond significa condición para la reescritura de las URLs. A las siguientes dos reglas solo se va a entrar si el host de petición es foo.example.com. Esto nos permite crear un VirtualHost entre otras cositas.
- RewriteRule indica que estamos escribiendo una regla de redirección. El siguiente parámetro es la expresión regular que tiene que verificar la URL de petición para que la regla se aplique. En este caso es cualquier cadena de petición que empiece por foo.example.com o /foo.example.com. El porque esta cadena en concreto lo veremos más adelante. El guión (-) que sigue a la expresión regular indica que no queremos hacer ninguna redirección. La [L] indica que la regla es final, es decir, que si podemos aplicar esa regla a la URL mod_rewrite no va a seguir buscando más reglas.
- El último RewriteRule significa que cualquier cadena de petición que le llegue la redirija a /foo.example.com/(PETICIÓN), donde foo.example.com es el directorio sobre el que tenemos montado nuestro VirtualHost (Por eso lo de foo.example.com en el punto anterior) y PETICIÓN es lo que pida el usuario.
- El usuario accede a http://foo.example.com/bar.html. Este genera una petición "GET /bar.html HTTP/1.1" contra el host foo.example.com
- mod_rewrite comprueba la URL y ve que para el host foo.example.com hay dos redirecciones definidas. /bar.html no verifica la primera expresión regular, por lo que no es aplicada. Sin embargo, /bar.html verifica la segunda expresión regular, por lo que mod_rewrite aplica la redirección.
- mod_rewrite ve que es una redirección interna, por lo que genera una "petición" "GET /foo.example.com/bar.html HTTP/1.1" contra el host foo.example.com
- mod_rewrite comprueba la nueva petición y ve que sigue verificando la condición bajo la cual se aplican las dos reglas de reescritura (HTTP_HOST == foo.example.com). Al comprobar /foo.example.com/bar.html ve que verifica la primera expresión regular, por lo que no hace una nueva redirección (-) y además para el procesamiento ([L]). Esto tiene como consecuencia que Apache sirva finalmente el fichero /foo.example.com/bar.html, es decir, que se haga correctamente la redirección






0 comentarios:
Añadir nuevo comentario:
Opciones de formato: [+]