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:
- Response without Content-Length:
HTTP/1.1 200 OK
Content-Type: text/html
[Connection close indicates end]
← Premature close cannot distinguish server from attacker →
- 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