This document defines the Edge Architecture, which extend the Web infrastructure through the use of HTTP surrogates - intermediaries that act on behalf of an origin server.
This document is part of a submission to the World Wide Web Consortium (see Submission Request, W3C Staff Comment) that outlines an approach to scaling the Web infrastructure. Comments to the authors are welcome, but you are also encouraged to share your views on the W3C publicly archived www-talk mailing list <firstname.lastname@example.org>. For a full list of all acknowledged Submissions, please see Acknowledged Submissions to W3C.
This document is a NOTE made available by the W3C for discussion only. Publication of this Note by W3C indicates no endorsement by W3C or the W3C Team, or any W3C Members. No W3C resources were or are allocated to the issues addressed by the NOTE. W3C has had no editorial control over the preparation of this NOTE.
A list of current W3C technical documents can be found at the Technical Reports page.
One approach to scaling the Web is the use of surrogates - intermediaries that act on behalf of and with authority of an origin server (also known as "reverse proxies"). This document describes a framework for the distribution of HTTP content by surrogates, by specifying a means of controlling surrogates with HTTP headers, along with caching and response processing models for them.
Surrogates may be deployed close to the origin server, or throughout the network - a configuration often referred to as a "Content Delivery Network" (CDN).
Because they act on behalf of the origin server (and therefore the content's owner), surrogates offer content owners greater control over their behavior than proxies. As a result, they offer greater potential for improving performance, offloading processing from the origin server, and adding unique functionality to the Web.
This document uses the Extended BNF syntax and rules from HTTP/1.1.
Unlike standard HTTP intermediaries, Surrogates offer the ability for finer control by the origin server and content owner, because of their implied relationship. To enable this, we define HTTP headers to advertise the capabilities of a particular surrogate device, and control how it behaves.
The Surrogate-Capabilities request header allows surrogates to advertise their capabilities with capability tokens. Capability tokens indicate sets of operations (e.g., caching, processing) that a surrogate is willing to perform. They follow the form of product tokens in the HTTP;
capability = token [ "/" token ]
Capability tokens are case-sensitive.
As requests pass through surrogates, the Surrogate-Capabilities header is appended;
capability-hdr = "Surrogate-Capability" ":" 1#capability-set capability-set = device-token "=" <"> capability \ *( SP capability ) <"> device-token = token
Surrogate-Capabilities: abc="Surrogate/1.0", def="Surrogate/1.0 ESI/1.0"
The name in each capability set identifies a device token, which uniquely identifies the surrogate that appended it. Device tokens must be unique within a request's Surrogate-Capabilities header.
The value contains a space-separated list of capability tokens. In the example above, two surrogates are present in the request chain; one identified as 'abc' is capable of applying "ESI/1.0", while 'def' is capable of handling both "Surrogate/1.0" and "ESI/1.0".
Surrogates must only append their information to any existing Surrogate-Capability headers, so that it may be read from left to right (or, if the headers are separate, from top to bottom) to construct a list of surrogates that the request passed through (and thus a list that may be read from right to left to discover surrogates that the response will pass through).
The Surrogate-Control response header allows origin servers to dictate how surrogates should handle response entities, with control directives. Currently defined directives control processing and cache behavior.
control-hdr = "Surrogate-Control" ":" 1#( control-directive \ *( ";" device-token ) ) control-directive = no-store | no-store-remote | max-age | content | extension-directive no-store = "no-store" ; see section 4.2.1 no-store-remote = "no-store-remote" ; see section 4.2.2 max-age = "max-age" "=" \ delta-seconds [ "+" delta-seconds ] ; see section 4.2.3 content = "content" "=" \ <"> capability *( SP capability ) <"> ; see section 4.2.4 extension-directive = token [ "=" ( token | quoted-string ) ]
Surrogate-Control: no-store, content="ESI/1.0"
Surrogates may modify the Surrogate-Control header to instruct downstream surrogates to process capabilities originally targetted at them. If no downstream surrogates have identified themselves, the header should be stripped from responses.
The no-store directive specifies that the response entity should not be stored in cache; it is only to be used for the original request, and may not be validated on the origin server.
The no-store-remote directive has similar semantics to the no-store directive, except that it should only be honored by those surrogates that consider themselves "remote". Generally, this means those that are more than one or two hops from the origin server, such as surrogates in a CDN.
The max-age directive specifies how long the response entity can be considered fresh, in seconds. After this time, implementations must consider the cached entity stale.
Optionally, a '+' and a freshness extension can be appended, that specifies an additional period of time (in seconds) the stale entity may be served, before it must be revalidated or refetched as appropriate.
If no freshness extension is specified, it should be considered as '0' (i.e., the object should be revalidated or refetched immediately).
The content directive identifies what processing surrogates should perform on the response before forwarding it. The value of the content directive is a left-to-right ordered, space-separated list of capabilities for processing by surrogates.
This directive specifies that first the operations represented by the "ESI/1.0" capability token and then the "ESI-Inline/1.0" capability token should be applied to the response entity. See also "Response Processing Model".
Once processing takes place, the capability token that invoked it (as well as the 'content' directive, if appropriate) is consumed; that is, it is not passed forward to surrogates.
Because surrogates can be deployed hetrogeneously in a hierarchy, it is necessary to enable the targetting of directives at individual devices.
Surrogate-Control directives may have a parameter that identifies the surrogate that they are targetted at, as identified by the device token in the request's Surrogate-Capabilities header. Directives without targetting parameters are applied to all surrogates, unless a targetted directive overrides it. For example,
Surrogate-Control: max-age=60;abc, max-age=300
Here, the device that identified itself as 'abc' in the Surrogate-Capabilties request header will apply a max-age of 300; all other surrogates will apply a max-age of 60.
Surrogate-Control: content="ESI/1.0";abc, content="ESI-Inline/1.0";def
This header specifies that the device that identified itself as 'abc' should process the response entity for ESI, while the surrogate that identified itself as 'def' should process it for ESI-Inline.
Implementations are not required to support targetting.
Caching in surrogates operates in a manner similar to the HTTP; the same freshness and validation mechanisms form its basis. However, there are additional mechanisms for controlling cacheability in Surrogates, that override such mechanisms in the HTTP.
The Surrogate-Control response header contains several directives that influence entity cacheability; specifically, "no-store", "no-store-remote", and "max-age" (see "Surrogate-Control Header" for more information). Collectively, these directives and their behaviors are described by the capability token
This token should be included in all requests sent by compliant surrogates (see "Surrogate-Capabilities Header").
When any of these directives are present, they override any HTTP cacheability information present in the response. If more than one is targetted at a surrogate, the most specific applies. For example,
Surrogate-Control: max-age=60, no-store;abc
The surrogate that identified itself as 'abc' (see "Controlling Surrogates with HTTP Headers") would apply no-store; others would apply max-age=60. Conversely,
Surrogate-Control: no-store, max-age=60;abc
In this example, 'abc' would apply max-age=60, while other surrogates would apply no-store.
Surrogates should ignore any HTTP Cache-Control request header directives.
Surrogates may also invoke processors on response entitities as they pass through. Examples of processing include images transcoding, the application of XSLT stylesheets, or the interpretation of an in-markup language. By default, processing takes place after caching; that is, cached entities have any applicable processing applied before being served. Processors and extension directives may modify this behavior.
Processing is invoked with the 'content' surrogate-control directive. The actual coorperative processing model depends on the nature of the processing, capabilities of surrogates, and their permissions to delegate processing to other surrogates. This document does not define any specific processing model.