Skip to content

HTTP & HTTPS

HTTP (HyperText Transfer Protocol) is the application-layer protocol that powers the web. Every time you open a web page, call an API, or submit a form, you are using HTTP. Understanding HTTP deeply is one of the most practically valuable skills a software engineer can develop, as it directly impacts API design, debugging, performance optimization, and security.


HTTP Versions: Evolution of the Protocol

HTTP has evolved significantly since its inception. Each version addressed limitations of its predecessor.

HTTP/1.1 vs HTTP/2 vs HTTP/3

FeatureHTTP/1.1 (1997)HTTP/2 (2015)HTTP/3 (2022)
TransportTCPTCPQUIC (UDP-based)
MultiplexingNo (one request per connection)Yes (multiple streams over one connection)Yes
Head-of-line blockingYes (at HTTP and TCP level)Solved at HTTP level, persists at TCP levelFully solved
Header compressionNoneHPACKQPACK
Server pushNoYesYes
Connection setupTCP handshake + TLS handshakeSame as HTTP/1.10-RTT or 1-RTT (faster)
Text/BinaryText-basedBinary framingBinary framing
PrioritizationN/AStream prioritizationImproved prioritization
HTTP/1.1 — Sequential requests on separate connections:
Client ──GET /page──────────────────────► Server
Client ◄────────────────── 200 OK ─────── Server
Client ──GET /style.css─────────────────► Server
Client ◄────────────────── 200 OK ─────── Server
Client ──GET /script.js─────────────────► Server
Client ◄────────────────── 200 OK ─────── Server
HTTP/2 — Multiplexed streams on a single connection:
Client ═══ Stream 1: GET /page ═══════►
═══ Stream 2: GET /style.css ══► Server
═══ Stream 3: GET /script.js ══►
Client ◄══ Stream 1: 200 OK ══════════
◄══ Stream 3: 200 OK ══════════ Server
◄══ Stream 2: 200 OK ══════════

When to use each:

  • HTTP/1.1: Legacy systems, simple APIs, environments where HTTP/2 is not supported
  • HTTP/2: Modern web applications, APIs serving multiple resources (enabled by default in most browsers and servers)
  • HTTP/3: Low-latency applications, mobile users on unreliable networks, where connection migration matters

HTTP Request/Response Structure

Every HTTP transaction consists of a request from the client and a response from the server.

Request Structure

POST /api/users HTTP/1.1 ← Request line (method, path, version)
Host: api.example.com ← Headers
Content-Type: application/json
Authorization: Bearer eyJhbGciOi...
Accept: application/json
Content-Length: 52
← Blank line separates headers from body
{"name": "Alice", "email": "a@b.com"} ← Request body

Response Structure

HTTP/1.1 201 Created ← Status line (version, code, reason)
Content-Type: application/json ← Headers
Location: /api/users/42
Cache-Control: no-cache
X-Request-Id: abc-123-def
Content-Length: 89
← Blank line separates headers from body
{"id": 42, "name": "Alice", ← Response body
"email": "a@b.com",
"created_at": "2025-01-15T10:30:00Z"}

HTTP Methods

HTTP defines several methods (also called verbs) that indicate the desired action to be performed on a resource.

MethodPurposeRequest BodyIdempotentSafeCacheable
GETRetrieve a resourceNoYesYesYes
POSTCreate a new resource or trigger an actionYesNoNoConditional
PUTReplace a resource entirelyYesYesNoNo
PATCHPartially update a resourceYesNot guaranteedNoNo
DELETERemove a resourceOptionalYesNoNo
HEADSame as GET but returns headers onlyNoYesYesYes
OPTIONSDescribe communication options (CORS preflight)NoYesYesNo

Key definitions:

  • Idempotent: Making the same request multiple times produces the same result. PUT /users/42 with the same body always results in the same state. POST /users may create duplicates.
  • Safe: The method does not modify the resource. GET and HEAD are safe — they only read data.

Method Usage Examples

# CRUD operations on a "users" resource
GET /api/users → List all users
GET /api/users/42 → Get user with ID 42
POST /api/users → Create a new user
PUT /api/users/42 → Replace user 42 entirely
PATCH /api/users/42 → Update specific fields of user 42
DELETE /api/users/42 → Delete user 42
HEAD /api/users/42 → Check if user 42 exists (headers only)
OPTIONS /api/users → Get allowed methods and CORS info

HTTP Status Codes

Status codes are 3-digit numbers in the response that indicate the result of the request. They are grouped into five categories.

1xx: Informational

The request was received, and the server is continuing to process it.

