Reading — step 1 of 5
Read
The Request Line
HTTP looks like magic until you see what actually crosses the wire — and then it looks like text. That's the protocol's superpower: every request your browser has ever sent begins with one human-readable line, and this lesson teaches you to parse it with the paranoia of a real server, because the wire is where hostile input lives.
What the bytes actually are
Connect to any web server and a request begins:
GET /search?q=redis HTTP/1.1\r\n
One line, three parts, single spaces between, terminated by CRLF (\r\n — carriage return + line feed):
- Method — the verb:
GET(fetch),POST(submit),PUT,DELETE,HEAD(GET without the body),OPTIONS. Methods are case-sensitive by spec:getis not a method; a real server answers it with an error, not charity. - Request-target — usually a path, possibly with a query:
/search?q=redis. Just an opaque string at this stage; routing (next chapter) gives it meaning. - HTTP version —
HTTP/1.1in this course. The exact grammarHTTP/<digit>.<digit>— anything else is malformed.
CRLF: the terminator that bites
HTTP's line ending is \r\n, always — a telegraph-era inheritance shared with SMTP and FTP. The two bugs it causes are rites of passage: splitting on \n alone leaves a stray \r glued to the end of your parsed version string (invisible in logs, fails every comparison — when "HTTP/1.1" != "HTTP/1.1", this is why); and writing responses with bare \n makes strict clients reject you. Handle both directions: tolerate nothing less than CRLF when parsing (malformed input is an error, not a shrug), emit exact CRLF when building.
Parse like a server, not like a demo
The demo version is split(' ') and hope. The server version enforces the grammar, because every violation is either a broken client or an attack probe:
- Exactly three parts. Two spaces means an extra field or a space smuggled into the target —
400 Bad Requesteither way. (Extra spaces have been used in real request-smuggling attacks; strictness here is security, not pedantry.) - Method from the known list — unknown method is
501, lowercase is400; your spec fixes the exact mapping. - Target must start with
/(for the origin form this course handles). - Version string exact.
HTTP/1.2?505.HTP/1.1?400.
The posture to internalize on lesson one: a parser's job is to reject, and only incidentally to accept. Every later stage — headers, body, routing — trusts what this stage let through. Web security lives or dies at these boundaries.
Your exercise: Parse Request Lines
Raw request lines in; either the parsed (method, target, version) triple or the correct rejection out, per the spec's format. The test ladder is the paranoia checklist: valid GET → valid POST with query → lowercase method → missing part → extra spaces → bad version → missing CRLF handling. Ten lines of splitting, twenty of validation — the correct ratio, now and forever. By the end you'll read GET / HTTP/1.1 the way musicians read notation, and you'll know that the browser devtools "Network" tab is just this text, prettified.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…