web-dev-qa-db-ja.com

「curl -I」と「curl -X HEAD」の違い

curl -I http://www.reddit.comが同じことをすると思ったとき、私は http://www.reddit.com からcurl -X HEAD http://www.reddit.comで面白いサーバータイプを監視していました。しかし、実際にはそうではありません。

なぜだろう。

これは、2つのコマンドの実行を観察したものです。

  • curl -I:期待どおりに動作し、ヘッダーを出力して存在します。

  • curl -X HEAD:何も表示せず、ユーザー入力を待機しているようです。

しかし、tsharkでスニッフィング2番目のコマンドが実際に同じ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

なぜこの動作の違いについての考えはありますか?

75
chmeee

違いは、Content-Lengthヘッダーと、両方のコマンドでどのように処理されるかと関係があるようです。

ただし、その前に、curl -X HEADは出力を提供しません。デフォルトでは、スイッチ-iが提供されていない場合、curlはヘッダーを出力しません(-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

この場合、タイムアウトの可能性があります(おそらくVarnishによる)ため、curlは、Content-Lengthバイト数を受信する前に接続が閉じられたことに抗議します。

ちなみに、おもしろいX-Bender(例に示されています)とX-Fry(自分で試してみてください)ヘッダーを見てください。

68
chmeee

これはカールのバグだと思います。 -Xでメソッドを指定した場合、curlはRFCに従って応答を処理する必要があります。残念ながら、curlのメンテナは同意しません。誰かがバグを報告し、パッチを提出しました:

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

しかし、カール管理者はそれを拒否しました。壊れた「-X HEAD」オプションは「設計どおりに機能している」ようです。

-ジャムシッド

12
jamshid

the docs から:

-X、-request

(HTTP)HTTPサーバーと通信するときに使用するカスタム要求メソッドを指定します。指定された要求メソッドは、他の方法で使用されるメソッド(デフォルトではGET)の代わりに使用されます。詳細と説明については、HTTP 1.1仕様をお読みください。一般的な追加のHTTPリクエストにはPUTとDELETEが含まれますが、WebDAVなどの関連テクノロジーはPROPFIND、COPY、MOVEなどを提供します。

通常、このオプションは必要ありません。すべての種類のGET、HEAD、POSTおよびPUT要求は、専用のコマンドラインオプションを使用して呼び出されます。

このオプションは、HTTPリクエストで使用される実際のWordのみを変更します。これはcurlの動作を変更しません。たとえば、適切なHEADリクエストを作成する場合、-X HEADを使用しても十分ではありません。-I、--headオプション。

つまり、-XGETHEADPOSTおよびPUT以外のメソッド用です。 HEADの場合は-Iを使用します。

6
x-yuri

Curl 7.34でcppコードを書くときに同じ問題に遭遇します、

curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "HEAD");

長い間そこでハングアップしますが、タイムアウトが発生するまでボディ転送を待機しているようです。新しい行を追加すると、この問題は解決されます。

curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );

from the doc

本文を取得せずにダウンロードリクエストを実行する

この行は、カールが待機しないように強制します。

0
dasons