在 Mac OS X Yosemite 上 Curl 本地主机名

在 Mac OS X Yosemite 上 Curl 本地主机名

我刚刚从 Mavericks 升级到 Yosemite,现在curl看不到环回主机名。

设置一个简单的http服务器进行测试:

$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

现在我可以在 chrome 中访问 localhost:8000。我甚至可以使用 wget 获取它。但在 curl 中,会发生这种情况:

$ curl localhost:8000
curl: (7) Failed to connect to localhost port 8000: Connection refused

但是,这是有效的:

$ curl 127.0.0.1:8000

我读关于 wget 代理设置的这个答案,但这没有帮助,因为这是有效的:

$ wget --proxy=off localhost:8000

这真的令人沮丧,因为我的文件中列出了几个不同的环回主机名,/etc/hosts所以我可以在本地开发应用程序,并且我习惯用 curl 来调试它们。

我已经尝试过 osx 附带的 curl 版本:

$ curl --version
curl 7.37.1 (x86_64-apple-darwin14.0) libcurl/7.37.1 SecureTransport zlib/1.2.5
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IPv6 Largefile NTLM NTLM_WB SSL libz

$ curl localhost:8000
curl: (7) Failed to connect to localhost port 8000: Connection refused

$ curl 127.0.0.1 # works

我已经尝试使用 brew 编译 curl:

$ /usr/local/Cellar/curl/7.38.0/bin/curl --version
curl 7.38.0 (x86_64-apple-darwin14.0.0) libcurl/7.38.0 SecureTransport zlib/1.2.5
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: IPv6 Largefile NTLM NTLM_WB SSL libz

$ /usr/local/Cellar/curl/7.38.0/bin/curl localhost:8000
curl: (7) Failed to connect to localhost port 8000: Connection refused

$ /usr/local/Cellar/curl/7.38.0/bin/curl 127.0.0.1:8000 # works

答案1

我只需从 /etc/hosts 文件中注释掉其中一个 IPv6 环回行即可使其正常工作:

#fe80::1%lo0    localhost

现在我的所有环回主机名都可以正常工作,而不仅仅是 localhost。我想知道这是怎么回事?

答案2

选择(不需要 sudo 或修改/etc/hosts- 始终使用 ipv4 直到 curl 变得更智能。

$ echo '--ipv4' >> ~/.curlrc

(然后一切都会按预期进行)

答案3

首先,0.0.0.0是一个特殊地址,意思是“任何 IPv4 地址”。

套接字可以绑定到 IPv4 或 IPv6 协议。如果套接字绑定到0.0.0.0,则意味着它将侦听任何尝试连接到它的 IPv4,并将按以下方式表示:

$ nc -l 0.0.0.0 8085
$ lsof -i4 -Pnl | grep 8085
  nc        23994 [xxx]    3u  IPv4 [xxx]      0t0  TCP *:8085 (LISTEN)

*标志相当于0.0.0.0IPv4上的。

对于 IPv6:

$ nc -l :: 8085
$ lsof -i6 -Pnl | grep 8085
  nc        24145 [xxx]    3u  IPv6 [xxx]      0t0  TCP *:8085 (LISTEN)

*标志相当于::在 IPv6 上,按照官方规范

原因是curl尝试解析为localhost中的随机条目/etc/hosts,并且正如@NickRetallack 提到的,该条目是在默认模式下curl解析时选择的条目localhost(假设是 IPv6 或 IPv4,无论哪个先解析)。

正如@CharlesHebdough 所建议的那样,强制进入--ipv4模式,将解决curl(假设没有其他 IPv4 条目)。localhost127.0.0.1localhost/etc/hosts

每个实施都会localhost按照他们的意愿解决,这就是为什么您可以使用不同的工具获得间歇性的成功。

为了尽可能精确,请使用127.0.0.1而不是 localhost,但它会将您绑定到 IPv4。localhost为您提供了在 IPv6 和 IPv4 协议中工作的灵活性,但是在某些实现中您可能会遇到麻烦,例如在特定版本的 中curl

相关内容