In HTTP protocol, the Connection
header serves as a communication channel between client and server to negotiate connection persistence. While most developers are familiar with its usage in requests, its appearance in responses carries significant implications.
When a server includes Connection: close
in its response, it's explicitly instructing that the TCP connection should be terminated after the current transaction, regardless of the client's initial request. This behavior overrides any keep-alive
request from the client.
HTTP/1.1 200 OK
Content-Type: text/html
Connection: close
Content-Length: 1234
<html>...</html>
Servers might enforce connection closure for several technical reasons:
- Resource conservation during high traffic periods
- Security policies preventing prolonged connections
- Legacy system compatibility requirements
- Server maintenance or configuration changes
Here's how different web servers handle this header:
Apache Configuration
<IfModule mod_headers.c>
Header set Connection "close"
</IfModule>
Nginx Implementation
server {
...
add_header Connection "close";
...
}
Modern HTTP clients should properly handle this directive. Here's example handling in Node.js:
const http = require('http');
const options = {
hostname: 'example.com',
port: 80,
path: '/',
method: 'GET',
headers: {
'Connection': 'keep-alive'
}
};
const req = http.request(options, (res) => {
if (res.headers.connection === 'close') {
console.log('Server requested connection closure');
// Implement cleanup logic here
}
});
While connection persistence improves performance, forced closures introduce:
- Additional TCP handshake overhead
- Increased latency for subsequent requests
- Higher server resource consumption
When encountering unexpected connection closures:
- Verify server configuration files
- Check for middleware interference
- Inspect load balancer settings
- Review server resource metrics
While most developers are familiar with Connection: close
in client requests, its appearance in server responses often causes confusion. In HTTP/1.1, connections are persistent by default, but either party (client or server) can signal the intention to close the connection after the current transaction.
When a server includes Connection: close
in its response headers, it overrides any keep-alive request from the client. This means the server will:
- Close the TCP connection immediately after sending the response
- Ignore any subsequent requests on the same connection
- Force the client to establish a new connection for future requests
Here's a common situation where servers might use this header:
// Server response example
HTTP/1.1 200 OK
Content-Type: application/json
Connection: close
Content-Length: 42
{"status":"complete","message":"Processing done"}
The server might choose to close connections when:
- Handling sensitive transactions (banking operations)
- Server is under heavy load and needs to free resources
- Implementing security measures against connection hijacking
- Upgrading or maintaining server infrastructure
Proper client implementation should anticipate this behavior:
// Python example with requests library
import requests
response = requests.get('https://api.example.com/resource', headers={'Connection': 'keep-alive'})
if response.headers.get('Connection') == 'close':
print("Server terminated connection - need new connection for next request")
# Re-establish connection for subsequent requests
Note that in HTTP/2, the Connection
header is prohibited as the protocol handles connection management differently. This behavior is specific to HTTP/1.x implementations.