Diferencia entre `curl -I` y` curl -X HEAD`

70

Estaba viendo el tipo de servidor divertido de http://www.reddit.com con curl -I http://www.reddit.comcuando supuse que curl -X HEAD http://www.reddit.comharía lo mismo. Pero, de hecho, no lo hace.

Tengo curiosidad sobre por qué.

Esto es lo que observo ejecutando los dos comandos:

  • curl -I: funciona como se esperaba, genera el encabezado y existe.

  • curl -X HEAD: no muestra nada y parece esperar la entrada del usuario.

Pero, olisqueando tshark, veo que el segundo comando en realidad envía la misma consulta HTML y recibe la respuesta correcta, pero no la muestra y no cierra la conexión.

curl -I

0.000000 333.33.33.33 -> 213.248.111.106 TCP 59675 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=47267342 TSER=0 WS=6
0.045392 213.248.111.106 -> 333.33.33.33 TCP http > 59675 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=2552532839 TSER=47267342 WS=1
0.045441 333.33.33.33 -> 213.248.111.106 TCP 59675 > http [ACK] Seq=1 Ack=1 Win=5888 Len=0 TSV=47267353 TSER=2552532839
0.045623 333.33.33.33 -> 213.248.111.106 HTTP HEAD / HTTP/1.1
0.091665 213.248.111.106 -> 333.33.33.33 TCP http > 59675 [ACK] Seq=1 Ack=155 Win=6432 Len=0 TSV=2552532886 TSER=47267353
0.861782 213.248.111.106 -> 333.33.33.33 HTTP HTTP/1.1 200 OK
0.861830 333.33.33.33 -> 213.248.111.106 TCP 59675 > http [ACK] Seq=155 Ack=321 Win=6912 Len=0 TSV=47267557 TSER=2552533656
0.862127 333.33.33.33 -> 213.248.111.106 TCP 59675 > http [FIN, ACK] Seq=155 Ack=321 Win=6912 Len=0 TSV=47267557 TSER=2552533656
0.910810 213.248.111.106 -> 333.33.33.33 TCP http > 59675 [FIN, ACK] Seq=321 Ack=156 Win=6432 Len=0 TSV=2552533705 TSER=47267557
0.910880 333.33.33.33 -> 213.248.111.106 TCP 59675 > http [ACK] Seq=156 Ack=322 Win=6912 Len=0 TSV=47267570 TSER=2552533705

curl -X HEAD

34.106389 333.33.33.33 -> 213.248.111.90 TCP 51690 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=47275868 TSER=0 WS=6
34.149507 213.248.111.90 -> 333.33.33.33 TCP http > 51690 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=3920268348 TSER=47275868 WS=1
34.149560 333.33.33.33 -> 213.248.111.90 TCP 51690 > http [ACK] Seq=1 Ack=1 Win=5888 Len=0 TSV=47275879 TSER=3920268348
34.149646 333.33.33.33 -> 213.248.111.90 HTTP HEAD / HTTP/1.1
34.191484 213.248.111.90 -> 333.33.33.33 TCP http > 51690 [ACK] Seq=1 Ack=155 Win=6432 Len=0 TSV=3920268390 TSER=47275879
34.192657 213.248.111.90 -> 333.33.33.33 TCP [TCP Dup ACK 15#1] http > 51690 [ACK] Seq=1 Ack=155 Win=6432 Len=0 TSV=3920268390 TSER=47275879
34.823399 213.248.111.90 -> 333.33.33.33 HTTP HTTP/1.1 200 OK
34.823453 333.33.33.33 -> 213.248.111.90 TCP 51690 > http [ACK] Seq=155 Ack=321 Win=6912 Len=0 TSV=47276048 TSER=3920269022

¿Alguna idea de por qué esta diferencia de comportamiento?

chmeee
fuente

Respuestas:

66

Parece que la diferencia tiene que ver con el Content-Lengthencabezado y cómo es tratado por ambos comandos.

Pero antes de entrar en eso, curl -X HEADno da ningún resultado porque, de forma predeterminada, curlno imprime encabezados si -ino se proporciona el interruptor ( -Iaunque no es necesario ).

En cualquier caso, curl -Ies la forma correcta de recuperar los encabezados. Solo pide el encabezado y cierra la conexión.

Por otro lado curl -X HEAD -iesperará la transmisión del número de bytes indicado por Content-Length. En el caso de que no Content-Lengthse especifique no, supongo que esperará algunos datos o ese encabezado en particular.

Algunos ejemplos que muestran este comportamiento:

$ curl -X HEAD -i http://www.elpais.es
HTTP/1.1 301 Moved Permanently
Server: AkamaiGHost
Content-Length: 0
Location: http://www.elpais.com/
Date: Wed, 12 May 2010 06:35:57 GMT
Connection: keep-alive

Como Content-Lengthes 0, en este caso ambos comandos se comportan igual. Y la conexión se cierra después.

$ curl -X HEAD -i http://slashdot.org
HTTP/1.1 200 OK
Server: Apache/1.3.41 (Unix) mod_perl/1.31-rc4
SLASH_LOG_DATA: shtml
X-Powered-By: Slash 2.005001296
X-Bender: Since I love you all so much, I'd like to give everyone hugs.
X-XRDS-Location: http://slashdot.org/slashdot.xrds
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=iso-8859-1
Content-Length: 115224
Date: Wed, 12 May 2010 06:37:20 GMT
X-Varnish: 1649060825 1649060810
Age: 1
Connection: keep-alive

curl: (18) transfer closed with 115224 bytes remaining to read

En este caso, parece haber un tiempo de espera (probablemente por Varnish), por lo curlque protesta porque la conexión se cerró antes de haber recibido el Content-Lengthnúmero de bytes.

Por cierto, mira los divertidos encabezados X-Bender (que se muestran en el ejemplo) y X-Fry (pruébalo tú mismo) :).

