:gen_tcp.recv() take long time to return

Hi! I’m trying implement a HTTP client using erlang library :gen_tcp and the section of code that should recover packet from socket are take too long time to return. My function is:

def request(url) do
    %{host: host, port: port, path: path} = get_information(url)
    {:ok, ipadress} = :inet.getaddr(String.to_charlist(host), :inet)
    {:ok, socket} = :gen_tcp.connect(ipadress, port, [:binary, active: false])

    :ok = :gen_tcp.send(socket, "GET #{path} HTTP/1.1")

    {:ok, response} = :gen_tcp.recv(socket, 0)

    {:ok, Response.process(response)}
 end

I run the lines above in IEx in this way: request("http://localhost:4000") and :gen_tcp.recv(socket, 0) takes seconds to return. To test my code I did a simple HTTP server in Node exactly like this:

const http = require("http");

const server = http.createServer((req, res) => {
 
  if (req.method === "GET" && req.url === "/") {
    res.statusCode = 200;
    res.setHeader("Content-Type", "text/plain");
    res.end("Hello, world!");
    return;
  }

  if (req.method === "GET" && req.url === "/user") {
    res.statusCode = 200;
    res.setHeader("Content-Type", "text/json");
    res.setHeader("X-Request-Id", "01");
    const user = {
      name: "João",
      age: 30,
      id: 15,
    };
    res.end(JSON.stringify(user));
    return;
  }
});

server.listen(4000, () => {
  console.log("Server is running on port 4000");
});

After many seconds waiting from :gen_tcp.recv(socket, 0), I receive this: {:ok, "HTTP/1.1 408 Request Timeout\r\nConnection: close\r\n\r\n"}

Somebody has any ideas about this issue?

Thanks!

I believe you need to close the writing side of the socket with :gen_tcp.shutdown(socket, :write) before being able to read the response.

1 Like

Try with

:ok = :gen_tcp.send(socket, "GET #{path} HTTP/1.1\r\n\r\n")
5 Likes

Exactly that, the message in original post is only partial HTTP request as it has no ending, so server waits for the rest until it times out.

2 Likes

This solved my problem. Thanks!

I miss-typed the \n, thank you very much! Didn’t know it has a real purpose on the :gen_tpc, oh well