HTTP Working Group Alexander Hopmann INTERNET-DRAFT ResNova Software, Inc. Expires SIX MONTHS FROM---> February 21st, 1996 Persistent HTTP Connections Status of this Memo This document is an Internet-Draft. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet- Drafts as reference material or to cite them other than as "work in progress." To learn the current status of any Internet-Draft, please check the "1id-abstracts.txt" listing contained in the Internet- Drafts Shadow Directories on ds.internic.net (US East Coast), nic.nordu.net (Europe), ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific Rim). Distribution of this document is unlimited. Please send comments to the HTTP working group at . Discussions of the working group are archived at . General discussions about HTTP and the applications which use HTTP should take place on the mailing list. This draft does not currently represent a consensus opinion of the HTTP Working Group. Abstract HTTP was designed to be an extremely lightweight stateless protocol based on TCP. However actual implementation experience suggests that the overhead inherent in establishing a separate TCP connection for every request represents a significant performance problem. This proposal suggests an optional facility for HTTP version 1.1 which allows a client to create persistent connections with a server. This facility is also designed to work with proxy servers. Table of Contents 1. Introduction 1.1 Purpose 1.2 Overall Operation 1.3 Proxy Servers 1.4 Sticky Headers 1.5 Compatibility with HTTP/1.0 1.6 Interaction With Security Protocols 1.7 Practical Considerations 2. Examples 3. Security Considerations 4. Acknowledgments 5. References 6. Author's Address 1. Introduction 1.1 Purpose The HyperText Transfer Protocol's strongest point is its simplicity. The creators of HTTP [1] made it stateless in order to simplify server design and also make servers more efficient. However with the extraordinary success of the World Wide Web, HTTP servers are often overloaded. In addition, the use of inline images and other associated data often requires a client to make multiple requests of the same server in a short amount of time. HTTP usually runs on top of TCP which has many performance limitations for short-lived connections. Because of the way that HTTP works, these performance problems can become quite serious. An excellent analysis of these performance problems is available [2]. This draft is being proposed as a component of HTTP version 1.1 [3]. It is based on work being done by the HTTP working group of the IETF. 1.2 Overall Operation HTTP version 1.1 provides a new request and response header field called "Connection". This header field allows the client and server to specify options which should only exist over that particular connection and must not communicated by proxies over further connections. The connection header field may have multiple tokens separated by commas. HTTP version 1.1 proxies must parse this field and for every value in this field, remove a header field of the same name from the request. When a client is connecting directly to an origin server it should send the following: Connection: persist Persist: The value is either a domain name for the origin server in the IANA domain, or the IP address of the origin server in dot form (a.b.c.d). The origin server must verify that this name corresponds to it, or must not establish a persistent connection. If the server agrees to create a persistent connection it will respond with the same two header fields. Both the client and server must send these two header fields with every request and response for the duration of the persistent connection. If either the client or the server omits the Persist header that request becomes the last one for the connection. A server should not establish a persistent connection with a HTTP/1.0 client that uses the above form of the Persist header (See section 1.5 for more information on backwards compatibility with HTTP 1.0 clients). Once the client has received the first response from the server containing the "Persist" header field, it may pipeline multiple requests without waiting for the response from the previous ones. The server must send all of the responses in the same order that the requests were made. When using persistent connections both the client and the server must obey one of the following two rules in order to transmit an entity body: either a) Send a content-length field in the header with the exact number of bytes in the entity-body. or b) Send the message as Content-type: multipart/mixed (Or some other multipart content type), with a boundary marker. The end of the entity-body is specified by the exact ending of the ending boundary. Although RFC 1521 (MIME part 1) specifies that multipart/mixed messages may have an epilogue after the ending boundary, this epilogue must not be present for clients and servers using persistent connections. 1.3 Proxy Servers When a client is connecting to a proxy server it must send an expanded form of the persist header: Connection: persist persist: The value is either a domain name for the proxy server in the IANA domain, or the IP address of the proxy server in dot form (a.b.c.d). When the proxy server receives this request it must check the value and make sure that it corresponds to itself. The server must choose some policy for determining if the proxy-name corresponds to itself. For example if the proxy-name is a domain name a server might do a domain-name lookup on that name and compare the returned IP address to its own. If the proxy-name does not correspond to the proxy, it must not establish a persistent connection. The proxy server must negotiate persistent connections separately with its clients and the origin servers (or other proxy servers) that it connects to. Each persistent connection applies to only one transport link. In no case should a proxy ever establish a persistent connection with an HTTP 1.0 client. 1.4 Sticky Headers In order to further maximize performance a client and a server may negotiate the use of sticky headers. Sticky headers can reduce the amount of redundant information that has to be transmitted with every request. The negotiation of the sticky headers option must take place on the first request of a persistent connection. The client may add the token "sticky" to the Connection header. If the server accepts the use of sticky headers, it responds with the same token in the Connection header of its response. When using sticky-headers, any values for the following header fields are remembered from request to request: accept, accept-charset, accept-language, accept-encoding, authorization, proxy-authorization, from, host, user-agent. When sticky-headers are being used, the server remembers the fields from the previous requests. If the client specifies a different value for a field in a request, the new value replaces the remembered value. Therefore the server acts as if the actual content of the fields of a request is the combination of the fields in the current request, and the remembered fields. If in any request the client does not include the "sticky" token in the connection header, the server must not use its stored values for the headers in interpreting the request. However, once the "sticky" option has been negotiated any subsequent request can contain the token. The server will then act as if the actual content of that new request is the combination of the fields in the current request and the fields of the previous request only. As a consequence, a server must record the values of the headers in each request, to be used in case the subsequent request specifies sticky headers. 1.5 Compatibility with HTTP/1.0 Some clients and servers may wish to be compatible with some pervious implementations of persistent connections in HTTP version 1.0 clients and servers. When connecting to an origin server an HTTP client may send the following instead of that specified in section 1.2: Connection: keep-alive,persist Persist: Keep-alive: A client must not send the Keep-alive header field to a proxy server. An HTTP/1.0 server would then respond with the Keep-Alive header field and the client may proceed with a persistent connection. An HTTP/1.1 server may receive a keep-alive header field. It may then establish a persistent connection. 1.6 Interaction with Security Protocols It is expected that the Session extension will operate with both SHTTP [5] and SSL [6]. When used in conjunction with SHTTP the SHTTP request is prepared normally, persistent connection headers in the outermost request block (the one containing the "Secure" method). When used in conjunction with SSL a SSL session is started as normal and the first HTTP request made using SSL contains the persistent connection header. 1.7 Practical Considerations Servers will usually have some time-out value beyond which they will no longer maintain an inactive connection. Proxy servers might make this a higher value since it is likely that the client will be making more connections through the same server. The use of persistent connections places no requirements on the length of this time-out for either the client or the server. When a client or server wishes to time-out it should reset the transport connection. 2. Examples The first example shows a client connecting to a server, requesting a session, and the server accepting. NOTE: In all examples the notation represents two octets, CR and LF. client: server: client: GET / HTTP/1.1 Accept: text/html Accept: image/jpeg Connection: persist Persist: www.resnova.com server: HTTP/1.1 200 OK MIME-Version: 1.0 Content-Type: text/html Content-Length: 94 Connection: persist Persist: www.resnova.com

