Skip to main content

RFC 2818 - 2. HTTP Over TLS

2. HTTP Over TLS​

Core Principle​

Conceptually very simple: HTTP/TLS is very simple. Simply use HTTP over TLS precisely as you would use HTTP over TCP.

2.1. Connection Initiation​

Process:

1. Client → Server: Establish TCP connection (port 443)
2. Client → Server: Send TLS ClientHello
3. ↔ TLS Handshake Process ↔
4. After handshake complete: Client may initiate first HTTP request

Requirements:

  • ✅ HTTP client acts as TLS client
  • ✅ Connect to appropriate port (default 443)
  • ✅ Send TLS ClientHello to begin handshake
  • ✅ All HTTP data MUST be sent as TLS "application data"

Example Flow:

Client:
1. TCP connect to www.example.com:443
2. Send ClientHello

Server:
3. Respond ServerHello + Certificate
4. ServerHelloDone

Client:
5. ClientKeyExchange
6. ChangeCipherSpec
7. Finished

Server:
8. ChangeCipherSpec
9. Finished

← TLS Handshake Complete →

Client:
10. Send encrypted HTTP request:
GET / HTTP/1.1
Host: www.example.com

2.2. Connection Closure​

TLS provides a facility for secure connection closure.

Closure Alert​

Definitions:

  • Valid Closure: Received proper closure alert
  • Incomplete Close: Close connection immediately after sending closure alert
  • Premature Close: Connection closed without receiving closure alert

Requirements:

  • ✅ Implementations MUST initiate closure alert exchange before closing connection
  • ⚠️ Implementations MAY close connection after sending closure alert (without waiting)
  • ❌ Connections with premature close MUST NOT reuse session

2.2.1. Client Behavior​

Issue: HTTP uses connection closure to signal end of server data.

Client MUST:

  • ✅ Treat any premature close as error
  • ✅ Treat received data as potentially truncated
  • ✅ Send closure alert before closing connection

Special Cases:

  1. Response without Content-Length:
HTTP/1.1 200 OK
Content-Type: text/html
[Connection close indicates end]

← Premature close cannot distinguish server from attacker →
  1. Content-Length present but not fully read:
HTTP/1.1 200 OK
Content-Length: 1000
[Only 500 bytes received before close]

← Cannot determine if server error or attack →

Exception: If received data matches Content-Length, should treat as complete.

Client Example:

✅ Normal closure:
Client: Send closure_alert
Wait for server closure_alert
Close connection

⚡ Quick closure:
Client: Send closure_alert
Close connection immediately (don't wait)
← This generates incomplete close at server →

2.2.2. Server Behavior​

RFC 2616 Requirement: Servers MUST recover gracefully from client closure.

Server SHOULD:

  • ✅ Be prepared to receive incomplete close from client
  • ✅ Be willing to resume TLS sessions closed in this fashion
  • ✅ Attempt to exchange closure alerts with client
  • ⚡ MAY close connection after sending closure alert

Implementation Note:

HTTP without persistent connections:
- Server signals end of data by closing connection
- But client may have already sent closure alert and disconnected

2.3. Port Number​

Default Port: 443

Rationale:

HTTP server expects: Request-Line (e.g., GET / HTTP/1.1)
TLS server expects: ClientHello

← Cannot distinguish on same port →

Solution: Use different ports
- HTTP: 80
- HTTPS: 443

Examples:

# HTTP (cleartext)
curl http://www.example.com:80/

# HTTPS (encrypted)
curl https://www.example.com:443/

2.4. URI Format​

Protocol Identifier: https:// (instead of http://)

Examples:

https://www.example.com/~smith/home.html
https://api.example.com:8443/v1/users
https://192.168.1.1/admin

URI Components:

https://www.example.com:443/path?query#fragment
↑ ↑ ↑ ↑ ↑ ↑
scheme host port path query fragment