HTTP and HTTPS Protocol: A Guide to Web Communication

Deep dive into HTTP methods, status codes, headers, keep-alive, and protocol evolution. Understand HTTP/1.1, HTTP/2, and HTTP/3 differences.

published: reading time: 33 min read author: GeekWorkBench updated: June 17, 2026
Quick Summary

HTTP defines how clients and servers exchange methods, status codes, and headers; HTTPS adds TLS for authentication and confidentiality. This guide compares HTTP/1.1 and HTTP/2 over TCP with HTTP/3 over QUIC, then covers caching, certificates, failure modes, and protocol trade-offs. It explains that resumed 0-RTT data can be replayed, distinguishes handshake time from full request latency, and includes curl checks for real endpoints.

HTTP and HTTPS Protocol: A Guide to Web Communication

Introduction

HTTP defines the request and response exchange between clients and servers. Methods describe the requested action, status codes report the result, and headers carry metadata; HTTPS adds TLS to protect the connection and authenticate the server.

Connection behavior also changes across versions: HTTP/1.1 reuses connections, HTTP/2 multiplexes streams over TCP, and HTTP/3 uses QUIC. This guide covers those mechanics alongside TLS, caching, trade-offs, and common operational failures.

HTTP Methods

HTTP defines several methods (also called verbs) that indicate the desired action:

Retrieving resources

GET

Retrieves data. GET requests should be safe and idempotent. Safe means they do not modify server state. Idempotent means multiple identical requests have the same effect as one.

GET /api/users HTTP/1.1
Host: example.com

Submitting and changing resources

POST

Submits data to be processed. POST requests typically cause state changes on the server.

POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json

{"name": "Alice", "email": "alice@example.com"}

PUT

Replaces a resource at a specific URL. If the resource exists, it is updated. If it does not exist, it is created.

PUT /api/users/123 HTTP/1.1
Host: example.com
Content-Type: application/json

{"name": "Alice", "email": "alice.new@example.com"}

PATCH

Partially updates a resource. Unlike PUT which replaces the whole resource, PATCH updates only the specified fields.

PATCH /api/users/123 HTTP/1.1
Host: example.com
Content-Type: application/json

{"email": "alice.updated@example.com"}

DELETE

Removes a resource.

DELETE /api/users/123 HTTP/1.1
Host: example.com

Other request methods

Other Methods

Method Purpose Safe Idempotent
HEAD Like GET but returns only headers Yes Yes
OPTIONS Returns supported methods for a URL Yes Yes
CONNECT Converts to a tunnel (used for proxies) No No
TRACE Echoes the request (for debugging) Yes Yes

The definitions of “safe” and “idempotent” sound clean in theory but get messy in practice. Here is where it gets interesting.

Safe methods (GET, HEAD, OPTIONS, TRACE) are supposed to not modify server state. But plenty of GET endpoints do logging, track analytics, or update last-accessed timestamps. The server changes; the request just isn’t supposed to request those changes. That is the distinction: safe means the request is not asking for side effects, not that side effects cannot happen.

Idempotent methods (GET, HEAD, PUT, DELETE, OPTIONS, TRACE) mean multiple identical requests should produce the same server state as one. DELETE is idempotent — deleting an already-deleted resource still yields “gone.” PUT is idempotent — overwriting the same data twice does not change anything after the first write.

POST and PATCH are neither safe nor idempotent. Sending POST twice creates two resources. PATCH twice on the same field applies the patch twice (which matters if the patch is relative, like “add 10 to counter”).

The murkier cases:

# GET with side effects — technically violates safe semantics
GET /api/users/123/activate

# A/B testing frameworks often do this. The fix:
POST /api/users/123/activate

Some frameworks let GET accept bodies (technically valid per RFC 9110, but most servers reject it). If you have a GET that modifies state, switch to POST.

HEAD is like GET but never returns a body. Useful for checking if a resource exists or getting headers without downloading anything. Proxies use HEAD to validate cached responses.

OPTIONS returns what the server supports for a given URL. CORS preflight requests use OPTIONS to ask “can I do a DELETE to this URL from a different origin?” The response includes Allow: GET, HEAD, OPTIONS if DELETE is not allowed.

CONNECT is odd — it converts the connection into a TCP tunnel, typically for HTTPS through a proxy. You rarely see it outside of corporate proxy setups.

TRACE echoes the request back so clients can see what proxies modified. It is mostly a debugging tool. Most production servers disable it to prevent information leakage.


HTTP Status Codes

Status codes tell you what happened with the request. They are grouped by range:

