Skip to main content

HTTP/1.1: Request/Response, Methods, Status Codes

What This Concept Is

HTTP/1.1 is a text-based, request/response protocol running on top of TCP. One connection carries many request/response pairs (persistent connections), one at a time in order.

A request is:

<method> <request-target> HTTP/1.1\r\n
<header-name>: <header-value>\r\n
<header-name>: <header-value>\r\n
\r\n
<optional body>

A response is:

HTTP/1.1 <status-code> <reason-phrase>\r\n
<header-name>: <header-value>\r\n
...
\r\n
<optional body>

Methods have agreed-on semantics (GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS). Status codes are grouped by first digit: 1xx informational, 2xx success, 3xx redirection, 4xx client error, 5xx server error.

Why It Matters Here

HTTP is the lingua franca of the Internet's application layer: APIs, web pages, webhooks, RPC façades, health checks. Almost everything you will build in later semesters speaks some dialect of HTTP. Reading a raw request on the wire without tooling is a core skill.

It also demonstrates something important: a "complex" protocol can be just bytes of well-formed text, and the protocol itself is decoupled from the transport beneath.

Concrete Example

A minimal request/response exchange over one TCP connection:

GET /hello HTTP/1.1\r\n
Host: example.com\r\n
User-Agent: curl/8.0\r\n
Accept: */*\r\n
\r\n

Response:

HTTP/1.1 200 OK\r\n
Content-Type: text/plain; charset=utf-8\r\n
Content-Length: 13\r\n
Connection: keep-alive\r\n
\r\n
Hello, world!

Same TCP connection, next request:

GET /favicon.ico HTTP/1.1\r\n
Host: example.com\r\n
\r\n

Response:

HTTP/1.1 404 Not Found\r\n
Content-Length: 0\r\n
\r\n

Key things to notice:

  • Headers end with a blank line (\r\n\r\n).
  • Content-Length or Transfer-Encoding: chunked tells the receiver where the body ends.
  • Host is mandatory in HTTP/1.1 -- it is how one IP can serve many domains.

Common Confusion / Misconception

"HTTP is stateless, so it has no sessions." Correct in spirit -- each request is independent -- but cookies, tokens, and server-side session stores layer state on top. The statelessness is about the wire protocol, not about the application.

"HTTP pipelining solves head-of-line blocking." It tried. Pipelining lets a client send request 2 before response 1 arrives, but responses still come back in order, so a slow response stalls everything behind it. This is the pain HTTP/2 and HTTP/3 fix.

How To Use It

For any HTTP exchange:

  1. Identify the method and target (what is being asked).
  2. Read Host and path together to know the resource.
  3. Check Content-Length or Transfer-Encoding for framing.
  4. Look at the status class to know whose fault the outcome is (4xx client, 5xx server).

When designing an endpoint, pick the method and status that fit the semantics, not whatever returns 200.

Check Yourself

  1. Why does HTTP/1.1 require a Host header even when there is only one site on a server?
  2. What is the difference between 404 Not Found and 410 Gone?
  3. Why is POST not safely retriable by default, but PUT usually is?

Mini Drill or Application

  1. Run curl -v https://example.com/ 2>&1 | sed -n '/>/,$p' | head -40.
  2. Identify the request line, each header, and the status line of the response.
  3. Write one short request to a hypothetical DELETE /users/42 endpoint, with the status code you would return for each of: success, user not found, unauthorized, server bug.

Read This Only If Stuck