COMPUTER NETWORKS / 5. HTTP & HTTPS

HTTP & HTTPS — The Language of the Web

Request-response protocol, headers, methods, status codes, TLS


EXPLANATION

HTTP (HyperText Transfer Protocol) is the application-layer protocol the web is built on. Every API call, webpage load, and file download is an HTTP transaction.

HTTP is stateless — each request is independent. The server remembers nothing between requests. State is managed externally via cookies, sessions, or JWTs.

HTTP Request structure:
• Request Line: METHOD /path HTTP/1.1
• Headers: key-value pairs (Host, Content-Type, Authorization, Accept…)
• Blank line (CRLF)
• Body (optional — for POST/PUT/PATCH)

HTTP Methods (verbs):
• GET → retrieve a resource. No body. Safe (no side effects) + Idempotent (same result repeatedly)
• POST → create a resource or trigger an action. Has body. Neither safe nor idempotent
• PUT → replace entire resource. Idempotent
• PATCH → partial update. Not necessarily idempotent
• DELETE → remove resource. Idempotent
• HEAD → like GET but response has no body (used to check if resource exists)
• OPTIONS → returns allowed methods (used in CORS preflight)

Status codes:
• 1xx Informational: 100 Continue
• 2xx Success: 200 OK, 201 Created, 204 No Content, 206 Partial Content
• 3xx Redirect: 301 Moved Permanently, 302 Found, 304 Not Modified
• 4xx Client Error: 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 405 Method Not Allowed, 409 Conflict, 422 Unprocessable Entity, 429 Too Many Requests
• 5xx Server Error: 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout

HTTP versions:
• HTTP/1.0 → one request per TCP connection (slow, new handshake each time)
• HTTP/1.1 → persistent connections (keep-alive), pipelining, chunked transfer
• HTTP/2 → multiplexing (multiple requests on one connection simultaneously), header compression (HPACK), binary frames, server push
• HTTP/3 → runs on UDP via QUIC (Google protocol), eliminates TCP head-of-line blocking, faster connection establishment

HTTPS = HTTP + TLS (Transport Layer Security). TLS provides:
• Encryption → data is unreadable in transit (symmetric encryption after handshake)
• Authentication → you're talking to the real server (server certificate, signed by CA)
• Integrity → data wasn't tampered with (MAC — message authentication code)
TLS Handshake: ClientHello → ServerHello + Certificate → Key Exchange → Finished. After this, all communication is encrypted with symmetric keys derived from the handshake.

DIAGRAM

HTTP REQUEST:
  GET /api/users/42 HTTP/1.1

  Host: api.example.com

  Authorization: Bearer eyJ...

  Accept: application/json

  

  (no body for GET)

  HTTP RESPONSE:
  HTTP/1.1 200 OK

  Content-Type: application/json

  Content-Length: 45

  Cache-Control: max-age=300

  

  {"id":42,"username":"kamran","email":"k@nii.ac.in"}

  TLS HANDSHAKE:
  Client                            Server
    │── ClientHello (TLS ver, ciphers)→│
    │←─ ServerHello + Certificate ──│
    │   (verify cert against CA)       │
    │── Key Exchange (pre-master) ───→│
    │   Both derive session keys        │
    │── Finished ───────────────────→│
    │←─ Finished ────────────────────│
    │═══ Encrypted HTTP traffic ════│

CODE

PYTHON
1import httpx
2import asyncio
3
4# ── Basic HTTP requests with httpx ────────────────────
5def http_demo():
6 with httpx.Client() as client:
7 # GET
8 r = client.get("https://httpbin.org/get", params={"foo": "bar"})
9 print(f"GET Status: {r.status_code}")
10 print(f"Headers: {dict(r.headers)}")
11
12 # POST with JSON body
13 r = client.post(
14 "https://httpbin.org/post",
15 json={"name": "Kamran", "role": "developer"},
16 headers={"Authorization": "Bearer fake-token"},
17 )
18 print(f"POST Status: {r.status_code}")
19 print(f"Body sent: {r.json()['json']}")
20
21 # Check redirect chain
22 r = client.get("http://google.com", follow_redirects=True)
23 print(f"
24Redirects: {[str(h.url) for h in r.history]}")
25 print(f"Final URL: {r.url}")
26
27http_demo()
28
29# ── Async HTTP (concurrent requests) ──────────────────
30async def async_http():
31 async with httpx.AsyncClient() as client:
32 urls = [
33 "https://httpbin.org/delay/1",
34 "https://httpbin.org/uuid",
35 "https://httpbin.org/ip",
36 ]
37 # All 3 fire concurrently — total ~1s, not ~3s
38 results = await asyncio.gather(*[client.get(url) for url in urls])
39 for url, r in zip(urls, results):
40 print(f"{url.split('/')[-1]:10s} {r.status_code}")
41
42asyncio.run(async_http())
43
44# ── Inspect HTTP/2 ────────────────────────────────────
45with httpx.Client(http2=True) as client:
46 r = client.get("https://www.cloudflare.com")
47 print(f"
48Protocol: HTTP/{r.http_version}")
49 print(f"HSTS: {r.headers.get('strict-transport-security', 'not set')}")
← PREV4. DNS — The Internet's Phone BookNEXT →6. Sockets & WebSockets