Network Working Group | J.M. Snell |
Internet-Draft | May 20, 2013 |
Intended status: Informational | |
Expires: November 21, 2013 |
HTTP/2.0 Discussion: Extension Frame Types
draft-snell-httpbis-ext-frames-00
This memo describes the structure and use cases for a handful of "extension" frames types for HTTP 2.0. The purpose of this document is to add to the overall discussion around the development of HTTP 2.0 by describing ways in which the framing layer can be leveraged and extended.
This Internet-Draft is submitted to IETF in full conformance with the provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at http://datatracker.ietf.org/drafts/current/.
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."
This Internet-Draft will expire on November 21, 2013.
Copyright (c) 2013 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document.
The 'CONTEXT' frame type is modeled after the existing 'HEADERS' frame and is intended to provide application-level contextual information. It is intended to provide a clear separation between name+value pairs intended for use as protocol headers (contained in HEADERS frames), and name+value pairs intended for application use.
Currently, there are two distinct use cases identified for the 'CONTEXT' frame: 1) use as an efficient replacement for Set-Cookie and Cookie headers and 2) use as an efficient replacement for the use of Multipart MIME packaging in HTTP messages.
The syntax of the 'CONTEXT' frame is identical to that of the 'HEADERS' frame but defines the following additional type specific flags:
Currently, the Set-Cookie and Cookie header fields are used to essentially provide a sub-layer of name-value pairs associated with an HTTP request or response. The serialization of these header field values is suboptimal. Even in the header compression proposals being put forward for HTTP 2.0, special handling of these fields to improve encoding efficiency has been suggested.
By replacing 'Set-Cookie' and 'Cookie' with the 'CONTEXT' frame, we allow that sub-layer of name+value pairs to take full direct advantage of the header compression proposals as well as the typed-codec proposal introduced by the Stored Header Encoding proposal.
The 'Set-Cookie' header can be replaced by a server sending a 'CONTEXT' frame in a stream with the 'PERSIST' flag set. This would trigger the user-agent to store the included name+value pairs just as it would store the information provided by a Set-Cookie header. The 'HTTPONLY' and 'SECURE' flags would be used as direct alternatives for the HttpOnly and Secure Set-Cookie parameters. The serialized header block would contain ':host' and ':path' fields corresponding to the Set-Cookie Domain and Path parameters.
The 'Cookie' header would be replace by a user-agent sending a 'CONTEXT' frame in a stream with the 'PERSISTED' flag set. This would tell the server that the name+value pairs contained are those the server had previously asked the user-agent to store.
The critical advantage of using the 'CONTEXT' frame as a replacement for Set-Cookie and Cookie is encoding efficiency. Experiments have demonstrated that equivalent values can be encoded with 50-60% fewer bytes.
Many existing HTTP based applications use variations on MIME multipart packaging to enable sending multiple entities within a request or response. Examples include HTML forms and multipart Atom posts. In every case, the use of MIME multipart consists of sending sequences of data octets separated by blocks of name+value pair headers.
Using 'CONTEXT' frames, we can eliminate the need for Multipart MIME packaging entirely, addressing precisely the same use cases in a significantly more efficient way.
For example, a simple multipart form data package:
POST /foo HTTP/1.0 Host: example.com Content-type: multipart/form-data, boundary=abcdefg Content-Length: ... --abcdefg content-disposition: form-data; name="f1" 12345 --abcdefg content-disposition: form-data; name="f2" 678890 --abcdefg content-disposition: form-data; name="f3"; filename="foo.jpg" Content-Type: image/jpeg Content-Transfer-Encoding: binary ...binary data... --abcdefg--
can be represented by a much more compact sequence of intermixed 'DATA' and 'CONTEXT' frames:
HEADERS :method = POST :host = example.com :content-type = application/context-separated CONTEXT content-disposition: form-data; name="f1" DATA 12345 CONTEXT content-disposition: form-data; name="f2" DATA 67890 CONTEXT content-disposition: form-data; name="f3"; filename="foo.jpg" content-type: image/jpeg DATA ...binary data...
Parsing and processing the sequence of frames is less error prone and more efficient than parsing the Multipart MIME packaging, and the fact that CONTEXT frames can make use of the header compression mechanisms means the data can be transmitted much more efficiently over the network.
For the 'CONTEXT' frame, the most significant considerations for the HTTP 2.0 are Flow Control, Header Compression State and handling of unknown header types.
Currently, HTTP 2.0 states that only DATA frames are covered by flow control. This means that CONTEXT and any other extension headers are automatically ruled out of the flow control limits. This is dangerous because it allows implementations to very easily work around flow control limits end-to-end by using a new frame type.
Because 'CONTEXT' frames consist of application-level data rather than protocol-level data, 'CONTEXT' frames ought to be covered by flow control mechanisms.
While the 'CONTEXT' frame can take advantage of the same header compression mechanism used by HEADERS, HEADERS+PRIORITY and PUSH_PROMISE frames, the fact that 'CONTEXT' frames express application-level data and not protocol-level data means that 'CONTEXT' frames ought to have their own compression state context. This allows intermediaries to pass such frames through completely untouched, just as it would a DATA frame, without any negative impact on the connection state.
Alternatively, the working group could rule that extension frames MUST NOT use header blocks and the header compression mechanism. Such a decision would place strict limitations on the types of new frames permitted unless a new protocol version is established. Such a decision is not out of the question but raises a number of difficult issues with regards to the deployment and support of new capabilities.
The current HTTP 2.0 draft states that unknown and unsupported frame types are to be ignored, but does not define exactly what that means. An intermediary might ignore a frame by dropping it completely from the stream and never passing it on, or it might ignore the frame by passing it through untouched to an upstream destination. Specific rules need to be put in place for handling unknown frame types so that mechanisms like 'CONTEXT' can be reliably deployed.
The rules ought to be simple. When detecting an unknown frame type used in a stream, the endpoint can either:
When detecting an unknown frame type whose stream ID is 0x0, the endpoint can choose to ignore it completely or reject the frame and terminate the connection using a GOAWAY with an UNSUPPORTED_FRAME_TYPE error code.
If these rules are not followed, the stream state or connection state can be easily corrupted by out of sync client and server implementations.
The 'CHECK' frame would be used to provide incremental verification of data transmitted within a stream.
The syntax of the 'CHECK' frame consists of a header block containing parameters of the hash algorithm being used.
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Header Block (*) ... +---------------------------------------------------------------+
CHECK Frame Payload Format
One frame-specific flag is defined:
Once an endpoint receives a 'CHECK' frame with the INIT flag set, it will initialize a verification context that will incrementally calculate a hash of all frames subsequently received on the same stream until a new 'CHECK' frame is received. The complete frame data, including the 8-byte header) is to be included in the hash calculation.
The sender would then, at some later point in the stream, send and additional 'CHECK' frame without the INIT flag set. That frame MUST include a ':hash' header whose value specifies what the calculated hash ought to be.
For example, to specify an MD5 hash for a set of frames
HEADERS :method = POST :host = example.org :content-type = application/json CHECK :algorithm = http://.../md5 INIT = ON DATA ... DATA ... DATA ... CHECK :hash = {expected hash value} INIT = OFF
If the calculated hash does not match that provided by the secondary CHECK frame, the stream SHOULD be terminated with an RST_FRAME.
The considerations for 'CHECK' are similar to those on the 'CONTEXT' frame.
Because 'CHECK' uses a Header block it can take advantage of the header compression mechanism but ought not have an impact on the connections compression state.
It is unclear whether a frame such a 'CHECK' ought to be covered by flow control. It is, essentially, a protocol-level extension that is not really intended for application-level use.
So long as the header compression state is isolated, an implementation could choose to ignore the CHECK frame entirely without risk of corrupting any connection or stream data.
[RFC2119] | Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. |