Networking
Beginner 13 min read Networking

HTTP & HTTPS

HTTP is the application protocol of the web: a request/response model built on TCP. Master methods, status codes, headers, caching and the TLS encryption that HTTPS adds on top.

HTTPHTTPSstatus codesmethodsTLSheaderscurl
Introduction

What is this?

HTTP (RFC 9110) is a stateless request/response protocol in which a client sends a method, target, headers and optional body, and a server replies with a status code, headers and a body. HTTPS is HTTP over TLS (RFC 8446), encrypting the message and authenticating the server. HTTP/2 (RFC 9113) adds multiplexing on top of the same semantics.

Motivation

Why do you need it?

  • Every API, web service and health check you will build speaks HTTP.
  • Status code classes let you triage failures instantly — 4xx is client, 5xx is server.
  • Headers control caching, auth, content negotiation and proxy behavior.
  • Understanding HTTPS is required for certificates, TLS termination and secure microservices.
Think about it

Mental model

Imagine

Ordering at a restaurant

Think of

An HTTP request/response

The menu is the API, your order is the request (method + target), and the kitchen's reply is the response with a status — a 200 dish, a 301 dish moved to another table, or a 404 dish not on the menu.

Mechanics

How it works

  • The client opens a TCP connection and sends a request line: METHOD /path HTTP/version, headers, and optionally a body.
  • The server reads the request, executes the handler, and responds with a status line, headers and a body.
  • Status codes are grouped: 1xx informational, 2xx success, 3xx redirection, 4xx client error, 5xx server error.
  • Connection reuse (keep-alive) and HTTP/2 multiplexing avoid a new handshake per request.
  • With HTTPS, a TLS handshake first exchanges certificates and a session key, then all HTTP bytes travel encrypted.

An HTTP transaction and the status code families.

Client request
Server processing
2xx
3xx
4xx
5xx
Reference

Key commands

curl -sI https://example.com

Fetch only the response headers with a HEAD request.

curl -v https://example.com

Verbose: show TLS handshake, request and response headers.

curl -s -o /dev/null -w '%{http_code} %{time_total}\n' https://example.com

Print just the status code and total time.

curl -X POST -H 'Content-Type: application/json' -d '{"name":"dev"}' https://api.example.com/users

Send a JSON POST request with a header and body.

openssl s_client -connect example.com:443 -servername example.com

Dump the TLS certificate and handshake details.

Hands-on

Examples

Inspect a real HTTPS response

Inspect a real HTTPS response
$ curl -I https://example.com
HTTP/2 200
content-encoding: gzip
content-type: text/html; charset=UTF-8
date: Sat, 08 Aug 2026 10:00:00 GMT
server: ECS (dcb/7EFE)
x-cache: HIT
$ curl -v -o /dev/null https://example.com
* Connected to example.com (93.184.216.34) port 443
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
> GET / HTTP/2
> Host: example.com
< HTTP/2 200

curl -I sends a HEAD request and shows response headers; curl -v reveals the TCP/TLS handshake and the exact request line. Both prove the server is up, speaks HTTP/2 over TLS 1.3, and returned 200.

Real world

In production

  • Health checks (GET /healthz) drive load balancer routing and orchestrator restarts.
  • Cache-Control and ETag headers shape CDN and browser caching to cut origin load.
  • Idempotent methods (PUT, DELETE) make retries safe when a proxy times out.
  • Standardized status codes let clients, SREs and on-call tooling share one triage vocabulary.
Guidelines

Best practices

  • Return accurate status codes — 404 for missing, 429 for rate limits, 503 for maintenance.
  • Use HEAD/GET for health checks so they don't write data or allocate heavy bodies.
  • Set Cache-Control and ETag explicitly; defaults often over-cache or under-cache.
  • Terminate TLS at the edge with modern suites, HTTP/2 and HSTS enabled.
  • Log method, path, status and duration to a central place for latency triage.
Watch out

Common mistakes

  • Returning 500 for client errors — clients can't fix what you mislabel.
  • Sending secrets in URL query strings that end up in access logs.
  • Disabling keep-alive so every request pays a new TCP handshake.
  • Ignoring the 429 Too Many Requests path, which silently turns into a thundering herd of retries.
Root cause analysis

Common issues

Error
502 Bad Gateway
Root cause

A reverse proxy could not get a valid response from the backend.

Fix

Check the backend service health, logs and whether it still listens on the configured port (ss -tulpn).

Error
503 Service Unavailable
Root cause

The server is up but refuses the request — maintenance, capacity or startup.

Fix

Inspect health checks, connection limits and deployment state; the client's retry with backoff is appropriate.

Error
504 Gateway Timeout
Root cause

The backend took longer than the proxy timeout to respond.

Fix

Raise proxy_read_timeout, or profile the slow endpoint — it is often a slow DB query or upstream call.

When things break

Debugging tips

  • curl -v to see the exact bytes both ways; headers often solve the mystery.
  • Compare status codes and timing with curl -w to separate latency from errors.
  • Use openssl s_client to verify the certificate chain and expiry.
  • Check for a reverse proxy adding X-Forwarded-For — the app must trust it to log real client IPs.
Interviews

Interview checkpoint

Test yourself

Quick quiz

0/3
1

Which status code tells the client it must authenticate before retrying?

2

Which HTTP method is idempotent?

3

HTTPS encrypts the URL path, headers and body of every request in transit.

Quick reference

Cheat sheet

Status code families
1xxInformational — request received, continuing
2xxSuccess — 200 OK, 201 Created, 204 No Content
3xxRedirection — 301, 302, 304 Not Modified
4xxClient error — 400, 401, 403, 404, 429
5xxServer error — 500, 502, 503, 504
curl essentials
curl -sI URLHeaders only (HEAD)
curl -v URLFull handshake + headers
curl -w '%{http_code}'Print only the status code
curl -X POST -d '...' URLSend a request body
Go deeper

Official documentation