RFC 7233
Hypertext Transfer Protocol (HTTP/1.1): Range Requests
Hypertext Transfer Protocol (HTTP/1.1): Range Requests ๐
Okay bestie, here's the lowdown on RFC 7233 โจ. It's a Standards Track document from June 2014, published as ISSN 2070-1721. The editors are R. Fielding (Adobe), Y. Lafon (W3C), and J. Reschke (greenbytes), and it's all about range requests in HTTP/1.1. It obsoletes RFC 2616, and its title block doesn't list any documents it updates ๐ .
Abstract ๐
HTTP is a stateless, application-level protocol for distributed, collaborative, hypertext information systems. This doc is where range requests get defined, along with the rules for building responses to them and putting those responses back together ๐ง.
Status of This Memo ๐
This one's an Internet Standards Track document ๐ฅ.
It's a product of the IETF, which means it reflects what the whole IETF community agreed on. It got public review and was approved for publication by the IESG (Internet Engineering Steering Group) ๐. If you want more on Internet Standards, check out Section 2 of RFC 5741.
For the latest status of this document, any errata, and how to send feedback, head to http://www.rfc-editor.org/info/rfc7233 ๐ฆ.
Copyright Notice ๐ซถ
Copyright (c) 2014 IETF Trust and the persons identified as the document authors. All rights reserved ๐.
This document falls under BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stood on the publication date. Read those carefully, because they spell out your rights and restrictions for this document ๐. Any Code Components pulled out of this document have to include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, same as the Simplified BSD License says ๐ธ.
Some of this document may include material from IETF Documents or IETF Contributions that were published or made publicly available before November 10, 2008. The people who control the copyright in some of that older material might not have given the IETF Trust permission to allow modifications outside the IETF Standards Process ๐. So unless you get a proper license from whoever controls that copyright, this document can't be modified outside the IETF Standards Process, and derivative works of it can't be made outside that process either. The one exceptions are formatting it for publication as an RFC or translating it into languages other than English ๐.
Table of Contents ๐๏ธ
1. Introduction ....................................................4
1.1. Conformance and Error Handling .............................4
1.2. Syntax Notation ............................................4
2. Range Units .....................................................5
2.1. Byte Ranges ................................................5
2.2. Other Range Units ..........................................7
2.3. Accept-Ranges ..............................................7
3. Range Requests ..................................................8
3.1. Range ......................................................8
3.2. If-Range ...................................................9
4. Responses to a Range Request ...................................10
4.1. 206 Partial Content .......................................10
4.2. Content-Range .............................................12
4.3. Combining Ranges ..........................................14
4.4. 416 Range Not Satisfiable .................................15
5. IANA Considerations ............................................16
5.1. Range Unit Registry .......................................16
5.1.1. Procedure ..........................................16
5.1.2. Registrations ......................................16
5.2. Status Code Registration ..................................17
5.3. Header Field Registration .................................17
5.4. Internet Media Type Registration ..........................17
5.4.1. Internet Media Type multipart/byteranges ...........18
6. Security Considerations ........................................19
6.1. Denial-of-Service Attacks Using Range .....................19
7. Acknowledgments ................................................19
8. References .....................................................20
8.1. Normative References ......................................20
8.2. Informative References ....................................20
Appendix A. Internet Media Type multipart/byteranges ..............21
Appendix B. Changes from RFC 2616 .................................22
Appendix C. Imported ABNF .........................................22
Appendix D. Collected ABNF ........................................23
Index .............................................................24
1. Introduction ๐ฆ
Okay so picture this: HTTP clients keep getting their transfers cut off because a request got canceled or a connection dropped ๐ญ. If a client already has part of a representation saved, it makes way more sense to ask for just the rest in a follow-up request instead of pulling the whole thing again. And devices with limited storage? They might only want one page of a massive document, or just the dimensions of an embedded image. Main character energy for partial transfers ๐ .
This document defines HTTP/1.1 range requests, partial responses, and the multipart/byteranges media type. Range requests are an OPTIONAL feature of HTTP โจ. They're built so that a recipient that doesn't implement the feature (or doesn't support it for the target resource) can just respond as if it's a normal GET request, so nothing breaks for interoperability ๐ซถ. Partial responses get their own distinct status code so that caches which don't implement the feature won't mistake them for full responses ๐.
Range requests were designed to allow extensible range types, but this specification only defines requests for byte ranges ๐.
1.1. Conformance and Error Handling ๐ฅ
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] ๐.
Conformance criteria and considerations about error handling are defined in Section 2.5 of [RFC7230] ๐.
1.2. Syntax Notation ๐
This spec uses the Augmented Backus-Naur Form (ABNF) notation of [RFC5234], plus a list extension from Section 7 of [RFC7230]. That extension lets you define comma-separated lists compactly with a # operator, kind of like how * indicates repetition ๐ง. Appendix C describes rules imported from other documents, and Appendix D shows the collected grammar with all the list operators expanded into standard ABNF notation ๐.
2. Range Units ๐
A representation can be split into subranges based on different structural units, depending on the structure built into its media type. This "range unit" gets used in three places: the Accept-Ranges (Section 2.3) response header field advertises support for range requests, the Range (Section 3.1) request header field marks which parts of a representation are being requested, and the Content-Range (Section 4.2) payload header field describes which part of a representation is being transferred ๐ฆ.
range-unit = bytes-unit / other-range-unit
2.1. Byte Ranges ๐ซง
Representation data gets transferred in payloads as a sequence of octets, so a byte range is a meaningful substructure for any representation that can be transferred over HTTP (Section 3 of [RFC7231]) ๐. The "bytes" range unit is defined for expressing subranges of that octet sequence โจ.
bytes-unit = "bytes"
A byte-range request can ask for a single range of bytes, or a set of ranges within a single representation ๐ธ.
byte-ranges-specifier = bytes-unit "=" byte-range-set
byte-range-set = 1#( byte-range-spec / suffix-byte-range-spec )
byte-range-spec = first-byte-pos "-" [ last-byte-pos ]
first-byte-pos = 1*DIGIT
last-byte-pos = 1*DIGIT
The first-byte-pos value in a byte-range-spec gives the byte offset of the first byte in a range. The last-byte-pos value gives the byte offset of the last byte in the range, and the positions are inclusive, so both ends count ๐ . Byte offsets start at zero ๐ง.
Here are some examples of byte-ranges-specifier values ๐ธ:
- The first 500 bytes (byte offsets 0-499, inclusive):
bytes=0-499
- The second 500 bytes (byte offsets 500-999, inclusive):
bytes=500-999
A byte-range-spec is invalid if last-byte-pos is present and it's less than first-byte-pos. That's a hard no ๐ โโ๏ธ.
A client can limit how many bytes it requests without knowing how big the selected representation is ๐. If last-byte-pos is absent, or if its value is greater than or equal to the current length of the representation data, the byte range gets interpreted as the remainder of the representation. In other words, the server replaces last-byte-pos with a value that's one less than the current length of the selected representation ๐.
A client can request the last N bytes of the selected representation with a suffix-byte-range-spec ๐ฆ.
suffix-byte-range-spec = "-" suffix-length
suffix-length = 1*DIGIT
If the selected representation is shorter than the specified suffix-length, the entire representation gets used ๐ซถ.
More examples, assuming a representation of length 10000 ๐:
- The final 500 bytes (byte offsets 9500-9999, inclusive):
bytes=-500
Or:
bytes=9500-
- The first and last bytes only (bytes 0 and 9999):
bytes=0-0,-1
- Other valid (but not canonical) specifications of the second 500 bytes (byte offsets 500-999, inclusive):
bytes=500-600,601-999
bytes=500-700,601-999
If a valid byte-range-set includes at least one byte-range-spec whose first-byte-pos is less than the current length of the representation, or at least one suffix-byte-range-spec with a non-zero suffix-length, then the byte-range-set is satisfiable. Otherwise, it's unsatisfiable ๐.
In the byte-range syntax, first-byte-pos, last-byte-pos, and suffix-length are written as decimal numbers of octets. Since there's no predefined limit on how long a payload can be, recipients MUST anticipate potentially large decimal numerals and prevent parsing errors caused by integer conversion overflows ๐จ. Bestie, this is a real one, so don't skip it ๐ญ.
2.2. Other Range Units ๐ท
Range units are meant to be extensible โจ. New range units ought to be registered with IANA, as defined in Section 5.1 ๐ง.
other-range-unit = token
2.3. Accept-Ranges โจ
okay so the Accept-Ranges header field is how a server tells the client it can handle range requests for the target resource ๐ฆ
Accept-Ranges = acceptable-ranges
acceptable-ranges = 1#range-unit / "none"
An origin server that supports byte-range requests for a given target resource MAY send
Accept-Ranges: bytes
to indicate which range units it supports ๐ A client MAY generate range requests without having received this header field for the resource involved. Range units are defined in Section 2.
A server that doesn't support any kind of range request for the target resource MAY send
Accept-Ranges: none
to tell the client not to bother trying a range request ๐
3. Range Requests ๐
3.1. Range
The Range header field on a GET request changes the method semantics so the client only asks for one or more subranges of the selected representation data, instead of the whole thing ๐
Range = byte-ranges-specifier / other-ranges-specifier
other-ranges-specifier = other-range-unit "=" other-range-set
other-range-set = 1*VCHAR
A server MAY ignore the Range header field. However, origin servers and intermediate caches ought to support byte ranges when possible, since Range makes it possible to recover efficiently from partially failed transfers and to retrieve large representations in pieces ๐ง A server MUST ignore a Range header field received with a request method other than GET.
An origin server MUST ignore a Range header field that contains a range unit it doesn't understand. A proxy MAY discard a Range header field that contains a range unit it doesn't understand.
A server that supports range requests MAY ignore or reject a Range header field that consists of more than two overlapping ranges, or a set of many small ranges that aren't listed in ascending order. Both of those are signs of either a broken client or a deliberate denial-of-service attack (Section 6.1) ๐ญ A client SHOULD NOT request multiple ranges that are inherently less efficient to process and transfer than a single range that covers the same data.
A client requesting multiple ranges SHOULD list them in ascending order (the order they would typically be received in a complete representation), unless there's a specific need to request a later part first. For example, a user agent processing a large representation with an internal catalog of parts might need to request later parts first. That's especially true if the representation consists of pages stored in reverse order and the user agent wants to transfer one page at a time ๐
The Range header field is evaluated after the precondition header fields defined in [RFC7232] have been evaluated, and only if the result without the Range header field would be a 200 (OK) response. In other words, Range is ignored when a conditional GET would result in a 304 (Not Modified) response ๐
The If-Range header field (Section 3.2) can be used as a precondition to applying the Range header field.
If all of the preconditions are true, the server supports the Range header field for the target resource, and the specified range(s) are valid and satisfiable (as defined in Section 2.1), the server SHOULD send a 206 (Partial Content) response. That response has a payload with one or more partial representations that correspond to the satisfiable ranges requested, as defined in Section 4 โจ
If all of the preconditions are true, the server supports the Range header field for the target resource, and the specified range(s) are invalid or unsatisfiable, the server SHOULD send a 416 (Range Not Satisfiable) response ๐ธ
3.2. If-Range
If a client has a partial copy of a representation and wants an up-to-date copy of the entire representation, it could use the Range header field with a conditional GET (using either or both of If-Unmodified-Since and If-Match). But if the precondition fails because the representation has been modified, the client would then have to make a second request to get the entire current representation ๐ฉ
The If-Range header field lets a client "short-circuit" that second request ๐ฆ Informally, it means: if the representation is unchanged, send me the part(s) I asked for in Range; otherwise, send me the entire representation.
If-Range = entity-tag / HTTP-date
A client MUST NOT generate an If-Range header field in a request that doesn't contain a Range header field. A server MUST ignore an If-Range header field received in a request that doesn't contain a Range header field. An origin server MUST ignore an If-Range header field received in a request for a target resource that doesn't support Range requests ๐ซ
A client MUST NOT generate an If-Range header field containing an entity-tag that is marked as weak. A client MUST NOT generate an If-Range header field containing an HTTP-date unless the client has no entity-tag for the corresponding representation and the date is a strong validator in the sense defined by Section 2.2.2 of [RFC7232] ๐ฅ
A server that evaluates an If-Range precondition MUST use the strong comparison function when comparing entity-tags (Section 2.3.2 of [RFC7232]). It MUST evaluate the condition as false if an HTTP-date validator is provided that is not a strong validator in the sense defined by Section 2.2.2 of [RFC7232]. You can tell a valid entity-tag apart from a valid HTTP-date by checking whether the first two characters are a DQUOTE ๐ง
If the validator given in the If-Range header field matches the current validator for the selected representation of the target resource, the server SHOULD process the Range header field as requested. If the validator doesn't match, the server MUST ignore the Range header field. Note that this exact-match comparison, including when the validator is an HTTP-date, is different from the "earlier than or equal to" comparison used when evaluating an If-Unmodified-Since conditional ๐
4. Responses to a Range Request ๐
4.1. 206 Partial Content
The 206 (Partial Content) status code means the server is successfully fulfilling a range request for the target resource by transferring one or more parts of the selected representation. Those parts correspond to the satisfiable ranges found in the request's Range header field (Section 3.1) ๐ซถ
If a single part is being transferred, the server generating the 206 response MUST generate a Content-Range header field describing which range of the selected representation is enclosed, plus a payload consisting of that range. For example:
HTTP/1.1 206 Partial Content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Range: bytes 21010-47021/47022
Content-Length: 26012
Content-Type: image/gif
... 26012 bytes of partial image data ...
If multiple parts are being transferred, the server generating the 206 response MUST generate a "multipart/byteranges" payload, as defined in Appendix A, along with a Content-Type header field containing the multipart/byteranges media type and its required boundary parameter. To avoid confusion with single-part responses, a server MUST NOT generate a Content-Range header field in the HTTP header section of a multiple-part response. That field gets sent in each part instead ๐งฉ
Inside the header area of each body part in the multipart payload, the server MUST generate a Content-Range header field matching the range enclosed in that body part. If the selected representation would have had a Content-Type header field in a 200 (OK) response, the server SHOULD generate that same Content-Type field in the header area of each body part. For example:
HTTP/1.1 206 Partial Content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Length: 1741
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 500-999/8000
...the first range...
--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 7000-7999/8000
...the second range
--THIS_STRING_SEPARATES--
When multiple ranges are requested, a server MAY coalesce any of the ranges that overlap, or that are separated by a gap smaller than the overhead of sending multiple parts. This applies regardless of the order in which the corresponding byte-range-spec appeared in the received Range header field. The typical overhead between parts of a multipart/byteranges payload is around 80 bytes, depending on the selected representation's media type and the length of the chosen boundary parameter. So it can be less efficient to transfer many small disjoint parts than to transfer the entire selected representation ๐
A server MUST NOT generate a multipart response to a request for a single range, because a client that didn't request multiple parts might not support multipart responses. However, a server MAY generate a multipart/byteranges payload with only a single body part if multiple ranges were requested and only one was found to be satisfiable, or only one remained after coalescing. A client that can't process a multipart/byteranges response MUST NOT generate a request asking for multiple ranges ๐
When a multipart response payload is generated, the server SHOULD send the parts in the same order that the corresponding byte-range-spec appeared in the received Range header field. The exception is ranges that were deemed unsatisfiable or that were coalesced into other ranges. A client that receives a multipart response MUST inspect the Content-Range header field present in each body part to figure out which range that part contains. A client can't count on getting the same ranges it requested, or in the same order it requested them ๐ง
When a 206 response is generated, the server MUST generate the following header fields, in addition to those required above, if the field would have been sent in a 200 (OK) response to the same request: Date, Cache-Control, ETag, Expires, Content-Location, and Vary โจ
If a 206 is generated in response to a request with an If-Range header field, the sender SHOULD NOT generate other representation header fields beyond those required above. That's because the client is understood to already have a prior response containing those header fields. Otherwise, the sender MUST generate all of the representation header fields that would have been sent in a 200 (OK) response to the same request ๐
A 206 response is cacheable by default, meaning that's true unless explicit cache controls say otherwise (see Section 4.2.2 of [RFC7234]) ๐ฆ
4.2. Content-Range ๐
okay so the Content-Range header field ๐
has three jobs. It shows up in a single-part 206 (Partial Content) response to say which part of the selected representation is in the message payload. It also shows up in each part of a multipart 206 response, to say what range is inside each body part. And it appears in 416 (Range Not Satisfiable) responses to give info about the selected representation.
Content-Range = byte-content-range
/ other-content-range
byte-content-range = bytes-unit SP
( byte-range-resp / unsatisfied-range )
byte-range-resp = byte-range "/" ( complete-length / "*" )
byte-range = first-byte-pos "-" last-byte-pos
unsatisfied-range = "*/" complete-length
complete-length = 1*DIGIT
other-content-range = other-range-unit SP other-range-resp
other-range-resp = *CHAR
bestie, listen ๐ซถ if a 206 (Partial Content) response has a Content-Range with a range unit (Section 2) that the recipient doesn't understand, the recipient MUST NOT attempt to recombine it with a stored representation. ๐
โโ๏ธ A proxy that gets a message like that SHOULD forward it downstream. no notes.
for byte ranges, a sender SHOULD tell you the complete length of the representation the range came from, unless that length is unknown or hard to figure out. a * where the complete-length goes just means the length was unknown when the header was generated. ๐ง
here's an example where the sender knows the selected representation is 1234 bytes:
Content-Range: bytes 42-1233/1234
and here's one where the complete length is unknown:
Content-Range: bytes 42-1233/*
a Content-Range value is invalid if its byte-range-resp has a last-byte-pos that's less than its first-byte-pos, or a complete-length that's less than or equal to its last-byte-pos. ๐ the recipient of an invalid Content-Range MUST NOT attempt to recombine the received content with a stored representation. absolutely not.
a server that's making a 416 (Range Not Satisfiable) response to a byte-range request SHOULD send a Content-Range header field with an unsatisfied-range value, like this:
Content-Range: bytes */1234
the complete-length in a 416 response tells you the current length of the selected representation. โจ
the Content-Range header field doesn't mean anything for status codes that don't explicitly describe its semantic. for this spec, only 206 (Partial Content) and 416 (Range Not Satisfiable) give Content-Range a meaning. ๐ธ
here are some Content-Range values where the selected representation is 1234 bytes total:
- The first 500 bytes:
Content-Range: bytes 0-499/1234
- The second 500 bytes:
Content-Range: bytes 500-999/1234
- All except for the first 500 bytes:
Content-Range: bytes 500-1233/1234
- The last 500 bytes:
Content-Range: bytes 734-1233/1234
4.3. Combining Ranges ๐งฉ
a response might only carry a subrange of a representation if the connection closed early, or if the request used one or more Range specifications. after a few of those transfers, a client could have several ranges of the same representation. these ranges can only be safely combined if they all share the same strong validator (Section 2.1 of [RFC7232]). ๐
a client that has gotten multiple partial responses to GET requests on a target resource MAY combine them into one bigger continuous range, as long as they share the same strong validator. โ
if the most recent response is an incomplete 200 (OK) response, then that response's header fields are used for any combined response, and they replace the header fields of the matching stored responses. ๐ซง
if the most recent response is a 206 (Partial Content) response and at least one matching stored response is a 200 (OK), then the combined response's header fields are the header fields of the most recent 200 response. if all of the matching stored responses are 206 responses, then the stored response with the most recent header fields is the source of header fields for the combined response. the exception is that the client MUST use the other header fields from the new response, apart from Content-Range, to replace all instances of the matching header fields in the stored response. ๐
the combined response message body is the union of the partial content ranges in the new response and in each of the selected responses. if that union covers the entire range of the representation, then the client MUST process the combined response as if it were a complete 200 (OK) response, including a Content-Length header field that reflects the complete length. ๐ otherwise, the client MUST process the set of continuous ranges as one of these: an incomplete 200 (OK) response if the combined response is a prefix of the representation, a single 206 (Partial Content) response containing a multipart/byteranges body, or multiple 206 (Partial Content) responses, where each one has one continuous range shown by a Content-Range header field. ๐ฆ
4.4. 416 Range Not Satisfiable ๐
the 416 (Range Not Satisfiable) status code means that none of the ranges in the request's Range header field (Section 3.1) overlap the current extent of the selected resource, or that the set of ranges asked for was rejected because the ranges were invalid or because there were too many small or overlapping ones. ๐ญ
for byte ranges, not overlapping the current extent means that the first-byte-pos of every byte-range-spec value was greater than the current length of the selected representation. when a byte-range request gets this status code, the sender SHOULD generate a Content-Range header field saying the current length of the selected representation (Section 4.2). ๐
for example:
HTTP/1.1 416 Range Not Satisfiable
Date: Fri, 20 Jan 2012 15:41:54 GMT
Content-Range: bytes */47022
Note: Because servers are free to ignore Range, lots of implementations just respond with the entire selected representation in a 200 (OK) response. that's partly because most clients can handle a 200 (OK) to finish the job (just less efficiently), and partly because clients might keep sending an invalid partial request until they've gotten a complete representation. so clients cannot count on getting a 416 (Range Not Satisfiable) response, even when it's the most appropriate one. ๐ฅฒ
5. IANA Considerations ๐
5.1. Range Unit Registry ๐๏ธ
the "HTTP Range Unit Registry" is the namespace for range unit names, and it points to their specs. the registry has been created and is maintained at http://www.iana.org/assignments/http-parameters. ๐
5.1.1. Procedure
registering an HTTP Range Unit MUST include these fields:
- Name
- Description
- Pointer to specification text
values added to this namespace need IETF Review (see [RFC5226], Section 4.1). ๐ง
5.1.2. Registrations
the initial range unit registry has these registrations:
+-------------+---------------------------------------+-------------+
| Range Unit | Description | Reference |
| Name | | |
+-------------+---------------------------------------+-------------+
| bytes | a range of octets | Section 2.1 |
| none | reserved as keyword, indicating no | Section 2.3 |
| | ranges are supported | |
+-------------+---------------------------------------+-------------+
the change controller is: "IETF (iesg@ietf.org) - Internet Engineering Task Force". ๐
5.2. Status Code Registration ๐ฆ
the "Hypertext Transfer Protocol (HTTP) Status Code Registry", at http://www.iana.org/assignments/http-status-codes, has been updated with these registrations:
+-------+-----------------------+-------------+
| Value | Description | Reference |
+-------+-----------------------+-------------+
| 206 | Partial Content | Section 4.1 |
| 416 | Range Not Satisfiable | Section 4.4 |
+-------+-----------------------+-------------+
5.3. Header Field Registration ๐ท๏ธ
HTTP header fields are registered in the "Message Headers" registry, which is maintained at http://www.iana.org/assignments/message-headers/.
this document defines the following HTTP header fields, so their registry entries have been updated with these permanent registrations (see [BCP90]): ๐
+-------------------+----------+----------+-------------+
| Header Field Name | Protocol | Status | Reference |
+-------------------+----------+----------+-------------+
| Accept-Ranges | http | standard | Section 2.3 |
| Content-Range | http | standard | Section 4.2 |
| If-Range | http | standard | Section 3.2 |
| Range | http | standard | Section 3.1 |
+-------------------+----------+----------+-------------+
the change controller is: "IETF (iesg@ietf.org) - Internet Engineering Task Force". ๐
5.4. Internet Media Type Registration ๐๏ธ
IANA keeps the registry of Internet media types [BCP13] at http://www.iana.org/assignments/media-types.
this document is the spec for the Internet media type "multipart/byteranges". it has been registered with IANA. ๐ฎ
5.4.1. Internet Media Type multipart/byteranges
- Type name: multipart
- Subtype name: byteranges
- Required parameters: boundary
- Optional parameters: N/A
- Encoding considerations: only "7bit", "8bit", or "binary" are permitted
- Security considerations: see Section 6
- Interoperability considerations: N/A
- Published specification: This specification (see Appendix A).
- Applications that use this media type: HTTP components supporting multiple ranges in a single request.
- Fragment identifier considerations: N/A
- Additional information:
- Deprecated alias names for this type: N/A
- Magic number(s): N/A
- File extension(s): N/A
- Macintosh file type code(s): N/A
- Person and email address to contact for further information: See Authors' Addresses section.
- Intended usage: COMMON
- Restrictions on usage: N/A
- Author: See Authors' Addresses section.
- Change controller: IESG
6. Security Considerations ๐
this section is here to tell developers, information providers, and users about known security concerns specific to the HTTP range request mechanisms. the more general security stuff is covered in HTTP messaging [RFC7230] and semantics [RFC7231]. ๐ก๏ธโจ
6.1. Denial-of-Service Attacks Using Range ๐
okay bestie, this one is SERIOUS ๐ญ unconstrained multiple range requests are a total denial-of-service magnet ๐จ because asking for a zillion overlapping ranges of the same data takes basically zero effort, but the server has to burn time, memory, and bandwidth to serve it all in pieces ๐. so servers ought to ignore, coalesce, or reject egregious range requests ๐ โโ๏ธ, like asking for more than two overlapping ranges or a bunch of tiny ranges in one set, especially when they're requested out of order for no apparent reason ๐. and multipart range requests are not designed to support random access, so don't go there ๐ซถ
7. Acknowledgments ๐
okay so the acknowledgments just send you to Section 10 of [RFC7230] ๐ฆ go check that one, it's giving credit and thanks ๐
8. References ๐
8.1. Normative References ๐
these are the must-read docs the spec leans on, so here they are exactly as written ๐ซถ
[RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
Extensions (MIME) Part Two: Media Types", RFC 2046,
November 1996.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", STD 68, RFC 5234, January 2008.
[RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
Protocol (HTTP/1.1): Message Syntax and Routing",
RFC 7230, June 2014.
[RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
Protocol (HTTP/1.1): Semantics and Content", RFC 7231,
June 2014.
[RFC7232] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
Protocol (HTTP/1.1): Conditional Requests", RFC 7232,
June 2014.
[RFC7234] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching",
RFC 7234, June 2014.
8.2. Informative References ๐ธ
and these are the extra-helpful reads, also verbatim ๐ง
[BCP13] Freed, N., Klensin, J., and T. Hansen, "Media Type
Specifications and Registration Procedures", BCP 13,
RFC 6838, January 2013.
[BCP90] Klyne, G., Nottingham, M., and J. Mogul, "Registration
Procedures for Message Header Fields", BCP 90, RFC 3864,
September 2004.
[RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext
Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.
[RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an
IANA Considerations Section in RFCs", BCP 26, RFC 5226,
May 2008.
Appendix A. Internet Media Type multipart/byteranges ๐งโจ
okay this is the media type slay ๐
when a 206 (Partial Content) response message includes the content of multiple ranges, they get sent as body parts in a multipart message body ([RFC2046], Section 5.1) with the media type of multipart/byteranges.
the multipart/byteranges media type includes one or more body parts, and each one has its own Content-Type and Content-Range fields ๐ the required boundary parameter says which boundary string separates each body part.
Implementation Notes:
- Additional CRLFs might precede the first boundary string in the body.
- Although [RFC2046] permits the boundary string to be quoted, some existing implementations handle a quoted boundary string incorrectly. ๐ญ
- A number of clients and servers were coded to an early draft of the byteranges specification that used a media type of
multipart/x-byteranges, which is almost (but not quite) compatible with this type. ๐
despite the name, the "multipart/byteranges" media type is not limited to byte ranges ๐ the example below uses an "exampleunit" range unit:
HTTP/1.1 206 Partial Content
Date: Tue, 14 Nov 1995 06:25:24 GMT
Last-Modified: Tue, 14 July 04:58:08 GMT
Content-Length: 2331785
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-Type: video/example
Content-Range: exampleunit 1.2-4.3/25
...the first range...
--THIS_STRING_SEPARATES
Content-Type: video/example
Content-Range: exampleunit 11.2-14.3/25
...the second range
--THIS_STRING_SEPARATES--
Appendix B. Changes from RFC 2616 ๐ฆ
here's the glow-up list from RFC 2616 ๐
- Servers are given more leeway in how they respond to a range request, in order to mitigate abuse by malicious (or just greedy) clients. (Section 3.1)
- A weak validator cannot be used in a 206 response. (Section 4.1)
- The Content-Range header field only has meaning when the status code explicitly defines its use. (Section 4.2)
- This specification introduces a Range Unit Registry. (Section 5.1)
- multipart/byteranges can consist of a single part. (Appendix A)
Appendix C. Imported ABNF ๐งฉ
the following core rules are included by reference, as defined in Appendix B.1 of [RFC5234]: ALPHA (letters), CR (carriage return), CRLF (CR LF), CTL (controls), DIGIT (decimal 0-9), DQUOTE (double quote), HEXDIG (hexadecimal 0-9/A-F/a-f), LF (line feed), OCTET (any 8-bit sequence of data), SP (space), and VCHAR (any visible US-ASCII character).
note that all rules derived from token are to be compared case-insensitively, like range-unit and acceptable-ranges ๐ฅ
the rules below are defined in [RFC7230]:
OWS = <OWS, see [RFC7230], Section 3.2.3>
token = <token, see [RFC7230], Section 3.2.6>
the rules below are defined in other parts:
HTTP-date = <HTTP-date, see [RFC7231], Section 7.1.1.1>
entity-tag = <entity-tag, see [RFC7232], Section 2.3>
Appendix D. Collected ABNF ๐
in the collected ABNF below, list rules are expanded as per Section 1.2 of [RFC7230] โจ
Accept-Ranges = acceptable-ranges
Content-Range = byte-content-range / other-content-range
HTTP-date = <HTTP-date, see [RFC7231], Section 7.1.1.1>
If-Range = entity-tag / HTTP-date
OWS = <OWS, see [RFC7230], Section 3.2.3>
Range = byte-ranges-specifier / other-ranges-specifier
acceptable-ranges = ( *( "," OWS ) range-unit *( OWS "," [ OWS
range-unit ] ) ) / "none"
byte-content-range = bytes-unit SP ( byte-range-resp /
unsatisfied-range )
byte-range = first-byte-pos "-" last-byte-pos
byte-range-resp = byte-range "/" ( complete-length / "*" )
byte-range-set = *( "," OWS ) ( byte-range-spec /
suffix-byte-range-spec ) *( OWS "," [ OWS ( byte-range-spec /
suffix-byte-range-spec ) ] )
byte-range-spec = first-byte-pos "-" [ last-byte-pos ]
byte-ranges-specifier = bytes-unit "=" byte-range-set
bytes-unit = "bytes"
complete-length = 1*DIGIT
entity-tag = <entity-tag, see [RFC7232], Section 2.3>
first-byte-pos = 1*DIGIT
last-byte-pos = 1*DIGIT
other-content-range = other-range-unit SP other-range-resp
other-range-resp = *CHAR
other-range-set = 1*VCHAR
other-range-unit = token
other-ranges-specifier = other-range-unit "=" other-range-set
range-unit = bytes-unit / other-range-unit
suffix-byte-range-spec = "-" suffix-length
suffix-length = 1*DIGIT
token = <token, see [RFC7230], Section 3.2.6>
unsatisfied-range = "*/" complete-length
Index ๐๏ธ
2
206 Partial Content (status code) 10
4
416 Range Not Satisfiable (status code) 15
A
Accept-Ranges header field 7
C
Content-Range header field 12
G
Grammar
Accept-Ranges 7
acceptable-ranges 7
byte-content-range 12
byte-range 12
byte-range-resp 12
byte-range-set 5
byte-range-spec 5
byte-ranges-specifier 5
bytes-unit 5
complete-length 12
Content-Range 12
first-byte-pos 5
If-Range 9
last-byte-pos 5
other-content-range 12
other-range-resp 12
other-range-unit 5, 7
Range 8
range-unit 5
ranges-specifier 5
suffix-byte-range-spec 6
suffix-length 6
unsatisfied-range 12
I
If-Range header field 9
M
Media Type
multipart/byteranges 18, 21
multipart/x-byteranges 19
multipart/byteranges Media Type 18, 21
multipart/x-byteranges Media Type 21
R
Range header field 8
Authors' Addresses ๐ซถ
Roy T. Fielding (editor)
Adobe Systems Incorporated
345 Park Ave
San Jose, CA 95110
USA
EMail: fielding@gbiv.com
URI: http://roy.gbiv.com/
Yves Lafon (editor)
World Wide Web Consortium
W3C / ERCIM
2004, rte des Lucioles
Sophia-Antipolis, AM 06902
France
EMail: ylafon@w3.org
URI: http://www.raubacapeu.net/people/yves/
Julian F. Reschke (editor)
greenbytes GmbH
Hafenweg 16
Muenster, NW 48155
Germany
EMail: julian.reschke@greenbytes.de
URI: http://greenbytes.de/tech/webdav/
๐ฆ where this page comes from
- ietf: rfc7233 2014-06
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms