httprustiphost

TCP server reachable via localhost but not 127.0.0.1 or 0.0.0.0 when bind to localhost


I am testing my REST server written in Rust with Httpie.

A http server framework "tide" is used. When the server is told to bind to localhost:3000, Httpie can successfully performed a GET to localhost:3000 but not 0.0.0.0:3000 or 127.0.0.1:3000.

On the contrary, when I bind the server to 0.0.0.0:3000 or 127.0.0.1:3000, Httpie can successfully GET from all 3 addresses.

I have read that localhost usually means bind to all local interfaces.

I would like to know is this a standard/OS/implementation behavior.


Solution

  • When you use a hostname like localhost that uses ToSocketAddrs to:

    yield multiple addresses, bind will be attempted with each of the addresses until one succeeds and returns the listener. If none of the addresses succeed in creating a listener, the error returned from the last attempt (the last address) is returned.

    And localhost can be any number of addresses even across IP versions v4 and v6:

    Therefore binding to localhost or any hostname or domain name and then attempting to connect to a specific IP (with 127.0.0.1) or IP version (with 0.0.0.0 only IPv4) is not valid and might fail if another address was bound.


    Note: async_std (which tide uses internally), tokio and most other async runtimes have own implementations of TcpListener and ToSocketAddrs but they are usually described as "async versions of the std counterpart" so this explanation holds for them as well.