You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix request clients for prefetch + service workers (#378)
Fixes#346. In particular:
* Fixed prefetch activation to use the correct reserved clients. Previously, the prefetch activation parts of the specification (in "create a navigation params from a prefetch record") would assume that the request they were being passed had a reserved client, when in reality they did not, because "create a navigation request" did not set a reserved client. We change them to consult the reserved clients from the redirect chain, which is more correct anyway.
* Properly creates a new reserved environment during each prefetch activation, by creating a new environment with correct values, including the active service worker. This is necessary to avoid prefetch record reuse from causing the creation of multiple clients with the same ID.
* Makes the resultingClientId on the FetchEvent that occurs during prefetch be the empty string. The client ID is not known at the time of the prefetch, so this is the only possibility that makes sense.
Copy file name to clipboardExpand all lines: prefetch.bs
+35-11Lines changed: 35 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -360,28 +360,33 @@ The user agent may [=prefetch record/cancel and discard=] records from the [=Doc
360
360
1. Let |coopEnforcementResult| be the result of [=creating a cross-origin opener policy enforcement result for navigation=] given |navigable|'s [=navigable/active document=] and |documentState|'s [=document state/initiator origin=].
361
361
1. Let |finalSandboxFlags| be an empty [=sandboxing flag set=].
362
362
1. Let |responsePolicyContainer| be null.
363
+
1. Let |activeServiceWorker| be null.
363
364
1. Let |urlList| be an empty [=list=].
364
365
1. [=list/For each=] |exchangeRecord| in |record|'s [=prefetch record/redirect chain=]:
365
-
1. Let |response| be |exchangeRecord|'s [=exchange record/response=].
366
-
1. [=list/Append=] |response|'s [=response/URL=] to |urlList|.
367
-
1. Set |responsePolicyContainer| to the result of [=creating a policy container from a fetch response=] given |response| and |request|'s [=request/reserved client=].
366
+
1. Let |redirectChainRequest| be |exchangeRecord|'s [=exchange record/request=].
367
+
1. Let |redirectChainResponse| be |exchangeRecord|'s [=exchange record/response=].
368
+
1. [=list/Append=] |redirectChainRequest|'s [=request/URL=] to |urlList|.
369
+
1. Set |responsePolicyContainer| to the result of [=creating a policy container from a fetch response=] given |redirectChainResponse| and |redirectChainRequest|'s [=request/reserved client=].
368
370
1. Set |finalSandboxFlags| to the [=set/union=] of |targetSnapshotParams|'s [=target snapshot params/sandboxing flags=] and |responsePolicyContainer|'s [=policy container/CSP list=]'s [=CSP-derived sandboxing flags=].
369
-
1. Set |responseOrigin| to the result of [=determining the origin=] given |response|'s [=response/URL=], |finalSandboxFlags|, |documentState|'s [=document state/initiator origin=], and null.
371
+
1. Set |responseOrigin| to the result of [=determining the origin=] given |redirectChainResponse|'s [=response/URL=], |finalSandboxFlags|, |documentState|'s [=document state/initiator origin=], and null.
372
+
1. Set |activeServiceWorker| to |redirectChainRequest|'s [=request/reserved client=]'s [=environment/active service worker=].
370
373
1. If |navigable| is a [=top-level traversable=], then:
371
-
1. Set |responseCOOP| to the result of [=obtaining a cross-origin opener policy=] given |response| and |request|'s [=request/reserved client=].
374
+
1. Set |responseCOOP| to the result of [=obtaining a cross-origin opener policy=] given |redirectChainResponse| and |redirectChainRequest|'s [=request/reserved client=].
372
375
1. [=Assert=]: If |finalSandboxFlags| is not empty, then |responseCOOP|'s [=cross-origin opener policy/value=] is "`unsafe-none`".
373
376
374
377
<p class="note">This is guaranteed since the sandboxing flags of the document cannot change to become non-empty since this was prefetched, and the check was not done for a different window. If this changes, this will need to be able to handle failure of this check.</p>
375
-
1. Set |coopEnforcementResult| to the result of [=enforcing a response's cross-origin opener policy=] given |navigable|'s [=active browsing context=], |response|'s [=response/URL=], |responseOrigin|, |responseCOOP|, |coopEnforcementResult|, and |exchangeRecord|'s [=exchange record/request=]'s [=request/referrer=].
378
+
1. Set |coopEnforcementResult| to the result of [=enforcing a response's cross-origin opener policy=] given |navigable|'s [=active browsing context=], |redirectChainResponse|'s [=response/URL=], |responseOrigin|, |responseCOOP|, |coopEnforcementResult|, and |exchangeRecord|'s [=exchange record/request=]'s [=request/referrer=].
376
379
1. Set |request|'s [=request/URL list=] to |urlList|.
380
+
1. <span id="prefetch-activation-client-creation"></span>Set |request|'s [=request/reserved client=] to the result of [=creating a reserved client=] given |navigable| and |request|'s [=request/URL=].
381
+
382
+
<p class="note">This will be the [=environment=] used for constructing the resulting {{Document}} and [=environment settings object=]. We need a separate [=environment=] for each time a [=prefetch record=] is consumed, instead of using |record|'s [=prefetch record/redirect chain=]'s last item's [=exchange record/request=]'s [=request/reserved client=], because otherwise reusing the same prefetch record for multiple [=navigation params=] (i.e., multiple navigations) would cause the created [=environment settings objects=] to share an [=environment/id=]. This would then be visible, e.g., through the {{Clients/get()|clients.get()}} API, in a very confusing way.
383
+
1. Set |request|'s [=request/reserved client=]'s [=environment/active service worker=] to |activeServiceWorker|.
377
384
1. Let |resultPolicyContainer| be the result of [=determining navigation params policy container=] given |record|'s [=prefetch record/response=]'s [=response/URL=], |documentState|'s [=document state/history policy container=], |sourceSnapshotParams|'s [=source snapshot params/source policy container=], null, and |responsePolicyContainer|.
378
385
1. Let |response| be |record|'s [=prefetch record/response=].
379
386
1. Optionally, set |response| to a [=response/clone=] of |response|.
380
387
381
388
<p class="note">An implementation might wish to do this if it believes that the prefetch will be consumed more than once. For example, if in the future the response is consumed by a prerender, that [=prerendering traversable=] might be [=destroy a top-level traversable|destroyed=] through various means. Normally that would mean the response is discarded, but if the implementation performs this step, then the prefetched response will still be available to serve a future navigation. [[PRERENDERING-REVAMPED]]
382
389
1. If the user agent did not perform the previous optional step, then it must [=list/remove=] |record| from |navigable|'s [=navigable/active document=]'s [=Document/prefetch records=].
383
-
384
-
385
390
1. Return a new [=navigation params=], with:
386
391
: [=navigation params/id=]
387
392
:: |navigationId|
@@ -433,6 +438,11 @@ A <dfn export>cross-origin prefetch IP anonymization policy</dfn> has an <dfn ex
433
438
434
439
This section contains patches to [[HTML]].
435
440
441
+
Add an additional item to [=environment=] as follows:
:: a [=string=] (corresponding to {{PerformanceResourceTiming}}[=PerformanceResourceTiming/delivery type=])
@@ -587,7 +597,9 @@ Modify the [=snapshot source snapshot params=] algorithm to set the return value
587
597
1. Run the [=environment discarding steps=] for |request|'s [=request/reserved client=].
588
598
1. Set |request|'s [=request/reserved client=] to null.
589
599
1. Set |commitEarlyHints| to null.
590
-
1. If |request|'s [=request/reserved client=] is null, then set |request|'s [=request/reserved client=] to the result of [=creating a reserved client=] given |navigable|, |currentURL| and |isolationOrigin|.
600
+
1. If |request|'s [=request/reserved client=] is null, then:
601
+
1. Set |request|'s [=request/reserved client=] to the result of [=creating a reserved client=] given |navigable|, |currentURL| and |isolationOrigin|.
602
+
1. If |prefetchRecord| was given, then set |request|'s [=request/reserved client=]'s [=environment/is navigational prefetch client=] to true.
591
603
1. If the result of [=should navigation request of type be blocked by Content Security Policy?=] given |request| and |cspNavigationType| is "`Blocked`", then set |response| to a [=network error=] and [=iteration/break=]. [[CSP]]
592
604
1. If |prefetchRecord| was given, then:
593
605
1. Let |purpose| be a [=structured header/List=] containing the [=structured header/Token=] `prefetch`.
@@ -721,6 +733,20 @@ This section contains patches to [[NAVIGATION-TIMING]].
721
733
Add an additional parameter to [=create the navigation timing entry=], which is a [=string=]<var ignore>deliveryType</var>, and pass it as an additional argument to [=setup the resource timing entry=].
This section contains patches to [[SERVICE-WORKERS]].
739
+
740
+
<div algorithm="Create Fetch Event and Dispatch">
741
+
Modify <a spec="SERVICE-WORKERS">Create Fetch Event and Dispatch</a>'s step which sets {{FetchEvent/resultingClientId}} as follows:
742
+
743
+
<blockquote>
744
+
If |request| is a [=non-subresource request=] and |request|'s [=request/destination=] is not "{{RequestDestination/report}}"<ins> and |reservedClient|'s [=environment/is navigational prefetch client=] is false</ins>, initialize <var ignore>e</var>'s {{FetchEvent/resultingClientId}} attribute to |reservedClient|'s [=environment/id=], and to the empty string otherwise.
745
+
</blockquote>
746
+
747
+
<p class="note">In the prefetch case, although |request| has a [=request/reserved client=] at this time, it is just a specification fiction to help the request go through. It does not represent an actual client, of the sort that can be seen in e.g. {{Clients/matchAll()|clients.matchAll()}}. Actual client creation happens <a href="#prefetch-activation-client-creation">at activation time</a>, which will be after the {{FetchEvent}} is done firing.
748
+
</div>
749
+
724
750
<h2 id="clear-site-data-patches">Clear Site Data patches</h2>
725
751
726
752
Add an additional header value description in [[CLEAR-SITE-DATA#header]]:
@@ -755,8 +781,6 @@ Modify <a abstract-op spec="CLEAR-SITE-DATA">clear site data for response</a>'s
<p class="issue">Check Service Worker integration</p>
759
-
760
784
The <dfn>list of sufficiently strict speculative navigation referrer policies</dfn> is a list containing the following: "", "`strict-origin-when-cross-origin`", "`strict-origin`", "`same-origin`", "`no-referrer`".
0 commit comments