HTTP Persistent Connections: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(48 intermediate revisions by the same user not shown)
Line 14: Line 14:
=Overview=
=Overview=


By ''connection'', we understand the TCP/IP connection opened between a HTTP client and a HTTP server. Prior to the introduction of the persistent connections by HTTP/1.1, there was no official specification on how to establish and maintain persistent connections. This article assumes HTTP/1.1 and it ''does not'' apply to HTTP/1.0. For Advantages and Disadvantages of persistent connections, see below.
By ''connection'', we understand the TCP/IP connection opened between a HTTP client and a HTTP server. Prior to the introduction of the persistent connections by HTTP/1.1, there was no official specification on how to establish and maintain persistent connections. In most cases, a separate TCP connection was established to fetch each URL. This article assumes HTTP/1.1 and it ''does not'' apply to HTTP/1.0. This is how [[HTTP/1.0 Persistent Connections|persistent connections are negotiated in HTTP/1.0]].


=A Persistent Connection is a Point to Point Affair=
{{Warn|A ''HTTP persistent connection'' is a connection that is kept open after the initial request/response exchange and that can be used for sending of further request/response sequences. In HTTP/1.1, persistent connection is the default behavior.}}


=Direct Client - Origin Server Connection=
Measurements of actual HTTP/1.1 connections had shown that persistent connections are preferable, for several reasons: ''resources'' (CPU time, memory, and network bandwidth) are saved on routers and hosts by opening and closing fewer TCP connections, ''network congestion'' is reduced by eliminating the packets caused by TCP open, ''latency on subsequent requests'' is reduced since there is no time spent with TCP connection opening handshake. This last point is even more important in the case of SSL connections. Persistent connections can be used to [[#Pipelining_Requests|pipeline]] requests.


=Connection via a Proxy=
Persistent connections may also present disadvantages, for heavily loaded servers by clients that stay idle for a long time. That is why [[#Timing_Out_a_Persistent_Connection|implementing timeout on persistent connections]] is important. The higher the timeout, more server processes will be kept occupied waiting on connections with the idle clients.
 
=Client/Origin Server Connection=
 
Both HTTP/1.1 client and server implementation must implement persistent connections, and assume persistent connections are the default. The client must assume that the server will maintain a persistent connection, even after an error response. The server must assume that the client that opened a connection intends to maintain it, unless a "Connection: close" header was sent with the request. Naturally, in order to remain persistent, all messages on the connection must have a self-defined message length, declared as value of the [[HTTP Entity Header Content-Length|Content-Length]] header, and not one defined by the closure of the connection, or be encoded with the chunkedtransfer encoding.
 
Both the client and the server may chose to close the underlying TCP connection, by signaling that with the use of the [[HTTP General Header Connection|Connection]] header. If the client intends to close the connection after sending a request, it must include the "Connection: close" header in the request:
 
<pre>
Connection: close
</pre>
 
If the server chooses to close the connection after sending a response, it must include the "Connection: close" header in the response. However, a server should not close the connection while in the middle of transmitting a response.


Once the connection has been signaled as "closed", none of the parties must send any more requests/responses on that connection: the request or response that was used to send the header becomes the last one for that connection.


=Connection via a Proxy=


HTTP/1.1 proxy implementation must implement persistent connections, and assume persistent connections are the default.


From the proxy's perspective, the connection with the client and the connection with the origin server are handled independently: each persistent connection signaling with "Connection" header applies to only one transport link. If a proxy receives a request with a "Connection: close" header, it must not be communicated by the proxy over further connections.


A HTTP persistent connection is a TCP/IP connection between the client and server that allows more that one request per connection.
=Timing Out a Persistent Connection=


It is the client that initially requests the connection to be kept alive. In HTTP 1.1, a persistent connection is initiated by specifying a "Keep-Alive" value for the "Connection" request header:
Persistent connections maintained by long-time idle clients change from resource-savers into a resource wasters. That is why the servers must monitor persistent connection to detect idle-ness and close a persistent connected after a certain timeout. The specification places no requirement on the existence or the length of the timeout, however the implementation of the timeout is a good idea. Not sending "Connection: close" does not mean that the server promises to keep the connection open forever.


<pre>
Browsers also are aware of their user's activity and usually close idle connections after a while. This is how the connection timeout can be configured for [[Firefox#Connection_Timeout|Firefox]].
GET ... HTTP/1.1
Host: ...
Connection: Keep-Alive
</pre>


The server may or may not support persistent connections. If the server does support them, it will confirm that by including with the response a "Connection" response header:
When either party wants to close the connection, it should do it gracefully by using the "Connection" header as described in "[[#Client.2FOrigin_Server_Connection|Client/Origin Server Connection]]" section.


<pre>
Clients, servers and servers may close the connection at any time, so all these parts must be coded to be able to handle an asynchronous closure of the connection. For example, the client should be able to create a new connection and re-send the idempotent request.
200 OK
Content-Length: ...
Connection: Keep-Alive
</pre>


Once both the client and the server have agreed on using persistent connections, they will keep the underlying TCP/IP connection open, and subsequent requests from that client will be sent over the persistent connection.
=Flow Control=


=Advantages=
The server should rely on the TCP's flow control mechanism to resolve temporary overloads, rather than terminating connections with the expectation that the client will retry. More details: {{External|https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2}}


* Both the client and the server avoid multiple TCP and SSL handshakes.
=Pipelining Requests=
* The network throughput is increasing by avoiding TCP slowstart algorithms.


=Disadvantages=
A client may choose to pipeline request over a persistent connection: it may sent multiple requests without waiting for each response. The server must respond in the same order in which the requests were received.


* If the persistent connections are maintained for too long for idle clients, this may cause performance problems in heavily loaded servers. The higher the timeout, the more server processes will be kept occupied waiting on connections with idle clients.
{{External|https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.2.2}}


=Configuration=
=Configuration=
==httpd==


For details on how to configure HTTP persistent connections with httpd, see:
For details on how to configure HTTP persistent connections with httpd, see:
Line 62: Line 71:
:[[httpd Persistent Connection Configuration]]
:[[httpd Persistent Connection Configuration]]
</blockquote>
</blockquote>
=Related=
* [[HTTP Entity Header Connection|The 'Connect' Header]]

Latest revision as of 16:48, 9 January 2017

External

Internal

Overview

By connection, we understand the TCP/IP connection opened between a HTTP client and a HTTP server. Prior to the introduction of the persistent connections by HTTP/1.1, there was no official specification on how to establish and maintain persistent connections. In most cases, a separate TCP connection was established to fetch each URL. This article assumes HTTP/1.1 and it does not apply to HTTP/1.0. This is how persistent connections are negotiated in HTTP/1.0.


A HTTP persistent connection is a connection that is kept open after the initial request/response exchange and that can be used for sending of further request/response sequences. In HTTP/1.1, persistent connection is the default behavior.

Measurements of actual HTTP/1.1 connections had shown that persistent connections are preferable, for several reasons: resources (CPU time, memory, and network bandwidth) are saved on routers and hosts by opening and closing fewer TCP connections, network congestion is reduced by eliminating the packets caused by TCP open, latency on subsequent requests is reduced since there is no time spent with TCP connection opening handshake. This last point is even more important in the case of SSL connections. Persistent connections can be used to pipeline requests.

Persistent connections may also present disadvantages, for heavily loaded servers by clients that stay idle for a long time. That is why implementing timeout on persistent connections is important. The higher the timeout, more server processes will be kept occupied waiting on connections with the idle clients.

Client/Origin Server Connection

Both HTTP/1.1 client and server implementation must implement persistent connections, and assume persistent connections are the default. The client must assume that the server will maintain a persistent connection, even after an error response. The server must assume that the client that opened a connection intends to maintain it, unless a "Connection: close" header was sent with the request. Naturally, in order to remain persistent, all messages on the connection must have a self-defined message length, declared as value of the Content-Length header, and not one defined by the closure of the connection, or be encoded with the chunkedtransfer encoding.

Both the client and the server may chose to close the underlying TCP connection, by signaling that with the use of the Connection header. If the client intends to close the connection after sending a request, it must include the "Connection: close" header in the request:

Connection: close

If the server chooses to close the connection after sending a response, it must include the "Connection: close" header in the response. However, a server should not close the connection while in the middle of transmitting a response.

Once the connection has been signaled as "closed", none of the parties must send any more requests/responses on that connection: the request or response that was used to send the header becomes the last one for that connection.

Connection via a Proxy

HTTP/1.1 proxy implementation must implement persistent connections, and assume persistent connections are the default.

From the proxy's perspective, the connection with the client and the connection with the origin server are handled independently: each persistent connection signaling with "Connection" header applies to only one transport link. If a proxy receives a request with a "Connection: close" header, it must not be communicated by the proxy over further connections.

Timing Out a Persistent Connection

Persistent connections maintained by long-time idle clients change from resource-savers into a resource wasters. That is why the servers must monitor persistent connection to detect idle-ness and close a persistent connected after a certain timeout. The specification places no requirement on the existence or the length of the timeout, however the implementation of the timeout is a good idea. Not sending "Connection: close" does not mean that the server promises to keep the connection open forever.

Browsers also are aware of their user's activity and usually close idle connections after a while. This is how the connection timeout can be configured for Firefox.

When either party wants to close the connection, it should do it gracefully by using the "Connection" header as described in "Client/Origin Server Connection" section.

Clients, servers and servers may close the connection at any time, so all these parts must be coded to be able to handle an asynchronous closure of the connection. For example, the client should be able to create a new connection and re-send the idempotent request.

Flow Control

The server should rely on the TCP's flow control mechanism to resolve temporary overloads, rather than terminating connections with the expectation that the client will retry. More details:

https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2

Pipelining Requests

A client may choose to pipeline request over a persistent connection: it may sent multiple requests without waiting for each response. The server must respond in the same order in which the requests were received.

https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.2.2

Configuration

httpd

For details on how to configure HTTP persistent connections with httpd, see:

httpd Persistent Connection Configuration