This is a message

client: (has read 94 octets of entity-body) GET /myimg.jpg HTTP/1.1 server: (using same accept: values as the first request) HTTP/1.1 200 OK MIME-Version: 1.0 Content-Type: image/jpeg Content-Length: 1024 Connection: persist Persist: www.resnova.com <1024 octets of data here> client: (has read 1024 octets of entity-body) GET /somecgi.cgi HTTP/1.1 Connection: persist Persist: www.resnova.com server: (Note that the server is running a CGI and doesn't know its expected size) HTTP/1.1 200 OK MIME-Version: 1.1 Content-Type: multipart/mixed; boundary="abcdefghijklmnop" Connection: persist Persist: www.resnova.com --abcdefghijklmnop Content-type: text/html

This is a message

--abcdefghijklmnop-- client: (has read the after the ending boundary server: The second example is identical to the first except that the server does not wish to establish a persistent connection. client: GET / HTTP/1.1 Accept: text/html Accept: image/jpeg Connection: persist Persist: www.resnova.com server: HTTP/1.1 200 OK MIME-Version: 1.0 Content-Type: text/html Content-Length: 94

This is a message

(client did not receive the persist header so it knows to identify the end of the body by the connection close). The third example demonstrates the use of sticky headers. client: GET / HTTP/1.1 Accept: text/html Accept-Language: en Connection: persist,sticky server: HTTP/1.1 200 OK MIME-Version: 1.0 Connection: persist,sticky Content-Type: text/html Content-Length:94 <94 bytes body data here> client: (client makes a request changing the Accept value but maintaining the value of the Accept-Language: field from the previous request) GET /myimg.jpg HTTP/1.1 Accept: image/jpeg Connection: persist,sticky server: HTTP/1.1 200 OK MIME-Version: 1.0 Connection: persist,sticky Content-Type: image/jpeg Content-Length:4000 <4000 bytes body data here> client: (client makes a non-sticky request) GET /something.html HTTP/1.1 Accept: text/html Accept-Language: x-pig-latin Connection: persist server: HTTP/1.1 200 OK MIME-Version: 1.0 Connection: persist Content-Type: text/html Content-Length:106 <106 bytes body data here> client: (client another sticky request) GET /more.html HTTP/1.1 Connection: persist,sticky server: HTTP/1.1 200 OK MIME-Version: 1.0 Connection: persist,sticky Content-Type: text/html Content-Length:164 <164 bytes body data here> 3. Security This HTTP extension has two indirect effects on security. Using sticky headers can reduce the performance penalty of authentication, since a client can send one authentication header and maintain that authentication for a period of time. On the other hand an attacker could theoretically intercept a previously initiated communication channel and substitute itself, gaining the authentication attributes of the client that initiated the communication. This latter attack could only work with the non-secure authentication methods anyway so it is not considered to be a serious concern by the author. 4. Acknowledgments The key contributors to the Persistent HTTP Connection effort include Roy T. Fielding (UCI), Alan Freier (Netscape), Jeff Mogul(DEC), Lou Montulli (Netscape), Paul Leach (Microsoft), Simon Spero (EIT), Andy Norman (HP), and Scott Powers (NCSA). Other contributors include Allan M. Schiffman (Terisa Systems), Greg Herlihy (ResNova Software), and Tim Berners-Lee (W3O). 5 References [1] T. Berners-Lee, R. T. Fielding, H. Frystyk Nielsen. "HyperText Transfer Protocol -- HTTP/1.0" Internet-Draft (work in progress), UC Irvine, , February 19, 1996. [2] S. Spero. "Analysis of HTTP Performance Problems" [3] T. Berners-Lee, R. T. Fielding, H. Frystyk Nielsen. "HyperText Transfer Protocol -- HTTP/1.1" Internet-Draft (work in progress), UC Irvine, , January 19, 1996. [4] E. Rescorla, A. Schiffman "The Secure HyperText Transfer Protocol" Internet-Draft (work in progress) , February, 1996. [5] A. Freier, P Karlton, P. Kocher. "SSL Version 3.0" Internet- Draft (work in progress) , December, 1995. 6 Author's Address Alex Hopmann alex.hopmann@resnova.com President ResNova Software, Inc. 5011 Argosy Dr. #13 Huntington Beach, CA 92649