CodeNameDescription
100ContinueClient should continue with the request body
101Switching ProtocolsServer is switching to a different protocol (e.g., WebSocket upgrade)
103Early HintsAllows preloading resources while the server prepares the final response

2xx: Success

The request was successfully received, understood, and accepted.

CodeNameDescription
200OKStandard success response for GET, PUT, PATCH, DELETE
201CreatedResource was successfully created (response to POST)
202AcceptedRequest accepted for processing but not yet complete (async operations)
204No ContentSuccess with no response body (common for DELETE)

3xx: Redirection

The client needs to take additional action to complete the request.

CodeNameDescription
301Moved PermanentlyResource has permanently moved to a new URL (cacheable)
302FoundTemporary redirect (historically ambiguous, prefer 307)
304Not ModifiedResource has not changed since last request (use cached version)
307Temporary RedirectSame as 302 but preserves the HTTP method
308Permanent RedirectSame as 301 but preserves the HTTP method

4xx: Client Error

The request contains an error or cannot be fulfilled due to client-side issues.

CodeNameDescription
400Bad RequestMalformed request syntax or invalid parameters
401UnauthorizedAuthentication is required but missing or invalid
403ForbiddenAuthenticated but not authorized to access the resource
404Not FoundResource does not exist
405Method Not AllowedHTTP method is not supported for this resource
409ConflictRequest conflicts with current state (e.g., duplicate resource)
413Payload Too LargeRequest body exceeds server limits
415Unsupported Media TypeServer does not support the Content-Type of the request
422Unprocessable EntityRequest is well-formed but contains semantic errors (validation failure)
429Too Many RequestsRate limit exceeded

5xx: Server Error

The server encountered an error while processing a valid request.

CodeNameDescription
500Internal Server ErrorUnexpected server error (generic catch-all)
502Bad GatewayServer acting as proxy received an invalid response from upstream
503Service UnavailableServer is temporarily overloaded or under maintenance
504Gateway TimeoutServer acting as proxy did not receive a timely response from upstream

HTTP Headers

Headers provide metadata about the request or response. They are key-value pairs separated by colons.

Common Request Headers

HeaderPurposeExample
HostTarget server hostname (required in HTTP/1.1)Host: api.example.com
AuthorizationAuthentication credentialsAuthorization: Bearer eyJhbG...
Content-TypeMedia type of the request bodyContent-Type: application/json
AcceptMedia types the client can handleAccept: application/json, text/html
User-AgentClient software identificationUser-Agent: Mozilla/5.0 ...
CookiePreviously stored cookiesCookie: session_id=abc123
If-None-MatchConditional request (ETag-based)If-None-Match: "v2.6"
If-Modified-SinceConditional request (date-based)If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT

Common Response Headers

HeaderPurposeExample
Content-TypeMedia type of the response bodyContent-Type: application/json; charset=utf-8
Cache-ControlCaching directivesCache-Control: public, max-age=3600
Set-CookieStore a cookie on the clientSet-Cookie: session_id=abc123; HttpOnly; Secure
LocationRedirect URL or location of created resourceLocation: /api/users/42
ETagEntity tag for cache validationETag: "v2.6"
X-Request-IdUnique request identifier for tracingX-Request-Id: req-abc-123

CORS Headers

Cross-Origin Resource Sharing (CORS) headers control which origins can access resources from a different domain.

HeaderPurposeExample
Access-Control-Allow-OriginAllowed originsAccess-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-MethodsAllowed HTTP methodsAccess-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-HeadersAllowed request headersAccess-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-AgePreflight cache duration (seconds)Access-Control-Max-Age: 86400
Access-Control-Allow-CredentialsAllow cookies/auth cross-originAccess-Control-Allow-Credentials: true

Cache-Control Directives

DirectiveMeaning
publicResponse can be cached by any cache (browser, CDN, proxy)
privateResponse can only be cached by the browser (not shared caches)
no-cacheCache must revalidate with the server before using the cached response
no-storeResponse must not be cached at all
max-age=NResponse is fresh for N seconds
s-maxage=NLike max-age but only for shared caches (CDN, proxy)
must-revalidateOnce stale, cache must revalidate before using
immutableResponse will never change (avoid revalidation requests)

Cookies and Sessions

HTTP is a stateless protocol — each request is independent. Cookies provide a mechanism for maintaining state across requests.

How Cookies Work