1xx: Informational

The request was received, continuing process.

HTTP/1.1 100 Continue

100 Continue means the client should send the request body. This is useful when sending large requests to check if the server will accept them first.

2xx: Success

The request was successfully received, understood, and accepted.

Code Meaning
200 OK - Standard success response
201 Created - Resource was created
204 No Content - Success with no response body

3xx: Redirection

Further action needed to complete the request.

HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-page
Code Meaning
301 Moved Permanently - Resource now at new URL
302 Found - Temporary redirect
304 Not Modified - Cached version is still valid

301 and 302 are the most common redirects. The difference matters for SEO: 301 tells search engines the move is permanent.

4xx: Client Errors

The request has bad syntax or cannot be fulfilled.

HTTP/1.1 404 Not Found
Code Meaning
400 Bad Request - Malformed syntax
401 Unauthorized - Authentication required
403 Forbidden - Authenticated but not authorized
404 Not Found - Resource does not exist
429 Too Many Requests - Rate limited

5xx: Server Errors

The server failed to fulfill a valid request.

Code Meaning
500 Internal Server Error - Something broke on the server
502 Bad Gateway - Upstream server returned error
503 Service Unavailable - Server is temporarily overloaded
504 Gateway Timeout - Upstream server took too long

HTTP Headers

Headers provide metadata about the request or response. They are essential for caching, authentication, content negotiation, and more.

Common Request Headers

GET /api/data HTTP/1.1
Host: example.com
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Header Purpose
Host Domain name of the server
Accept Media types the client can handle
Authorization Credentials for authentication
Cache-Control Caching directives
User-Agent Client application information
Cookie Session data previously set by server

Common Response Headers

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 512
Cache-Control: max-age=3600
Set-Cookie: session=abc123; HttpOnly; Secure
X-Request-ID: req-12345
Header Purpose
Content-Type Media type of the response
Content-Length Size of the response body
Cache-Control Caching directives for clients
Set-Cookie Data to store on the client
ETag Version identifier for caching
X-Request-ID Unique request identifier

Keep-Alive and Connection Management

HTTP/1.0 closed the connection after each request by default. HTTP/1.1 introduced persistent connections.

With Keep-Alive, multiple requests can reuse the same TCP connection:

# Without Keep-Alive: 3 TCP connections for 3 requests
GET /page1.html -> TCP connection 1 -> close
GET /page2.html -> TCP connection 2 -> close
GET /page3.html -> TCP connection 3 -> close

# With Keep-Alive: 1 TCP connection for 3 requests
GET /page1.html -> TCP connection 1
GET /page2.html -> TCP connection 1 (reused)
GET /page3.html -> TCP connection 1 (reused)
Connection: close -> close

Keep-Alive reduces latency by avoiding TCP handshake overhead. It also reduces server load by needing fewer connections.

# Request with Keep-Alive
GET /api/data HTTP/1.1
Host: example.com
Connection: keep-alive

# After response, connection stays open for more requests

HTTP/2: Multiplexing

HTTP/1.1 improved with persistent connections, but requests still had to complete in order (head-of-line blocking). HTTP/2 introduced multiplexing.

With multiplexing, multiple requests and responses flow simultaneously over a single connection:

graph LR
    A[Stream 1: GET /index.html] --> B[Single TCP Connection]
    C[Stream 2: GET /style.css] --> B
    D[Stream 3: GET /app.js] --> B
    B --> A
    B --> C
    B --> D

Multiplexing removes the HTTP/1.1 requirement that responses on one connection follow request order. Packet loss can still block all HTTP/2 streams because they share TCP; HTTP/3 avoids that transport-level blocking between streams.

HTTP/2 adds header compression (HPACK), server push, and stream prioritization. RFC 9218 defines newer priority signals shared by HTTP/2 and HTTP/3.


HTTP/3: QUIC Transport

HTTP/3 takes a different approach. It runs over QUIC instead of TCP. QUIC is a transport protocol built on UDP.

Why UDP? TCP requires a handshake before sending data. QUIC combines the handshake with TLS, reducing connection establishment time:

TCP + TLS Connection Setup

graph LR
    A[TCP + full TLS 1.3] --> B[about 2 RTTs before application data]

QUIC + TLS Connection Setup

graph LR
    C[QUIC + full TLS 1.3] --> D[about 1 RTT before application data]

HTTP/3 can establish a new connection in fewer round trips, send eligible data early on resumption, and avoid TCP-level head-of-line blocking between streams. Each stream still delivers data in order. QUIC also supports connection migration when a client switches networks.

