G
GuideDevOps
Lesson 14 of 28

HTTP / HTTPS Protocols

Part of the Networking Basics tutorial series.

HTTP and HTTPS are the protocols that power the web. Understanding how they work is essential for deploying web services, debugging connectivity issues, and building scalable APIs.

HTTP Basics

HTTP (HyperText Transfer Protocol) is a request-response protocol for transferring data:

Client                          Server
   ↓ (Request: GET /index.html)  ↓
   ├─────────────────────────────→
   │
   ← (Response: 200 OK)          ←
   ├─────────────────────────────┤
   │  [HTML content]             │
   │

Key Characteristics:

  • Stateless — Each request independent
  • Request-Response — Client initiates, server responds
  • Plain text — Human-readable headers
  • Port 80 — Default for HTTP
  • Insecure — No encryption (visible to anyone on network)

HTTP Versions

VersionReleaseSpeedMultiplexingServer PushStatus
HTTP/1.01996SlowNoNoObsolete
HTTP/1.11997ModerateNoNoStill used
HTTP/22015FastYesYesCommon
HTTP/32022FasterYesYesModern

HTTP/1.1 Problem: Each request needs separate TCP connection

Request 1 → Connection 1 → Response 1
Request 2 → Connection 2 → Response 2
Request 3 → Connection 3 → Response 3
→ Slow! Multiple connections = overhead

HTTP/2 Solution: Multiplexing over single connection

Request 1 ─┬→ Single Connection → Response 1
Request 2 ─┤                    → Response 2
Request 3 ─┘                    → Response 3
→ Fast! All requests over same connection

HTTP Request

Anatomy of an HTTP request:

GET /api/users HTTP/1.1
Host: api.example.com
User-Agent: curl/7.68.0
Accept: application/json
Authorization: Bearer token123
Content-Length: 0

[Optional body for POST/PUT/PATCH]

Components:

  • Method (GET, POST, PUT, DELETE, PATCH)
  • Path (/api/users)
  • Version (HTTP/1.1)
  • Headers (Host, User-Agent, Authorization)
  • Body (data payload for POST/PUT)

HTTP Methods

MethodPurposeSafeIdempotentBody
GETRetrieve dataYesYesNo
POSTCreate new resourceNoNoYes
PUTReplace entire resourceNoYesYes
PATCHPartial updateNoNoYes
DELETERemove resourceNoYesNo
HEADLike GET, no bodyYesYesNo
OPTIONSQuery allowed methodsYesYesNo

Safe: Doesn't modify data on server Idempotent: Multiple calls = same result

HTTP Status Codes

CodeCategoryMeaningExamples
1xxInformationalRequest received, continuing100 Continue
2xxSuccessRequest succeeded200 OK, 201 Created
3xxRedirectFurther action needed301 Moved, 304 Not Modified
4xxClient ErrorBad request400 Bad Request, 404 Not Found
5xxServer ErrorServer failed500 Server Error, 503 Unavailable

Common Codes:

200 OK                 Request succeeded
201 Created            Resource created successfully
204 No Content         Success, no response body
301 Moved Permanently  Redirect to new location
304 Not Modified       Use cached version
400 Bad Request        Invalid syntax
401 Unauthorized       Authentication required
403 Forbidden          Permission denied
404 Not Found          Resource doesn't exist
500 Server Error       Unexpected error
503 Service Unavailable Server temporarily down

HTTPS (HTTP Secure)

HTTPS is HTTP over TLS/SSL encryption:

HTTP:  Client ←→ Server  (plain text, visible)
HTTPS: Client ←TLS/SSL→ Server  (encrypted, invisible)

Differences:

  • Port 443 (vs HTTP port 80)
  • TLS handshake before data transfer
  • Certificates verify server identity
  • Encryption protects data
  • Required for sensitive data (login, payment)

HTTPS Connection Establishment

Client                              Server
   ├─ ClientHello (supported ciphers) ──→
   ├──────────────────────────────────→ ServerHello
   ├← ServerCertificate (public key) ←──┤
   ├← ServerKeyExchange
   ├← ServerHelloDone
   ├─ ClientKeyExchange (symmetric key)→
   ├─ ChangeCipherSpec ─────────────────→
   ├─ Finished (encrypted) ────────────→
   ├← ChangeCipherSpec
   ├← Finished (encrypted)
   │
   └─ Encrypted data transfer ←────────→
      (Now all data is encrypted)

