Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Keep-Alive Connections

In HTTP/1.0, a new TCP connection was opened for every single request. The client would send a request, the server would send a response, and then the server would immediately close the TCP connection.

This was incredibly slow because TCP requires a 3-way handshake to establish a connection. If a webpage needed 50 images, it required 50 separate handshakes!

HTTP/1.1 introduced Persistent Connections (often called Keep-Alive) to solve this.

According to RFC 9112 Section 9.3:

HTTP/1.1 defaults to the use of “persistent connections”, allowing multiple requests and responses to be carried over a single connection.

By default, a server must NOT close the connection after sending a response. It should keep the connection open and wait for the client to send another request.

What about Connection: keep-alive?

You might have seen headers like Connection: keep-alive or Keep-Alive: timeout=5 in the wild.

In the older HTTP/1.0 protocol, connections were closed by default. To keep a connection open, clients had to explicitly send a Connection: keep-alive header.

However, in HTTP/1.1, persistent connections are the default. This means Connection: keep-alive is technically redundant (though many browsers still send it for backwards compatibility). Unless the client or server explicitly sends a Connection: close header, you should assume the connection remains open.

The Keep-Alive header (which provides timeout hints) is also an older extension and is not strictly required by the modern HTTP/1.1 spec. You do not need to parse or send these headers for this stage!

Your Task

Ensure your server keeps the connection open after sending a response.

The tester will open a single connection and send two separate HTTP requests sequentially over that same connection. Your server must respond to both of them.

Tip

You can implement this by wrapping your connection handling logic in a continuous loop! Just be sure to detect when the client closes the connection (typically when reading from the socket returns 0 bytes, or an EOF signal is received). Once that happens, you should safely break out of the loop and clean up.


Important

Run the below docker command to test your solution.

docker run \
  --rm \
  --add-host host.docker.internal:host-gateway \
  codeberg.org/level0/buildit/http-server:latest \
  --addr host.docker.internal:8080 \
  --until keep_alive