The catch: HTTP/3 requires UDP traffic to be allowed through firewalls. Most modern sites support it alongside HTTP/2.


QUIC vs TCP: Under the Hood

This deserves a closer look. TCP and QUIC both provide reliable, ordered delivery, but take different paths to get there.

Connection setup

TCP’s problem: connection establishment is slow

To send encrypted data over TCP, you need:

  1. TCP handshake: SYN -> SYN-ACK -> ACK (1 RTT)
  2. TLS 1.3 full handshake: ClientHello -> ServerHello and encrypted server flight -> client Finished (typically 1 RTT; a HelloRetryRequest can add one)

A full TCP + TLS 1.3 handshake typically takes about 2 RTTs before application data. TLS 1.3 resumption can send eligible early data in the first flight, but that data is replayable.

QUIC combines transport and security in one handshake

QUIC is built on UDP. It re-implements everything TCP gives you — reliability, ordering, congestion control — but inside UDP. This lets it fold the TLS handshake directly into the first connection handshake:

  1. New connection: a full QUIC and TLS 1.3 handshake takes about 1 RTT before application data.
  2. Resumed connection: the client can include eligible 0-RTT application data in its first flight.

The server can receive resumed data without waiting for another handshake round trip, though network propagation and server processing still take time.

New Connection Setup

graph LR
    A[New connection, cold start] --> B[TCP + full TLS 1.3: ~2 RTTs]
    A --> C[QUIC+TLS 1.3: ~1 RTT]

Session Resumption

graph LR
    D[Resumption, warm] --> E[TCP + TLS: TCP setup takes ~1 RTT before eligible early data]
    D --> F[QUIC: eligible 0-RTT early data in first flight]

Stream and path behavior

Head-of-line blocking comparison

HTTP/2 solves application-layer head-of-line blocking with multiplexing, but TCP still enforces ordering at the transport layer. If packet 5 is lost, TCP blocks all Stream 2 data until packet 5 retransmits, even if Stream 3’s data arrived fine.

QUIC tracks streams independently. A lost packet only blocks the stream that packet belongs to — other streams keep flowing. This matters a lot on lossy networks (mobile, coffee shop WiFi).

Connection migration

TCP connections are identified by the 4-tuple (client IP, client port, server IP, server port). Switch from WiFi to cellular and the connection dies.

QUIC connection IDs allow a connection to survive an address change. The client and server validate the new path before using it, and support depends on both endpoints and network policy.

Packet Loss Behavior

graph LR
    G[Packet loss] --> H[TCP: all streams blocked on lost packet]
    G --> I[QUIC: only that stream blocked, others continue]

QUIC is commonly implemented in user space, while TCP has mature kernel support. QUIC’s encryption and packet processing can add CPU cost, but the difference depends on the implementation and workload; benchmark the target service before choosing a transport.


Network constraints

The UDP firewall problem

Most networks allow TCP and UDP ports 80 and 443. QUIC runs on UDP:443, which some firewalls block or throttle. HTTP/3 falls back to HTTP/2 when QUIC is blocked, but you lose the performance gains on those connections.

HTTP/3 Performance Considerations

Connection setup provides a useful comparison, but total performance depends on the network path, server, and workload.

Cold connection latency (new server, no cache)

For HTTPS with a full TLS 1.3 handshake, TCP setup takes one RTT and TLS takes about one more. QUIC combines transport setup and TLS, so HTTP/3 can send application data after about one RTT.

Protocol Setup before application data At 50ms RTT
HTTP/1.1 or HTTP/2 TCP + TLS 1.3 (about 2 RTTs) About 100ms
HTTP/3 QUIC + TLS 1.3 (about 1 RTT) About 50ms

These are handshake estimates, not total page-load times. DNS lookup, server processing, congestion, and packet loss add time.

Resumed connections

TLS 1.3 supports early data over TCP and QUIC. Over TCP, the TCP handshake still has to complete before the TLS early data can reach the server. QUIC combines transport setup and TLS, so a resumed HTTP/3 connection can send eligible data in its first flight. Early data can be replayed, so applications should protect non-idempotent operations.

Protocol Setup before early data reaches the server
HTTP/1.1 or HTTP/2 over TCP + TLS 1.3 About 1 RTT for TCP setup
HTTP/3 over QUIC Eligible 0-RTT early data can use the first flight

The actual delay depends on the network path and server. 0-RTT means no extra handshake round trip before sending data, not zero network time.

Packet loss impact

