当我猜curl -I http://www.reddit.com会做同样的事情时,我正在看来自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


关于为什么这种行为差异的任何想法吗?

评论

另请参阅daniel.haxx.se/blog/2015/09/11/unnecessary-use-of-curl-x

#1 楼

看来差异与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


在这种情况下,似乎存在超时(可能是Varnish的原因),因此curl抗议连接已关闭,然后再进行连接收到了Content-Length的字节数。

顺便看看有趣的X-Bender(如示例所示)和X-Fry(为自己尝试)标题:)。

评论


万一有人来找这个:在PHP的curl库中设置的选项是CURLOPT_NOBODY。

–马修
2012年7月13日14:39

#2 楼

我认为这是卷曲的错误。如果我用-X指定方法,curl应该根据RFC处理响应。不幸的是,卷曲的维持者不同意。有人提出了一个错误,甚至提交了一个补丁:

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

但是卷曲维护者拒绝了。损坏的“ -X HEAD”选项显然是“按设计方式工作”。

--Jamshid

评论


公平地说,我可以遵循票证响应的逻辑:--head确实为我们提供了HEAD请求的有效实现,并且-X 只是覆盖了请求中的HTTP方法。

–汉克
2014年2月20日在11:07

是的,这实际上是我所需要的。我有一个越野车服务器,当收到HEAD请求时可以提供内容。 -X HEAD是我尝试使服务器遵循RFC时测试它的唯一方法

–棕褐色
17年8月21日在8:13

#3 楼

从docs:

-X,--request
(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适用于GETHEADPOSTPUT以外的方法。对于HEAD,请使用-I

#4 楼

在curl 7.34上编写cpp代码时遇到相同的问题,

curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "HEAD");


会挂在那里很长时间,似乎正在等待身体转移,直到发生超时。
添加新行后,此问题已解决。

curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );


从文档


执行下载请求而无需获取身体


这条线将迫使卷曲不等待。