Not every client sends valid HTTP, and a broken request should get a clean 400 rather than a dropped connection. Today you turn the parse errors you have been raising into a real response.
Respond with 400 Bad Request when the request cannot be parsed.
Your parser has been returning errors since chapter two — a request line without
three tokens, a missing Host, a bad header — but the connection loop ignored
them. Now it handles them: a parse error becomes a 400 Bad Request response
instead of a crash or a hang.
This is the server’s contract with the outside world. The internet is full of
malformed and malicious input, and answering it with a well-formed 400 (rather
than dropping the connection) is what separates a robust server from a fragile
one. Every guard you built earlier now has a visible effect.
req, err := parseRequest(r)if err != nil {conn.Write(Response{Status: 400, Body: []byte("Bad Request")}.serialize())return}