Packet loss has different effects by version. HTTP/1.1 responses on a pipelined connection must remain ordered, though browsers commonly use multiple connections. HTTP/2 streams share TCP ordering, so a lost segment can delay data across streams. QUIC keeps ordering within each stream, so loss in one stream does not block unrelated streams. The throughput impact depends on RTT, congestion, request mix, and implementation; measure it on the paths your users actually use.

Measuring HTTP/3 Adoption

HTTP/3 adoption depends on what a dataset measures. HTTP Archive reports the share of requests in its crawl whose endpoints support HTTP/3, while Cloudflare Radar reports the HTTP-version mix of requests served through Cloudflare; those populations and methods are not interchangeable. Both dashboards change over time, so use their latest data and methodology when assessing adoption. A configured endpoint also does not mean every client connection will use HTTP/3; UDP reachability and connection discovery matter.


HTTPS: HTTP Over TLS

HTTPS adds encryption via TLS (Transport Layer Security). The SSL/TLS and HTTPS post covers the details, but here is the quick version:

sequenceDiagram
    participant Client
    participant Server
    Note over Client,Server: Full TLS 1.3 handshake
    Client->>Server: ClientHello (supported versions and key share)
    Server->>Client: ServerHello (key share)
    Server->>Client: EncryptedExtensions, Certificate, CertificateVerify, Finished
    Client->>Server: Finished
    Note over Client,Server: Encrypted application data after about 1 RTT

The padlock icon in your browser means the connection uses HTTPS and the server certificate has been verified.


Certificate Trust and Pinning

Browser clients normally validate a server certificate through the Web PKI: the certificate chain must lead to a trusted authority, match the hostname, and remain valid. Certificate pinning adds an application-specific allowlist of certificates or public keys. It can reduce reliance on the wider CA system, but a stale pin can lock every client out during certificate rotation.

For ordinary websites, use correctly configured HTTPS and HSTS rather than pinning in the browser. HTTP Public Key Pinning (HPKP) is obsolete, and Chromium deprecated the Expect-CT header in version 107 because Certificate Transparency is enforced by default. Other browsers did not implement Expect-CT; see MDN’s Expect-CT reference.

For a native app with a threat model that justifies pinning, pin public keys rather than leaf certificates, include a backup key, and test rotation and emergency recovery before release. Do not fetch replacement pins through the same unverified connection they are meant to protect.


Caching with HTTP

HTTP caching reduces server load and improves performance. The Cache-Control header controls caching behavior:

# Cache for 1 hour
Cache-Control: max-age=3600

# Do not cache at all
Cache-Control: no-store

# Check freshness but reuse cached copy
Cache-Control: no-cache

# Cache only on CDN, not in browser
Cache-Control: private, max-age=3600

ETags provide another caching mechanism:

# Server response includes ETag
HTTP/1.1 200 OK
ETag: "v1.2.3"

# Client caches and later checks if changed
GET /api/data HTTP/1.1
If-None-Match: "v1.2.3"

# Server responds with 304 if unchanged
HTTP/1.1 304 Not Modified

When to Use HTTP

HTTP is the right choice when:

  • You need stateless request-response communication
  • Clients and servers have no shared state
  • Standard browser clients need to access your API
  • You want simple, well-understood semantics
  • Caching through standard HTTP mechanisms helps performance
  • You are building web applications, REST APIs, or serving content

When to Use HTTPS

HTTPS is required when:

  • You transmit any sensitive data (credentials, personal info, payment data)
  • Your application requires authentication
  • You need to prevent man-in-the-middle attacks
  • Browser security warnings would harm your users
  • You handle session cookies or tokens
  • Your application deals with financial or healthcare data

When Not to Use HTTP/HTTPS

HTTP/HTTPS may not be the right choice when:

  • Real-time bidirectional communication is needed (use WebSockets)
  • You need server-to-server streaming with minimal overhead (use gRPC)
  • You are building low-latency games or trading systems where TCP/UDP directly makes more sense
  • You need to push data to clients without polling (consider Server-Sent Events)

HTTP Version Trade-off Analysis

Factor HTTP/1.1 HTTP/2 HTTP/3
Transport TCP TCP QUIC (UDP)
HTTPS setup TCP + TLS 1.3: about 2 RTTs TCP + TLS 1.3: about 2 RTTs QUIC full handshake: about 1 RTT; eligible resumptions can send 0-RTT early data
Multiplexing No (pipelining broken) Yes (stream-based) Yes (independent streams)
Head-of-line blocking Yes (application) Yes (TCP layer) No cross-stream TCP blocking; per-stream ordering remains
Header compression None HPACK QPACK
Server push No Yes Yes
Connection migration No No Yes (via Connection ID)
Firewall issues None None Some UDP restrictions
Deployment Widely supported Widely supported UDP path and endpoint support required
Complexity Low Medium High
CPU overhead Low Medium Higher
Best for Simple APIs, legacy Mixed-content sites Mobile, lossy networks, repeat visitors