1. Client sends login request:
POST /login {username: "alice", password: "..."}
2. Server creates a session and returns a Set-Cookie header:
HTTP/1.1 200 OK
Set-Cookie: session_id=abc123; HttpOnly; Secure; SameSite=Strict; Max-Age=3600
3. Client includes the cookie in subsequent requests:
GET /api/profile
Cookie: session_id=abc123
4. Server looks up the session by ID and identifies the user.
AttributePurpose
HttpOnlyCookie is inaccessible to JavaScript (prevents XSS theft)
SecureCookie is only sent over HTTPS connections
SameSite=StrictCookie is not sent with cross-site requests (CSRF protection)
SameSite=LaxCookie is sent with top-level navigations but not cross-site subrequests
Max-Age=NCookie expires after N seconds
Domain=.example.comCookie is valid for the domain and all subdomains
Path=/apiCookie is only sent for requests matching this path prefix

Sessions vs Tokens

AspectSession-Based (Cookies)Token-Based (JWT)
StorageServer-side (session store)Client-side (localStorage, cookie)
ScalabilityRequires shared session store across serversStateless, any server can validate
RevocationEasy (delete from session store)Harder (token valid until expiry)
SizeSmall cookie (just session ID)Larger (contains claims/payload)
Best forTraditional web appsSPAs, mobile apps, microservices

HTTPS and the TLS Handshake

HTTPS is HTTP over TLS (Transport Layer Security). It provides three critical security properties:

  • Encryption: Data is encrypted in transit, preventing eavesdropping
  • Authentication: The server’s identity is verified using digital certificates
  • Integrity: Data cannot be tampered with without detection

The TLS 1.3 Handshake

TLS 1.3 (the current version) simplified the handshake to just 1 round trip (down from 2 in TLS 1.2).

Client Server
│ │
│─── ClientHello ──────────────────────────────►│
│ - Supported TLS versions │
│ - Supported cipher suites │
│ - Client random │
│ - Key share (Diffie-Hellman public key) │
│ │
│◄── ServerHello + EncryptedExtensions ────────│
│ - Selected TLS version and cipher suite │
│ - Server random │
│ - Server key share │
│ - Server certificate │
│ - Certificate verify (signature) │
│ - Finished │
│ │
│─── Finished ─────────────────────────────────►│
│ (Client verifies certificate, │
│ computes shared secret) │
│ │
│════ Encrypted Application Data ══════════════►│
│◄═══════════════════════════════════════════════│

Digital Certificates

Certificates are issued by Certificate Authorities (CAs) and form a chain of trust.

Root CA Certificate (pre-installed in OS/browser)
└── Intermediate CA Certificate
└── Server Certificate (your-site.com)
Contains:
- Domain name
- Public key
- Issuer (CA)
- Validity period
- Digital signature

Key concepts:

  • Certificate chain: Server cert -> Intermediate CA cert -> Root CA cert
  • Let’s Encrypt: Free, automated CA that issues certificates (used by the majority of HTTPS sites)
  • Certificate pinning: Hardcoding the expected certificate in the client (used in mobile apps for extra security)

Making HTTP Requests: Code Examples

Here are practical examples of making HTTP requests in popular languages.

GET Request

import requests
# Simple GET request
response = requests.get(
"https://api.example.com/users/42",
headers={
"Authorization": "Bearer your-token-here",
"Accept": "application/json"
},
timeout=10
)
# Check status and parse response
if response.status_code == 200:
user = response.json()
print(f"User: {user['name']}, Email: {user['email']}")
elif response.status_code == 404:
print("User not found")
else:
print(f"Error: {response.status_code} - {response.text}")

POST Request

import requests
# Create a new user
response = requests.post(
"https://api.example.com/users",
json={
"name": "Alice Johnson",
"email": "alice@example.com",
"role": "engineer"
},
headers={
"Authorization": "Bearer your-token-here"
},
timeout=10
)
if response.status_code == 201:
user = response.json()
print(f"Created user with ID: {user['id']}")
print(f"Location: {response.headers.get('Location')}")
elif response.status_code == 422:
errors = response.json()
print(f"Validation errors: {errors}")
else:
print(f"Error: {response.status_code}")

Key Takeaways

  • HTTP/2 multiplexes requests over a single connection, significantly improving performance over HTTP/1.1
  • HTTP/3 uses QUIC (UDP-based) to eliminate head-of-line blocking at the transport level
  • Know the correct HTTP method for each operation: GET for retrieval, POST for creation, PUT for replacement, PATCH for partial updates, DELETE for removal
  • Status codes communicate the result: 2xx for success, 4xx for client errors, 5xx for server errors
  • Headers control caching, authentication, content negotiation, and cross-origin access
  • HTTPS with TLS provides encryption, authentication, and integrity for all web communication
  • The TLS 1.3 handshake completes in just 1 round trip, making HTTPS nearly as fast as HTTP

Next Steps