Network Working Group | J.M. Snell |
Internet-Draft | March 2013 |
Intended status: Informational | |
Expires: September 02, 2013 |
HTTP/2.0 Discussion: Using Multiple Request URI's in Idempotent and Safe Requests
draft-snell-httpbis-mget-00
This memo describes a proposed mechanism for specifying multiple request URI's within Idempotent methods (i.e. "Multi-GET", "Multi-Delete")
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 September 02, 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.
This document introduces the concept of allowing Idempotent and Safe HTTP/2 requests to contain multiple, independent Request URIs. For example, if a User-Agent wishes to retrieve multiple image resources from a server, it could send a single GET request separately listing each of the resources being requested:
An example "Multi-GET" request
Header | Value |
---|---|
:method | GET |
:path | "/images/foo.png", "/images/bar.png" |
:host | example.org |
Upon receiving this request, a server supporting multiple Request URIs would respond by initiating two distinct response streams back to the requesting-user agent, one for each of the requested resources:
UA SERVER ---------------------- | | | MGET REQUEST | |--------------->| | | | Resp#1:foo.png | |<---------------| | Resp#2:bar.png | |<---------------| | |
This singular Multiple-GET request is semantically equivallent to sending two simultaneous, separate GET requests for each of the two resources. There is no implicit or explicit ordering or relationship between the resources being requested. Each has their own distinct response stream, with it's own headers and response status code. The server can choose to return the requested resources in any order it chooses.
All request header fields included in the request apply equally to each of the listed request URIs. To perform a conditional GET request using the If-None-Match request header, for example, the entity tags for each of the requested resources would be listed:
Header | Value |
---|---|
:method | GET |
:path | "/images/foo.png", "/images/bar.png" |
:host | example.org |
if-none-match | "some-opaque-etag", "another-opaque-etag" |
The condition would be evaluated for each of the requested URIs; that is, each of the listed Entity Tags would be evaluated against each of the individual requested resources, preserving the existing semantics of the conditional headers and enforcing the notion that a Multi-GET is semantically equivalent to multiple, simultaneous independent GET requests.
Because each of the requested resources are returned using separately identifiable response streams, each with their own set of metadata, response status codes and data frames, intermediate caches with support for Multiple Request URIs can simply and transparently "do the right thing".
UA CACHE SERVER ---------------------------------------- | | | | MGET REQUEST | | |foo.png, bar.png| | |--------------->| GET REQUEST | | | bar.png | | Resp#1:foo.png |--------------->| |<---------------| | | | Resp:bar.png | | Resp#2:bar.png |<---------------| |<---------------| | | | |
Here, the intermediate cache receives the initial GET containing multiple request URIs and determines that one of the resources (foo.png) can be served from it's cache, while the second (bar.png) needs to be fetched from the origin server. From the User-Agents point of view, this action is entirely transparent.
Because such requests are semantically equivalent to multiple, simultaneous individual requests, translating to and from HTTP/1 becomes a simple matter of splitting out each request URI into its own distinct HTTP/1 request, each with its own exact copy of the full set of request header fields. Intermediaries should be able to handle the translation in a manner that is completely transparent to the User-Agent.
UA PROXY SERVER ---------------------------------------- | | | | MGET REQUEST | | |foo.png, bar.png| | |--------------->| GET REQUEST | | | foo.png | | |--------------->| | | GET REQUEST | | | bar.png | | |--------------->| | | Resp:foo.png | | |<---------------| | Resp#1:foo.png | | |<---------------| Resp:bar.png | | Resp#2:bar.png |<---------------| |<---------------| | | | |
Multiple Request URIs are only permitted on requests methods that are known to be both Safe and Idempotent with one notable exception: The DELETE method, which is Idempotent but not Safe MAY include multiple request URIs.
An example Multi-HEAD Request:
Header | Value |
---|---|
:method | HEAD |
:path | "/images/foo.png", "/images/bar.png" |
:host | example.org |
An example Multi-DELETE Request:
Header | Value |
---|---|
:method | DELETE |
:path | "/images/foo.png", "/images/bar.png" |
:host | example.org |
In particular, Multiple Request URIs MUST NOT ever be used for POST or PUT requests and SHOULD NOT be used for any other request method carrying a request entity unless the method is known to be both Safe and Idempotent.
Server support for Multiple-Request URIs within HTTP/2 implementations ought to be required. If, however, the working group decides that the mechanism is to be optional, a server endpoint not supporting multiple request URIs can return a 400 "Bad Request" error when it receives such requests. A mechanism such as Mark Nottingham's proposed "Browser Hints" format can be used to communicate to User-Agents whether or not multiple request URIs are supported on a given host.
Whether and when to bundle multiple request URIs into a single GET request is entirely up to the requesting HTTP/2 client. A user-agent that is attempting to optimize page load times, for instance, could choose to send a mix of multi- and single-request URI requests to the server depending on whatever strategy it chooses for optimization.
This document specifically rules out the notion of "globbed" Multi-Requests. That is, sending a request with a single "wildcard" request URI that returns multiple independent streams, e.g.:
An example "Multi-GET" request
Header | Value |
---|---|
:method | GET |
:path | "/images/*.png" |
:host | example.org |
The reason this is not defined is because such requests play havoc with the existing HTTP Caching Model, greatly complicates implementation and carries with it a variety of security risks.
TBD
[RFC2119] | Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. |