Search code examples
scalarustiron

Curl can connect to an Iron server on localhost, but Scala intermittently cannot


In my Rust app, I start Iron like so:

let host: &str = &format!("localhost:{}", port);
info!("Server running at http://{}", host);
Iron::new(Chain::new(router)).http(host).expect("Could not start Iron server");

It responds:

INFO Server running at http://localhost:3000

I can curl it:

$ curl "http://localhost:3000/v1/foo"
{"bar":"baz"}

However, in Scala I cannot connect:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_40).
Type in expressions for evaluation. Or try :help.

scala> scala.io.Source.fromURL("http://localhost:3000/v1/foo").mkString
java.net.ConnectException: Connection refused
  at java.net.PlainSocketImpl.socketConnect(Native Method)

spray-client also cannot connect:

spray.can.Http$ConnectionAttemptFailedException: Connection attempt to 127.0.0.1:3000 failed

Both of these attempts are from the same IP and localhost is correct. The Iron server logs nothing on a failed connection request.

Different combinations of localhost vs 127.0.0.1 in both client and server do not fix the problem. I misdiagnosed this. Using 127.0.0.1 in the Rust client does fix the problem.

After taking a break, the code started working. I don't recall if I restarted Iron. I then did several hours of development against it. At some stage it stopped working again. Restarts of the JVM and/or Iron server are not helping to fix the issue.

This is not specific to my Rust app;

I can recreate the problem with the example hello world Iron app.

$ git clone https://github.com/iron/iron.git
$ (cd iron && cargo run --example hello)

and then

$ curl "http://localhost:3000/"
Hello world!

but

$ scala
scala> scala.io.Source.fromURL("http://localhost:3000/").mkString
java.net.ConnectException: Connection refused
  • OSX 10.11.6
  • cargo 0.13.0-nightly (9399229 2016-09-14)
  • also tested against cargo 0.13.0-nightly (19cfb67 2016-09-28)

Solution

  • According to this comment on this bug report, "Iron will resolve ('localhost') to IPv6 by default while your other services use IPv4"

    Bind Iron to 127.0.0.1 whilst that bug is unresolved.