- 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