14. Range Requests
Clients often encounter interrupted transfers or need to obtain only a subset of a large representation. Range requests are an optional feature that allows clients to request one or more subranges of the selected representation, rather than the entire representation.
The range request mechanism is useful in several different scenarios:
- Partial downloads of large files can be split into multiple concurrent requests, thereby speeding up overall retrieval
- Interrupted transfers can be resumed from the point of interruption rather than restarting
- Some media types allow incremental rendering or playback, and user agents can start processing data as it is received
Servers are not required to support range requests. However, origin servers SHOULD support range requests, since range requests can reduce network usage and improve service responsiveness.
14.1. Range Units
Representations can be partitioned into subranges in different ways. A range unit defines how representation data is partitioned.
range-unit = token
All range unit names are case-insensitive and SHOULD be registered in the HTTP Range Unit Registry.
14.1.1. Range Specifiers
A range specifier defines one or more subranges of representation data.
range-spec = range-unit "=" range-set
range-set = 1#range-spec-value
range-spec-value = int-range / suffix-range / other-range
Range units allow clients to state what kind of range they are requesting.
14.1.2. Byte Ranges
The "bytes" range unit is defined for HTTP, representing subranges of an octet sequence (i.e., byte ranges).
byte-ranges-specifier = bytes-unit "=" byte-range-set
byte-range-set = 1#byte-range-spec
byte-range-spec = first-byte-pos "-" [ last-byte-pos ]
/ suffix-byte-range-spec
suffix-byte-range-spec = "-" suffix-length
first-byte-pos = 1*DIGIT
last-byte-pos = 1*DIGIT
suffix-length = 1*DIGIT
bytes-unit = "bytes"
The first-byte-pos value gives the byte-offset of the first byte in the range. The last-byte-pos value gives the byte-offset of the last byte in the range; that is, the byte positions specified are inclusive. Byte offsets start at zero.
Examples:
bytes=0-499represents the first 500 bytesbytes=500-999represents the second 500 bytesbytes=-500represents the last 500 bytesbytes=500-represents all bytes from byte 500 onwardsbytes=0-0,-1represents the first and last bytes
14.2. Range
The "Range" header field is used to request one or more subranges of representation data.
Range = range-unit "=" range-set
A server MAY ignore the Range header field. However, origin servers and intermediate caches SHOULD support byte ranges when possible, since Range support enables efficient recovery from partially failed transfers and partial retrieval of large representations.
A server MUST ignore a Range header field received with a request method other than GET.
An origin server that supports the Range header field MUST, if all preconditions are true:
- Ignore the Range header field if it contains a range unit it does not support
- Return a 416 (Range Not Satisfiable) status code if the Range header field is syntactically invalid
- Return a 206 (Partial Content) response containing one or more partial representations if the Range header field contains a satisfiable set of byte ranges
Example request:
GET /document HTTP/1.1
Host: www.example.com
Range: bytes=0-1023
14.3. Accept-Ranges
The "Accept-Ranges" header field allows a server to indicate that it supports range requests for the target resource.
Accept-Ranges = acceptable-ranges
acceptable-ranges = 1#range-unit / "none"
An origin server that accepts range requests for a given target resource SHOULD send an Accept-Ranges header field to indicate what range units are supported. A client MAY generate range requests without receiving this header field.
Examples:
Accept-Ranges: bytes
Accept-Ranges: none
The "none" value indicates that no range units are accepted, meaning the server does not support any range requests for that resource.
14.4. Content-Range
The "Content-Range" header field is sent in a single-part 206 (Partial Content) response to indicate the byte range of the enclosed partial representation, or in a 416 (Range Not Satisfiable) response to provide information about the selected representation.
Content-Range = range-unit SP
( range-resp / unsatisfied-range )
range-resp = byte-content-range
/ other-range-resp
byte-content-range = bytes-unit SP
( byte-range-resp / unsatisfied-range )
byte-range-resp = first-byte-pos "-" last-byte-pos
"/" ( complete-length / "*" )
complete-length = 1*DIGIT
unsatisfied-range = "*/" complete-length
other-range-resp = *CHAR
Examples:
Content-Range: bytes 0-1023/5000
Content-Range: bytes 1024-2047/5000
Content-Range: bytes */5000
The first example indicates that the first 1024 bytes of a complete representation (with a length of 5000 bytes) are being transferred. The third example indicates that a range request could not be satisfied because the complete length of the selected representation is 5000 bytes.
14.5. Partial PUT
A partial PUT request is not a range request, but it uses the same mechanism as range requests to describe the content being transferred. A client can send a partial PUT by including a Content-Range header field in the PUT request.
However, partial PUT is rarely used in practice because:
- It requires the client to know the current state of the resource
- It is vulnerable to race conditions
- Most origin servers do not support it
Therefore, clients SHOULD NOT use partial PUT unless they are certain the target server supports it.
14.6. Media Type multipart/byteranges
When sending multiple ranges, a server SHOULD use the multipart/byteranges media type.
multipart/byteranges
Each body part of this media type MUST include:
- A Content-Type header field indicating the media type of the representation contained in that body part
- A Content-Range header field indicating the range contained
Example response:
HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-Type: text/html
Content-Range: bytes 0-100/1234
[first 101 bytes]
--THIS_STRING_SEPARATES
Content-Type: text/html
Content-Range: bytes 500-999/1234
[bytes 500-999]
--THIS_STRING_SEPARATES--
When a client requests multiple disjoint ranges, a server SHOULD return a multipart response only if:
- The ranges do not overlap
- The order of ranges is the same as their order in the representation
Otherwise, the server SHOULD return the entire representation or coalesce overlapping ranges.