- From: Anne van Kesteren <notifications@github.com>
- Date: Fri, 06 Apr 2018 09:33:34 +0000 (UTC)
- To: whatwg/fetch <fetch@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/fetch/pull/560/review/109988303@github.com>
annevk commented on this pull request.
This generally looks pretty reasonable, assuming I understand it all correctly. It's a little hard to think through all the implications in the abstract. Lots of nits though.
> @@ -1277,6 +1288,29 @@ or "<code>worker</code>".
</ol>
</ol>
+<hr>
+
+<p>To <dfn export for=request id=concept-request-add-range-header>add a range header</dfn> to a <a
+for=/>request</a> <var>request</var>, with an integer <var>first</var>, and an optional integer
+<var>last</var>, run these steps:
+
+<ol>
+ <li><p>Let <var>rangeValue</var> be `<code>bytes </code>`.
+
+ <li><p><a>Encode</a> <var>first</var> and append the result to <var>rangeValue</var>.
Encode takes two parameters, neither of which is an integer. You probably want to phrase this differently somehow.
> @@ -1277,6 +1288,29 @@ or "<code>worker</code>".
</ol>
</ol>
+<hr>
+
+<p>To <dfn export for=request id=concept-request-add-range-header>add a range header</dfn> to a <a
+for=/>request</a> <var>request</var>, with an integer <var>first</var>, and an optional integer
+<var>last</var>, run these steps:
+
+<ol>
+ <li><p>Let <var>rangeValue</var> be `<code>bytes </code>`.
+
+ <li><p><a>Encode</a> <var>first</var> and append the result to <var>rangeValue</var>.
+
+ <li><p>Append `<code>-</code>` to <var>rangeValue</var>.
+
+ <li><p>If <var>last</var> is provided, <a>encode</a> it and append the result to
then encode* (though encode is wrong per above)
I prefer to follow "If" conditionals by "then" for clarity.
> +
+<ol>
+ <li><p>Let <var>rangeValue</var> be `<code>bytes </code>`.
+
+ <li><p><a>Encode</a> <var>first</var> and append the result to <var>rangeValue</var>.
+
+ <li><p>Append `<code>-</code>` to <var>rangeValue</var>.
+
+ <li><p>If <var>last</var> is provided, <a>encode</a> it and append the result to
+ <var>rangeValue</var>.
+
+ <li><p><a for="header list">Append</a> `<code>Range</code>`/<var>rangeValue</var> to
+ <var>request</var>'s <a for=request>header list</a>.
+</ol>
+
+<p class=note>Ranges are inclusive. A range where <var>first</var> is 0 and <var>last</var> is
Perhaps say something like "A Range header denotes an inclusive byte range." as ranges in general (as a concept) are not necessarily inclusive.
> @@ -3186,6 +3224,27 @@ optional <i>CORS flag</i> and <i>CORS-preflight flag</i>, run these steps:
<!-- not resetting actualResponse since it's no longer used anyway -->
</ol>
+ <li>
+ <p>If <var>response</var>'s <a for=response>status</a> is <code>206</code>,
+ and <var>response</var>'s <a for=response>range requested flag</a> is set, and
+ <var>request</var>'s <a for=request>header list</a> does not <a for="header list">contain</a>
+ "<code>`Range`</code>", then return a <a>network error</a>.
Please only use a single "and" when there's multiple conditions that need to be met.
> @@ -3186,6 +3224,27 @@ optional <i>CORS flag</i> and <i>CORS-preflight flag</i>, run these steps:
<!-- not resetting actualResponse since it's no longer used anyway -->
</ol>
+ <li>
+ <p>If <var>response</var>'s <a for=response>status</a> is <code>206</code>,
Shouldn't you look at actualResponse here?
> @@ -3186,6 +3224,27 @@ optional <i>CORS flag</i> and <i>CORS-preflight flag</i>, run these steps:
<!-- not resetting actualResponse since it's no longer used anyway -->
</ol>
+ <li>
+ <p>If <var>response</var>'s <a for=response>status</a> is <code>206</code>,
+ and <var>response</var>'s <a for=response>range requested flag</a> is set, and
+ <var>request</var>'s <a for=request>header list</a> does not <a for="header list">contain</a>
+ "<code>`Range`</code>", then return a <a>network error</a>.
+
+ <div class=note>
+ <p>Traditionally, APIs accept a ranged response even if a range wasn't requested. However, we
+ need to prevent a partial response from an earlier ranged request being provided to an API that
+ didn't make a range request.
+
+ <p>Example attack: A media element is used to request a range of a cross-origin HTML resource.
Instead of saying "Example attack" it would be more consistent to use class=example here, though I don't know how that would render. I guess we should just try. Perhaps just make it a note followed by an example, each as their own paragraph.
> @@ -4442,9 +4501,8 @@ objects.</span>
"<code>request</code>" and <var>name</var> is a <a>forbidden header name</a>,
return.
- <li><p>Otherwise, if <a for=Headers>guard</a> is
- "<code>request-no-cors</code>" and <var>name</var>/<var>value</var> is not a
- <a>CORS-safelisted request-header</a>, return.
+ <li><p>Otherwise, if <a for=Headers>guard</a> is "<code>request-no-cors</code>" and
+ <var>name</var>/<var>value</var> is not a <a>CORS-safelisted request-header</a>, return.
It seems you didn't change this line, either undo the changes or make it say "then return".
> @@ -4509,9 +4587,9 @@ method, when invoked, must run these steps:
"<code>request</code>" and <var>name</var> is a <a>forbidden header name</a>,
return.
- <li><p>Otherwise, if <a for=Headers>guard</a> is
- "<code>request-no-cors</code>" and <var>name</var>/`<code>invalid</code>` is
- not a <a>CORS-safelisted request-header</a>, then return.
+ <li><p>Otherwise, if <a for=Headers>guard</a> is "<code>request-no-cors</code>" and
+ <var>name</var>/`<code>invalid</code>` is not a <a>CORS-safelisted request-header</a>, and
+ <var>name</var> is not a <a>privileged no-cors request-header name</a>, then return.
Just one "and" please.
> @@ -4522,6 +4600,9 @@ method, when invoked, must run these steps:
<li><p><a for="header list">Delete</a> <var>name</var> from
<a for=Headers>header list</a>.
+
+ <li><p>If <a for=Headers>guard</a> is "<code>request-no-cors</code>", then
+ <a for=Headers>remove privileged no-cors request headers</a> from <a>context object</a>.
I'm not sure how consistent Fetch is about it, but I've started using "the context object" elsewhere.
> @@ -4566,9 +4647,8 @@ method, when invoked, must run these steps:
"<code>request</code>" and <var>name</var> is a <a>forbidden header name</a>,
return.
- <li><p>Otherwise, if <a for=Headers>guard</a> is
- "<code>request-no-cors</code>" and <var>name</var>/<var>value</var> is not a
- <a>CORS-safelisted request-header</a>, return.
+ <li><p>Otherwise, if <a for=Headers>guard</a> is "<code>request-no-cors</code>" and
+ <var>name</var>/<var>value</var> is not a <a>CORS-safelisted request-header</a>, return.
then return* or undo the formatting changes.
> @@ -4577,6 +4657,9 @@ method, when invoked, must run these steps:
<li><p><a for="header list">Set</a>
<var>name</var>/<var>value</var> in
<a for=Headers>header list</a>.
+
+ <li><p>If <a for=Headers>guard</a> is "<code>request-no-cors</code>", then
+ <a for=Headers>remove privileged no-cors request headers</a> from <a>context object</a>.
the context object*
> - <a for=request>credentials mode</a>,
- <a for=request>cache mode</a> is
- <var>request</var>'s
- <a for=request>cache mode</a>,
- <a for=request>redirect mode</a> is
- <var>request</var>'s
- <a for=request>redirect mode</a>,
- <a for=request>integrity metadata</a> is
- <var>request</var>'s
- <a for=request>integrity metadata</a>, and
- <a>keepalive flag</a> is <var>request</var>'s <a>keepalive flag</a>.
+ <li>
+ <p>Set <var>request</var> to a new <a for=/>request</a> with the following properties:
+
+ <dl>
+ <dt><a for=request>url</a> <dd><var>request</var>'s <a for=request>current url</a>.
`<dd>` on a new line
> @@ -5156,17 +5244,19 @@ constructor must run these steps:
<li><p>Set <var>request</var>'s <a for=request>referrer</a> to
"<code>client</code>"
- <li><p>Set <var>request</var>'s
- <a for=request>referrer policy</a> to the empty string.
+ <li>
+ <p>Set <var>request</var>'s <a for=request>referrer policy</a> to the empty string.
+
+ <p class=note>This is done to ensure that when a service worker "redirects" a request, e.g.,
+ from an image in a cross-origin stylesheet, and makes modifications, it no longer appears to
style sheet* (throughout)
> @@ -5156,17 +5244,19 @@ constructor must run these steps:
<li><p>Set <var>request</var>'s <a for=request>referrer</a> to
"<code>client</code>"
- <li><p>Set <var>request</var>'s
- <a for=request>referrer policy</a> to the empty string.
+ <li>
+ <p>Set <var>request</var>'s <a for=request>referrer policy</a> to the empty string.
+
+ <p class=note>This is done to ensure that when a service worker "redirects" a request, e.g.,
+ from an image in a cross-origin stylesheet, and makes modifications, it no longer appears to
+ come from the original source (i.e., the cross-origin stylesheet), but instead from the service
+ worker that "redirected" the request. This is important as the original source might not even be
+ able to generate the same kind of requests as the service worker. Services that trust the
+ original source could therefore be exploited were this not done, although that is somewhat
+ farfetched.
Why did you move this note by the way? It really applies to the whole "if any of init's member are present" clause.
> @@ -5451,10 +5550,18 @@ run these steps:
<li><p>Set <var>clonedRequestObject</var>'s <a for=Request>request</a> to <var>clonedRequest</var>.
- <li><p>Set <var>clonedRequestObject</var>'s <a for=Request>headers</a> to a new {{Headers}} object
- whose <a for=Headers>header list</a> is set to <var>clonedRequest</var>'s
- <a for=Headers>header list</a>, and <a for=Headers>guard</a> is <a>context object</a>'s
- <a for=Request>headers</a>' <a for=Headers>guard</a>.
+ <li>
+ <p>Set <var>clonedRequestObject</var>'s <a for=Request>headers</a> to a new {{Headers}} object
+ whose:
+
+ <ul>
+ <li><p><a for=Headers>header list</a> is set to <var>clonedRequest</var>'s
+ <a for=Headers>header list</a>.
+
+ <li><p><a for=Headers>guard</a> is <a>context object</a>'s <a for=Request>headers</a>'s
the context object*
> @@ -5451,10 +5550,18 @@ run these steps:
<li><p>Set <var>clonedRequestObject</var>'s <a for=Request>request</a> to <var>clonedRequest</var>.
- <li><p>Set <var>clonedRequestObject</var>'s <a for=Request>headers</a> to a new {{Headers}} object
- whose <a for=Headers>header list</a> is set to <var>clonedRequest</var>'s
- <a for=Headers>header list</a>, and <a for=Headers>guard</a> is <a>context object</a>'s
- <a for=Request>headers</a>' <a for=Headers>guard</a>.
+ <li>
+ <p>Set <var>clonedRequestObject</var>'s <a for=Request>headers</a> to a new {{Headers}} object
+ whose:
It's a little weird we use `<ol>` here and for a similar thing above we use `<dl>`. I'm not really sure what style I prefer though.
> @@ -1360,6 +1394,10 @@ specified. [[!CSP]]
`<a http-header><code>Access-Control-Expose-Headers</code></a>` header. This list is used by a
<a>CORS filtered response</a> to determine which headers to expose.
+<p>A <a for=/>response</a> has an associated
+<dfn for=response id=concept-response-range-requested-flag>range requested flag</dfn>, which is
+initially unset.
It'd be good to add a note here about the purpose. Also, "range-requested" perhaps?
> @@ -1360,6 +1394,10 @@ specified. [[!CSP]]
`<a http-header><code>Access-Control-Expose-Headers</code></a>` header. This list is used by a
<a>CORS filtered response</a> to determine which headers to expose.
+<p>A <a for=/>response</a> has an associated
+<dfn for=response id=concept-response-range-requested-flag>range requested flag</dfn>, which is
+initially unset.
Also, do we need to export this or is it fine for just internal usage?
> @@ -4477,6 +4538,23 @@ run these steps:
<var>key</var>/<var>value</var> to <var>headers</var>.
</ol>
+<p>To
+<dfn for=Headers id=concept-headers-remove-privileged-no-cors-request-headers>remove privileged no-cors request headers</dfn>
+from a {{Headers}} object (<var>headers</var>), run these steps:
It seems this would be a little better as instead iterating over the privileged no-cors request-header names and then deleting (concept-header-list-delete) them.
> @@ -446,6 +446,17 @@ documented in <a href=#cors-protocol-exceptions>CORS protocol exceptions</a>.
<p>A <dfn export>CORS non-wildcard request-header name</dfn> is a <a>byte-case-insensitive</a> match
for `<code>Authorization</code>`.
+<p>A <dfn export>privileged no-cors request-header name</dfn> is a <a for=/>header</a>
+<a for=header>name</a> that is a <a>byte-case-insensitive</a> match for one of
+
+<ul class=brief>
+ <li>`<code>Range</code>`
+</ul>
+
+<p class="note no-backref">These are headers that <span class=allow-2119>may</span> be set by
Use can or could instead? No reason to use may I think. If you think it should be a normative statement then this should not be a note.
> @@ -446,6 +446,17 @@ documented in <a href=#cors-protocol-exceptions>CORS protocol exceptions</a>.
<p>A <dfn export>CORS non-wildcard request-header name</dfn> is a <a>byte-case-insensitive</a> match
for `<code>Authorization</code>`.
+<p>A <dfn export>privileged no-cors request-header name</dfn> is a <a for=/>header</a>
+<a for=header>name</a> that is a <a>byte-case-insensitive</a> match for one of
+
+<ul class=brief>
+ <li>`<code>Range</code>`
+</ul>
+
+<p class="note no-backref">These are headers that <span class=allow-2119>may</span> be set by
Perhaps this note should also point out the "add a range header" primitive.
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/fetch/pull/560#pullrequestreview-109988303
Received on Friday, 6 April 2018 09:34:06 UTC