Acabo de actualizar de Mavericks a Yosemite y ahora curl
no puedo ver los nombres de host del loopback.
Configure un servidor http simple para probar:
$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
Ahora puedo acceder a localhost:8000 en Chrome. Incluso puedo entenderlo. Pero en curl sucede esto:
$ curl localhost:8000
curl: (7) Failed to connect to localhost port 8000: Connection refused
Sin embargo, esto funciona:
$ curl 127.0.0.1:8000
Yo leoesta respuesta sobre la configuración del proxy wget, pero no ayudó, porque esto funciona:
$ wget --proxy=off localhost:8000
Esto es realmente frustrante, porque tengo algunos nombres de host de bucle invertido diferentes enumerados en mi /etc/hosts
archivo para poder desarrollar aplicaciones localmente y estoy acostumbrado a depurarlas con curl.
Lo intenté con la versión de curl que viene con 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
Y intenté compilar curl con cerveza:
$ /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
Respuesta1
Lo hice funcionar comentando una de las líneas de loopback IPv6 de mi archivo /etc/hosts:
#fe80::1%lo0 localhost
Ahora todos mis nombres de host de loopback funcionan, no solo localhost. Me pregunto ¿qué pasa con esto?
Respuesta2
Alternativa(no requiere sudo ni modificación/etc/hosts
)- Utilice siempre ipv4 hasta que curl se vuelva más inteligente.
$ echo '--ipv4' >> ~/.curlrc
(entonces todo funcionará como se desea)
Respuesta3
En primer lugar, 0.0.0.0
hay una dirección especial que significa "cualquier dirección IPv4".
Un socket puede vincularse al protocolo IPv4 o IPv6. Si un socket está vinculado a 0.0.0.0
, eso significa que escuchará cualquier IPv4 que intente conectarse a él y se representará de la siguiente manera:
$ nc -l 0.0.0.0 8085
$ lsof -i4 -Pnl | grep 8085
nc 23994 [xxx] 3u IPv4 [xxx] 0t0 TCP *:8085 (LISTEN)
El *
signo equivale a 0.0.0.0
IPv4.
Para IPv6:
$ nc -l :: 8085
$ lsof -i6 -Pnl | grep 8085
nc 24145 [xxx] 3u IPv6 [xxx] 0t0 TCP *:8085 (LISTEN)
El *
signo equivale a::
en IPv6,como en la especificación oficial.
La razón es que curl
intenta resolverse localhost
en una entrada aleatoria /etc/hosts
y, como mencionó @NickRetallack, esa entrada es la elegida cuando curl
se resuelve localhost
en su modo predeterminado (supuestamente IPv6 o IPv4, lo que se resuelva primero).
Forzarlo en --ipv4
modo, como sugirió @CharlesHebdough, resolverá curl
( suponiendo localhost
que 127.0.0.1
no haya otras entradas IPv4 para localhost
in /etc/hosts
).
Cada implementación se resolverá localhost
como desee, de ahí que haya tenido éxito intermitente con diferentes herramientas.
Para ser lo más preciso posible, utilícelo 127.0.0.1
en lugar de localhost, pero lo vinculará a IPv4. localhost
le brinda la flexibilidad de trabajar en protocolos IPv6 e IPv4; sin embargo, en algunas implementaciones puede tener problemas, como en esa versión específica de curl
.