HTTP and HTTPS

K
Kai··5 min read

DNS gives us the IP, TCP opens the connection — now the client and server talk. On the web, that language is HTTP. It's the application-layer protocol every developer touches daily (APIs, web), so understanding it well pays off. This article dissects HTTP and the "S" part (HTTPS).

What HTTP is

Per MDN, HTTP (HyperText Transfer Protocol) is a client-server protocol for fetching resources. A few core traits:

  • Client-server, request-response: the client sends a request, the server returns a response. The server doesn't send unsolicited.
  • Stateless: each request is independent; the server doesn't remember the previous request on its own. (State like "logged in" is simulated with cookies/tokens — the last section.)
  • Text-based (up to HTTP/1.1): messages are human-readable — which is why we can inspect them with curl -v.

The structure of a request and a response

See a real request/response with curl -v:

curl -v https://example.com
   REQUEST (client → server):        RESPONSE (server → client):
   > GET / HTTP/2                     < HTTP/2 200
   > Host: example.com                < date: Sat, 23 May 2026 ...
   > User-Agent: curl/8.9.1           < content-type: text/html
   > Accept: */*                      <
   >                                  < <!doctype html>...
   (blank line = end of headers)      (blank line, then the body)

(> is a line sent, < is a line received.) The structure:

A request consists of: - Start line: method (GET) + path (/) + version (HTTP/2). - Headers: extra info (Host, User-Agent, Accept...). - Body (optional): data sent up, e.g. with POST.

A response consists of: - Status line: version + status code (200) + message. - Headers: content-type, date... - Body: the content (HTML, JSON...).

HTTP methods

The method says what you want to do with the resource:

   GET      fetch a resource (changes nothing)
   POST     send data up (create, submit a form)
   PUT      replace the entire resource
   PATCH    modify part of the resource
   DELETE   delete the resource
   HEAD     like GET but headers only (no body)
   OPTIONS  ask what the server supports (used in CORS)

This is also the foundation of REST APIs — these are the very methods we used in the AWS/blog series (POST /api/posts, PATCH /api/posts/:id, DELETE...). GET should be safe (no data changes); PUT/DELETE should be idempotent (doing it many times yields the same result as once).

Status codes

The status code in the response tells you the outcome. It splits into 5 groups by the first digit:

   1xx  Informational  100 Continue, 101 Switching Protocols
   2xx  Success        200 OK, 201 Created, 204 No Content
   3xx  Redirection    301 Moved Permanently, 302 Found, 304 Not Modified
   4xx  CLIENT error   400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found
   5xx  SERVER error   500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable

Telling 4xx from 5xx matters enormously when troubleshooting: 4xx = the caller's fault (wrong URL, missing permission, missing parameter), 5xx = the server's fault (buggy code, overloaded server, dead backend). See a 404 → recheck your request; see 500/502 → the problem is on the server.

A real 3xx example: cloudflare.com returns 301 with a location: https://www.cloudflare.com/ header — telling the browser to redirect to the new address:

< HTTP/2 301
< location: https://www.cloudflare.com/

Headers: the info that comes along

Headers are name: value pairs carrying control information. A few common ones:

   Request:                          Response:
   Host: example.com                 Content-Type: text/html
   User-Agent: ...                   Content-Length: 1256
   Accept: application/json          Cache-Control: max-age=3600
   Authorization: Bearer <token>     Set-Cookie: session=...
   Content-Type: application/json    Location: https://...  (for 3xx)

Host lets one IP serve many websites (the server looks at Host to know which site you asked for — called virtual hosting). Content-Type says the data type (text/html, application/json). Authorization carries the API auth token.

HTTP/1.1, 2, 3: ever faster

HTTP evolved mainly to cut latency:

  • HTTP/1.1 — text, basically one request at a time per connection; it added keep-alive to reuse the TCP connection instead of opening a new one each time.
  • HTTP/2 — binary, with multiplexing: many requests/responses in parallel over one TCP connection (no more queuing). This is what curl -v above used (using HTTP/2).
  • HTTP/3 — runs over QUIC (on UDP) instead of TCP (recall Article 6), avoiding TCP's handshake latency and "head-of-line blocking." Servers advertise support via the alt-svc header.

You rarely pick the version by hand (the browser/library negotiates it), but knowing it helps you understand why the web keeps getting faster, and helps you read correctly when troubleshooting.

HTTPS: HTTP plus encryption

Plain HTTP is cleartext — anyone who can wedge into the path (recall ARP spoofing in Article 3) can read/modify it. HTTPS = HTTP running inside an encrypted TLS channel (port 443). It provides three guarantees:

  • Confidentiality: the content is encrypted; a man in the middle can't read it.
  • Integrity: it isn't tampered with in transit.
  • Authentication: you're sure you're talking to the real example.com (via a certificate), not an impostor.

This TLS part — the handshake, certificates, CAs — is the subject of Article 9. The point to keep for now: HTTPS isn't a different protocol; it is HTTP, just wrapped in TLS.

Stateless and cookies

Since HTTP is stateless, how does a website remember "you're logged in"? With cookies: the server sends Set-Cookie: session=abc in the response, the browser stores it and automatically attaches Cookie: session=abc on every subsequent request. The server reads the cookie to recognize you. Tokens (like Authorization: Bearer ... in APIs) are the same idea. This is how "state" is built on a protocol that is inherently stateless.

Wrap-up

HTTP is the web's client-server, request-response, stateless protocol. A request has a method (GET/POST/PUT/DELETE...) + path + headers + body; a response has a status code (2xx OK, 3xx redirect, 4xx client error, 5xx server error) + headers + body. Headers carry control info (Host, Content-Type, Authorization...). HTTP evolved 1.1 → 2 (multiplexing) → 3 (QUIC/UDP) to get faster. HTTPS is HTTP wrapped in TLS for confidentiality/integrity/authentication, and cookies/tokens simulate state. curl -v lets you inspect all of it.

The "S" in HTTPS rests on TLS — the encryption handshake and certificates. Article 9 digs into that.