4.3.24 · D5Computer Networks

Question bank — HTTP - 1.1 — methods, status codes, headers, persistent connections

1,526 words7 min readBack to topic

True or false — justify

Each answer is the reason, not a bare verdict — say your justification before revealing.

HTTP is stateless, so a server can never remember who you are.
False — the protocol carries no memory between requests, but Cookie:/Set-Cookie: headers rebuild identity on top, so state lives in the application not the transport.
On a persistent connection, "read until the socket closes" still works fine.
False — the socket deliberately stays open for reuse, so there is no close to mark the end; you must read exactly Content-Length bytes or follow chunked framing.
GET is safe because it has no request body.
False — safety is the semantic promise of no side effects; a body-less request that still mutated data would break the contract, so the body's absence is a symptom, not the cause.
PUT and DELETE are both idempotent.
True — repeating "set the resource to this" or "remove this resource" lands on the same final state as doing it once, so retries after a lost reply are safe.
Connection: keep-alive is required in HTTP/1.1 to keep the socket open.
False — persistence is the default in 1.1, so that header is a 1.0 relic; in 1.1 you only ever add Connection: close to opt out.
A 200 response guarantees the operation you asked for actually succeeded.
False for POST/PUT — 200 means the HTTP exchange succeeded, but application-level failure can still be reported inside a 200 body; the status describes the protocol, not always your business logic.
Every HTTP response must contain a body.
False — 204 No Content, 304 Not Modified, and responses to HEAD carry no body by design; the blank line ends the message.
Pipelining removes head-of-line blocking.
False — pipelining sends requests back-to-back but responses must come back in order, so one slow response still stalls everyone behind it; only HTTP-2 multiplexing truly fixes this at the HTTP layer.
Host: is optional as long as one IP serves only one domain.
False — 1.1 makes it mandatory regardless; the parser and Virtual hosting logic depend on it always being present, so omitting it is a 400 Bad Request.

Spot the error

Each line contains one concrete mistake — name it, then reveal.

"404 means the server has crashed and can't respond."
The server did respond — 404 is a 4xx client error meaning the requested resource does not exist; a crash would surface as 5xx.
"Send Connection: keep-alive in HTTP/1.1 or the connection closes after one request."
In 1.1 the connection persists by default; the header changes nothing here and its absence does not force a close.
"A response ends when we hit a blank \r\n\r\n line."
The blank line ends the headers, not the response — after it comes the body, whose length is fixed by Content-Length or chunked encoding.
"Since GET is idempotent, POST must be too."
POST is neither safe nor idempotent — repeating it can create duplicate resources (two orders, two comments), which is why browsers warn before resubmitting.
"Content-Length counts characters in the body."
It counts bytes, not characters — a multi-byte UTF-8 character (e.g. an emoji) is several bytes, so character count would misframe the message.
"HEAD returns the resource but omits the status line."
HEAD returns the full status line and headers exactly like GET; it only omits the body, so you can check size/freshness cheaply.
"Use Transfer-Encoding: chunked together with Content-Length for extra safety."
These are two mutually exclusive framing schemes — sending both is a conflict, and a strict parser treats it as an error/security risk (request smuggling).
"A 301 and a 302 mean the same thing, just different numbers."
301 says permanently moved (clients and caches may update their links); 302 says temporarily moved (keep using the original URL next time) — the caching consequences differ.

Why questions

The answer must give the mechanism, not restate the question.

Why did HTTP/1.1 make persistent connections the default?
Each new TCP connection costs a TCP three-way handshake (one RTT) plus TCP slow start ramping bandwidth slowly, so reusing one socket amortizes those startup costs across many requests.
Why does persistence force explicit message framing?
With the socket kept open there is no connection-close to mark "body finished," so the receiver needs Content-Length (exact byte count) or chunked encoding to know where one response ends and the next begins.
Why is the Host header essential for Virtual hosting?
One IP address can serve many domains, and the TCP layer only knows the IP; Host: is the only place the request names which site it wants.
Why does slow-network latency make persistence more valuable, not less?
The saving is roughly for resources, so it scales with RTT — high-latency links (mobile, satellite) benefit most.
Why can Transfer-Encoding: chunked stream a body the server can't measure in advance?
Chunked encoding sends the body in size-prefixed pieces ending with a zero-length chunk, so the server never needs the total length up front — perfect for generated or streamed content.
Why does head-of-line blocking exist even with pipelining?
HTTP/1.1 requires responses in request order on a single connection, so a slow first response holds back every ready response queued behind it.
Why is 304 Not Modified faster than re-downloading?
The client sends its cached validator (If-None-Match with the ETag); if unchanged the server returns a tiny bodyless 304 and the client reuses its local copy instead of transferring bytes.
Why does HTTP run on top of TCP rather than sending bytes directly?
TCP provides ordered, reliable, error-checked delivery, so HTTP can assume its text arrives intact and in sequence and focus only on request/response semantics.

Edge cases

Boundary and degenerate scenarios — cover the case, not just the rule.

What frames the body of a 204 No Content response?
Nothing needs framing — there is no body by definition, so the message ends at the blank line and the connection stays free for the next request.
On a keep-alive connection, what happens after the last expected response if the server wants to close?
It sends Connection: close in that final response's headers, signalling the client to read this body then treat the socket as closed after it.
If a persistent request has no Content-Length and no chunked encoding on a POST body, what breaks?
The server cannot tell where the body ends versus the next request begins, so it either hangs waiting or misparses — an ambiguous frame, often a 400.
What does an idempotent retry protect you from when a reply is lost mid-flight?
You can safely resend a PUT or DELETE without fear of a second effect, because the final state after two identical calls equals the state after one.
Is a request with zero headers (only a start line and blank line) ever valid in 1.1?
No — Host: is mandatory in 1.1, so at minimum one header must be present or the server returns 400 Bad Request.
What status class covers 503 Service Unavailable, and who is at fault?
5xx — a server error meaning the server is temporarily unable to handle the request (overload, maintenance); the client's request was well-formed.
Can a single persistent connection carry requests to two different domains?
Only if they resolve to the same server and the server accepts it; each request still needs its own Host: header, and TLS/certificate constraints usually pin the connection to one origin.

Recall One-line self-test

Cover the answers. If you can state the mechanism for "why does persistence force framing?" and "why is 404 a client error?" in one breath each, you've cleared the two traps this topic invites most. Why does persistence force framing? ::: No close-to-signal-end, so Content-Length or chunked draws the boundary. Why is 404 a client error not a crash? ::: The server answered fine; the resource asked for is missing — crashes are 5xx.