Production Failure Scenarios

Failure Impact Mitigation
Server returns 500 errors Users see errors, no data retrieved Implement retry logic with exponential backoff; monitor error rates
Slow response times Poor user experience, timeouts Set appropriate timeouts; use circuit breakers; scale horizontally
SSL/TLS certificate expired Browser warnings, service unavailable Automate certificate renewal (Let’s Encrypt, certbot); monitor expiration
Malformed responses Client crashes or data corruption Validate responses with schema; implement graceful degradation
Header injection Security vulnerability Sanitize all header values; use security headers (HSTS, CSP)
HTTP/2 connection drops Reconnection overhead Implement connection pooling; use HTTP/3 as fallback
Reverse proxy timeout Gateway 504 errors Configure appropriate timeouts; implement health checks
Content-Type mismatch Client cannot parse response Always set correct Content-Type; use content negotiation

Common Pitfalls / Anti-Patterns

Improper Use of Status Codes

Do not return 200 OK for errors. Clients rely on status codes to determine success or failure.

# Wrong - 200 for error
HTTP/1.1 200 OK
{"error": "User not found"}

# Correct - proper status code
HTTP/1.1 404 Not Found
{"error": "User not found"}

Ignoring Idempotency

GET and HEAD should be safe (no side effects). PUT should be idempotent. POST is neither.

# GET with side effects - BAD
GET /api/users/123/activate  # Changes server state!

# Proper REST - use POST or PATCH
POST /api/users/123/activate
PATCH /api/users/123 {"status": "active"}

Not Handling Timeouts

A request that hangs eventually produces a worse outcome than a fast failure. When the client never times out, threads pile up waiting for responses that will never arrive; memory grows; the connection pool exhausts. Under enough load, the whole service stalls and every upstream caller faces the same backpressure.

There are three timeouts worth distinguishing. Connect timeout caps how long a TCP or TLS handshake may take. Read timeout caps how long the client waits for the next byte after the request is sent. Total request timeout caps the wall-clock duration of the whole operation, including any retries. Set each independently and let the tightest one fail first.

Retry logic needs a budget. Unbounded retries on a 5xx response will multiply the load on an already-struggling server and turn a transient blip into an outage. Use exponential backoff with jitter, cap retry count at two or three, and only retry on idempotent verbs (GET, HEAD, PUT, DELETE). Non-idempotent POSTs should require an idempotency key to be retried safely. After the budget is exhausted, surface a 504 Gateway Timeout to the upstream caller so the failure mode stays explicit.

Missing Content-Type

Always specify Content-Type for requests with bodies. Clients may not guess correctly.

# Always specify content type
Content-Type: application/json

Keeping Connections Open Indefinitely

Without Keep-Alive, each request requires a new TCP handshake. With Keep-Alive but no timeout, servers can run out of connections.

Every idle Keep-Alive connection holds kernel resources: a socket buffer, a TIME_WAIT state entry, and a file descriptor. On a busy server with thousands of clients holding connections open for minutes, the file descriptor limit hits first. When descriptors are exhausted, the server cannot accept new connections. Every new client gets a Connection refused even if the process itself is healthy.

TIME_WAIT is the other problem. When a connection closes, the kernel holds the 4-tuple in TIME_WAIT for 2MSL (typically 60 seconds) to absorb delayed packets. With many short-lived connections, this table fills up and new connections cannot be established on that port. Setting keep-alive timeout to close idle connections promptly, 30 to 60 seconds is common, prevents both problems. You can also set max Keep-Alive requests to close connections after N requests regardless of idle time.

# Server-side Keep-Alive configuration (nginx example)
keepalive_timeout 30s;
keepalive_requests 100;

# Proxies and load balancers also need timeout settings
# otherwise they hold connections open to upstream servers indefinitely
upstream backend {
    server 127.0.0.1:8080;
    keepalive 32;      # connection pool size
    keepalive_timeout 60s;
}

Set a timeout, set a request limit, and size the connection pool to match your concurrency. Without those guards, a busy site will eventually exhaust what it has.

