Skip to content
The Request Line
step 1/5

Reading — step 1 of 5

Read

~3 min readConnection & Parsing

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: get is 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 versionHTTP/1.1 in this course. The exact grammar HTTP/<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 Request either 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 is 400; 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…