我正在从http://www.reddit.com看curl -I http://www.reddit.com
I http://www.reddit.com的搞笑服务器types,当我猜测curl -X HEAD http://www.reddit.com
会做相同。 但事实上,事实并非如此。
我很好奇为什么。
这是我观察运行这两个命令:
curl -I
:按预期工作,输出标题并存在。
curl -X HEAD
:不显示任何内容,似乎等待用户input。
但是,用tshark
嗅探我看到第二个命令实际上发送相同的HTML查询并收到正确的答案,但它不显示它,它不会closures连接。
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
任何想法为什么这种行为的差异?
这看起来与Content-Length
标题有什么不同,它是如何处理这两个命令的。
但是在进入之前, curl -X HEAD
不会给出任何输出,因为默认情况下,如果没有提供-i
,则curl
不会打印标题(虽然-I
不需要)。
无论如何, curl -I
是获取标题的正确方法。 它只是要求标题和closures连接。
另一方面, 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,在这种情况下,两个命令的行为都是相同的。 之后连接closures。
$ 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
字节数之前closures。
顺便说一下,看看有趣的X-Bender(示例中显示)和X-Fry(尝试自己)标题:)。
我认为这是一个curl的错误。 如果我用-X指定一个方法,curl应该根据RFC处理响应。 不幸的是,curl的维护者不同意。 有人提出了一个错误,甚至提交了一个补丁:
http://sourceforge.net/tracker/?func=detail&atid=100976&aid=1810273&group_id=976
但卷毛维护者拒绝了它。 显然,一个破碎的“-X HEAD”选项是“按devise工作”。
–Jamshid
从文档 :
-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
。
在curl 7.34上编写cpp代码时遇到同样的问题,
curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "HEAD");
会挂在那里很长一段时间,似乎是等待身体转移,直到超时发生。 在添加新行后,解决此问题。
curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );
从文档
做下载请求没有得到身体
这条线会迫使curl不要等待。