POST , GET y 301
abr 3, 08:00
Hay un detalle curioso que encontré al estar revisando un script en PHP. El script se llama index.php y se encuentra dentro de un directorio mail. Entonces si se quiere llamarlo desde un formulario se podría usar:
<form action="http://dominio.com/mail" method="post">
Con mod_dir lo que debe hacer Apache es convertir mail a mail/ (haciendo un redirect 301) y llamar al index.php ya que está definido en la directiva DirectoryIndex de la configuración del Apache . El redireccionamiento también se podría hacer con mod_rewrite o un Alias. Todo funciona a la perfección excepto por el detalle que los datos no pasan al script, todo lo que se envía por POST se pierde.
Revisando los logs de apache se encuentra:
x.x.x.x – - [02/Apr/2008:15:33:10 -0500] “POST /mail HTTP/1.1” 301 320
x.x.x.x – - [02/Apr/2008:15:33:10 -0500] “GET /mail/ HTTP/1.1” 200 8176
Se ve que /mail se considera un redireccionamiento (301) y pasa a /mail/ pero el detalle está en que el POST se convierte en GET. En la documentación de los códigos de respuesta de HTTP se encuentra en una nota para el 301:
Note: When automatically redirecting a POST request after receiving a 301 status code, some existing HTTP/1.0 user agents will erroneously change it into a GET request.
Parece que éste error no sólo se aplica a clientes HTTP/1.0. Lo he probado con Firefox y Opera como clientes y además en Apache y Lighttpd con idénticos resultados.
La solución: poner el trailing slash al final. Además por una cuestión de orden. Cuando el servidor web recibe una petición a mail lo primero que hace es buscar un archivo con ese nombre y luego recién busca el directorio y hace el redireccionamiento. Doble trabajo que no realizaría con el trailing slash colocado.
A List Apart dice El trailing slash es tu amigo y Steve Souders de Yahoo que evitemos los redirect