Різниця між `curl -I` та` curl -X HEAD`


70

Я спостерігав тип забавну сервера з http://www.reddit.com з , curl -I http://www.reddit.comколи я зрозумів , що curl -X HEAD http://www.reddit.comбуде робити те ж саме. Але насправді це не так.

Мені цікаво чому.

Це те, що я спостерігаю за виконанням двох команд:

  • curl -I: працює як очікувалося, виводить заголовок і існує.

  • curl -X HEAD: нічого не показує і, здається, чекає введення користувача.

Але, обнюхуючи, tsharkя бачу, що друга команда фактично надсилає той самий HTML-запит і отримує правильну відповідь, але це не показує, і це не закриває з'єднання.

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

Будь-яке уявлення про те, чому така різниця в поведінці?


Відповіді:


66

Здається, різниця пов’язана із Content-Lengthзаголовком та способом поводження з обома командами.

Але перед тим, як переходити до цього, curl -X HEADне дає жодного виводу, оскільки за замовчуванням curlне друкує заголовки, якщо комутатор -iне передбачений (не потрібен на -Iхоч).

У будь-якому випадку, curl -Iце правильний спосіб отримання заголовків. Це просто попросити заголовок і закрити з'єднання.

З іншого боку, curl -X HEAD -iбуде чекати передачі кількості байтів, зазначених Content-Length. У випадку, коли номер Content-Lengthне вказано, я думаю, він буде чекати деяких даних або для цього конкретного заголовка.

Деякі приклади, що показують таку поведінку:

$ 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

Оскільки Content-Lengthце 0, в цьому випадку обидві команди ведуть себе однаково. І зв’язок після цього закритий.

$ 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

У цьому випадку, здається, є час очікування (можливо, Варніш), тому curlпротестує, що з'єднання було закрито, перш ніж отримати Content-Lengthкількість байтів.

До речі, подивіться на смішні заголовки X-Bender (показані на прикладі) та заголовки X-Fry (спробуйте самі) :).


2
Якщо хтось шукає цього: можливість встановити в бібліотеці curl PHP є CURLOPT_NOBODY.
Метью

12

Я думаю, це помилка в завитку. Якщо я задаю метод з -X, curl повинен обробляти відповідь відповідно до RFC. На жаль, утримувач локон не погоджується. Хтось подав помилку і навіть надіслав патч:

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

але утримувач завивки відхилив це. Мабуть, зламаний варіант "-X HEAD" - це "працює так, як було розроблено".

- Джамшид


4
Справедливо кажучи, я можу дотримуватися логіки відповіді на отримання квитка: --headчи дає нам дійсну реалізацію запиту HEAD і -X <method>просто перекриває метод HTTP у запиті.
Хенк

3
так, це було власне те, що мені було потрібно. У мене є сервер-баггі, який обслуговує вміст, коли йому подається запит HEAD. -X HEADце був єдиний спосіб, коли я міг це перевірити, намагаючись примусити сервер дотримуватися RFC
Hashbrown

5

З документів :

-X, --запит

(HTTP) Вказує спеціальний метод запиту, який слід використовувати під час спілкування з HTTP-сервером. Зазначений метод запиту використовуватиметься замість використовуваного способу (який за замовчуванням GET). Прочитайте специфікацію HTTP 1.1 для отримання детальної інформації та пояснень. Загальні додаткові HTTP-запити включають PUT та DELETE, але такі технології, як WebDAV, пропонують PROPFIND, COPY, MOVE та багато іншого.

Зазвичай ця опція вам не потрібна. Усі види запитів GET, HEAD, POST та PUT викликаються за допомогою спеціальних параметрів командного рядка.

Ця опція змінює лише фактичне слово, яке використовується у запиті HTTP, воно не змінює поводження curl . Так, наприклад, якщо ви хочете зробити належний запит HEAD, використання -X HEAD буде недостатньо. Вам потрібно скористатися опцією -I, --head.

Іншими словами, -Xдля інших , ніж методи GET, HEAD, POSTі PUT. Для HEADвикористання -I.


0

Я зустрічаюся з тією ж проблемою, коли пишуть cpp-код на curl 7.34

curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "HEAD");

буде довго висіти там, здається, чекає на перенесення тіла, поки не відбудеться тайм-аут. після додавання нового рядка це питання вирішується.

curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );

від док

виконайте запит на завантаження, не отримуючи тіло

ця лінія змусить завиток не чекати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.