Unterschied zwischen "curl -I" und "curl -X HEAD"

70

Ich habe den lustigen Servertyp von http://www.reddit.com mit angesehen, curl -I http://www.reddit.comals ich vermutete, dass dies auch so sein curl -X HEAD http://www.reddit.comwürde. Tatsächlich aber nicht.

Ich bin gespannt warum.

Folgendes beobachte ich beim Ausführen der beiden Befehle:

  • curl -I: funktioniert wie erwartet, gibt den Header aus und existiert.

  • curl -X HEAD: zeigt nichts an und scheint auf Benutzereingaben zu warten.

Beim Schnüffeln mit wird tsharkangezeigt, dass der zweite Befehl tatsächlich dieselbe HTML-Abfrage sendet und die richtige Antwort empfängt, diese jedoch nicht anzeigt und die Verbindung nicht schließt.

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

Irgendeine Idee, warum dieser Unterschied im Verhalten?

chmeee
quelle

Antworten:

66

Es scheint, dass der Unterschied mit dem Content-LengthHeader zusammenhängt und wie er von beiden Befehlen behandelt wird.

Vorher wird curl -X HEADjedoch keine Ausgabe ausgegeben, da standardmäßig curlkeine Header gedruckt werden, wenn der Schalter -inicht angegeben ist (wird jedoch nicht benötigt -I).

In jedem Fall curl -Iist der richtige Weg, um die Header abzurufen. Es fragt nur nach dem Header und schließt die Verbindung.

Auf der anderen Seite curl -X HEAD -iwird auf die Übertragung der von angegebenen Anzahl von Bytes gewartet Content-Length. Wenn no Content-Lengthnicht angegeben ist, wird es wahrscheinlich auf einige Daten oder auf diesen bestimmten Header warten.

Einige Beispiele, die dieses Verhalten zeigen:

$ 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

Da Content-Length0 ist, verhalten sich in diesem Fall beide Befehle gleich. Und die Verbindung wird danach geschlossen.

$ 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 diesem Fall scheint es eine Zeitüberschreitung zu geben (wahrscheinlich von Varnish), weshalb curlprotestiert wird, dass die Verbindung geschlossen wurde, bevor die Content-LengthAnzahl der Bytes empfangen wurde .

Schauen Sie sich im Übrigen die lustigen X-Bender- (siehe Beispiel) und X-Fry-Header (probieren Sie es selbst aus) an :).

chmeee
quelle
2
Für den Fall, dass jemand anderes danach sucht: Die Option, die in der PHP-Curl-Bibliothek festgelegt wird, ist CURLOPT_NOBODY.
Matthew
12

Ich denke das ist ein Bug in Curl. Wenn ich mit -X eine Methode spezifiziere, sollte curl die Antwort gemäß RFC behandeln. Leider ist der Betreuer von Curl nicht einverstanden. Jemand hat einen Fehler gemeldet und sogar einen Patch eingereicht:

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

aber der Curl-Betreuer lehnte es ab. Anscheinend funktioniert eine kaputte "-X HEAD" -Option "wie geplant".

- Jamshid

Jamshid
quelle
4
Um fair zu sein, kann ich der Logik der Ticketantwort folgen: --headVersieht uns mit einer gültigen Implementierung einer HEAD-Anfrage und -X <method>überschreibt einfach die HTTP-Methode in der Anfrage.
Hank
3
Ja, das war genau das, was ich brauchte. Ich habe einen Buggy-Server, der bei einer HEAD-Anfrage Inhalte bereitstellt. -X HEADNur so konnte ich es testen, als ich versuchte, den Server dazu zu bringen, sich an den RFC zu halten
Hashbrown
5

Aus den Dokumenten :

-X, --anforderung

(HTTP) Gibt eine benutzerdefinierte Anforderungsmethode für die Kommunikation mit dem HTTP-Server an. Die angegebene Anforderungsmethode wird anstelle der anderen Methode verwendet (standardmäßig GET). Weitere Informationen und Erklärungen finden Sie in der HTTP 1.1-Spezifikation. Häufige zusätzliche HTTP-Anforderungen sind PUT und DELETE, verwandte Technologien wie WebDAV bieten jedoch PROPFIND, COPY, MOVE und mehr.

Normalerweise brauchen Sie diese Option nicht. Alle Arten von GET-, HEAD-, POST- und PUT-Anforderungen werden eher über dedizierte Befehlszeilenoptionen aufgerufen.

Diese Option ändert nur das tatsächliche Wort, das in der HTTP-Anforderung verwendet wird, und nicht das Verhalten von Curl . Wenn Sie beispielsweise eine richtige HEAD-Anfrage stellen möchten, reicht die Verwendung von -X HEAD nicht aus. Sie müssen die Option -I, --head verwenden.

Mit anderen Worten, -Xist für andere Verfahren als GET, HEAD, POSTund PUT. Zur HEADVerwendung -I.

x-yuri
quelle
0

Ich treffe das gleiche Problem beim Schreiben von CPP-Code auf Curl 7.34,

curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "HEAD");

wird dort eine lange Zeit hängen, scheint es auf Körperübertragung zu warten, bis eine Auszeit eintritt. Nach dem Hinzufügen einer neuen Zeile ist das Problem behoben.

curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );

aus dem doc

Mach die Download-Anfrage, ohne den Body zu bekommen

Diese Linie würde die Locke zwingen, nicht zu warten.

Dasons
quelle