Like Wrikken , this is a valid request. It is also quite common when a client requests media or resumes loading.
The client will often test whether the server will process requests in a range, rather than just looking for an Accept-Ranges response. Chrome always sends Range: bytes=0- with the first GET request for the video, so it cannot be rejected.
Whenever a client includes Range: in its request, even if it is garbled, it expects a partial content response (206). When you search ahead while playing HTML5 video, the browser only asks for the starting point. For example:
Range: bytes=3744-
So, for the client to play the video correctly, your server must be able to handle these incomplete range requests.
You can handle the type of "range" specified in your question in two ways:
First, you can respond with the requested starting point indicated in the response, and then the total file length minus one (the requested byte range is indexed by zero). For example:
Inquiry:
GET /BigBuckBunny_320x180.mp4 Range: bytes=100-
Answer:
206 Partial Content Content-Type: video/mp4 Content-Length: 64656927 Accept-Ranges: bytes Content-Range: bytes 100-64656926/64656927
Secondly, you can answer with the starting point specified in the request and the length (size) of the open file. This is for webcasts or other media where the total length is unknown. For example:
Inquiry:
GET /BigBuckBunny_320x180.mp4 Range: bytes=100-
Answer:
206 Partial Content Content-Type: video/mp4 Content-Length: 64656927 Accept-Ranges: bytes Content-Range: bytes 100-64656926/*
Advice:
You should always respond with the length of the content included in the range. If the range is complete, from start to finish, then the length of the content will simply be the difference:
Request: Range: Bytes = 500-1000
Answer: Content-Range: Bytes 500-1000 / 123456
Remember that a range is indexed by a null value, so Range: bytes=0-999 actually asks for 1000 bytes, not 999, so answer something like:
Content-Length: 1000 Content-Range: bytes 0-999/123456
Or:
Content-Length: 1000 Content-Range: bytes 0-999/*
But, if possible, avoid the latter method, because some media players try to determine the duration of the file size. If your request is for media content, which is my guess, then you should include its duration in the response. This is done in the following format:
X-Content-Duration: 63.23
It must be a floating point. Unlike Content-Length , this value does not have to be exact. This helped the player search for the video. If you are broadcasting a webcast and only have a general idea of how long it will be, it is better to include the estimated duration rather than ignoring it at all. So, for a two hour broadcast, you can include something like:
X-Content-Duration: 7200.00
With some types of media, such as webm, you must also specify the type of content, for example:
Content-Type: video/webm
All this is necessary for the correct playback of multimedia, especially in HTML5. If you do not give a duration, the player may try to determine the duration (to provide a search) from his file size, but this will be inaccurate. This is great and necessary for broadcasting webcasts or live broadcasts, but is not ideal for playing video files. You can extract the duration using software such as FFMPEG and save it in a database or even in a file name.
X-Content-Duration ends in favor of Content-Duration , so I would include that too. A basic response to a 0- request will include at least the following:
HTTP/1.1 206 Partial Content Date: Sun, 08 May 2013 06:37:54 GMT Server: Apache/2.0.52 (Red Hat) Accept-Ranges: bytes Content-Length: 3980 Content-Range: bytes 0-3979/3980 Content-Type: video/webm X-Content-Duration: 2054.53 Content-Duration: 2054.53
Another point: Chrome always starts its first video request with the following:
Range: bytes=0-
Some servers will send a regular 200 response as an answer that it accepts (but with limited playback options), but try sending 206 instead to show what your server ranges are. RFC 2616 says that it is acceptable to ignore range headers.