Observability Checklist

  • Logs: Record method, route, status, duration, and a request ID; redact credentials and sensitive values.
  • Metrics: Track request volume, p95/p99 latency, error rates, active connections, and TLS handshake duration.
  • Traces: Propagate a trace context across gateways and services, and capture spans for DNS, connection setup, TLS, and upstream work.
  • Alerts: Page on sustained error-rate or latency breaches, certificate expiry, and connection or health-check failures.

Security and Compliance Notes

  • Enable HTTPS on all endpoints (no HTTP fallback for sensitive data)
  • Set Strict-Transport-Security header (HSTS)
  • Implement Content-Security-Policy header
  • Set X-Content-Type-Options: nosniff
  • Set X-Frame-Options: DENY to prevent clickjacking
  • Remove or obfuscate server version headers
  • Implement rate limiting to prevent abuse
  • Use secure, HttpOnly, SameSite cookies
  • Validate all request headers and body data
  • Implement CORS properly for cross-origin requests
  • Log and monitor authentication failures
  • Use POST, not GET, for sensitive data transmission
  • Keep personal and payment data out of URLs, where browser history, proxy logs, and referrer headers can expose it.
  • Collect only the request data needed for the service, restrict log access, and set retention periods that match applicable privacy and industry requirements.
  • For regulated workloads, map controls to the rules that apply to the data and jurisdiction; HTTPS alone does not make an application compliant.

Quick Recap Checklist

  • Use HTTPS for production traffic and keep certificates renewed.
  • Keep GET safe; make retries of write requests safe with idempotent behavior or an idempotency key.
  • Return status codes that describe the outcome and set the correct Content-Type.
  • Set cache directives and connection timeouts deliberately.

Interview Questions

1. Describe the differences between HTTP/1.1, HTTP/2, and HTTP/3. What problems does each solve, and what new problems do they introduce?
  • HTTP/1.1: persistent connections, no multiplexing (head-of-line blocking)
  • HTTP/2: multiplexing, HPACK compression, server push, but still TCP head-of-line blocking at transport layer
  • HTTP/3: QUIC over UDP, optional 0-RTT resumption, independent streams that avoid TCP-level head-of-line blocking, and connection migration
  • New problems: QUIC needs UDP, CPU overhead higher, firewall issues, more complex server implementation
2. What is the difference between idempotent and safe HTTP methods? Give examples of each.
  • Safe methods: GET, HEAD, OPTIONS, TRACE — should not modify server state
  • Idempotent methods: GET, HEAD, PUT, DELETE, OPTIONS, TRACE — multiple identical requests have same effect as one
  • POST and PATCH are neither safe nor idempotent
  • Edge case: GET requests can have side effects (logging, timestamps) which violates safe semantics
3. Walk through a complete HTTPS TLS 1.3 handshake. How many round trips does it take, and what is exchanged in each?
  • A full TLS 1.3 handshake takes 1 RTT; on an eligible resumption, the client may send replayable 0-RTT early data while the handshake continues
  • Client sends ClientHello with supported cipher suites and key share
  • Server responds with ServerHello, certificate, key share, finished
  • Client sends finished, data can start flowing immediately
  • 0-RTT uses a pre-shared key from an earlier session to send replayable early data while the handshake continues
4. What is a 100 Continue response? When would you use it, and what problems does it solve?
  • 100 Continue indicates the server is willing to receive the request body
  • Client sends Expect: 100-continue header before sending large body
  • Server responds with 100 if it will accept, or 417 if not
  • Solves: avoid sending large body to a server that might reject it (auth, Content-Type validation)
5. Explain how HTTP caching works. What is the difference between `max-age`, `no-cache`, and `no-store`?
  • `max-age=3600`: cache for 1 hour, serve from cache without revalidation
  • `no-cache`: always revalidate with server (send If-None-Match or If-Modified-Since), use cached copy if 304
  • `no-store`: never cache, must fetch fresh every time
  • ETag vs Last-Modified: ETags are opaque validators, more precise; Last-Modified is timestamp-based
  • `private` vs `public`: private only caches in browser, public can be cached by CDNs/proxies
6. What is certificate pinning and why would you use it? What are the risks?
  • Pinning locks your client to only trust a specific certificate or public key
  • Prevents MITM even if a CA is compromised and issues a forged certificate
  • HSTS tells browsers to use HTTPS; it does not pin a certificate. Expect-CT is deprecated and is not a pinning mechanism.
  • For native apps, pinning a certificate or public key can reduce reliance on the CA system, but stale pins can lock users out after rotation.
  • Use backup public-key pins and test certificate rotation and recovery before release. Avoid fetching replacement pins over the connection being protected.
