multiple - ¿Cómo manejar el mensaje HTTP "100 continue"?
curl post php (5)
Elaborando sobre la respuesta de USTED, y aún utilizando PHP como ejemplo:
Es posible que se puedan recibir múltiples 100 Continue
encabezados 100 Continue
. Uso lo siguiente para trabajar lentamente en los encabezados y eliminar cada una de las 100 Continue
respuestas de 100 Continue
si existen:
<?php
// a little setup first
$ch = curl_init();
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_HEADER,1);
// etc...
$str = curl_exec($ch);
// the goods
$delimiter = "/r/n/r/n"; // HTTP header delimiter
// check if the 100 Continue header exists
while ( preg_match(''#^HTTP/[0-9//.]+/s+100/s+Continue#i'',$str) ) {
$tmp = explode($delimiter,$str,2); // grab the 100 Continue header
$str = $tmp[1]; // update the response, purging the most recent 100 Continue header
} // repeat
// now we just have the normal header and the body
$parts = explode($delimiter,$str,2);
$header = $parts[0];
$body = $parts[1];
?>
Estoy escribiendo un servidor HTTP simplista que aceptará solicitudes PUT principalmente de cURL como cliente y estoy teniendo un problema con el manejo del encabezado Expect: 100-continue
.
Según tengo entendido, se supone que el servidor debe leer el encabezado, enviar una respuesta HTTP/1.1 100 Continue
en la conexión, leer el flujo hasta el valor en Content-Length
y luego devolver el código de respuesta real (por lo general, HTTP/1.1 200 OK
pero cualquier otra respuesta HTTP válida debería hacerlo).
Bueno, eso es exactamente lo que hace mi servidor. El problema es que, aparentemente, si envío una respuesta 100 Continue
, cURL no informa ningún código de error HTTP posterior y asume que la carga fue un éxito. Por ejemplo, si se rechaza la carga debido a la naturaleza del contenido (hay una verificación de datos básicos), quiero que el cliente llamante detecte el problema y actúe en consecuencia.
¿Me estoy perdiendo algo obvio?
editar: aquí hay un resultado de muestra de cURL con un encabezado secundario que contiene un error:
> PUT /test1%2Epdf HTTP/1.1
> Authorization: Basic xxxx
> User-Agent: curl/7.20.0 (i386-pc-win32) libcurl/7.20.0 OpenSSL/0.9.8l zlib/1.2.3
> Host: localhost
> Accept: */*
> Content-Length: 24
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
< HTTP/1.1 415 Unsupported Media Type
< Connection: close
< Content-Type: text/xml
< Content-Length: 289
<
En realidad, debe haber un encabezado real después de 100 encabezado Continuar
Por lo tanto, normalmente me gusta esto en el lado del cliente.
$contents=curl_exec($ch);
list( $header, $contents ) = explode( "/r/n/r/n", $contents , 2);
if(strpos($header," 100 Continue")!==false){
list( $header, $contents) = explode( "/r/n/r/n", $contents , 2);
}
Intenta agregar una línea vacía (CRLF) después de la línea 100 Continuar (ver RFC 2616, Sección 6 ),
Sé que esto es viejo, pero aquí está mi entendimiento de "100 Continue"
Se supone que su servidor valida la solicitud basada solo en el encabezado del cliente, es decir, si la solicitud no es válida, no envíe "100 Continue" sino error http real, por ejemplo, 403. Esto evitará que el cliente publique los datos que entiendo es el punto principal de ida y vuelta al servidor (es decir, cliente que espera "100 Continuar") en primer lugar.
Si está validando los datos reales publicados, entonces debe aplicar el protocolo de nivel superior aquí, es decir, envíe su error envuelto en un contenido de respuesta HTTP válido. Sí, parece una limitación y no estoy asumiendo que sea una limitación de protocolo; es más probable que la confusión del cliente tenga que manejar la respuesta del servidor más de una vez.
Si está utilizando libcURL para escribir su programa del lado del cliente, asegúrese de configurar la opción CURLOPT_FAILONERROR
en 1
. Por ejemplo, en C, harías algo como:
curl_easy_setopt (curl_handle, CURLOPT_FAILONERROR, 1L);
De acuerdo con la documentation libcURL, esta opción "le dice a la biblioteca que falle silenciosamente si el código HTTP devuelto es igual o mayor que 400".
Además, la documentación deja en claro que "la acción predeterminada sería devolver la página normalmente, ignorando ese código".
Si está utilizando la herramienta de línea de comandos curl, simplemente agregando -f
o --fail
en su comando curl provocará un comportamiento similar al descrito anteriormente. Esto también se describe en la página man curl.
Tenga en cuenta que estos dos métodos no son a prueba de fallas, como se establece claramente en los documentos:
"Este método no es seguro y hay ocasiones en que los códigos de respuesta no exitosos se deslizarán, especialmente cuando se trata de autenticación (códigos de respuesta 401 y 407)".