build-an-http-server / lesson-33.md
Lesson 33 · Robust & concurrent

Keep the connection alive

HTTP/1.1 connections are persistent - a client can send several requests down one connection. Today you loop on a connection, answering request after request instead of closing after one.

The goal

Read and answer multiple requests on a single connection until the client stops sending.

Start here - the target
TO DO
Scenario: Two requests on one connection
Givenone connection on which the client sends two complete GET "/" requests back to back
Whenthe server handles the connection
Thenit sends two responses on that same connection, one per request
Andit closes the connection only when the client stops sending (the reader reaches end of input)
Background

Under HTTP/1.1 a connection is persistent by default: opening a fresh TCP connection per request is wasteful, so a client sends several requests down the same one and reads back several responses in order. Your handler must therefore loop, parsing and answering requests until the client is done.

The loop ends when the reader hits end of input — the client closed its side — which surfaces as an EOF from the parser. Because you always wrote an accurate Content-Length, each response’s boundary is unambiguous, so the next request starts cleanly right after the previous body.

Make it work
r := bufio.NewReader(conn)
for {
req, err := parseRequest(r)
if err == io.EOF { break } // client closed; nothing more to read
conn.Write(handle(req).serialize())
}
CheckpointDONE
The server answers several requests on one persistent connection. Commit.