Je viens de passer de Mavericks à Yosemite, et maintenant curl
ne peut pas 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 à propos des 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 fichier /etc/hosts
, ce qui me permet de développer des applications localement et 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
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?
Alternative (ne nécessite ni Sudo ni la modification du /etc/hosts
) - utilisez toujours ipv4 jusqu'à ce que curl devienne plus intelligent.
$ echo '--ipv4' >> ~/.curlrc
(alors tout fonctionnera comme souhaité)
Tout d'abord, 0.0.0.0
est une adresse spéciale signifiant "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.0
sur 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 la spécification officielle .
La raison en est que curl
tente de résoudre une entrée localhost
aléatoire dans /etc/hosts
et, comme @NickRetallack l'a mentionné, cette entrée est celle choisie par curl
lors de la résolution de localhost
dans son mode par défaut (supposément IPv6 ou IPv4, quelle que soit la solution résolue).
Le forcer en mode --ipv4
, comme @CharlesHebdough le suggère, fera curl
résoudre localhost
en 127.0.0.1
(en supposant qu'il n'y a pas d'autres entrées IPv4 pour localhost
dans /etc/hosts
).
Chaque implémentation résoudra localhost
comme ils le souhaitent, d’où le succès intermittent obtenu avec différents outils.
Pour être le plus précis possible, utilisez 127.0.0.1
au lieu de localhost, mais vous serez lié à IPv4. localhost
vous donne la possibilité de travailler à la fois dans les protocoles IPv6 et IPv4. Cependant, dans certaines implémentations, vous pourriez avoir des problèmes, comme dans cette version spécifique de curl
.