Re: clarity needed for browser behaviors when receiving 206 status codes

Yes, I don't think the HTTP range spec was specifically designed for
this but it nearly fits the application of controlled content
streaming and doesn't try to block this application.  My response is
sort of long and includes various ways to address my concerns so I
added flow interrupting headings (joy).

==  Sending smaller than requested ranges in a 206 ==

If the spec spelled out how to handle smaller responses (as WebKit
handles these) we could circumvent the unnecessary error and
redirection phase:

In Webkit it works like this:
  GET /file.mp4 HTTP/1.1
  ...
  HTTP/1.1 206 partial (smaller than requested)
  Content-Range: bytes 0-99999/300000
  ...
  GET /file.mp4 HTTP/1.1
  Range: bytes=100000-
  ...
  HTTP/1.1 206 partial (smaller than requested)
  Content-Range: bytes 100000-199999/300000

Despite http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-09#section-3.1
- browsers seem to be ok with a 206 response when no Range was sent -
but this should be defined somewhere (changing 'The request MUST have
included a Range header field') or by defining a 307+Accept-Ranges
behavior or by defining a new '4xx Range Required' status code.

On Fri, Jun 25, 2010 at 9:00 AM, Julian Reschke <julian.reschke@gmx.de> wrote:
> On 25.06.2010 04:20, Marques Johansson wrote:
>> A way to prime some web browsers to send Range: requests is to send
>> the Accept-Ranges: header in a 307 redirect response to the initial
>> un-ranged request.  The behavior of following this redirect and
>> sending a partial request is not taken by many text based browsers but
>> appears to be taken by modern desktop browsers.
>
> Me confused.
>
> Could you show an example? If a GET on URI1 returns a 307 with
> Accept-Ranges, and a Location of URI2, why would a client assume that URI2
> accepts range requests?

I agree that URL1 and URL2 could exist on different servers and there
is no reason why "Accept-Ranges" should be followed - but this is way
browsers seem to work.  The behavior could be restricted to relative
or same-server URIs.

Every other client does not handle shorter-than-requested range
responses the way WebKit does.  Their expectation is that the 206
response includes the full requested range and they do not follow up
with additional requests.  And when they request "Range: 0-" or send
no "Range" at all they essentially treat a 206 response as a 200
response (a whole response).

== Using 4xx to get a range the server will accept ==

>> The HTTP specification for ranges does not deal with a few range
>> related matters that I encountered while attempting to create a
>> streaming video script.
>>
>> How can servers inform clients that all requests must be made with
>> ranges specified?
>
> I don't think they can.
>
>> How should a client or server respond when the server is not willing
>> to fulfill the entire range requested by the client?
>
> A 4xx status, such as 403 Forbidden, comes to mind. However, I wouldn't
> count on any generic client coming to the conclusion that other ranges may
> work on the same resource.

I mentioned that a 416 server response to requests with
larger-than-permitted ranges could solve this, but  there is no way
for the server to tell the client what a permissible upper bound for
the requested range should be:

  GET /file.mp4 HTTP/1.1
  Range: bytes=0-
  ...
  HTTP/1.1 416 range was bad
  Accept-Ranges: bytes
  Content-Range: bytes */300000

would need to be more like,

  GET /file.mp4 HTTP/1.1
  Range: bytes=0-
  ...
  HTTP/1.1 416 range was too large
  Content-Range: bytes */300000
  Accept-Ranges: bytes; max-range-length=100000;
* or to potentially prevent breaking UAs that only understand "bytes"
without a semicolon
  Accept-Range-Max-Length: bytes=100000;
  ...
  GET /file.mp4 HTTP/1.1
  Range: bytes=0-99999
  ...
  HTTP/1.1 206 partial
  Content-Range: bytes 0-99999/300000
  Accept-Ranges: bytes; max-range-length=100000;

adding a max-range-length to Accept-Ranges or a an
Accept-Range-Max-Length header.

Perhaps a 416 could send "Content-Range: bytes 0-99999/300000" (rather
than */300000) but that doesn't seem obvious.  "Content-Range: bytes
0-99999/*" or "Content-Range: bytes */99999" might also be used to
hint a client to the acceptable range but either of these are
deceptive because the server knows the true length of the file and the
client may confuse these responses with later responses for earlier
ranges that resulted in a smaller reported length.

>> ...  There should be a response status the server can use
>> in cases where no range was specified but a range is required.
>
> A response code could be defined. Write a spec :-)

Perhaps a new 4xx could be made for "Range too large" but any 4xx
response would add to the HTTP transaction count as a client would
first receive a 307+Accept-Range (rerequest with ranges please - or
4xx (range required)), then a 416 or 4xx (range too large), and then
finally a 206.

== New 2xx for shorter partial responses or defining short 206s ==

A new 2xx response could be devised for "short partial responses" but
I don't think a new 2xx response is necessary since some existing UAs
are ok with a 206 (namely WebKit).  Likewise adding a max-range-length
response would be unnecessary if 206s were specifically allowed to be
shorter than the requested range.  The spec doesn't say that servers
can't respond with less data than requested.  And the spec already
defines the necessary headers for the server to respond with in any
case (Range: bytes x-y/z).

== Cheating with a disconnect ==

An alternative to this would be for the server to take advantage of
"Client Behavior if Server Prematurely Closes Connection" and
disconnect after sending the the willing portion of the response with
an "Accept-Ranges".  The response would be less than content-length
that the server reported.  But there is no defined behavior for how a
client should respond to a successful status with an interrupted
responses so there is no guarantee that the client would follow-up
with a Ranged request continuing where the server left off.

== Winning Punch ==

> Well, this is something HTTP range requests obviously haven't been designed
> for. I'm not convinced that they should be used for this, nor that making
> these minor changes would be sufficient to deal with your use case.

Just about any one of these small changes on their own would extend
the application range of HTTP to include content-controlled seek-able
streaming video without resorting to dissecting a video file (using
additional client scripting to navigate to the appropriate video
segments) or using a proprietary streaming solution and player.

Received on Friday, 25 June 2010 15:28:05 UTC