HTTP Range Request
HTTP supports the concept of range requests, where the HTTP response message body includes only a subset of the resource. This is most often used when downloading large files that are unlikely to be changed, such as large high-resolution images.
HTTP range requests are not supported by all servers and as such, it is worthwhile for clients to check for support using an HTTP HEAD request in advance of requesting the actual resource. If the server returns the HTTP Accept-Ranges header and includes a value other than
none then support is available, and the parameter will indicate the range unit. Currently
bytes is the only range unit that is formally defined.
The HTTP Range header can be subsequently sent by the client to request a specific range of bytes or even a set of different ranges. In response, the server will include the Content-Type and Content-Range headers with each that is sent back in the HTTP response. When only a portion of a resource is returned, the server will use the 206 Partial Content HTTP status code in the HTTP response.
If the client submits a HTTP request for an illegal byte range, such as one that is out of bounds, then the server cannot process the HTTP request and will send the 416 Range Not Satisfiable HTTP status code.
If the server does not return Accept-Ranges or includes the
Accept-Ranges: none HTTP header then range requests are not supported. In cases where ranges are not supported, the server will ignore the Range HTTP header and instead, will return a 200 OK status code with the full resource.
Example checking for support
In this example, the client checks to see if the server supports range requests by sending an HTTP HEAD request. The server acknowledges the HTTP request and responds to include the
Accept-Ranges: bytes, letting the client know that range requests are allowed. It is also relevant that the total size of the image file is 25000 bytes.
HEAD /large-image.jpg HTTP/1.1 Host: www.example.ai
HTTP/1.1 200 OK Content-Type: image/jpeg Content-Length: 25000 Accept-Ranges: bytes
Single Part Ranges
Example of single part range request
In this example, the client has already confirmed that the server supports range requests and asks for the first 1000 bytes of a large JPEG image file. The server responds with the 206 Partial Content HTTP status code, and the Content-Range HTTP header indicates which byte range is sent, as well as the total length of the file.
The Content-Length HTTP response header includes the number of bytes that are included in the message body, as opposed to the length of the full file.
GET /large-image.jpg HTTP/1.1 Host: www.example.ai Range: bytes=0-999
HTTP/1.1 206 Partial Content Content-Type: image/jpeg Content-Length: 1000 Content-Range: bytes 0-999/25000 <1000 bytes of image data are included in the message body>
HTTP also supports requests for multiple ranges in a single request. For the HTTP request, the ranges are separated by a comma in the Range HTTP header or sent on multiple lines. In the HTTP response, the server will include a special content type called
multipart/byteranges, which is accompanied by a boundary string to delimit ranges in the HTTP response of the message body. Within each range, the Content-Type and Content-Range HTTP headers are repeated for that particular portion of the original resource.
When a client makes a HTTP request for ranges that overlap, the server can optionally merge them. This is a bandwidth-conserving measure. Similarly, if the server determines that it is more efficient to merge ranges, perhaps because two of them are consecutive, then they can be combined. This implies that a valid HTTP response may contain fewer ranges than was originally asked for, yet still fulfill the HTTP request.
Example of multiple part range request
In this example, the client has already confirmed that the server supports range requests and asks for the first 1000 bytes of a large JPEG image file, as well as the ranges from 2000-2499 and 5000-5999. Presumably, these ranges were either lost or corrupted and the client wants them re-sent.
The HTTP request includes
Range: bytes=0-999, 2000-2499, 5000-5999 to specify the two ranges, to which the server responds with the 206 Partial Content status code. The initial Content-Type HTTP header includes the
multipart/byteranges and the boundary, whereas the subsequent ones are specific to the ranges in the blocks that are separated by the boundary markers.
The Content-Length HTTP header has a value that is greater than the sum of the data in the ranges because of the overhead associated with each range, including the boundary delimiter.
GET /large-image.jpg HTTP/1.1 Host: www.example.ai Range: bytes=0-999 Range: bytes=2000-2499, 5000-5999
HTTP/1.1 206 Partial Content Content-Type: image/jpeg Content-Length: 2712 Content-Range: multipart/byteranges; boundary=range_divider --range_divider Content-Type: image/jpeg Content-Range: 0-999/25000 <1000 bytes of image data is the first range> --range_divider Content-Type: image/jpeg Content-Range: 2000-2499/25000 <500 bytes of image data is the second range> --range_divider Content-Type: image/jpeg Content-Range: 5000-5999/25000 <1000 bytes of image data is the third range>
Conditional Range Requests
As with other HTTP requests, range requests can also be performed conditionally. It is important, for example, to make sure that the resource has not changed since the time that previous sections of it were downloaded.
A conditional request is made using the If-Range HTTP request header. If the condition is satisfied then the specific range or ranges will be returned in a message that begins with the 206 Partial Content HTTP status code. If the range cannot be satisfied then the server will return the entire resource, prefixed with the 200 OK HTTP status code. Finally, if the range is out of bounds then the server will return the 416 Range Not Satisfiable HTTP status code.
The If-Range header can be supplied with either the Last-Modified validator or with a specific ETag validator. However, only one of these can be included. For example:
If-Range: Sun, 1 Jan 2023 12:00:00 GMT
HTTP range requests can be made for a single range or multiple ranges, but this feature is not supported by all servers or for all types of resources. Ranges are returned with identifying HTTP headers in the message body, accompanied by the 206 Partial Content HTTP status code. Conditional range requests can also be made and are encouraged in cases where the resource is regularly modified. If a range request cannot be satisfied then the full resource is usually returned.