build-an-http-server / lesson-22.md
Lesson 22 · Building responses

Send a real response

The hand-built reply bytes finally retire - today the connection loop serializes a real Response, so the server speaks proper HTTP with headers and a correct length.

The goal

Have the connection loop build a Response and write its serialized form to the client.

Start here - the target
TO DO
Scenario: The server sends a serialized Response
Giventhe server receives any valid request
Whenit responds
Thenthe response is "HTTP/1.1 200 OK\r\nContent-Length: 13\r\nContent-Type: text/plain\r\n\r\nHello, world!" (headers serialize in sorted order, so Content-Length comes before Content-Type)
Background

Everything the chapter built now runs live. The connection loop stops concatenating strings by hand and instead constructs a Response and calls serialize. The Content-Length is computed, the status line is looked up, the headers are formatted — the server emits fully correct HTTP.

curl -v against it now shows real response headers, and a browser renders the body. From here the body and status stop being constant: the next lessons pick them based on the request, which is what a web server actually does.

Make it work
resp := Response{
Status: 200,
Headers: map[string]string{"Content-Type": "text/plain"},
Body: []byte("Hello, world!"),
}
conn.Write(resp.serialize()) // Content-Length is filled in for you
CheckpointDONE
curl -v shows a proper HTTP/1.1 response with headers and a matching Content-Length. Commit.