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
Don't fail update upon error fetching the incumbent worker's import s… (#1377)
* Don't fail update upon error fetching the incumbent worker's import scripts.
To include imported scripts in the byte-for-byte comparison, the Update
algorithm fetches the incumbent worker's scripts in order to
detect if there is a difference. But it would abort the update upon
MIME type error if fetching the script failed. This is undesirable
because the new worker might not use these scripts at all, e.g.,
the scripts may have legitimately been removed from the server.
I considered setting the Updated flag on failure, but it turns out Firefox
treats the failure as "no change" and Chrome's WIP implementation
was also doing that. The consensus at #1374 is to just consider
network errors to be "no change", so do that.
A [=/service worker=] has an associated <dfn export id="dfn-script-resource-map">script resource map</dfn> which is an <a>ordered map</a> where the keys are [=/URLs=] and the values are [=/responses=].
165
165
166
+
A [=/service worker=] has an associated <dfn export id="dfn-set-of-used-scripts">set of used scripts</dfn> (a [=ordered set|set=]) whose [=list/item=] is a [=/URL=]. It is initially a new [=ordered set|set=].
167
+
168
+
Note: The [=set of used scripts=] is only used to prune unused resources from a new worker's map after installation, that were populated based on the old worker's map during the update check.
169
+
166
170
A [=/service worker=] has an associated <dfn export id="dfn-skip-waiting-flag">skip waiting flag</dfn>. Unless stated otherwise it is unset.
167
171
168
172
A [=/service worker=] has an associated <dfn export id="dfn-classic-scripts-imported-flag">classic scripts imported flag</dfn>. It is initially unset.
169
173
170
-
A [=/service worker=] has an associated <dfn export id="dfn-set-of-event-types-to-handle">set of event types to handle</dfn> (a [=ordered set|set=]) whose [=list/item=] is an <a>event listener</a>'s event type. It is initially an empty set.
174
+
A [=/service worker=] has an associated <dfn export id="dfn-set-of-event-types-to-handle">set of event types to handle</dfn> (a [=ordered set|set=]) whose [=list/item=] is an <a>event listener</a>'s event type. It is initially a new [=ordered set|set=].
171
175
172
-
A [=/service worker=] has an associated <dfn export id="dfn-set-of-extended-events">set of extended events</dfn> (a [=ordered set|set=]) whose [=list/item=] is an {{ExtendableEvent}}. It is initially an empty set.
176
+
A [=/service worker=] has an associated <dfn export id="dfn-set-of-extended-events">set of extended events</dfn> (a [=ordered set|set=]) whose [=list/item=] is an {{ExtendableEvent}}. It is initially a new [=ordered set|set=].
When the <dfn method for="ServiceWorkerGlobalScope" id="importscripts-method"><code>importScripts(|urls|)</code></dfn> method is called on a {{ServiceWorkerGlobalScope}} object, the user agent *must* <a>import scripts into worker global scope</a>, given this {{ServiceWorkerGlobalScope}} object and |urls|, and with the following steps to [=fetching scripts/perform the fetch=] given the [=/request=] |request|:
2064
2068
2065
2069
1. Let |serviceWorker| be |request|'s [=request/client=]'s [=environment settings object/global object=]'s [=ServiceWorkerGlobalScope/service worker=].
2066
-
1. If |serviceWorker|'s [=script resource map=][|request|'s [=request/url=]] [=map/exists=], return the [=map/entry=]'s [=map/value=].
2067
-
1. If |serviceWorker|'s [=state=] is not *parsed* or *installing*, return a [=network error=].
2070
+
1. Let |map| be |serviceWorker|'s [=script resource map=].
2071
+
1. Let |url| be |request|'s [=request/url=].
2072
+
1. If |serviceWorker|'s [=state=] is not *parsed* or *installing*:
2073
+
1. Return |map|[|url|] if it [=map/exists=] and a [=network error=] otherwise.
2074
+
1. If |map|[|url|][=map/exists=]:
2075
+
1. [=set/Append=] |url| to |serviceWorker|'s [=set of used scripts=].
2076
+
1. Return |map|[|url|].
2068
2077
1. Let |registration| be |serviceWorker|'s [=containing service worker registration=].
2069
2078
1. Set |request|'s [=service-workers mode=] to "`none`".
2070
2079
1. Set |request|'s [=request/cache mode=] to "`no-cache`" if any of the following are true:
1. Let |response| be the result of [=fetch|fetching=] |request|.
2075
2084
1. If |response|’s [=response/cache state=] is not "`local`", set |registration|’s [=service worker registration/last update check time=] to the current time.
2076
2085
1. If |response|'s [=unsafe response=] is a [=bad import script response=], then return a [=network error=].
2077
-
1. [=map/Set=] |serviceWorker|'s [=script resource map=][|request|'s [=request/url=]] to |response|.
2086
+
1. [=map/Set=] |map|[|url|] to |response|.
2087
+
1. [=set/Append=] |url| to |serviceWorker|'s [=set of used scripts=].
2078
2088
1. Set |serviceWorker|'s [=classic scripts imported flag=].
1. Invoke [=Reject Job Promise=] with |job| and `TypeError`.
2405
2415
1. Invoke <a>Finish Job</a> with |job| and abort these steps.
2406
2416
1. Let |newestWorker| be the result of running <a>Get Newest Worker</a> algorithm passing |registration| as the argument.
2407
-
1. If |job|'s <a>job type</a> is *update*, and |newestWorker|'s[=service worker/script url=] does not [=url/equal=] |job|'s [=job/script url=], then:
2417
+
1. If |job|'s <a>job type</a> is *update*, and |newestWorker| is not null and its [=service worker/script url=] does not [=url/equal=] |job|'s [=job/script url=], then:
2408
2418
1. Invoke [=Reject Job Promise=] with |job| and `TypeError`.
2409
2419
1. Invoke <a>Finish Job</a> with |job| and abort these steps.
1. Invoke [=Reject Job Promise=] with |job| and "{{SecurityError}}" {{DOMException}}.
2460
2470
1. Asynchronously complete these steps with a <a>network error</a>.
2461
-
1. Set |updatedResourceMap|[|request|'s [=request/url=]] to |response|.
2471
+
1. Let |url| be |request|'s [=request/url=].
2472
+
1. Set |updatedResourceMap|[|url|] to |response|.
2462
2473
1. If |response|'s [=response/cache state=] is not "`local`", set |registration|'s [=last update check time=] to the current time.
2463
-
1. If |newestWorker| is null, or |newestWorker|'s [=script resource map=][|request|'s [=request/url=]]'s [=response/body=] is not byte-for-byte identical with |response|'s [=response/body=], set |hasUpdatedResources| to true.
2474
+
1. Let |map| be |newestWorker|'s [=script resource map=] if |newestWorker| is not null, and null otherwise.
2475
+
1. If |map| is null or |map|[|url|]'s [=response/body=] is not byte-for-byte identical with |response|'s [=response/body=], set |hasUpdatedResources| to true.
2464
2476
1. Else if |newestWorker|'s [=classic scripts imported flag=] is set, then:
2465
2477
2466
2478
Note: The following checks to see if an imported script has been updated, since the main script has not changed.
1. Set |updatedResourceMap|[|importRequest|'s [=request/url=]] to |fetchedResponse|.
2477
2489
1. Set |fetchedResponse| to |fetchedResponse|'s [=unsafe response=].
2478
2490
1. If |fetchedResponse|'s [=response/cache state=] is not "`local`", set |registration|’s [=last update check time=] to the current time.
2479
-
1. If |fetchedResponse| is a [=bad import script response=], then asynchronously complete these steps with a [=network error=].
2491
+
1. If |fetchedResponse| is a [=bad import script response=], continue.
2492
+
2493
+
Note: Bad responses for <a>importScripts()</a> are ignored for the purpose of the byte-to-byte check. Only good responses for the incumbent worker and good responses for the potential update worker are considered. See <a href="https://github.com/w3c/ServiceWorker/issues/1374">issue #1374</a> for some rationale.
2494
+
2480
2495
1. If |fetchedResponse|'s [=response/body=] is not byte-for-byte identical with |storedResponse|'s [=unsafe response=]'s [=response/body=], set |hasUpdatedResources| to true.
2481
2496
2482
2497
Note: The control does not break the loop in this step to continue with all the imported scripts to populate the cache.
1. Invoke [=Resolve Job Promise=] with |job| and |registration|.
2497
2512
1. Invoke [=Finish Job=] with |job| and abort these steps.
2498
2513
1. Let |worker| be a new [=/service worker=].
2499
-
1. Set |worker|'s [=service worker/script url=] to |job|'s [=job/script url=], |worker|'s <a>script resource</a> to |script|, and |worker|'s [=service worker/type=] to |job|'s <a>worker type</a>.
2500
-
1. [=map/For each=] |url| → |response| of |updatedResourceMap|:
2501
-
1. Set |worker|'s [=script resource map=][|url|] to |response|.
2514
+
1. Set |worker|'s [=service worker/script url=] to |job|'s [=job/script url=], |worker|'s [=script resource=] to |script|, |worker|'s [=service worker/type=] to |job|'s [=worker type=], and |worker|'s [=script resource map=] to |updatedResourceMap|.
2515
+
1. Append |url| to |worker|'s [=set of used scripts=].
2502
2516
1. Set |worker|'s <a>script resource</a>'s <a>HTTPS state</a> to |httpsState|.
2503
2517
1. Set |worker|'s <a>script resource</a>'s [=script resource/referrer policy=] to |referrerPolicy|.
2504
2518
1. Invoke [=Run Service Worker=] algorithm given |worker|, with the *force bypass cache for importscripts flag* set if |job|'s [=job/force bypass cache flag=] is set, and with the following callback steps given |evaluationStatus|:
0 commit comments