7. What is the HEAD method used for in practice?
  • Like GET but returns only headers, no body
  • Checking if a resource exists before fetching (for large files)
  • Checking cache freshness with a conditional request, such as `HEAD /file` plus `If-None-Match`; a matching validator can produce `304 Not Modified`
  • Proxies use HEAD to validate if cached response is still fresh without downloading entire body
  • Used in webhook signature verification (HEAD to check payload without processing)
8. Describe the head-of-line blocking problem in HTTP/1.1 and HTTP/2. How does HTTP/3 solve it?
  • HTTP/1.1: browsers open 6 connections per origin, but each connection still queues requests (pipelining was never fully implemented)
  • HTTP/2: multiplexing allows parallel requests, but TCP enforces ordering — if packet N is lost, all streams wait for retransmission even if their data arrived
  • HTTP/3: QUIC tracks streams independently, loss only blocks the affected stream, others continue
  • Trade-off: HTTP/3's reliability is at stream level, so a single lost packet in stream 1 does not block stream 2
9. What is the Connection header used for with Keep-Alive? How does it affect server resource usage?
  • HTTP/1.1 connections are persistent by default; `Connection: keep-alive` can request reuse explicitly
  • `Connection: close` terminates after response
  • Reduces TCP handshake overhead (3-way handshake per request without keep-alive)
  • Server must manage connection pool per client — too many idle keep-alive connections can exhaust file descriptors and memory
  • Servers set `keep-alive timeout` to close idle connections after N seconds
10. What is QUIC and why does HTTP/3 use UDP instead of TCP?
  • QUIC is a reliable, ordered, congestion-controlled transport built on UDP
  • TCP requires separate handshakes for TCP and TLS; QUIC combines them into fewer round trips
  • QUIC implements its own loss detection and recovery independently of the path (handles reordering natively)
  • Allows connection migration (switch IP addresses without dropping connection)
  • Runs on UDP:443 so it needs firewall cooperation; drops back to HTTP/2 when blocked
  • Trade-off: userspace implementation means more CPU overhead than kernel-space TCP
11. How does the HTTP Upgrade header work? When would you use it?
  • `Upgrade: websocket` header tells server the client wants to switch protocols
  • Server responds with `101 Switching Protocols` if it accepts
  • Commonly used for WebSocket over HTTP/1.1; HTTPS through an HTTP proxy normally uses CONNECT to establish a tunnel
  • After 101, the connection switches to the new protocol — same TCP connection, different application protocol
  • Most common: WebSocket upgrade from HTTP to ws:// or wss://
12. What is Content-Encoding and how does it affect HTTP performance? Name the common encodings.
  • Content-Encoding: gzip, br (Brotli), deflate, zstd — tells client how to decode the response body
  • Compression reduces bytes over wire, significant for text-based content (HTML, JSON, CSS, JS)
  • Accept-Encoding: client advertises what it supports; server picks one
  • Order matters: typically `Accept-Encoding: gzip, br, deflate` — server picks preferred
  • For binary formats (images, video), compression is often already applied; additional HTTP compression adds overhead
13. What is the difference between `Vary: Accept-Encoding` and `Vary: Accept-Language` headers?
  • Vary tells caches that the response varies based on those request headers
  • `Vary: Accept-Encoding`: same URL, different encoding (gzip vs brotli) = different cached response
  • `Vary: Accept-Language`: same URL, different language (en vs fr) = different cached response
  • Without Vary, a cache might serve gzip-compressed response to a client that expects plain text
  • Can combine: `Vary: Accept-Encoding, Accept-Language` — cache key becomes tuple of all three
14. What is HTTP/2 server push? How does it work, and why might you disable it?
  • Server push lets server send resources to client before client asks for them (push promises)
  • Client receives pushed responses alongside requested page — no extra RTT for CSS/JS/fonts
  • Implementation: `` in HTML or `PUSH_PROMISE` frames in HTTP/2
  • Problem: server pushes resources client already has (already in cache) — wastes bandwidth
  • Modern alternative: `` in HTML gives client control — browser only fetches what's needed
  • Most sites disable HTTP/2 server push in favor of preload hints
15. Explain the HTTP/2 stream prioritization mechanism. How does it affect page load performance?
  • The original HTTP/2 prioritization scheme used stream weights (1-256) and dependency flags; RFC 9218 notes that this scheme was deprecated because deployment and interoperability were limited
  • RFC 9218 defines the version-independent `Priority` header and HTTP/2 and HTTP/3 reprioritization frames
  • Priority values are hints; servers choose how to schedule competing responses and may ignore them
  • Prioritization can help deliver critical resources before less urgent ones, but results depend on client, server, and intermediary behavior
