HTTP, HTTPS, and the Application Layer¶
Overview¶
HTTP is the language of the web — and of most microservice communication. Every curl, browser request, Kubernetes liveness probe, and CI/CD webhook speaks HTTP or its encrypted sibling HTTPS. As a DevOps engineer, you debug 502 Bad Gateway, 413 Payload Too Large, 301 redirect loops, and certificate expired errors daily. These are application-layer problems that sit above TCP and DNS but depend on both working correctly.
This tutorial is Tutorial 10 in Module 4: Application Layer of the REBASH Academy Networking series. You will learn HTTP request/response structure, status codes, essential headers, how TLS secures HTTPS, and practical curl techniques for production troubleshooting. For transport-layer details, see TCP and UDP Deep Dive.
Prerequisites¶
- DNS Fundamentals — hostname resolution before HTTP connects
- TCP and UDP Deep Dive — ports 80/443, connection states
- Linux VM or local machine with
curl,openssl, and optionalhttpie - Basic familiarity with web applications and APIs
Learning Objectives¶
By the end of this tutorial, you will be able to:
- Describe HTTP request and response structure (method, path, headers, body)
- Explain common HTTP methods and when to use each (GET, POST, PUT, PATCH, DELETE)
- Interpret status code classes (1xx–5xx) and diagnose production errors
- Use essential headers (Host, Content-Type, Authorization, Cache-Control, Cookie)
- Explain the TLS handshake and what HTTPS adds beyond HTTP
- Debug HTTP with
curl -v,-I,-L, and--resolve - Compare HTTP/1.1, HTTP/2, and HTTP/3 at a high level
- Relate application-layer concepts to load balancers and reverse proxies
Architecture Diagram¶
sequenceDiagram
participant Client as curl / Browser
participant DNS as DNS Resolver
participant LB as Load Balancer
participant TLS as TLS Termination
participant App as Application Server
Client->>DNS: Resolve api.example.com
DNS->>Client: 203.0.113.10
Client->>LB: TCP SYN :443
LB->>Client: TCP SYN-ACK (established)
Client->>TLS: ClientHello (TLS 1.3)
TLS->>Client: ServerHello + Certificate
Client->>TLS: Encrypted HTTP GET /health
alt L7 routing
LB->>App: Forward GET /health (HTTP or re-encrypted)
end
App->>LB: 200 OK {"status":"ok"}
LB->>Client: 200 OK (encrypted)```
## Theory
### Application Layer in the Stack
In the **TCP/IP model**, HTTP operates at the **Application layer** (Layer 7 in OSI terms). It assumes reliable transport (TCP, or QUIC over UDP for HTTP/3) and assumes the client already resolved the hostname via DNS.
| Layer | Protocol | DevOps touchpoint |
|-------|----------|-------------------|
| Application | HTTP, HTTPS, gRPC | Ingress, API gateways, health checks |
| Transport | TCP, UDP | Connection timeouts, port 443 |
| Network | IP | Routing, security groups |
| Link | Ethernet | Rarely direct concern |
### HTTP Request Structure
An HTTP request consists of:
```http
GET /api/v1/users HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
User-Agent: curl/8.5.0
| Component | Purpose |
|---|---|
| Request line | Method, path, HTTP version |
| Headers | Metadata (Host, auth, content type, cookies) |
| Blank line | Separates headers from body |
| Body | Optional payload (POST/PUT/PATCH) |
The Host header is mandatory in HTTP/1.1 — it enables virtual hosting (many sites on one IP). Load balancers and ingress controllers route based on Host and path.
HTTP Methods¶
| Method | Idempotent | Safe | Typical Use |
|---|---|---|---|
| GET | Yes | Yes | Retrieve resource |
| POST | No | No | Create resource, submit form |
| PUT | Yes | No | Replace resource entirely |
| PATCH | No | No | Partial update |
| DELETE | Yes | No | Remove resource |
| HEAD | Yes | Yes | Like GET but headers only |
| OPTIONS | Yes | Yes | CORS preflight, capability discovery |
Idempotent means multiple identical requests have the same effect as one. Safe means no state change on the server. POST retry logic must handle duplicate submissions; GET can be retried freely.
HTTP Response and Status Codes¶
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 47
Cache-Control: no-cache
{"status":"ok","version":"2.1.0"}
Status codes are grouped by first digit:
| Class | Range | Meaning | Examples |
|---|---|---|---|
| 1xx | 100–199 | Informational | 100 Continue, 101 Switching Protocols |
| 2xx | 200–299 | Success | 200 OK, 201 Created, 204 No Content |
| 3xx | 300–399 | Redirection | 301 Moved Permanently, 302 Found, 304 Not Modified |
| 4xx | 400–499 | Client error | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests |
| 5xx | 500–599 | Server error | 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout |
Production debugging shortcuts:
- 502 — Load balancer/proxy received invalid response from upstream (app crashed, wrong port, protocol mismatch)
- 503 — Service unavailable (maintenance, overload, no healthy backends)
- 504 — Upstream timeout (slow app, database lock, missing health check)
- 421 Misdirected Request — TLS/SNI routed to wrong backend (common in multi-tenant ingress)
Essential Headers¶
| Header | Purpose |
|---|---|
| Host | Target hostname for virtual hosting |
| Content-Type | Body format (application/json, multipart/form-data) |
| Content-Length | Body size in bytes |
| Authorization | Credentials (Bearer token, Basic auth) |
| Cookie / Set-Cookie | Session state |
| Cache-Control | Caching policy (max-age, no-store) |
| Location | Redirect target (3xx responses) |
| X-Forwarded-For | Original client IP (added by proxies) |
| X-Request-ID | Correlation ID for distributed tracing |
X-Forwarded-* trust
Only trust X-Forwarded-For and X-Forwarded-Proto from known proxies (load balancer, ingress). Clients can spoof these if the app accepts them directly from the internet.
HTTPS and TLS¶
HTTPS is HTTP over TLS (Transport Layer Security). TLS provides:
- Confidentiality — encrypted data in transit
- Integrity — tampering detection
- Authentication — server (and optionally client) identity via certificates
TLS 1.3 Handshake (simplified)¶
- ClientHello — supported ciphers, TLS version, SNI (server hostname)
- ServerHello — chosen cipher, certificate chain
- Key exchange — (ECDHE) establishes session keys
- Encrypted application data — HTTP request/response flows encrypted
SNI (Server Name Indication) lets multiple HTTPS sites share one IP — the client sends the hostname during handshake. Missing or wrong SNI causes certificate mismatch errors.
Certificate validation checks:
- Hostname matches certificate CN/SAN
- Chain trusted by system CA store
- Not expired (
notBefore/notAfter) - Not revoked (OCSP stapling where supported)
HTTP Versions¶
| Version | Transport | Key Features |
|---|---|---|
| HTTP/1.1 | TCP | Persistent connections, chunked encoding, pipelining (limited) |
| HTTP/2 | TCP | Multiplexing, header compression (HPACK), server push (rarely used) |
| HTTP/3 | QUIC (UDP) | Multiplexing without head-of-line blocking, faster handshake |
Most production ingress controllers terminate HTTP/2 from clients and may speak HTTP/1.1 to backends. Check with curl -v --http2.
Cookies and Sessions¶
Set-Cookie from server stores session ID in browser. Cookie header sends it back on subsequent requests. Attributes matter for security:
| Attribute | Purpose |
|---|---|
| HttpOnly | JavaScript cannot access — mitigates XSS theft |
| Secure | Sent only over HTTPS |
| SameSite | CSRF mitigation (Strict, Lax, None) |
| Domain / Path | Scope of cookie |
Load balancers use session affinity (sticky sessions) via cookie injection when stateful apps require it — prefer stateless design when possible.
Hands-on Lab¶
These exercises use public endpoints. Replace URLs with your own services for deeper practice.
Step 1 – Basic GET request¶
Command:
curl -s -o /dev/null -w "HTTP %{http_code} in %{time_total}s\n" https://example.com
curl -s -D - -o /dev/null https://example.com | head -15
Explanation: First command shows status and timing. Second dumps response headers only.
Expected output:
Step 2 – Verbose request with TLS details¶
Command:
Explanation: -v shows TCP connection, TLS handshake, certificate info, and HTTP headers. Essential for HTTPS debugging.
Expected output:
* Connected to example.com (93.184.216.34) port 443
* TLSv1.3 (OUT), TLS handshake, Client hello
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* Server certificate: subject: CN=example.com
> GET / HTTP/1.1
< HTTP/1.1 200 OK
Step 3 – HEAD request (headers only)¶
Command:
curl -I https://example.com
curl -sI https://example.com | grep -iE '^(HTTP|cache|content-type|server|location)'
Explanation: HEAD is useful for health checks without downloading body. -I is shorthand for HEAD.
Step 4 – Follow redirects¶
Command:
curl -sI -L http://example.com 2>&1 | grep -E '^HTTP|^Location'
curl -s -o /dev/null -w "Final URL: %{url_effective}\nCode: %{http_code}\n" -L http://example.com
Explanation: -L follows 301/302 redirects. Watch for redirect loops (max 50 by default).
Expected output:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/
HTTP/2 200
Final URL: https://example.com/
Code: 200
Step 5 – POST JSON with headers¶
Command:
curl -s -X POST https://httpbin.org/post \
-H "Content-Type: application/json" \
-H "X-Request-ID: lab-$(date +%s)" \
-d '{"service":"api","status":"test"}' | head -20
Explanation: httpbin.org echoes request for learning. In production, replace with your API endpoint.
Step 6 – Inspect certificate with openssl¶
Command:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
Explanation: Validates certificate subject, issuer, and expiry without HTTP layer. Use when curl reports SSL errors.
Expected output:
subject=CN=example.com
issuer=C=US, O=DigiCert Inc, CN=DigiCert Global G3 TLS ECC SHA384 2020 CA1
notBefore=Jan 15 00:00:00 2024 GMT
notAfter=Feb 16 23:59:59 2025 GMT
Step 7 – Test specific Host header (virtual hosting)¶
Command:
curl -sI -H "Host: example.com" http://93.184.216.34 2>&1 | head -5
curl -sI --resolve example.com:443:93.184.216.34 https://example.com | head -5
Explanation: --resolve forces DNS mapping for testing before propagation. Host header routes to correct vhost on shared IP.
Step 8 – Compare HTTP/1.1 and HTTP/2¶
Command:
curl -s -o /dev/null -w "HTTP/1.1: %{http_version} %{http_code}\n" --http1.1 https://example.com
curl -s -o /dev/null -w "HTTP/2: %{http_version} %{http_code}\n" --http2 https://example.com
Explanation: Confirms server HTTP/2 support. ALPN negotiates during TLS handshake.
Commands & Code¶
| Command | Description | Example |
|---|---|---|
curl -v URL | Verbose HTTP + TLS debug | curl -v https://api.example.com |
curl -I URL | HEAD request (headers only) | curl -I https://example.com |
curl -L URL | Follow redirects | curl -L http://example.com |
curl -X METHOD | Specify HTTP method | curl -X DELETE URL |
curl -H "Header: val" | Custom request header | curl -H "Accept: application/json" |
curl -d 'data' | POST body | curl -d "name=test" URL |
curl --resolve | Override DNS for test | curl --resolve host:443:IP https://host |
curl -w '%{http_code}' | Print status code only | curl -s -o /dev/null -w '%{http_code}' URL |
openssl s_client | TLS/certificate inspection | openssl s_client -connect host:443 |
HTTP health check script¶
#!/usr/bin/env bash
# http-health.sh — quick endpoint check for monitoring
set -euo pipefail
URL="${1:?Usage: http-health.sh https://example.com/health}"
TIMEOUT="${2:-5}"
code=$(curl -s -o /dev/null -w '%{http_code}' --max-time "$TIMEOUT" "$URL")
time_total=$(curl -s -o /dev/null -w '%{time_total}' --max-time "$TIMEOUT" "$URL")
if [[ "$code" =~ ^2 ]]; then
echo "OK $URL → HTTP $code (${time_total}s)"
exit 0
else
echo "FAIL $URL → HTTP $code (${time_total}s)"
exit 1
fi
Common Mistakes¶
Ignoring redirect chains
HTTP → HTTPS redirects add latency. Point health checks and internal services directly at HTTPS endpoints.
Hardcoding HTTP in production
Mixed content, session hijacking, and cookie theft. Enforce HTTPS with HSTS after validating TLS works.
Trusting X-Forwarded-For from clients
Use only when request passes through known load balancer. Otherwise, log the TCP source IP.
502 blamed on application when upstream is wrong
502 often means LB cannot reach backend port or backend speaks wrong protocol (HTTP vs HTTPS mismatch).
Certificate hostname mismatch
Cert issued for *.example.com does not cover example.com unless SAN includes apex. Check with openssl.
Best Practices¶
Use curl -v as first HTTP debug step
Faster than tcpdump for most L7 issues — shows DNS, TCP, TLS, request, and response in one output.
Set reasonable timeouts everywhere
Client, load balancer, and application timeouts should decrease down the chain — avoid 504 cascades.
Return meaningful 4xx/5xx with correlation IDs
X-Request-ID in logs links user report to server trace instantly.
Prefer 301 over 302 for permanent HTTPS migration
301 is cached by browsers; 302 may be re-evaluated repeatedly.
Monitor certificate expiry proactively
Alert at 30/14/7 days before expiry. Automate renewal with ACME (Let's Encrypt, cert-manager).
Troubleshooting¶
| Issue | Cause | Solution |
|---|---|---|
502 Bad Gateway | Backend down, wrong port, protocol mismatch | Check upstream health; verify HTTP vs HTTPS to backend |
503 Service Unavailable | No healthy backends, maintenance mode | Inspect LB target group; review health check path |
504 Gateway Timeout | Backend slower than LB timeout | Increase timeout or fix slow queries; align timeout chain |
Connection refused on :443 | Nothing listening or wrong IP | ss -tlnp; verify DNS points to correct LB |
SSL certificate problem | Expired, wrong hostname, untrusted CA | openssl s_client; renew cert; fix SAN |
| Redirect loop | HTTP/HTTPS misconfiguration | Check X-Forwarded-Proto; fix ingress annotations |
421 Misdirected Request | SNI/route mismatch on shared ingress | Verify Host header and TLS cert match route |
| Slow first request | Cold start or DNS/TLS overhead | Enable keep-alive; HTTP/2; connection pooling |
| 413 Payload Too Large | Body exceeds limit | Increase client_max_body_size / LB limit |
| CORS errors in browser | Missing Access-Control headers | Server-side CORS config — not visible in curl alone |
Summary¶
- HTTP is the application-layer protocol for web and API communication — built on TCP (or QUIC for HTTP/3)
- Methods (GET, POST, PUT, DELETE) and status codes (2xx–5xx) tell you what happened at L7
- Headers carry metadata: Host for routing, Authorization for auth, Cache-Control for caching
- HTTPS adds TLS encryption and certificate-based server authentication
curl -vis the primary DevOps tool for HTTP/TLS debugging- 502/503/504 at the load balancer usually mean upstream or timeout issues — not always application bugs
- Understand HTTP/2 multiplexing and HTTP/3 QUIC benefits for modern ingress design
Interview Questions¶
- What are the main parts of an HTTP request?
- Explain the difference between 301 and 302 redirects.
- What does a 502 Bad Gateway mean at the load balancer?
- How does TLS differ from HTTP?
- What is the purpose of the Host header?
- Which HTTP methods are idempotent and safe?
- What is SNI and why does it matter for HTTPS?
- How would you debug a certificate expiry issue?
- Compare HTTP/1.1, HTTP/2, and HTTP/3.
- What is the difference between 401 Unauthorized and 403 Forbidden?
Sample Answers (Questions 3, 4, and 10)
Q3 — 502 Bad Gateway: The load balancer or reverse proxy received an invalid or no response from the upstream backend. Common causes: backend process crashed, wrong port configured, backend speaks HTTP while proxy expects HTTPS (or vice versa), or connection reset mid-response.
Q4 — TLS vs HTTP: HTTP defines request/response semantics for applications. TLS operates below HTTP, encrypting the TCP connection and authenticating the server via certificates. HTTPS is HTTP running inside a TLS-encrypted tunnel.
Q10 — 401 vs 403: 401 Unauthorized means authentication is required or credentials are invalid — client should retry with valid auth. 403 Forbidden means the server understood the request and identity but refuses to authorize access — retrying with same credentials will not help.
Related Tutorials¶
- Networking – Category Overview
- DNS Records and Troubleshooting (previous — Module 3)
- Firewalls and Access Control (next in Module 4)
- TCP and UDP Deep Dive
- Load Balancing Fundamentals
- Learning Paths – DevOps Engineer