Curl de nombres de host locales en Mac OS X Yosemite

Curl de nombres de host locales en Mac OS X Yosemite

Acabo de actualizar de Mavericks a Yosemite y ahora curlno 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/hostsarchivo 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.0hay 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.0IPv4.

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 curlintenta resolverse localhosten una entrada aleatoria /etc/hostsy, como mencionó @NickRetallack, esa entrada es la elegida cuando curlse resuelve localhosten su modo predeterminado (supuestamente IPv6 o IPv4, lo que se resuelva primero).

Forzarlo en --ipv4modo, como sugirió @CharlesHebdough, resolverá curl( suponiendo localhostque 127.0.0.1no haya otras entradas IPv4 para localhostin /etc/hosts).

Cada implementación se resolverá localhostcomo desee, de ahí que haya tenido éxito intermitente con diferentes herramientas.

Para ser lo más preciso posible, utilícelo 127.0.0.1en lugar de localhost, pero lo vinculará a IPv4. localhostle 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.

información relacionada