HTTP Headers

Request Headers (client → server):

Host: api.example.com              # Server hostname
Authorization: Bearer token123     # Authentication
Content-Type: application/json     # Request body format
Accept: application/json           # Desired response format
User-Agent: curl/7.68.0           # Client identifier
Cache-Control: no-cache           # Caching instructions
If-Modified-Since: <date>         # Conditional request
Cookie: session_id=abc123         # Session data

Response Headers (server → client):

Content-Type: application/json            # Response body format
Content-Length: 1024                      # Body size in bytes
Cache-Control: max-age=3600              # Cache for 1 hour
Set-Cookie: session_id=xyz789; Path=/   # Set session cookie
Location: /api/users/123                  # Redirect target
ETag: "abc123"                          # Version identifier
Access-Control-Allow-Origin: *           # CORS (cross-origin)
Strict-Transport-Security: max-age=31536000  # Force HTTPS

REST API Example

Making HTTP requests:

# GET request
curl -X GET "http://api.example.com/users" \
  -H "Authorization: Bearer token123" \
  -H "Accept: application/json"
 
# POST request (create)
curl -X POST "http://api.example.com/users" \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice", "email": "alice@example.com"}'
 
# PUT request (replace)
curl -X PUT "http://api.example.com/users/123" \
  -H "Content-Type: application/json" \
  -d '{"name": "Bob", "email": "bob@example.com"}'
 
# DELETE request
curl -X DELETE "http://api.example.com/users/123"

HTTP Connection Management

Keep-Alive (persistent connections):

# HTTP/1.1 keeps connection open by default
curl -v http://example.com
 
# Output: Connection #0 to example.com left intact
# (Connection stays open for next request)

Connection Pooling:

Application
    ↓
  Pool 1: ← Connection to api.example.com
  Pool 2: ← Connection to db.example.com
  Pool 3: ← Connection to cache.example.com
    ↓
Reuse connections instead of creating new ones

Checking HTTP/HTTPS

View response headers:

curl -i http://example.com
 
# Output:
# HTTP/1.1 200 OK
# Date: Wed, 09 Apr 2026 10:00:00 GMT
# Server: nginx/1.18.0
# Content-Length: 1234
# Content-Type: text/html

Check HTTP version:

curl -w "HTTP Version: %{http_version}\n" http://example.com
 
# Result: HTTP Version: 1.1 or 2.0

Test HTTPS certificate:

openssl s_client -connect example.com:443
 
# Shows certificate details, chain, expiration

HTTP/HTTPS Best Practices

1. Always Use HTTPS

✓ Encrypt all traffic
✓ Verify server identity
✗ Never use HTTP for sensitive data

2. Set Appropriate Cache Headers

# Cache static assets
Cache-Control: public, max-age=31536000
 
# Don't cache sensitive data
Cache-Control: no-store, no-cache

3. Use Connection Pooling

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
 
session = requests.Session()
retry = Retry(connect=3, backoff_factor=0.5)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
 
# Now session reuses connections
response = session.get('http://api.example.com/users')

4. Implement Compression

Accept-Encoding: gzip, deflate

# Server responds with:
Content-Encoding: gzip

# Saves bandwidth on large responses

5. Monitor Performance

# Measure response time
time curl http://example.com
 
# Check connection time vs response time
curl -w "Connect: %{time_connect}\nTotal: %{time_total}\n" http://example.com

Key Concepts

  • HTTP = Request-response protocol for web
  • HTTPS = HTTP over TLS/SSL encryption
  • Methods = GET, POST, PUT, DELETE, PATCH
  • Status Codes = 2xx (success), 3xx (redirect), 4xx (client error), 5xx (server error)
  • Headers = Metadata about request/response
  • Port 80 = HTTP, Port 443 = HTTPS
  • Stateless = Each request independent
  • Keep-Alive = Reuse TCP connections
  • Always use HTTPS for production
  • Use appropriate cache headers for performance