16. What is the `Expect: 100-continue` header used for? What can go wrong if you don't handle it?
  • Client sends `Expect: 100-continue` before sending body, waits for 100 before proceeding
  • Purpose: check if server will accept the body before sending large data (avoid sending GB to a 401 response)
  • Server responds 100 to proceed, or 417 (Expectation Failed) to reject
  • `Expect: 100-continue` is optional. Clients can send the body after receiving 100 or after their wait period expires.
  • Some proxies mishandle the interim response, so clients need a timeout and a fallback that sends the body.
  • Used in resumable uploads and large file uploads where auth must be validated first
17. How does HTTP tunneling work? When is it used and what are the security implications?
  • CONNECT method creates a tunnel — opens a TCP pipe to the destination through a proxy
  • `CONNECT example.com:443 HTTP/1.1` → proxy responds `200 Connection Established` → full encrypted tunnel
  • Used for HTTPS through corporate proxies — client establishes tunnel, then does TLS inside it
  • Security issue: proxies cannot inspect encrypted traffic (MITM is impossible on CONNECT tunnels)
  • Enterprise proxies use this to inspect HTTPS traffic — they terminate TLS at the proxy first
  • Malicious use: exfiltrate data through tunnel to bypass DLP controls
18. What is a partial range request (byte serving)? How does `Content-Range` work?
  • Client requests specific byte range: `Range: bytes=0-1023` — gets only that portion
  • Server responds `206 Partial Content` with `Content-Range: bytes 0-1023/4096`
  • `Content-Range: bytes 0-1023/4096` — served bytes 0-1023 of 4096 total
  • Used by video players (seek to specific position without downloading entire file)
  • Without Range header: `200 OK` with full file — wasteful for large media
  • Server can also respond `416 Range Not Satisfiable` if range is invalid (beyond file size)
19. What is the difference between `Transfer-Encoding: chunked` and Content-Length? When must you use chunked?
  • Content-Length: server tells client exact byte count before sending body
  • Chunked: server sends data in chunks with size prefix, no Content-Length needed
  • Chunked is required when: response is generated dynamically and total size unknown upfront
  • Example: streaming JSON array — you start sending `[` before knowing if it will be 10 or 10 million elements
  • For an HTTP/1.1 message with a body, Content-Length or chunked transfer coding can frame it when the length is known or unknown; a response can also be close-delimited
  • Use chunked encoding when the sender does not know the body size in advance; it is not required when Content-Length is available
20. What are Server-Sent Events (SSE) and how do they differ from WebSockets in terms of HTTP usage?
  • SSE is one-way: server pushes events over a long-lived HTTP connection
  • Uses `Content-Type: text/event-stream` and standard HTTP — works through proxies without special handling
  • WebSockets use `Upgrade: websocket` and switch to a different protocol on the same TCP connection
  • SSE: simpler, works with HTTP/2 multiplexing, automatic reconnection, no custom client library needed
  • WebSockets: bidirectional, lower latency for high-frequency two-way communication
  • For server-to-client push (notifications, live updates, streams): SSE is often simpler to implement and debug

Further Reading


Conclusion

Copy/Paste Checklist

# Check HTTP headers with curl
curl -I https://example.com

# Check SSL/TLS configuration
curl -v https://example.com 2>&1 | grep -E "(SSL|TLS|HTTP/)"

# Test specific HTTP method
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name":"Alice"}'

# Check for security headers
curl -I https://example.com | grep -iE "(strict-transport|x-frame|x-content-type)"

# Monitor response time
curl -w "\nTime: %{time_total}s\n" https://example.com

Use HTTP methods, status codes, and headers consistently so clients and intermediaries can act on responses without guessing. For production services, use HTTPS and choose protocol features based on measured client and network behavior.

Category

Related Posts

Forward and Reverse Proxies: Routing, Trust, and Use Cases

Learn how forward and reverse proxies handle HTTP traffic, CONNECT tunnels, TLS termination, caching, routing, trusted headers, and production failures.

#networking #proxies #http

SSL, TLS, and HTTPS: Securing Web Communication

Understand TLS handshake, certificates, cipher suites, and how HTTPS works. Learn the differences between SSL and TLS and why encryption matters.

#networking #security #ssl

TCP, IP, and UDP: Understanding Internet Transport Protocols

Compare TCP vs UDP, learn the three-way handshake, flow control, congestion control, when to use each protocol, and how QUIC changes things.

#networking #tcp #udp