Re: Range response with empty content

> On Jul 23, 2015, at 12:16 PM, A. Rothman <amichai2@amichais.net> wrote:
> 
> Hi,
> 
> I'd like to suggest that RFC 7233 (or whatever will succeed it) should mention explicitly how a server should respond to a Range request when the requested resource has no content (e.g. empty file). Going through the RFC, this is what I found:

Sec 3.1: A server MAY ignore the Range header field.

> One section says:
> 
> "If a valid byte-range-set includes at least one byte-range-spec with
> a first-byte-pos that 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, the byte-range-set is unsatisfiable."
> 
> so since first-byte-pos can never be less than 0, it will always be unsatisfiable, and should return 416.

I agree that it would be better to say up front, somewhere, that Range
MUST be ignored if the current selected representation is zero length.
Likewise, we have already been asked to clarify that a 200 response is
sent whenever the entire representation is used.

However, Sec 3.1:
   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.

and that requirement is a SHOULD to allow for these cases.  I believe that
the reason for sending 416 instead of 200 is so that a client can request
the next N bytes of a representation that it knows is append-only but
doesn't know if anything has been appended yet; this is an important use
case for things like large logfiles.  If 200 is preferred instead, the
If-Range header field can be sent.

> But the section on 416 says:
> 
> "The 416 (Range Not Satisfiable) status code indicates that none of
> the ranges in the request's Range header field (Section 3.1) overlap
> the current extent...
> For byte ranges, failing to overlap the current extent means that the
> first-byte-pos of all of the byte-range-spec values were greater than
> the current length of the selected representation."
> 
> so a first-byte-pos of 0 is not greater than 0, and thus the 416 Not Satisfiable status does not apply here.

There are two bugs there. First, it should say "selected representation",
not selected resource.  Second, it means that the first-byte-pos of each
byte-range-spec value, if any, is greater than or equal to the current
length of the selected representation.

For example, "1-1" is one byte IFF content length is at least 2;
             "0-1" is one byte IFF content length is at least 1.
             "0-0" is one byte IFF content length is at least 1.

Thanks for noticing that error.  Did I mention that I hate this feature?
It should have just referred to the definitions of invalid and unsatisfiable.

> In addition to this contradiction, a 206 Partial Content response is not possible either since the required Content-Range can't specify an empty range (I think), plus, the response is not actually partial content.

There is no need to require that 206 not be sent when its semantics are not met.

> For a suffix-byte-range-spec with a non-zero suffix length, it says:
> 
> "If the selected representation is shorter than the specified
> suffix-length, the entire representation is used."
> 
> which will trivially include an empty representation if you're a mathematician, but in practice some implementations might try and calculate an actual numbered range and fall back into the same ambiguous 416 code path (this is only a guess). And you still can't return a 206 for it.

Right, that implies a 200 or 204 can be returned (assuming all other checks pass).
You don't need to be a mathematician: representation is a defined term that
includes zero-length bodies.

> As for a suffix-byte-range spec with a 0 suffix length (-0)... I don't know what happens there.

It is inherently unsatisfiable.

> Another consideration is the paragraph about allowing a client to limit the number of bytes requested without knowing the size of the selected representation. If a client always requests a range of e.g. 0-100000 for this stated purpose, it would likely expect to get normal 200 responses for anything under 100000 bytes (or possibly a 206?), and a truncated 206 for anything larger, but not suddenly have to deal with a 416 and interpret it as a successful empty content response, or worse, perform another round-trip to the server without the Range to handle this case.

See above.

> In short, the RFC's handling of empty resources with regards to ranges appears to be self-contradictory or not well-specified or unintuitive (I'm not sure which).
> 
> My humble suggestion would be to specify that servers should return an empty 200 response if the resource content is empty, which I think would minimize complexity on client and server. I may be wrong. But at the very least, the current wording should be clarified to mention this case explicitly and how it should be dealt with, since it's quite confusing currently.
> 
> Thanks for your time :-)
> 
> Amichai

The two bugs should be an errata.  We should probably explain why and when
the 416 code is used, but that's editorial.

Cheers,

....Roy

Received on Saturday, 25 July 2015 10:46:05 UTC