Różnica między `curl -I` a` curl -X HEAD`

70

I było oglądać śmieszne typ serwera z http://www.reddit.com ze curl -I http://www.reddit.comkiedy przypuszczał, że curl -X HEAD http://www.reddit.comzrobi to samo. Ale tak nie jest.

Jestem ciekawy dlaczego.

Oto, co obserwuję, uruchamiając dwa polecenia:

  • curl -I: działa zgodnie z oczekiwaniami, wyświetla nagłówek i istnieje.

  • curl -X HEAD: nic nie pokazuje i wydaje się czekać na dane wejściowe użytkownika.

Ale węsząc z tshark, widzę, że drugie polecenie faktycznie wysyła to samo zapytanie HTML i otrzymuje poprawną odpowiedź, ale nie pokazuje go i nie zamyka połączenia.

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

Masz pojęcie o tym, dlaczego ta różnica w zachowaniu?

chmeee
źródło

Odpowiedzi:

66

Wygląda na to, że różnica dotyczy Content-Lengthnagłówka i sposobu, w jaki są traktowane przez oba polecenia.

Ale przed przejściem do tego curl -X HEADnie daje żadnych wyników, ponieważ domyślnie curlnie drukuje nagłówków, jeśli przełącznik -inie jest dostępny ( -Ichoć nie jest potrzebny ).

W każdym razie curl -Ijest to właściwy sposób na pobranie nagłówków. Wystarczy poprosić o nagłówek i zamknąć połączenie.

Z drugiej strony curl -X HEAD -ibędzie czekać na przesłanie liczby bajtów podanej przez Content-Length. W przypadku, gdy Content-Lengthnie podano nie, chyba będzie czekać na jakieś dane lub na ten konkretny nagłówek.

Kilka przykładów pokazujących to zachowanie:

$ 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

Ponieważ Content-Lengthwynosi 0, w tym przypadku oba polecenia zachowują się tak samo. Połączenie zostaje następnie zamknięte.

$ 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

W tym przypadku wydaje się, że upłynął limit czasu (prawdopodobnie przez Varnish), więc curlprotestuje, że połączenie zostało zamknięte przed otrzymaniem Content-Lengthliczby bajtów.

Nawiasem mówiąc, spójrz na zabawne nagłówki X-Bender (pokazane w przykładzie) i X-Fry (spróbuj sam) nagłówki :).

chmeee
źródło
2
Na wypadek, gdyby ktoś inny tego szukał: istnieje opcja ustawienia w bibliotece curl PHP CURLOPT_NOBODY.
Matthew
12

Myślę, że to błąd w zwijaniu. Jeśli podam metodę z -X, curl powinien obsłużyć odpowiedź zgodnie z RFC. Niestety opiekun curl się nie zgadza. Ktoś zgłosił błąd, a nawet przesłał łatkę:

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

ale opiekun loków odrzucił to. Najwyraźniej zepsuta opcja „-X HEAD” działa „zgodnie z przeznaczeniem”.

- Jamshid

jamshid
źródło
4
Aby być uczciwym, mogę postępować zgodnie z logiką odpowiedzi na bilet: --headzapewnia nam prawidłową implementację żądania HEAD i -X <method>po prostu zastępuje metodę HTTP w żądaniu.
Hank
3
tak, właśnie tego potrzebowałem. Mam błędny serwer, który wyświetla treść po otrzymaniu żądania HEAD. -X HEADbył to jedyny sposób, w jaki mogłem to przetestować, próbując zmusić serwer do przestrzegania RFC
Hashbrown
5

Z dokumentów :

-X, - zapytanie

(HTTP) Określa niestandardową metodę żądania, która ma być używana podczas komunikacji z serwerem HTTP. Podana metoda żądania zostanie użyta zamiast innej metody (domyślnie GET). Przeczytaj specyfikację HTTP 1.1, aby uzyskać szczegółowe informacje i objaśnienia. Typowe dodatkowe żądania HTTP obejmują PUT i DELETE, ale powiązane technologie, takie jak WebDAV, oferują PROPFIND, COPY, MOVE i inne.

Zwykle nie potrzebujesz tej opcji. Wszystkie rodzaje żądań GET, HEAD, POST i PUT są raczej wywoływane przy użyciu dedykowanych opcji wiersza poleceń.

Ta opcja zmienia tylko rzeczywiste słowo użyte w żądaniu HTTP, nie zmienia zachowania curl . Na przykład, jeśli chcesz złożyć prawidłowe żądanie HEAD, użycie -X HEAD nie wystarczy. Musisz użyć opcji -I, --head.

Innymi słowy, -Xjest dla metod innych niż GET, HEAD, POSTi PUT. Do HEADużytku -I.

x-yuri
źródło
0

Ten sam problem występuje podczas pisania kodu CPP w curl 7.34,

curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "HEAD");

zawiesi się tam długo, wygląda na to, że czeka na przeniesienie ciała, aż dojdzie do limitu czasu. po dodaniu nowej linii problem został rozwiązany.

curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );

z dokumentu

wykonaj żądanie pobierania bez pobierania treści

ta linia zmusiłaby curl do nie czekania.

pory roku
źródło