Curl nama host lokal di Mac OS X Yosemite

30

Saya baru saja meningkatkan dari Mavericks ke Yosemite, dan sekarang curltidak dapat melihat nama host loopback.

Siapkan server http sederhana untuk menguji:

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

Sekarang saya dapat menekan localhost: 8000 di chrome. Aku bahkan bisa melupakannya. Tetapi dalam ikal, ini terjadi:

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

Namun, ini berfungsi:

$ curl 127.0.0.1:8000

Saya membaca jawaban ini tentang pengaturan proxy wget , tetapi tidak membantu, karena ini berfungsi:

$ wget --proxy=off localhost:8000

Ini benar-benar membuat frustrasi, karena saya memiliki beberapa nama host loopback berbeda yang tercantum dalam /etc/hostsfile saya sehingga saya dapat mengembangkan aplikasi secara lokal, dan saya terbiasa men-debug mereka dengan curl.

Saya sudah mencoba dengan versi curl yang disertakan dengan osx:

$ 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

Dan saya sudah mencoba mengkompilasi ikal dengan minuman:

$ /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
Nick Retallack
sumber
Saya mengalami masalah serupa menguji aplikasi node.js. Saya melihat bahwa debugging simpul mengatakan itu mengikat ke 0.0.0.0, dan mencoba 'curl -4 localhost ...' dan berhasil, tetapi tanpa -4 gagal. Tampaknya alamat IPv6 sedang diselesaikan dari / etc / hosts sebelum IPv4.
Neth
Saya memiliki masalah yang sama dengan yang Anda jelaskan pada Nick.
nerdburn

Jawaban:

36

Saya baru saja bekerja dengan mengomentari salah satu baris loopback IPv6 dari file / etc / hosts saya:

#fe80::1%lo0    localhost

Sekarang semua nama host loopback saya berfungsi, bukan hanya localhost. Aku ingin tahu ada apa dengan ini?

Nick Retallack
sumber
Saya memilikinya dan itu membantu saya juga. Saya tidak tahu apa masalahnya dengan garis itu; itu melihat sistem saya memilikinya dari sebelum Yosemite.
mislav
Terima kasih banyak. Saya bertanya-tanya, mengapa pada intinya itu mendukung IPv6 untuk perangkat loopback melalui IPv4. Ini baru mulai terjadi pada saya di Yosemite.
lukecampbell
24

Alternatif (tidak memerlukan sudo atau modifikasi /etc/hosts) - selalu gunakan ipv4 sampai curl menjadi lebih pintar.

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

(maka semuanya akan berfungsi seperti yang diinginkan)

Charles Hebdough
sumber
Terima kasih - masalah ini membuat saya gila, tetapi solusi Anda bekerja dengan sempurna.
Kyle Fox
2

Pertama-tama, 0.0.0.0adalah alamat khusus yang berarti "alamat IPv4".

Soket dapat diikat ke protokol IPv4 atau IPv6. Jika soket terikat 0.0.0.0, itu berarti ia akan mendengarkan IPv4 yang mencoba menyambungkannya, dan akan ditampilkan sebagai berikut:

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

The *tanda setara dengan 0.0.0.0di IPv4.

Untuk IPv6:

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

The *tanda setara dengan ::pada IPv6, seperti pada spesifikasi resmi .

Alasannya adalah bahwa curlmencoba untuk menyelesaikan localhostentri acak /etc/hosts, dan seperti yang disebutkan @NickRetallack, entri tersebut adalah yang dipilih curlsaat menyelesaikan localhostdalam mode default-nya (diasumsikan IPv6 atau IPv4, apa pun yang diselesaikan terlebih dahulu).

Memaksakannya dalam --ipv4mode, seperti yang disarankan @CharlesHebdough, akan membuat curltekad localhostuntuk 127.0.0.1(dengan asumsi tidak ada entri IPv4 lain untuk localhostmasuk /etc/hosts).

Setiap implementasi akan diselesaikan localhostsesuai keinginan, maka dari itu mengapa Anda memiliki kesuksesan yang terputus-putus dengan alat yang berbeda.

Agar seakurat mungkin, gunakan 127.0.0.1alih-alih localhost, tetapi itu akan mengikat Anda ke IPv4. localhostmemberi Anda fleksibilitas untuk bekerja di kedua protokol IPv6 dan IPv4, namun dalam beberapa implementasi Anda mungkin mengalami masalah, seperti dalam versi spesifik IPv6 curl.

Jose Alban
sumber