Differenza tra `curl -I` e` curl -X HEAD`


70

Stavo guardando il tipo di server divertente da http://www.reddit.com con curl -I http://www.reddit.comquando immaginavo che curl -X HEAD http://www.reddit.comavrebbe fatto lo stesso. Ma, in effetti, non lo è.

Sono curioso di sapere perché.

Questo è ciò che osservo eseguendo i due comandi:

  • curl -I: funziona come previsto, genera l'intestazione ed esiste.

  • curl -X HEAD: non mostra nulla e sembra attendere l'input dell'utente.

Ma, annusando, tsharkvedo che il secondo comando in realtà invia la stessa query HTML e riceve la risposta corretta, ma non la mostra e non chiude la connessione.

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

Qualche idea sul perché questa differenza di comportamento?


Risposte:


66

Sembra che la differenza abbia a che fare con l' Content-Lengthintestazione e come viene trattata da entrambi i comandi.

Ma prima di entrare in questo, curl -X HEADnon fornisce alcun output perché, per impostazione predefinita, curlnon stampa le intestazioni se lo switch -inon è fornito (non è necessario su -Iperò).

In ogni caso, curl -Iè il modo corretto di recuperare le intestazioni. Basta chiedere l'intestazione e chiudere la connessione.

D'altra parte curl -X HEAD -iattenderà la trasmissione del numero di byte indicato da Content-Length. Nel caso in cui no Content-Lengthnon sia specificato, suppongo che attenderà alcuni dati o quella particolare intestazione.

Alcuni esempi che mostrano questo comportamento:

$ 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

Poiché Content-Lengthè 0, in questo caso entrambi i comandi si comportano allo stesso modo. E la connessione viene chiusa in seguito.

$ 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

In questo caso, sembra esserci un timeout (probabilmente di Varnish), quindi curlprotesta che la connessione è stata chiusa prima di aver ricevuto il Content-Lengthnumero di byte.

A proposito, guarda le divertenti intestazioni X-Bender (mostrate nell'esempio) e X-Fry (provalo tu stesso) :).


2
Nel caso in cui qualcuno venga a cercarlo: l'opzione da impostare nella libreria di arricciatura di PHP è CURLOPT_NOBODY.
Matteo,

12

Penso che questo sia un bug nel ricciolo. Se specifico un metodo con -X, l'arricciatura dovrebbe gestire la risposta secondo la RFC. Sfortunatamente, il manutentore del ricciolo non è d'accordo. Qualcuno ha presentato un bug e ha persino inviato una patch:

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

ma il manutentore del ricciolo l'ha respinto. Apparentemente l'opzione "-X HEAD" non funzionante "funziona come previsto".

--Jamshid


4
Per essere onesti, posso seguire la logica della risposta del ticket: --headci fornisce un'implementazione valida di una richiesta HEAD e -X <method>semplicemente ignora il metodo HTTP nella richiesta.
Hank

3
sì, questo era in realtà quello di cui avevo bisogno. Ho un server buggy che serve contenuti quando viene data una richiesta HEAD. -X HEADera l'unico modo in cui potevo provarlo quando cercavo di far aderire il server alla RFC
Hashbrown,

5

Dai documenti :

-X, --request

(HTTP) Specifica un metodo di richiesta personalizzato da utilizzare durante la comunicazione con il server HTTP. Verrà utilizzato il metodo di richiesta specificato anziché il metodo altrimenti utilizzato (il cui valore predefinito è GET). Leggi la specifica HTTP 1.1 per dettagli e spiegazioni. Le richieste HTTP aggiuntive comuni includono PUT e DELETE, ma tecnologie correlate come WebDAV offrono PROPFIND, COPY, MOVE e altro.

Normalmente non hai bisogno di questa opzione. Tutti i tipi di richieste GET, HEAD, POST e PUT vengono invece invocati utilizzando le opzioni della riga di comando dedicate.

Questa opzione modifica solo la parola effettiva utilizzata nella richiesta HTTP, non altera il comportamento del ricciolo . Ad esempio, se si desidera effettuare una richiesta HEAD corretta, l'utilizzo di -X HEAD non sarà sufficiente. Devi usare l'opzione -I, --head.

In altre parole, -Xè per metodi diversi GET, HEAD, POSTe PUT. Per l' HEADuso -I.


0

Incontro lo stesso problema quando scrivo il codice cpp sul ricciolo 7.34,

curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "HEAD");

rimarrà lì a lungo, sembra che stia aspettando il trasferimento del corpo fino a quando si verifica un timeout. dopo aver aggiunto una nuova riga, questo problema è stato risolto.

curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );

dal doc

eseguire la richiesta di download senza ottenere il corpo

questa linea costringerebbe il ricciolo a non aspettare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.