Sự khác biệt giữa `curl -I` và` curl -X HEAD`


70

Tôi đã xem các loại máy chủ hài hước từ http://www.reddit.com với curl -I http://www.reddit.comkhi tôi đoán rằng curl -X HEAD http://www.reddit.comsẽ làm như vậy. Nhưng, trên thực tế, nó không.

Tôi tò mò về lý do tại sao.

Đây là những gì tôi quan sát thấy khi chạy hai lệnh:

  • curl -I: hoạt động như mong đợi, xuất ra tiêu đề và tồn tại.

  • curl -X HEAD: không hiển thị bất cứ điều gì và dường như chờ đợi đầu vào của người dùng.

Nhưng, đánh hơi với tsharktôi thấy lệnh thứ hai thực sự gửi cùng một truy vấn HTML và nhận được câu trả lời đúng, nhưng nó không hiển thị và nó không đóng kết nối.

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

Bất kỳ ý tưởng về lý do tại sao sự khác biệt trong hành vi này?


Câu trả lời:


66

Có vẻ như sự khác biệt phải làm với Content-Lengthtiêu đề và cách nó được xử lý bởi cả hai lệnh.

Nhưng trước khi đi vào điều đó, curl -X HEADkhông đưa ra bất kỳ đầu ra nào vì theo mặc định, curlkhông in các tiêu đề nếu công tắc -ikhông được cung cấp ( -Imặc dù không cần thiết ).

Trong mọi trường hợp, curl -Ilà cách thích hợp để lấy các tiêu đề. Nó chỉ yêu cầu tiêu đề và đóng kết nối.

Mặt khác, curl -X HEAD -isẽ chờ truyền số lượng byte được nêu bởi Content-Length. Trong trường hợp không Content-Lengthđược chỉ định, tôi đoán nó sẽ đợi một số dữ liệu hoặc cho tiêu đề cụ thể đó.

Một số ví dụ cho thấy hành vi này:

$ 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-Lengthlà 0 nên trong trường hợp này cả hai lệnh đều hoạt động giống nhau. Và kết nối được đóng lại sau đó.

$ 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

Trong trường hợp này, dường như có một khoảng thời gian chờ (có thể là do Varnish), vì vậy curlphản đối rằng kết nối đã bị đóng trước khi nhận được Content-Lengthsố byte.

Nhân tiện, hãy nhìn vào các tiêu đề X-Bender vui nhộn (hiển thị trong ví dụ) và các tiêu đề X-Fry (tự mình thử) :).


2
Trong trường hợp bất kỳ ai khác tìm kiếm điều này: tùy chọn để đặt trong thư viện curl của PHP là CURLOPT_NOBODY.
Matthew

12

Tôi nghĩ rằng đây là một lỗi trong curl. Nếu tôi chỉ định một phương thức với -X, curl sẽ xử lý phản hồi theo RFC. Thật không may, người duy trì curl không đồng ý. Ai đó đã gửi một lỗi và thậm chí gửi một bản vá:

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

nhưng người duy trì curl đã từ chối nó. Rõ ràng một tùy chọn "-X Head" bị hỏng là "hoạt động như thiết kế".

--Jamshid


4
Để công bằng, tôi có thể tuân theo logic của phản hồi vé: --headkhông cung cấp cho chúng tôi triển khai hợp lệ yêu cầu CHÍNH và -X <method>chỉ cần ghi đè phương thức HTTP trong yêu cầu.
Hank

3
vâng, đây thực sự là những gì tôi cần. Tôi có một máy chủ lỗi phục vụ nội dung khi được yêu cầu CHÍNH. -X HEADlà cách duy nhất tôi có thể kiểm tra nó khi cố gắng để máy chủ tuân thủ RFC
Hashbrown

5

Từ các tài liệu :

-X, - yêu cầu

(HTTP) Chỉ định phương thức yêu cầu tùy chỉnh để sử dụng khi giao tiếp với máy chủ HTTP. Phương thức yêu cầu đã chỉ định sẽ được sử dụng thay cho phương thức được sử dụng khác (mặc định là GET). Đọc đặc tả HTTP 1.1 để biết chi tiết và giải thích. Các yêu cầu HTTP bổ sung phổ biến bao gồm PUT và DELETE, nhưng các công nghệ liên quan như WebDAV cung cấp PROPFIND, COPY, DI CHUYỂN và hơn thế nữa.

Thông thường bạn không cần tùy chọn này. Tất cả các loại yêu cầu GET, HEAD, POST và PUT được gọi bằng cách sử dụng các tùy chọn dòng lệnh chuyên dụng.

Tùy chọn này chỉ thay đổi từ thực tế được sử dụng trong yêu cầu HTTP, nó không thay đổi cách hành xử của curl . Vì vậy, ví dụ nếu bạn muốn thực hiện một yêu cầu CHÍNH thích hợp, sử dụng -X HEAD sẽ không đủ. Bạn cần sử dụng tùy chọn -I, --head.

Nói cách khác, -Xlà cho các phương pháp khác hơn là GET, HEAD, POSTPUT. Để HEADsử dụng -I.


0

Tôi gặp vấn đề tương tự khi viết mã cpp trên curl 7.34,

curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "HEAD");

sẽ treo ở đó rất lâu, dường như nó đang chờ chuyển cơ thể cho đến khi hết thời gian. Sau khi thêm một dòng mới, vấn đề này được giải quyết.

curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );

từ tài liệu

làm yêu cầu tải xuống mà không nhận được cơ thể

dòng này sẽ buộc curl không chờ đợi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.