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 了。我什至可以得到它。但在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,無論先解析哪一個)。

--ipv4正如 @CharlesHebdough 所建議的那樣,強制其進入模式將curl解析localhost為(假設in127.0.0.1沒有其他 IPv4 條目)。localhost/etc/hosts

每個實施都會localhost按照他們的意願解決,這就是為什麼你使用不同的工具時斷時續地取得成功的原因。

為了盡可能準確,請使用127.0.0.1localhost 代替,但它會將您綁定到 IPv4。localhost使您可以靈活地在 IPv6 和 IPv4 協定中工作,但是在某些實作中您可能會遇到麻煩,例如在curl.

相關內容