httphttp-headershttp-content-lengthhttp-range

Does a HTTP resource that accepts range requests always specify content-length?


Before starting a Range request, I first check if it is supported using a HEAD request. Normally I get back something like this:

curl -X HEAD -i http://bits.wikimedia.org/images/wikimedia-button.png

HTTP/1.1 200 OK
...
Content-Length: 2426
Accept-Ranges: bytes
...

Is the Content-Length guaranteed per the HTTP/1.1 specification in this case? I can't find a definitive answer but it seems like I would need to know the Content-Length before I do a Range request.


Solution

  • No.

    As per any other response with a 200 status code, such a response SHOULD (in the RFC 2119 sense of "SHOULD" which can be summarised as "better have a damn good reason why not, and be able to say what that damn good reason is") include a length (RFC 2616 §14.13) bar a few scenarios in which it is prohibited (§4.4) (in particular, the value must be both the entity and transfer length and as such is only valid when the transfer-encoding is "identity" [the default]). There is no reason why an Accept-Ranges header need not be sent along with a chunked and/or compressed transfer-encoding. (Different to compressed content-encoding, in which case range, like content-length refers to the compressed size).

    Some things worth noting:

    1. A server may always ignore a range request and respond with the full length, even if it had suggested otherwise. (§14.35.2) Hence, you should always be prepared to receive this.
    2. A server may honour a Range or If-Range even if it didn't indicate it would through Accept-Ranges. (§14.5)
    3. A valid Range could be e.g. 123- meaning "send me everything from octet 123 on to the end. (§14.35.1)
    4. A Range of e.g. 123-500 is valid even if the size of the entity is less than 500, in which case as many octets as are available are to be sent. However, it would not be valid if there were fewer than 123 octets in the entire entity. (§14.35.1)
    5. Values other than bytes are valid but undefined for Accept-Range. (§3.12) This means that the server is doing something non-standard, so unless bytes is also mentioned, you should interpret it as not including an Accept-Range.
    6. While not including Content-Length in a response including Accept-Range is valid, it's not very likely. As a rule, if you were to treat such responses as if they had not included an Accept-Range header then you would be safe from mis-steps in the face of such behaviour, while also benefiting from the range behaviour the vast majority of the time it came up.