Subject: Semantics: clarify handling of invalid or unsatisfiable range requests

From: "Roy T. Fielding" <[email-masked]>
Date: Wed, 2 Mar 2022 18:07:25 -0800

A very late request was received for some editorial clarification
around invalid or unsatisfiable range requests.

   https://github.com/httpwg/http-core/issues/1011

I have proposed a patch that may (or may not) be too late to apply,
but could use some review in any case.

   https://github.com/httpwg/http-core/pull/1012

and pasted below. I don't think it has any effect on the protocol
itself, but may make it easier to implement the edge cases.

....Roy

index bbf438d4..885a3c5e 100644
--- draft-ietf-httpbis-semantics-latest.xml
+++ draft-ietf-httpbis-semantics-latest.xml
@@ -7717,6 +7717,8 @@ If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
 </t>
 
 <section title="Range Specifiers" anchor="range.specifiers">
+  <iref primary="true" item="satisfiable"/>
+  <iref primary="true" item="unsatisfiable"/>
 <t>
    Ranges are expressed in terms of a range unit paired with a set of range
    specifiers. The range unit name determines what kinds of range-spec
@@ -7781,6 +7783,18 @@ If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
   <x:ref>other-range</x:ref>   = 1*( %x21-2B / %x2D-7E )
                 ; 1*(VCHAR excluding comma)
 </sourcecode>
+<t>
+   A <x:ref>ranges-specifier</x:ref> is invalid if it contains any
+   <x:ref>range-spec</x:ref> that is invalid or undefined for the indicated
+   <x:ref>range-unit</x:ref>.
+</t>
+<t anchor="satisfiable">
+   A valid <x:ref>ranges-specifier</x:ref> is <x:dfn>satisfiable</x:dfn>
+   if it contains at least one <x:ref>range-spec</x:ref> that is
+   satisfiable, as defined by the indicated <x:ref>range-unit</x:ref>.
+   Otherwise, the <x:ref>ranges-specifier</x:ref> is
+   <x:dfn>unsatisfiable</x:dfn>.
+</t>
 </section>
 
 <section title="Byte Ranges" anchor="byte.ranges">
@@ -7867,13 +7881,15 @@ bytes=500-700,601-999
    </li>
 </ul>
 <t>
-   If a valid bytes <x:ref>range-set</x:ref> includes at least one
-   <x:ref>range-spec</x:ref> with a <x:ref>first-pos</x:ref> that is
-   less than the current length of the representation, or at least one
-   <x:ref>suffix-range</x:ref> with a non-zero <x:ref>suffix-length</x:ref>,
-   then the bytes <x:ref>range-set</x:ref> is satisfiable. Otherwise,
-   the bytes <x:ref>range-set</x:ref> is unsatisfiable.
+   A valid bytes <x:ref>range-spec</x:ref> is satisfiable if it is either:
 </t>
+<ul>
+   <li><t>an <x:ref>int-range</x:ref> with a <x:ref>first-pos</x:ref> that
+       is less than the current length of the selected representation;
+       or,</t></li>
+   <li><t>a <x:ref>suffix-range</x:ref> with a non-zero
+       <x:ref>suffix-length</x:ref>.</t></li>
+</ul>
 <t>
    If the selected representation has zero length, the only satisfiable form of
    <x:ref>range-spec</x:ref> is a <x:ref>suffix-range</x:ref> with a non-zero
@@ -7957,11 +7973,14 @@ bytes=500-700,601-999
 </t>
 <t>
    If all of the preconditions are true, the server supports the Range header
-   field for the target resource, and the specified range(s) are valid and
-   satisfiable (as defined in <xref target="byte.ranges"/>), the
-   server &SHOULD; send a <x:ref>206 (Partial Content)</x:ref> response with a
-   content containing one or more partial representations that correspond to
-   the satisfiable ranges requested.
+   field for the target resource, the received Range field-value contains a
+   valid <x:ref>ranges-specifier</x:ref> (<xref target="range.specifiers"/>)
+   with a <x:ref>range-unit</x:ref> supported for that target resource,
+   and that <x:ref>ranges-specifier</x:ref> is satisfiable with respect to
+   the selected representation,
+   the server &SHOULD; send a <x:ref>206 (Partial Content)</x:ref> response
+   with content containing one or more partial representations
+   that correspond to the satisfiable <x:ref>range-spec</x:ref>(s) requested.
 </t>
 <t>
    The above does not imply that a server will send all requested ranges.
@@ -7972,8 +7991,17 @@ bytes=500-700,601-999
 </t>
 <t>
    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
+   field for the target resource, and the received Range field-value contains
+   an invalid <x:ref>ranges-specifier</x:ref>,
+   the server &SHOULD; send a <x:ref>400 (Bad Request)</x:ref> response.
+</t>
+<t>
+   If all of the preconditions are true, the server supports the Range header
+   field for the target resource, the received Range field-value contains a
+   valid <x:ref>ranges-specifier</x:ref>, and either the
+   <x:ref>range-unit</x:ref> is not supported for that target resource or
+   the <x:ref>ranges-specifier</x:ref> is unsatisfiable with respect to
+   the selected representation, the server &SHOULD; send a
    <x:ref>416 (Range Not Satisfiable)</x:ref> response.
 </t>
 </section>

---

From: Eric J Bowman <[email-masked]>
Date: Wed, 02 Mar 2022 22:54:50 -0800

Wait, what? I feel like I'm speaking out-of-turn here nowadays. But if, to satisfy some edge cases, PUT would now have the semantics of PATCH then maybe we need a new method, let's call it PLACE, that absolutely reflects the save-file-to-disk user intent, specifically disallowing any sort of range request. Thought this was settled ages ago.

-Eric

---- On Wed, 02 Mar 2022 18:07:25 -0800 Roy T. Fielding <[email-masked]> wrote ----

 

 
....Roy

---

From: "Roy T. Fielding" <[email-masked]>
Date: Thu, 3 Mar 2022 09:38:08 -0800

> On Mar 2, 2022, at 10:54 PM, Eric J Bowman <[email-masked]> wrote:
> 

This is just explaining what to do with an invalid or unsatisfiable GET range request
in terms that are less vague. It does not change the protocol at all. It explains
which error codes are preferred, which was already implied by the code semantics.

It does not have anything to do with PUT ranges, which is not defined by this spec.
If you think that needs to be clarified within this change, then why and where would
be a more useful comment.

....Roy

---

From: Julian Reschke <[email-masked]>
Date: Mon, 14 Mar 2022 10:06:06 +0100

Am 03.03.2022 um 18:38 schrieb Roy T. Fielding:
>> On Mar 2, 2022, at 10:54 PM, Eric J Bowman <[email-masked]
>> <mailto:[email-masked]>> wrote:
>>
>> Wait, what? I feel like I'm speaking out-of-turn here nowadays. But
>> if, to satisfy some edge cases, PUT would now have the semantics of
>> PATCH then maybe we need a new method, let's call it PLACE, that
>> absolutely reflects the save-file-to-disk user intent, specifically
>> disallowing any sort of range request. Thought this was settled ages ago.
>

FWIW, a slightly modified iteration of this PR was just merged, and we
expect to finish publication preparations this week.

So please have a look at <https://github.com/httpwg/http-core/issues/1011>.

Best regards, Julian