HTTP & HTTPS Fundamentals
HTTP (HyperText Transfer Protocol) is the foundation of web communication. HTTPS = HTTP over TLS — the same protocol but encrypted. Understanding the protocol is essential for debugging, API design, and performance optimization.
HTTP Versions
HTTP/1.1 (1997): persistent connections, pipelining (rarely used), text-based headers, one request at a time per connection → head-of-line blocking
HTTP/2 (2015): binary protocol, multiplexing (multiple concurrent requests per connection), header compression (HPACK), server push (deprecated), requires HTTPS in practice
HTTP/3 (2022): uses QUIC over UDP instead of TCP — eliminates TCP head-of-line blocking, faster connection establishment (0-RTT), better on lossy networks (mobile)
Request Structure
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbG...
Accept: application/json
Accept-Encoding: gzip, deflate, br
User-Agent: MyApp/1.0
{"name": "Alice", "email": "alice@example.com"}Response Structure
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Location: /api/users/42
Cache-Control: no-cache
X-Request-Id: abc123
{"id": 42, "name": "Alice"}HTTP Methods & Semantics
Method | Safe | Idempotent | Body | Use Case
--------|------|------------|------|----------------------------------
GET | ✓ | ✓ | no | Retrieve resource
HEAD | ✓ | ✓ | no | GET without body (check headers)
OPTIONS | ✓ | ✓ | no | CORS preflight, capability check
POST | ✗ | ✗ | yes | Create resource, trigger action
PUT | ✗ | ✓ | yes | Replace resource (full update)
PATCH | ✗ | ✗* | yes | Partial update
DELETE | ✗ | ✓ | no | Remove resource
Safe: no side effects on server state
Idempotent: same result if called multiple times
*PATCH idempotency depends on implementationStatus Codes
2xx Success
200 OK — Standard success
201 Created — Resource created (include Location header)
204 No Content — Success, no body (DELETE, some PUT)
206 Partial Content — Range requests (file downloads)
3xx Redirection
301 Moved Permanently — SEO-friendly, cached by browsers
302 Found — Temporary redirect (don't cache)
304 Not Modified — Client cache is valid, no body
307 Temporary Redirect — Same as 302, preserves method (POST stays POST)
308 Permanent Redirect — Same as 301, preserves method
4xx Client Errors
400 Bad Request — Invalid syntax, validation failed
401 Unauthorized — Not authenticated (login required)
403 Forbidden — Authenticated but not authorized
404 Not Found — Resource doesn't exist
405 Method Not Allowed — Wrong HTTP method
409 Conflict — State conflict (e.g., duplicate)
410 Gone — Resource permanently deleted
422 Unprocessable Entity — Semantic validation error (JSON is valid, but...)
429 Too Many Requests — Rate limiting
5xx Server Errors
500 Internal Server Error — Generic server error
502 Bad Gateway — Upstream server issue
503 Service Unavailable — Server down, retry later (add Retry-After header)
504 Gateway Timeout — Upstream timeoutHTTP Caching
Cache-Control: public, max-age=86400, stale-while-revalidate=3600
public — cacheable by CDN and browser
private — browser only (not CDN) — for user-specific responses
no-store — never cache (sensitive data)
no-cache — cache but revalidate on every request
max-age=N — seconds until stale
s-maxage=N — CDN-specific max-age (overrides max-age for shared caches)
immutable — never revalidate (for content-hashed assets)
stale-while-revalidate=N — serve stale while fetching fresh in background
ETag + 304 conditional requests:
Server: ETag: "abc123"
Client: If-None-Match: "abc123"
Server: 304 Not Modified (empty body)
Last-Modified + conditional requests:
Server: Last-Modified: Wed, 01 Jan 2025 00:00:00 GMT
Client: If-Modified-Since: Wed, 01 Jan 2025 00:00:00 GMT
Server: 304 Not ModifiedCORS (Cross-Origin Resource Sharing)
// Simple request: GET/HEAD/POST with safe Content-Types
// No preflight needed
// Preflight request (sent for non-simple requests like PUT, DELETE, custom headers)
// Browser sends OPTIONS first:
// Origin: https://myapp.com
// Access-Control-Request-Method: DELETE
// Access-Control-Request-Headers: Authorization
// Server must respond:
// Access-Control-Allow-Origin: https://myapp.com
// Access-Control-Allow-Methods: GET, POST, PUT, DELETE
// Access-Control-Allow-Headers: Authorization, Content-Type
// Access-Control-Max-Age: 86400 (cache preflight for 1 day)
// For authenticated requests (cookies/Authorization header):
// Client: credentials: 'include' in fetch
// Server must set: Access-Control-Allow-Credentials: true
// AND Access-Control-Allow-Origin must be a specific origin (not *)
// Node.js/Express example
app.use((req, res, next) => {
const allowedOrigins = ['https://myapp.com', 'https://staging.myapp.com'];
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
}
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization');
if (req.method === 'OPTIONS') return res.sendStatus(204);
next();
});Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free