chmeee
fuente
2
En caso de que alguien más venga a buscar esto: la opción para establecer en la biblioteca de curl de PHP es CURLOPT_NOBODY.
Mateo
12

Creo que esto es un error en el rizo. Si especifico un método con -X, curl debería manejar la respuesta de acuerdo con el RFC. Desafortunadamente, el mantenedor de curl no está de acuerdo. Alguien presentó un error e incluso envió un parche:

http://sourceforge.net/tracker/?func=detail&atid=100976&aid=1810273&group_id=976

pero el encargado de curl lo rechazó. Aparentemente, una opción rota "-X HEAD" está "funcionando según lo diseñado".

--Jamshid

jamshid
fuente
44
Para ser justos, puedo seguir la lógica de la respuesta del ticket: --headnos proporciona una implementación válida de una solicitud HEAD y -X <method>simplemente anula el método HTTP en la solicitud.
Hank
3
Sí, esto era realmente lo que necesitaba. Tengo un servidor con errores que sirve contenido cuando recibe una solicitud HEAD. -X HEADera la única forma en que podía probarlo cuando intentaba que el servidor se adhiriera al RFC
Hashbrown
5

De los documentos :

-X, --solicitud

(HTTP) Especifica un método de solicitud personalizado para usar cuando se comunica con el servidor HTTP. Se utilizará el método de solicitud especificado en lugar del método utilizado de otro modo (que por defecto es GET). Lea la especificación HTTP 1.1 para obtener detalles y explicaciones. Las solicitudes HTTP adicionales comunes incluyen PUT y DELETE, pero las tecnologías relacionadas como WebDAV ofrecen PROPFIND, COPY, MOVE y más.

Normalmente no necesitas esta opción. Se invoca todo tipo de solicitudes GET, HEAD, POST y PUT utilizando opciones de línea de comandos dedicadas.

Esta opción solo cambia la palabra real utilizada en la solicitud HTTP, no altera el comportamiento de curl . Entonces, por ejemplo, si desea realizar una solicitud HEAD adecuada, usar -X HEAD no será suficiente. Debe usar la opción -I, --head.

En otras palabras, -Xes por métodos distintos GET, HEAD, POSTy PUT. Para HEADsu uso -I.

x-yuri
fuente
0

Me encuentro con el mismo problema al escribir el código cpp en curl 7.34,

curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "HEAD");

pasará mucho tiempo allí, parece que está esperando la transferencia del cuerpo hasta que se agote el tiempo de espera. después de agregar una nueva línea, este problema se resuelve.

curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );

del doc

hacer la solicitud de descarga sin obtener el cuerpo

esta línea obligaría al rizo a no esperar.

dasons
fuente