Curl des noms d’hôtes locaux sur Mac OS X Yosemite

30

Je viens de passer de Mavericks à Yosemite et je curlne peux plus voir les noms d’hôte en boucle.

Configurez un serveur http simple pour tester:

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

Maintenant, je peux frapper localhost: 8000 en chrome. Je peux même y aller. Mais en boucle, cela se produit:

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

Cependant, cela fonctionne:

$ curl 127.0.0.1:8000

J'ai lu cette réponse sur les paramètres de proxy wget , mais cela n'a pas aidé, car cela fonctionne:

$ wget --proxy=off localhost:8000

Cela est vraiment frustrant, car plusieurs noms d’hôte de bouclage différents sont répertoriés dans mon /etc/hostsfichier, ce qui me permet de développer des applications localement, et j’ai l’habitude de les déboguer avec curl.

J'ai essayé avec la version de curl fournie avec 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

Et j'ai essayé de compiler curl with brasser:

$ /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
la source
J'ai rencontré un problème similaire lors du test d'une application node.js. J'ai vu que le débogage de ce noeud indiquait qu'il était lié à 0.0.0.0 et j'ai essayé 'curl -4 localhost ...' et cela a fonctionné, mais sans le -4 cela a échoué. Il apparaît que l'adresse IPv6 est en cours de résolution depuis / etc / hosts avant celle d'IPv4.
Néant
J'ai le même problème que vous avez décrit Nick.
nerdburn

Réponses:

36

Je viens de le faire fonctionner en commentant l'une des lignes de bouclage IPv6 de mon fichier / etc / hosts:

#fe80::1%lo0    localhost

Maintenant, tous mes noms d’hôte en boucle fonctionnent, pas seulement localhost. Je me demande ce qui se passe avec ça?

Nick Retallack
la source
J'avais ça et ça m'a aidé aussi. Je ne sais pas quel est le problème avec cette ligne; il semble que mon système l’ait depuis avant Yosemite.
Mislav
Merci beaucoup. Je me demande cependant pourquoi, au fond, il privilégie l’IPv6 pour le périphérique de bouclage par rapport à l’IPv4. Cela a seulement commencé à se produire pour moi sur Yosemite.
lukecampbell
24

Alternative (ne nécessite ni sudo ni modification /etc/hosts) - utilisez toujours ipv4 jusqu'à ce que curl devienne plus intelligent.

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

(alors tout fonctionnera comme souhaité)

Charles Hebdough
la source
Merci - ce problème me rendait dingue, mais votre solution a parfaitement fonctionné.
Kyle Fox
2

Tout d’abord, 0.0.0.0une adresse spéciale signifie "toute adresse IPv4".

Un socket peut être lié au protocole IPv4 ou IPv6. Si un socket est lié à 0.0.0.0, cela signifie qu'il écoutera tout IPv4 essayant de s'y connecter et sera représenté comme suit:

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

Le *signe est équivalent à 0.0.0.0sur IPv4.

Pour IPv6:

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

Le *signe est équivalent à ::sur IPv6, comme dans les spécifications officielles .

La raison en est que curltente de résoudre une localhostentrée aléatoire /etc/hosts, et comme @NickRetallack l'a mentionné, cette entrée est celle choisie par curllors de la résolution localhostdans son mode par défaut (supposément IPv6 ou IPv4, quelle que soit la résolution précédente).

Forcing en --ipv4mode comme suggéré @CharlesHebdough, fera curldétermination localhostà 127.0.0.1( en supposant qu'il n'y a pas d' autres entrées IPv4 pour localhosten /etc/hosts).

Chaque mise en œuvre se résoudra localhostcomme ils le souhaitent, d’où votre succès intermittent avec différents outils.

Pour être le plus précis possible, utilisez 127.0.0.1plutôt lieu de localhost, mais vous serez lié à IPv4. localhostvous donne la possibilité de travailler à la fois dans les protocoles IPv6 et IPv4. Toutefois, dans certaines implémentations, vous pourriez rencontrer des problèmes, comme dans cette version spécifique de curl.

Jose Alban
la source