Perbedaan antara `curl -I` dan` curl -X HEAD`

70

Saya menonton jenis server lucu dari http://www.reddit.com dengan curl -I http://www.reddit.comketika saya kira itu curl -X HEAD http://www.reddit.comakan melakukan hal yang sama. Tetapi kenyataannya tidak.

Saya ingin tahu mengapa.

Inilah yang saya amati menjalankan dua perintah:

  • curl -I: berfungsi seperti yang diharapkan, menampilkan tajuk dan ada.

  • curl -X HEAD: tidak menunjukkan apa-apa dan tampaknya menunggu input pengguna.

Tapi, mengendus dengan tsharksaya melihat perintah kedua sebenarnya mengirimkan permintaan HTML yang sama dan menerima jawaban yang benar, tetapi tidak menunjukkannya dan tidak menutup koneksi.

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

Adakah yang tahu mengapa perbedaan perilaku ini?

chmeee
sumber

Jawaban:

66

Tampaknya perbedaannya ada pada Content-Lengthheader dan bagaimana diperlakukan oleh kedua perintah.

Tapi sebelum masuk ke sana, curl -X HEADtidak memberikan output apa pun karena, secara default, curltidak mencetak header jika saklar -itidak disediakan (tidak diperlukan -Imeskipun).

Bagaimanapun, curl -Iadalah cara yang tepat untuk mengambil header. Hanya meminta header dan menutup koneksi.

Di sisi lain curl -X HEAD -iakan menunggu pengiriman jumlah byte yang dinyatakan oleh Content-Length. Dalam hal tidak Content-Lengthada tidak ditentukan, saya kira itu akan menunggu beberapa data atau untuk header tertentu.

Beberapa contoh yang menunjukkan perilaku ini:

$ 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

Karena Content-Length0, dalam hal ini kedua perintah berperilaku sama. Dan koneksi ditutup setelahnya.

$ 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

Dalam hal ini, tampaknya ada batas waktu (mungkin oleh Varnish), jadi curlprotes bahwa koneksi ditutup sebelum menerima Content-Lengthjumlah byte.

Omong-omong, lihat header X-Bender yang lucu (ditunjukkan pada contoh) dan X-Fry (coba sendiri) :).

chmeee
sumber
2
Jika ada orang lain yang mencari ini: opsi untuk diatur di pustaka curl PHP adalah CURLOPT_NOBODY.
Matius
12

Saya pikir ini adalah bug di curl. Jika saya menentukan metode dengan -X, curl harus menangani respons sesuai dengan RFC. Sayangnya, pengelola curl tidak setuju. Seseorang mengajukan bug dan bahkan mengirimkan tambalan:

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

tapi pengelola ikal menolaknya. Rupanya opsi "-X HEAD" yang rusak adalah "berfungsi seperti yang dirancang".

- Jamshid

jamshid
sumber
4
Agar adil, saya bisa mengikuti logika respons tiket: --headapakah memberi kami implementasi yang valid dari permintaan HEAD, dan -X <method>cukup mengganti metode HTTP dalam permintaan.
Hank
3
ya, ini sebenarnya yang saya butuhkan. Saya memiliki server kereta yang menyajikan konten ketika diberikan permintaan HEAD. -X HEADadalah satu-satunya cara saya bisa mengujinya ketika mencoba untuk mendapatkan server untuk mematuhi RFC
Hashbrown
5

Dari dokumen :

-X, --request

(HTTP) Menentukan metode permintaan khusus untuk digunakan saat berkomunikasi dengan server HTTP. Metode permintaan yang ditentukan akan digunakan alih-alih metode yang digunakan (yang standarnya adalah GET). Baca spesifikasi HTTP 1.1 untuk detail dan penjelasan. Permintaan HTTP tambahan umum termasuk PUT dan DELETE, tetapi teknologi terkait seperti WebDAV menawarkan PROPFIND, COPY, MOVE dan banyak lagi.

Biasanya Anda tidak membutuhkan opsi ini. Segala macam permintaan GET, HEAD, POST dan PUT agak dipanggil dengan menggunakan opsi baris perintah khusus.

Opsi ini hanya mengubah kata aktual yang digunakan dalam permintaan HTTP, itu tidak mengubah cara curl berperilaku . Jadi misalnya jika Anda ingin membuat permintaan HEAD yang tepat, menggunakan -X HEAD tidak akan cukup. Anda perlu menggunakan opsi -I, --head.

Dengan kata lain, -Xadalah untuk metode selain GET, HEAD, POSTdan PUT. Untuk HEADpenggunaan -I.

x-yuri
sumber
0

Saya bertemu masalah yang sama ketika menulis kode cpp pada curl 7.34,

curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "HEAD");

akan bertahan lama di sana, sepertinya sedang menunggu transfer tubuh sampai timeout terjadi. setelah menambahkan baris baru, masalah ini teratasi.

curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );

dari doc

lakukan permintaan unduhan tanpa mendapatkan tubuh

baris ini akan memaksa curl untuk tidak menunggu.

alasan
sumber