rfc8673xml2.original.xml | rfc8673.xml | |||
---|---|---|---|---|
<?xml version="1.0" encoding="UTF-8"?> | <?xml version='1.0' encoding='utf-8'?> | |||
<!DOCTYPE rfc [ | ||||
<!ENTITY RFC2119 SYSTEM "http://www.rfc-editor.org/refs/bibxml/reference.RFC.211 | ||||
9.xml"> | ||||
<!ENTITY RFC5234 SYSTEM "http://www.rfc-editor.org/refs/bibxml/reference.RFC.523 | ||||
4.xml"> | ||||
<!ENTITY RFC7230 SYSTEM "http://www.rfc-editor.org/refs/bibxml/reference.RFC.723 | ||||
0.xml"> | ||||
<!ENTITY RFC7233 SYSTEM "http://www.rfc-editor.org/refs/bibxml/reference.RFC.723 | ||||
3.xml"> | ||||
<!ENTITY RFC7234 SYSTEM "http://www.rfc-editor.org/refs/bibxml/reference.RFC.723 | ||||
4.xml"> | ||||
<!ENTITY RFC8216 SYSTEM "http://www.rfc-editor.org/refs/bibxml/reference.RFC.821 | ||||
6.xml"> | ||||
<!-- Fudge for XMLmind which doesn't have this built in --> | ||||
<!ENTITY nbsp " "> | ||||
]> | ||||
<!-- Extra statement used by XSLT processors to control the output style. --> | ||||
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?> | ||||
<!-- Processing Instructions can be placed here but if you are editing | ||||
with XMLmind (and maybe other XML editors) they are better placed | ||||
after the rfc element start tag as shown below. --> | ||||
<rfc | ||||
category="exp" | ||||
ipr="trust200902" | ||||
docName="draft-ietf-httpbis-rand-access-live-04" | ||||
xmlns:x="http://purl.org/net/xml2rfc/ext"> | ||||
<!-- Processing Instructions- PIs (for a complete list and description, | ||||
see file http://xml.resource.org/authoring/README.html and below... -- | ||||
> | ||||
<!-- Some of the more generally applicable PIs that most I-Ds might want to | ||||
use --> | ||||
<!-- Try to enforce the ID-nits conventions and DTD validity --> | ||||
<?rfc strict="yes" ?> | ||||
<!-- Items used when reviewing the document --> | ||||
<?rfc comments="no" ?> <!-- Controls display of <cref> elements --> | ||||
<?rfc inline="no" ?> <!-- When no, put comments at end in comments sectio | ||||
n, | ||||
otherwise, put inline --> | ||||
<?rfc editing="no" ?> <!-- When yes, insert editing marks: editing marks c | ||||
onsist of a | ||||
string such as <29> printed in the blank line a | ||||
t the | ||||
beginning of each paragraph of text. --> | ||||
<!-- Create Table of Contents (ToC) and set some options for it. | <!DOCTYPE rfc SYSTEM "rfc2629-xhtml.ent"> | |||
Note the ToC may be omitted for very short documents,but idnits insists | ||||
on a ToC | ||||
if the document has more than 15 pages. --> | ||||
<?rfc toc="yes"?> | ||||
<?rfc tocompact="yes"?> <!-- If "yes" eliminates blank lines before main sect | ||||
ion entries. --> | ||||
<?rfc tocdepth="4"?> <!-- Sets the number of levels of sections/subsection | ||||
s... in ToC --> | ||||
<!-- Choose the options for the references. | <rfc xmlns:xi="http://www.w3.org/2001/XInclude" number="8673" consensus="true" | |||
Some like symbolic tags in the references (and citations) and others pr | submissionType="IETF" category="exp" ipr="trust200902" | |||
efer | docName="draft-ietf-httpbis-rand-access-live-04" tocInclude="true" | |||
numbers. The RFC Editor always uses symbolic tags. | symRefs="true" sortRefs="true" version="3" xml:lang="en"> | |||
The tags used are the anchor attributes of the references. --> | ||||
<?rfc symrefs="yes"?> | ||||
<?rfc sortrefs="yes" ?> <!-- If "yes", causes the references to be sorted in | ||||
order of tags. | ||||
This doesn't have any effect unless symrefs is | ||||
"yes" also. --> | ||||
<!-- These two save paper: Just setting compact to "yes" makes savings by no | <!-- xml2rfc v2v3 conversion 2.28.0 --> | |||
t starting each | ||||
main section on a new page but does not omit the blank lines between li | ||||
st items. | ||||
If subcompact is also "yes" the blank lines between list items are also | ||||
omitted. --> | ||||
<?rfc compact="yes" ?> | ||||
<?rfc subcompact="no" ?> | ||||
<!-- end of list of popular I-D processing instructions --> | ||||
<!-- ***** FRONT MATTER ***** --> | <!-- ***** FRONT MATTER ***** --> | |||
<front> | <front> | |||
<title>HTTP Random Access and Live Content</title> | <title>HTTP Random Access and Live Content</title> | |||
<author | <seriesInfo name="RFC" value="8673" /> | |||
fullname="Craig Pratt" | ||||
initials="C." | <author fullname="Craig Pratt" initials="C." surname="Pratt"> | |||
surname="Pratt"> | <address> | |||
<address> | <postal> | |||
<postal> | <street/> | |||
<city>Portland</city> | <city>Portland</city> | |||
<region>OR</region> | <region>OR</region> | |||
<code>97229</code> | <code>97229</code> | |||
<country>US</country> | <country>United States of America</country> | |||
</postal> | </postal> | |||
<email>pratt@acm.org</email> | <email>pratt@acm.org</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<author fullname="Darshak Thakore" initials="D." surname="Thakore"> | ||||
<author fullname="Darshak Thakore" | <organization abbrev="CableLabs">CableLabs</organization> | |||
initials="D." | <address> | |||
surname="Thakore" > | <postal> | |||
<organization abbrev="CableLabs">CableLabs</organization> | <street>858 Coal Creek Circle</street> | |||
<address> | <city>Louisville</city> | |||
<postal> | <region>CO</region> | |||
<street>858 Coal Creek Circle</street> | <code>80027</code> | |||
<city>Louisville</city> | <country>United States of America</country> | |||
<region>CO</region> | </postal> | |||
<code>80027</code> | <email>d.thakore@cablelabs.com</email> | |||
<country>US</country> | </address> | |||
</postal> | ||||
<email>d.thakore@cablelabs.com</email> | ||||
</address> | ||||
</author> | </author> | |||
<author fullname="Barbara Stark" initials="B." surname="Stark"> | ||||
<author fullname="Barbara Stark" | ||||
initials="B.H." | ||||
surname="Stark" > | ||||
<organization>AT&T</organization> | <organization>AT&T</organization> | |||
<address> | <address> | |||
<postal> | <postal> | |||
<street/> | ||||
<city>Atlanta</city> | <city>Atlanta</city> | |||
<region>GA</region> | <region>GA</region> | |||
<country>US</country> | <country>United States of America</country> | |||
</postal> | </postal> | |||
<email>barbara.stark@att.com</email> | <email>barbara.stark@att.com</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<date year="2019" month="November"/> | ||||
<date year="2019" month="March"/> | ||||
<!-- Meta-data Declarations --> | ||||
<!-- Notice the use of & as an escape for & which would otherwise | ||||
start an entity declaration, whereas we want a literal &. --> | ||||
<area>Applications and Real-Time</area> | <area>Applications and Real-Time</area> | |||
<!-- WG name at the upperleft corner of the doc, | ||||
IETF fine for individual submissions. You can also | ||||
omit this element in which case in defaults to "Network Working Group" | ||||
- | ||||
a hangover from the ancient history of the IETF! --> | ||||
<workgroup>HTTP</workgroup> | <workgroup>HTTP</workgroup> | |||
<keyword>http range unit live aggregation</keyword> | <keyword>http</keyword> | |||
<keyword>range</keyword> | ||||
<!-- The DTD allows multiple area and workgroup elements but only the first | <keyword>live</keyword> | |||
one has any | <keyword>aggregation</keyword> | |||
effect on output. --> | ||||
<!-- You can add <keyword/> elements here. They will be incorporated into H | ||||
TML output | ||||
files in a meta tag but they have no effect on text or nroff output. -- | ||||
> | ||||
<abstract> | <abstract> | |||
<t> | <t> | |||
To accommodate byte range requests for content that has | To accommodate byte-range requests for content that has | |||
data appended over time, this document defines semantics | data appended over time, this document defines semantics | |||
that allow a HTTP client and server to perform byte-range | that allow an HTTP client and a server to perform byte-range | |||
GET and HEAD requests that start at an arbitrary byte offset | GET and HEAD requests that start at an arbitrary byte offset | |||
within the representation and ends at an indeterminate offset. | within the representation and end at an indeterminate offset. | |||
</t> | </t> | |||
</abstract> | </abstract> | |||
</front> | ||||
<middle> | ||||
<note title="Editorial Note (To be removed by RFC Editor before publication) | <section anchor="introduction"> | |||
"> | <name>Introduction</name> | |||
<t> | <t> | |||
Discussion of this draft takes place on the HTTPBIS working group mailin | Some Hypertext Transfer Protocol (HTTP) clients use byte-range requests | |||
g list | (range requests using the "bytes" range unit) to transfer select | |||
(ietf-http-wg@w3.org), which is archived at <eref | portions of large representations <xref target="RFC7233"/>. In some | |||
target="https://lists.w3.org/Archives/Public/ietf-http-wg/"/>. | cases, large representations require content to be continuously or | |||
periodically appended, such as representations consisting of live audio | ||||
or video sources, blockchain databases, and log files. Clients cannot | ||||
access the appended/live content using a range request with the "bytes" | ||||
range unit using the currently defined byte-range semantics without | ||||
accepting performance or behavior sacrifices that are not acceptable for | ||||
many applications. | ||||
</t> | </t> | |||
<t> | <t> | |||
Working Group information can be found at <eref target="http://httpwg.gi | For instance, HTTP clients have the ability to access appended content | |||
thub.io/"/>; source code and issues | on an indeterminate-length resource by transferring the entire | |||
list for this draft can be found at | representation from the beginning and continuing to read the appended | |||
<eref target="https://github.com/httpwg/http-extensions/labels/rand-acce | content as it's made available. Obviously, this is highly inefficient | |||
ss-live"/>. | for cases where the representation is large and only the most recently | |||
</t><!-- | appended content is needed by the client. | |||
</t> | ||||
<t> | <t> | |||
The changes in this draft are summarized in <xref target="change.log"/>. | Alternatively, clients can access appended | |||
</t>--> | content by sending periodic, open-ended byte-range | |||
</note> | requests using the last known end byte position as the | |||
</front> | range start. Performing low-frequency periodic | |||
byte-range requests in this fashion (polling) introduces | ||||
<middle> | latency since the client will necessarily be somewhat | |||
behind in transferring the aggregated content, effectively | ||||
<section anchor="introduction" title="Introduction"> | resulting in the same kind of latency issues with the segmented content | |||
<t> | transfer mechanisms in "HTTP Live Streaming" (HLS) <xref | |||
Some Hypertext Transfer Protocol (HTTP) clients use byte-range requests (R | target="RFC8216"/> and "Dynamic Adaptive Streaming | |||
ange requests using the "bytes" Range Unit) to transfer select portions of large | over HTTP" <xref target="MPEG-DASH"/>. | |||
representations (<xref target="RFC7233"/>). And in some cases large representat | While performing | |||
ions require content to be continuously or periodically appended - such as repre | these range requests at higher frequency can reduce this latency, | |||
sentations consisting of live audio or video sources, blockchain databases, and | it also incurs more processing overhead and HTTP exchanges as | |||
log files. Clients cannot access the appended/live content using a Range request | many of the requests will return no content, since content is | |||
with the bytes range unit using the currently defined byte-range semantics with | usually aggregated in groups of bytes (e.g., a video frame, audio | |||
out accepting performance or behavior sacrifices which are not acceptable for ma | sample, block, or log entry). | |||
ny applications. | </t> | |||
</t> | <t> | |||
<t> | This document describes a usage model for range requests that enables | |||
For instance, HTTP clients have the ability to access app | efficient retrieval of representations that are appended to over time | |||
ended content on an indeterminate-length resource by transferring the entire rep | by using large values and associated semantics for communicating | |||
resentation from the beginning and continuing to read the appended content as it | range end positions. This model allows representations to be | |||
's made available. Obviously, this is highly inefficient for cases where the rep | progressively delivered by servers as new content is added. It also | |||
resentation is large and only the most recently appended content is needed by th | ensures compatibility with servers and intermediaries that don't | |||
e client. | support this technique. | |||
</t> | </t> | |||
<t> | ||||
Alternatively, clients can also access appended content b | ||||
y sending periodic open-ended bytes Range requests using the last-known end byte | ||||
position as the range start. Performing low-frequency periodic bytes Range requ | ||||
ests in this fashion (polling) introduces latency since the client will necessar | ||||
ily be somewhat behind the aggregated content - mimicking the behavior (and late | ||||
ncy) of segmented content representations such as "HTTP Live Streaming" (HLS, <x | ||||
ref target="RFC8216"/>) or "Dynamic Adaptive Streaming over HTTP" (MPEG-DASH, <x | ||||
ref target="DASH"/>). And while performing these Range requests at higher freque | ||||
ncy can reduce this latency, it also incurs more processing overhead and HTTP ex | ||||
changes as many of the requests will return no content - since content is usuall | ||||
y aggregated in groups of bytes (e.g. a video frame, audio sample, block, or log | ||||
entry). | ||||
</t> | ||||
<t> | ||||
This document describes a usage model for range requests which enabl | ||||
es | ||||
efficient retrieval of representations that are appended to over tim | ||||
e | ||||
by using large values and associated semantics for communicating | ||||
range end positions. This model allows representations to be | ||||
progressively delivered by servers as new content is added. It also | ||||
ensures compatibility with servers and intermediaries that don't | ||||
support this technique. | ||||
</t> | ||||
<section title="Requirements Language"> | <section> | |||
<t>The key words "MUST", "MUST NOT", | <name>Notational Conventions</name> | |||
"REQUIRED", "SHALL", "SHALL NOT", | ||||
"SHOULD", "SHOULD NOT", "RECOMMENDED", | ||||
"MAY", and "OPTIONAL" in this document are to be | ||||
interpreted as described in <xref target="RFC2119">RFC 2119</xref>. | ||||
</t> | ||||
</section> | ||||
<section title="Notational Conventions"> | <t>This document cites Augmented Backus-Naur Form (ABNF) productions | |||
<t>This document cites productions in Augmented Backus-Naur Form (AB | ||||
NF) productions | ||||
from <xref target="RFC7233"/>, using the notation defined in <xref t arget="RFC5234"/>. | from <xref target="RFC7233"/>, using the notation defined in <xref t arget="RFC5234"/>. | |||
</t> | </t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="definition"> | ||||
<section anchor="definition" title="Performing Range requests on Random-Acce | <name>Performing Range Requests on Random-Access Aggregating (Live) Conten | |||
ss Aggregating ("live") Content"> | t</name> | |||
<t> | <t> | |||
This document recommends a two-step process for accessing resources | This document recommends a two-step process for accessing resources | |||
that have indeterminate length representations. | that have indeterminate-length representations. | |||
</t><t> | </t> | |||
Two steps are necessary because of limitations with the Range reques | <t> | |||
t | Two steps are necessary because of limitations with the range reques | |||
t | ||||
header fields and the Content-Range response header fields. A server cannot | header fields and the Content-Range response header fields. A server cannot | |||
know from a range request that a client wishes to receive a response | know from a range request that a client wishes to receive a response | |||
that does not have a definite end. More critically, the header field s | that does not have a definite end. More critically, the header field s | |||
do not allow the server to signal that a resource has indeterminate | do not allow the server to signal that a resource has indeterminate | |||
length without also providing a fixed portion of the resource. | length without also providing a fixed portion of the resource. | |||
</t><t> | </t> | |||
<t> | ||||
A client first learns that the resource has a representation of | A client first learns that the resource has a representation of | |||
indeterminate length by requesting a range of the resource. The serv er | indeterminate length by requesting a range of the resource. The serv er | |||
responds with the range that is available, but indicates that the | responds with the range that is available but indicates that the | |||
length of the representation is unknown using the existing | length of the representation is unknown using the existing | |||
Content-Range syntax. See <xref target="establishing-range" /> | Content-Range syntax. See <xref target="establishing-range"/> | |||
for details and examples. | for details and examples. | |||
</t><t> | </t> | |||
<t> | ||||
Once the client knows the resource has indeterminate length, it can | Once the client knows the resource has indeterminate length, it can | |||
request a range with a very large end position from the resource. Th e | request a range with a very large end position from the resource. Th e | |||
client chooses an explicit end value larger than can be transferred in | client chooses an explicit end value larger than can be transferred in | |||
the foreseeable term. A server which supports range requests of | the foreseeable term. A server that supports range requests of | |||
indeterminate length signals its understanding of the client's | indeterminate length signals its understanding of the client's | |||
indeterminate range request by indicating that the range it is | indeterminate range request by indicating that the range it is | |||
providing has a range end that exactly matches the client's requeste d | providing has a range end that exactly matches the client's requeste d | |||
range end rather than a range that is bounded by what is currently | range end rather than a range that is bounded by what is currently | |||
available. See <xref target="live-range-requests" /> for details. | available. See <xref target="live-range-requests"/> for details. | |||
</t> | ||||
<section anchor="establishing-range" title="Establishing the Randomly Acce | ||||
ssible Byte Range"> | ||||
<t> | ||||
Establishing if a representation is continuously aggregating ("live") an | ||||
d determining the randomly-accessible byte range can both be determined using th | ||||
e existing definition for an open-ended byte-range request. Specifically, <xref | ||||
x:sec="2.1" x:fmt="of" target="RFC7233"/> defines a byte-range request of the fo | ||||
rm: | ||||
</t> | </t> | |||
<figure><artwork type="abnf"> | <section anchor="establishing-range"> | |||
<name>Establishing the Randomly Accessible Byte Range</name> | ||||
<t> | ||||
Determining if a representation is continuously aggregating ("live") | ||||
and determining the randomly accessible byte range can both be | ||||
performed using the existing definition for an open-ended byte-range | ||||
request. Specifically, <xref target="RFC7233" | ||||
sectionFormat="of" section="2.1"/> defines a byte-range request of the fo | ||||
rm: | ||||
</t> | ||||
<sourcecode type="abnf"><![CDATA[ | ||||
byte-range-spec = first-byte-pos "-" [ last-byte-pos ] | byte-range-spec = first-byte-pos "-" [ last-byte-pos ] | |||
</artwork></figure> | ]]></sourcecode > | |||
<t> | <t> | |||
which allows a client to send a HEAD request with a first-byte-pos and lea | which allows a client to send a HEAD request with a first-byte-pos and | |||
ve last-byte-pos absent. A | leave last-byte-pos absent. A server that receives a satisfiable | |||
server that receives a satisfiable byte-range request (with first-byte-pos | byte-range request (with first-byte-pos smaller than the current | |||
smaller than the current | representation length) may respond with a 206 status code (Partial | |||
representation length) may respond with a 206 status code (Partial Content | Content) with a Content-Range | |||
) with a Content-Range | ||||
header field indicating the currently satisfiable byte range. For example: | header field indicating the currently satisfiable byte range. For example: | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="request"" x:indent-with=" | <artwork type="message/http; msgtype="request""><![CDATA[ | |||
"> | ||||
HEAD /resource HTTP/1.1 | HEAD /resource HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Range: bytes=0- | Range: bytes=0- | |||
]]></artwork> | ||||
</artwork></figure> | <t> | |||
<t> | ||||
returns a response of the form: | returns a response of the form: | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="response"" x:indent-with=" | <artwork type="message/http; msgtype="response""><![CDATA[ | |||
"> | ||||
HTTP/1.1 206 Partial Content | HTTP/1.1 206 Partial Content | |||
Content-Range: bytes 0-1234567/* | Content-Range: bytes 0-1234567/* | |||
</artwork></figure> | ]]></artwork> | |||
<t> | <t> | |||
from the server indicating that (1) the complete representation length is | from the server indicating that (1) the complete representation length | |||
unknown (via the "*" in place of the complete-length field) and (2) that only by | is unknown (via the "*" in place of the complete-length field) and (2) | |||
tes 0-1234567 were accessible at the time the request was processed by the serve | only bytes 0-1234567 were accessible at the time the request was | |||
r. The client can infer from this response that bytes 0-1234567 of the represent | processed by the server. The client can infer from this response that | |||
ation can be requested and returned in a timely fashion (the bytes are immediate | bytes 0-1234567 of the representation can be requested and transfer | |||
ly available). | can be performed immediately. | |||
</t> | ||||
</section> | </t> | |||
<section anchor="live-range-requests" title="Byte-Range Requests Beyond the | </section> | |||
Randomly Accessible Byte Range"> | <section anchor="live-range-requests"> | |||
<t> | <name>Byte-Range Requests beyond the Randomly Accessible Byte Range</nam | |||
Once a client has determined that a representation has an indeterminate | e> | |||
length and established the byte range that can be accessed, it may want to perfo | <t> | |||
rm a request with a start position within the randomly-accessible content range | Once a client has determined that a representation has an | |||
and an end position at an indefinite "live" point - a point where the byte-range | indeterminate length and established the byte range that can be | |||
GET request is fulfilled on-demand as the content is aggregated. | accessed, it may want to perform a request with a start position | |||
</t> | within the randomly accessible content range and an end position | |||
<t> | at an indefinite/live point -- a point where the byte-range GET | |||
For example, for a large video asset, a client may wish to start a conte | request is fulfilled on-demand as the content is aggregated. | |||
nt transfer from the video "key" frame immediately before the point of aggregati | </t> | |||
on and continue the content transfer indefinitely as content is aggregated - in | <t> | |||
order to support low-latency startup of a live video stream. | For example, for a large video asset, a client may wish to start a | |||
</t> | content transfer from the video "key" frame immediately before the | |||
<t> | point of aggregation and continue the content transfer indefinitely | |||
Unlike a byte-range Range request, a byte-range Content-Range response h | as content is aggregated, in order to support low-latency startup | |||
eader field cannot be "open ended", per <xref x:sec="4.2" x:fmt="of" target="RFC | of a live video stream. | |||
7233"/>: | </t> | |||
</t> | ||||
<figure><artwork type="abnf"> | <t> | |||
Unlike a byte-range request header field, a byte-content-range response | ||||
header field cannot be "open-ended", per <xref | ||||
target="RFC7233" sectionFormat="of" section="4.2"/>: | ||||
</t> | ||||
<sourcecode type="abnf"><![CDATA[ | ||||
byte-content-range = bytes-unit SP | byte-content-range = bytes-unit SP | |||
( byte-range-resp / unsatisfied-range ) | ( byte-range-resp / unsatisfied-range ) | |||
byte-range-resp = byte-range "/" ( complete-length / "*" ) | byte-range-resp = byte-range "/" ( complete-length / "*" ) | |||
byte-range = first-byte-pos "-" last-byte-pos | byte-range = first-byte-pos "-" last-byte-pos | |||
unsatisfied-range = "*/" complete-length | unsatisfied-range = "*/" complete-length | |||
complete-length = 1*DIGIT | complete-length = 1*DIGIT | |||
</artwork></figure> | ]]></sourcecode> | |||
<t> | <t> | |||
Specifically, last-byte-pos is required in byte-range. So in order to pr | Specifically, last-byte-pos is required in byte-range. So, in order | |||
eserve interoperability with existing HTTP clients, servers, proxies, and caches | to preserve interoperability with existing HTTP clients, servers, | |||
, this document proposes a mechanism for a client to indicate support for handli | proxies, and caches, this document proposes a mechanism for a client | |||
ng an indeterminate-length byte-range response, and a mechanism for a server to | to indicate support for handling an indeterminate-length byte-range | |||
indicate if/when it's providing an indeterminate-length response. | response and a mechanism for a server to indicate if/when it's | |||
</t> | providing an indeterminate-length response. | |||
<t> | </t> | |||
A client can indicate support for handling indeterminate-length byte-ran | <t> | |||
ge responses by providing a very large value for the last-byte-pos in the byte-r | A client can indicate support for handling indeterminate-length | |||
ange request. For example, a client can perform a byte-range GET request of the | byte-range responses by providing a very large value for the | |||
form: | last-byte-pos in the byte-range request. For example, a client can | |||
</t> | perform a byte-range GET request of the form: | |||
<figure><artwork type="message/http; msgtype="request"" x:indent-with=" | </t> | |||
"> | <artwork type="message/http; msgtype="request""><![CDATA[ | |||
GET /resource HTTP/1.1 | GET /resource HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Range: bytes=1230000-999999999999 | Range: bytes=1230000-999999999999 | |||
]]></artwork> | ||||
</artwork></figure> | <t> | |||
<t> | where the last-byte-pos in the request is much larger than the | |||
where the last-byte-pos in the Request is much larger than the last-byte | last-byte-pos returned in response to an open-ended byte-range | |||
-pos returned in response to an open-ended byte-range HEAD request, as described | HEAD request, as described above, and much larger than the expected | |||
above, and much larger than the expected maximum size of the representation. Se | maximum size of the representation. See <xref target="Security"/> for | |||
e <xref target="Security"/> for range value considerations. | range value considerations. | |||
</t> | </t> | |||
<t> | <t> | |||
In response, a server may indicate that it is supplying a continuously a | In response, a server may indicate that it is supplying a continuously | |||
ggregating ("live") response by supplying the client request's last-byte-pos in | aggregating/live response by supplying the client request's | |||
the Content-Range response header field. | last-byte-pos in the Content-Range response header field. | |||
</t> | </t> | |||
<t> | <t> | |||
For example: | For example: | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="request"" x:indent-with=" | <artwork type="message/http; msgtype="request""><![CDATA[ | |||
"> | ||||
GET /resource HTTP/1.1 | GET /resource HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Range: bytes=1230000-999999999999 | Range: bytes=1230000-999999999999 | |||
]]></artwork> | ||||
</artwork></figure> | <t> | |||
<t> | ||||
returns | returns | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="response"" x:indent-with=" | <artwork type="message/http; msgtype="response""><![CDATA[ | |||
"> | ||||
HTTP/1.1 206 Partial Content | HTTP/1.1 206 Partial Content | |||
Content-Range: bytes 1230000-999999999999/* | Content-Range: bytes 1230000-999999999999/* | |||
</artwork></figure> | ]]></artwork> | |||
<t> | <t> | |||
from the server to indicate that the response will start at byte 1230000 | from the server to indicate that the response will start at byte | |||
and continues indefinitely to include all aggregated content, as it becomes ava | 1230000 and continue indefinitely to include all aggregated content, as i | |||
ilable. | t becomes available. | |||
</t> | </t> | |||
<t> | <t> | |||
A server that doesn't support or supply a continuously aggregating ("liv | A server that doesn't support or supply a continuously aggregating/live | |||
e") response will supply the currently satisfiable byte range, as it would with | response will supply the currently satisfiable byte range, | |||
an open-ended byte request. | as it would with an open-ended byte request. | |||
</t> | </t> | |||
<t> | <t> | |||
For example: | For example: | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="request"" x:indent-with=" | <artwork type="message/http; msgtype="request""><![CDATA[ | |||
"> | ||||
GET /resource HTTP/1.1 | GET /resource HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Range: bytes=1230000-999999999999 | Range: bytes=1230000-999999999999 | |||
]]></artwork> | ||||
</artwork></figure> | <t> | |||
<t> | returns | |||
will return | </t> | |||
</t> | <artwork type="message/http; msgtype="response""><![CDATA[ | |||
<figure><artwork type="message/http; msgtype="response"" x:indent-with=" | ||||
"> | ||||
HTTP/1.1 206 Partial Content | HTTP/1.1 206 Partial Content | |||
Content-Range: bytes 1230000-1234567/* | Content-Range: bytes 1230000-1234567/* | |||
</artwork></figure> | ]]></artwork> | |||
<t> | <t> | |||
from the server to indicate that the response will start at byte 1230000 | from the server to indicate that the response will start at byte | |||
and end at byte 1234567 and will not include any aggregated content. This is th | 1230000, end at byte 1234567, and not include any aggregated content. | |||
e response expected from a typical HTTP server - one that doesn't support byte-r | This is the response expected from a typical HTTP server -- one that | |||
ange requests on aggregating content. | doesn't support byte-range requests on aggregating content. | |||
</t> | </t> | |||
<t> | <t> | |||
A client that doesn't receive a response indicating it is continuously a | A client that doesn't receive a response indicating it is continuously | |||
ggregating must use other means to access aggregated content (e.g. periodic byte | aggregating must use other means to access aggregated content (e.g., | |||
-range polling). | periodic byte-range polling). | |||
</t> | </t> | |||
<t> | <t> | |||
A server that does return a continuously aggregating ("live") response s | A server that does return a continuously aggregating/live response | |||
hould return data using chunked transfer coding and not provide a Content-Length | should return data using chunked transfer coding and not provide a | |||
header field. A 0-length chunk indicates the end of the transfer, per <xref x:s | Content-Length header field. A 0-length chunk indicates the end of the | |||
ec="4.1" x:fmt="of" target="RFC7230"/>. | transfer, per <xref target="RFC7230" sectionFormat="of" | |||
</t> | section="4.1"/>. | |||
</t> | ||||
</section> | ||||
</section> | </section> | |||
</section> | <section anchor="other-applications"> | |||
<section anchor="other-applications" title="Other Applications of Random-Acc | <name>Other Applications of Random-Access Aggregating Content</name> | |||
ess Aggregating Content"> | <section anchor="starting-at-live"> | |||
<section anchor="starting-at-live" title="Requests Starting at the Aggrega | <name>Requests Starting at the Aggregation/Live Point</name> | |||
tion ("Live") Point"> | <t> | |||
<t> | A client that wishes to only receive newly aggregated portions of a | |||
A client that wishes to only receive newly-aggregated portions of a | resource (i.e., start at the live point) can use a HEAD request to | |||
resource (i.e., start at the "live" point), can use a HEAD request to | ||||
learn what range the server has currently available and initiate an | learn what range the server has currently available and initiate an | |||
indeterminate-length transfer. For example: | indeterminate-length transfer. For example: | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="request"" x:indent-with=" | <artwork type="message/http; msgtype="request""><![CDATA[ | |||
"> | ||||
HEAD /resource HTTP/1.1 | HEAD /resource HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Range: bytes=0- | Range: bytes=0- | |||
]]></artwork> | ||||
</artwork></figure> | ||||
<t> | <t> | |||
With the Content-Range response header field indicating the range (o | with the Content-Range response header field indicating the range | |||
r ranges) available. For example: | (or ranges) available. For example: | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="response"" x:indent-with=" "> | <artwork type="message/http; msgtype="response""><![CDATA[ | |||
206 Partial Content | 206 Partial Content | |||
Content-Range: bytes 0-1234567/* | Content-Range: bytes 0-1234567/* | |||
</artwork></figure> | ]]></artwork> | |||
<t> | <t> | |||
The client can then issue a request for a range starting at the end | The client can then issue a request for a range starting at the end | |||
value (using a very large value for the end of a range) and receive | value (using a very large value for the end of a range) and receive | |||
only new content. | only new content. | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="request"" x:indent-with=" | <t> | |||
"> | For example: | |||
</t> | ||||
<artwork type="message/http; msgtype="request""><![CDATA[ | ||||
GET /resource HTTP/1.1 | GET /resource HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Range: bytes=1234567-999999999999 | Range: bytes=1234567-999999999999 | |||
]]></artwork> | ||||
</artwork></figure> | ||||
<t> | <t> | |||
with a server returning a Content-Range response indicating that an in | with a server returning a Content-Range response indicating that an | |||
determinate-length response body will be provided | indeterminate-length response body will be provided: | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="response"" x:indent-with=" "> | <artwork type="message/http; msgtype="response""><![CDATA[ | |||
206 Partial Content | 206 Partial Content | |||
Content-Range: bytes 1234567-999999999999/* | Content-Range: bytes 1234567-999999999999/* | |||
</artwork></figure> | ]]></artwork> | |||
</section> | </section> | |||
<section anchor="shift-buffers" title="Shift Buffer Representations"> | ||||
<t> | <section anchor="shift-buffers"> | |||
Some representations lend themselves to front-end content removal in add | <name>Shift-Buffer Representations</name> | |||
ition to aggregation. While still supporting random access, representations of t | <t> | |||
his type have a portion at the beginning (the "0" end) of the randomly-accessibl | Some representations lend themselves to front-end content removal in | |||
e region that become inaccessible over time. Examples of this kind of representa | addition to aggregation. While still supporting random access, | |||
tion would be an audio-video time-shift buffer or a rolling log file. | representations of this type have a portion at the beginning (the "0" | |||
</t> | end) of the randomly accessible region that becomes inaccessible over | |||
<t> | time. Examples of this kind of representation would be an audio-video | |||
For example a Range request containing: | time-shift buffer or a rolling log file. | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="request"" x:indent-with=" | <t> | |||
"> | For example, a range request containing: | |||
</t> | ||||
<artwork type="message/http; msgtype="request""><![CDATA[ | ||||
HEAD /resource HTTP/1.1 | HEAD /resource HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Range: bytes=0- | Range: bytes=0- | |||
]]></artwork> | ||||
</artwork></figure> | <t> | |||
<t> | ||||
returns | returns | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="response"" x:indent-with=" | <artwork type="message/http; msgtype="response""><![CDATA[ | |||
"> | ||||
206 Partial Content | 206 Partial Content | |||
Content-Range: bytes 1000000-1234567/* | Content-Range: bytes 1000000-1234567/* | |||
</artwork></figure> | ]]></artwork> | |||
<t> | <t> | |||
indicating that the first 1000000 bytes were not accessible at the time | indicating that the first 1000000 bytes were not accessible at the | |||
the HEAD request was processed. Subsequent HEAD requests could return: | time the HEAD request was processed. Subsequent HEAD requests could retur | |||
</t> | n: | |||
<figure><artwork type="example" x:indent-with=" "> | </t> | |||
<artwork type="example"><![CDATA[ | ||||
Content-Range: bytes 1000000-1234567/* | Content-Range: bytes 1000000-1234567/* | |||
</artwork></figure> | ]]></artwork> | |||
<figure><artwork type="example" x:indent-with=" "> | <artwork type="example"><![CDATA[ | |||
Content-Range: bytes 1010000-1244567/* | Content-Range: bytes 1010000-1244567/* | |||
</artwork></figure> | ]]></artwork> | |||
<figure><artwork type="example" x:indent-with=" "> | <artwork type="example"><![CDATA[ | |||
Content-Range: bytes 1020000-1254567/* | Content-Range: bytes 1020000-1254567/* | |||
</artwork></figure> | ]]></artwork> | |||
<t> | <t> | |||
Note though that the difference between the first-byte-pos and last-byte | Note though that the difference between the first-byte-pos and | |||
-pos need not be constant. | last-byte-pos need not be constant. | |||
</t> | </t> | |||
<t> | <t> | |||
The client could then follow-up with a GET Range request containing | The client could then follow up with a GET range request containing: | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="request"" x:indent-with=" | <artwork type="message/http; msgtype="request""><![CDATA[ | |||
"> | ||||
GET /resource HTTP/1.1 | GET /resource HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Range: bytes=1020000-999999999999 | Range: bytes=1020000-999999999999 | |||
]]></artwork> | ||||
</artwork></figure> | <t> | |||
<t> | ||||
with the server returning | with the server returning | |||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="response"" x:indent-with=" | <artwork type="message/http; msgtype="response""><![CDATA[ | |||
"> | ||||
206 Partial Content | 206 Partial Content | |||
Content-Range: bytes 1020000-999999999999/* | Content-Range: bytes 1020000-999999999999/* | |||
</artwork></figure> | ]]></artwork> | |||
<t> | <t> | |||
with the response body returning bytes 1020000-1254567 immediately and a | with the response body returning bytes 1020000-1254567 immediately | |||
ggregated ("live") data being returned as the content is aggregated. | and aggregated/live data being returned as the content is aggregated. | |||
</t> | </t> | |||
<t> | <t> | |||
A server that doesn't support or supply a continuously aggregating ("liv | A server that doesn't support or supply a continuously aggregating/live | |||
e") response will supply the currently satisfiable byte range, as it would with | response will supply the currently satisfiable byte range, as | |||
an open-ended byte request. | it would with an open-ended byte request. For example: | |||
</t> | </t> | |||
<t> | <artwork type="message/http; msgtype="request""><![CDATA[ | |||
For example: | ||||
</t> | ||||
<figure><artwork type="message/http; msgtype="request"" x:indent-with=" | ||||
"> | ||||
GET /resource HTTP/1.1 | GET /resource HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Range: bytes=0-999999999999 | Range: bytes=0-999999999999 | |||
]]></artwork> | ||||
<t> | ||||
returns | ||||
</t> | ||||
<artwork type="message/http; msgtype="response""><![CDATA[ | ||||
HTTP/1.1 206 Partial Content | ||||
Content-Range: bytes 1020000-1254567/* | ||||
]]></artwork> | ||||
<t> | ||||
from the server to indicate that the response will start at byte | ||||
1020000, end at byte 1254567, and not include any aggregated | ||||
content. This is the response expected from a typical HTTP | ||||
server -- one that doesn't support byte-range requests on aggregating con | ||||
tent. | ||||
</t> | ||||
<t> | ||||
Note that responses to GET requests performed on shift-buffer | ||||
representations using Range headers can be cached by intermediaries, s | ||||
ince | ||||
the Content-Range response header indicates which portion of the | ||||
representation is being returned in the response body. However, GET | ||||
requests without a Range header cannot be cached since the first | ||||
byte of the response body can vary from request to request. To | ||||
ensure GET requests without Range headers on shift-buffer representati | ||||
ons | ||||
are not cached, servers hosting a shift-buffer representation should | ||||
either not return a 200-level response (e.g., send a 300-level | ||||
redirect response with a URI that represents the current start of | ||||
the shift buffer) or indicate the response is non-cacheable. See | ||||
<xref target="RFC7234"/> for details on HTTP cache control. | ||||
</t> | ||||
</section> | ||||
</section> | ||||
</artwork></figure> | <section anchor="RecommendedVLV"> | |||
<name>Recommendations for Byte-Range Request last-byte-pos Values</name> | ||||
<t> | <t> | |||
will return | While it would be ideal to define a single large last-byte-pos | |||
value for byte-range requests, there's no single value that would wo | ||||
rk for all | ||||
applications and platforms. For example, JavaScript numbers cannot | ||||
represent all integer values above 2^^53, so a JavaScript | ||||
application may want to use 2^^53-1 for last-byte-pos. This | ||||
value, however, would not be sufficient for all applications, such | ||||
as long-duration high-bitrate streams. So | ||||
2^^53-1 (9007199254740991) is recommended as a last-byte-pos | ||||
unless an application has a good justification to use a smaller or | ||||
larger value. For example, if it is always known that the resource w | ||||
on't | ||||
exceed a value smaller than the recommended last-byte-pos for | ||||
an application, a smaller value can be used. If it's likely | ||||
that an application will utilize resources larger than the | ||||
recommended last-byte-pos (such as a continuously aggregating | ||||
high-bitrate media stream), a larger value should be used. | ||||
</t> | </t> | |||
<figure><artwork type="message/http; msgtype="response"" x:indent-with=" | ||||
"> | ||||
HTTP/1.1 206 Partial Content | ||||
Content-Range: bytes 1020000-1254567/* | ||||
</artwork></figure> | ||||
<t> | <t> | |||
from the server to indicate that the response will start at byte 1020000 | Note that, in accordance with the semantics defined above, servers | |||
, end at byte 1254567, and will not include any aggregated content. This is the | that support random-access live content will need to return the | |||
response expected from a typical HTTP server - one that doesn't support byte-ran | last-byte-pos provided in the byte-range request in some cases -- eve | |||
ge requests on aggregating content. | n | |||
if the last-byte-pos cannot be represented as a numerical value | ||||
internally by the server. As is the case with any | ||||
continuously aggregating/live resource, the server should | ||||
terminate the content transfer when the end of the resource is | ||||
reached -- whether the end is due to termination of the content | ||||
source or the content length exceeds the server's maximum representat | ||||
ion length. | ||||
</t> | </t> | |||
</section> | ||||
<section anchor="IANA"> | ||||
<name>IANA Considerations</name> | ||||
<t>This document has no IANA actions.</t> | ||||
</section> | ||||
<section anchor="Security"> | ||||
<name>Security Considerations</name> | ||||
<t> | <t> | |||
Note that responses to GET requests against shift-buffer representatio | As described above, servers need to be prepared to receive | |||
ns using Range | last-byte-pos values in range requests that are numerically larger | |||
can be cached by intermediaries, since the Content-Range response head | than the server implementation supports and return these values in | |||
er indicates | Content-Range response header fields. Servers should check the | |||
which portion of the representation is being returned in the response | last-byte-pos value before converting and storing them into | |||
body. However | numeric form to ensure the value doesn't cause an overflow or | |||
GET requests without a Range header cannot be cached since the first b | index incorrect data. The simplest way to satisfy the live-range | |||
yte of the response | semantics defined in this document without potential overflow | |||
body can vary from request to request. To ensure Range-less GET reques | issues is to store the last-byte-pos as a string value and return | |||
ts against | it in the byte-range Content-Range response header's last-byte-pos fi | |||
shift-buffer representations are not cached, servers hosting a shift-b | eld. | |||
uffer | ||||
representation should either not return a 200-level response (e.g. sen | ||||
ding a | ||||
300-level redirect response with a URI that represents the current sta | ||||
rt of the | ||||
shift-buffer) or indicate the response is non-cacheable. See HTTP Cach | ||||
ing | ||||
(<xref target="RFC7234"/>) for details on HTTP cache control. | ||||
</t> | </t> | |||
</section> | ||||
</section> | </section> | |||
</middle> | ||||
<!-- *****BACK MATTER ***** --> | ||||
<!-- Possibly a 'Contributors' section ... --> | <back> | |||
<references> | ||||
<name>References</name> | ||||
<section anchor="RecommendedVLV" title="Recommendations for Very Large Value | <references> | |||
s"> | ||||
<t> | ||||
While it would be ideal to define a single numerical Very Large Valu | ||||
e, there's no single value that would work for all applications and platforms. e | ||||
.g. JavaScript numbers cannot represent all integer values above 2^^53, so a Jav | ||||
aScript application may want to use 2^^53-1 for a Very Large Value. This value, | ||||
however, would not be sufficient for all applications, such as continuously-stre | ||||
aming high-bitrate streams. So the value 2^^53-1 (9007199254740991) is recommend | ||||
ed as a Very Large Value unless an application has a good justification to use a | ||||
smaller or larger value. e.g. If it's always known that the resource won't exce | ||||
ed a value smaller than the recommended Very Large Value for an application, a s | ||||
maller value can be used. And if it's likely that an application will utilize re | ||||
sources larger than the recommended Very Large Value - such as a continuously ag | ||||
gregating high-bitrate media stream - a larger value should be used. | ||||
</t> | ||||
<t> | ||||
Note that, in accordance with the semantics defined above, servers t | ||||
hat support random-access live content will need to return the last-byte-pos pro | ||||
vided in the Range request in some cases - even if the last-byte-pos cannot be r | ||||
epresented as a numerical value internally by the server. As is the case with an | ||||
y live/continuously aggregating resource, the server should terminate the conten | ||||
t transfer when the end of the resource is reached - whether the end is due to t | ||||
ermination of the content source or the content length exceeds the server's maxi | ||||
mum representation length. | ||||
</t> | ||||
</section> | ||||
<section anchor="IANA" title="IANA Considerations"> | <name>Normative References</name> | |||
<t>This document has no actions for IANA.</t> | ||||
</section> | ||||
<section anchor="Security" title="Security Considerations"> | <xi:include | |||
<t> | href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7230.xml"/> | |||
As described above, servers need to be prepared to receive last-byte | ||||
-pos values in Range requests that are numerically larger than the server implem | ||||
entation supports - and return these values in Content-Range response header fie | ||||
lds. Servers should check the last-byte-pos value before converting and storing | ||||
them into numeric form to ensure the value doesn't cause an overflow or index in | ||||
correct data. The simplest way to satisfy the live-range semantics defined in th | ||||
is document without potential overflow issues is to store the last-byte-pos as a | ||||
string value and return it in the byte-range Content-Range response header's la | ||||
st-byte-pos field. | ||||
</t> | ||||
</section> | ||||
</middle> | ||||
<!-- *****BACK MATTER ***** --> | <xi:include | |||
<back> | href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7233.xml"/> | |||
<!-- References split to informative and normative --> | ||||
<references title="Normative References"> | <xi:include | |||
&RFC2119; | href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7234.xml"/> | |||
&RFC7230; | ||||
&RFC7233; | <xi:include | |||
&RFC7234; | href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5234.xml"/> | |||
</references> | ||||
</references> | ||||
<references> | ||||
<name>Informative References</name> | ||||
<xi:include | ||||
href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8216.xml"/> | ||||
<reference anchor="MPEG-DASH" | ||||
target="https://www.iso.org/standard/75485.html"> | ||||
<references title="Informative References"> | ||||
&RFC5234; | ||||
&RFC8216; | ||||
<reference anchor="DASH" target="http://standards.iso.org/ittf/PubliclyA | ||||
vailableStandards/c065274_ISO_IEC_23009-1_2014.zip"> | ||||
<front> | <front> | |||
<title>Information technology -- Dynamic adaptive streaming over HTT P (DASH) -- Part 1: Media presentation description and segment formats | <title>Information technology -- Dynamic adaptive streaming over HTT P (DASH) -- Part 1: Media presentation description and segment formats | |||
</title> | </title> | |||
<author><organization>ISO</organization></author> | <seriesInfo name="ISO/IEC" value="23009-1"/> | |||
<date month="May" year="2014" /> | <author> | |||
<organization>ISO</organization> | ||||
</author> | ||||
<date month="August" year="2019"/> | ||||
</front> | </front> | |||
<seriesInfo name="ISO/IEC" value="23009-1:2014" /> | ||||
</reference> | </reference> | |||
</references> | ||||
</references> | </references> | |||
<section anchor="Acknowledgements" title="Acknowledgements" numbered="false" | <section anchor="Acknowledgements" numbered="false"> | |||
> | <name>Acknowledgements</name> | |||
<t> | <t> | |||
Mark Nottingham, Patrick McManus, Julian Reschke, Remy Lebeau, Rodger Comb | The authors would like to thank Mark Nottingham, Patrick McManus, Julian R | |||
s, Thorsten Lohmar, Martin Thompson, Adrien de Croy, K. Morgan, Roy T. Fielding, | eschke, Remy Lebeau, Rodger | |||
Jeremy Poulter. | Combs, Thorsten Lohmar, Martin Thompson, Adrien de Croy, K. Morgan, R | |||
</t> | oy | |||
T. Fielding, and Jeremy Poulter. | ||||
</t> | ||||
</section> | </section> | |||
</back> | </back> | |||
</rfc> | </rfc> | |||
End of changes. 90 change blocks. | ||||
555 lines changed or deleted | 457 lines changed or added | |||
This html diff was produced by rfcdiff 1.45. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |