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.
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 bind
ing 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.