From 7deb2380a2b8fc327d73636f7c185a22f85f11d5 Mon Sep 17 00:00:00 2001 From: Jungkee Song Date: Mon, 12 Dec 2016 16:06:00 +0900 Subject: [PATCH] Fetch service worker scripts with "no-cache" by default (#1020) This introduces service worker registration's use cache field and its related APIs: options.useCache to register method and registration.useCache for ServiceWorkerRegistration objects. This changes the default cache mode of fetching SW scripts to "no-cache". After the change, 24 hours limit and job's force bypass cache flag rules are still enforced. register() method's options value set to { useCache: true } re-enables the previous default behavior provided before this change. Fixes #893 #894. --- docs/index.bs | 76 ++++++--- docs/index.html | 416 +++++++++++++++++++++++++++++---------------- docs/v1/index.bs | 61 ++++--- docs/v1/index.html | 400 +++++++++++++++++++++++++++---------------- 4 files changed, 612 insertions(+), 341 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index a54d097a..b7fdad7e 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -187,8 +187,6 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe A [=/service worker registration=] has an associated scope url (a [=/URL=]). - A [=/service worker registration=] has an associated registering script url (a [=/URL=]). - A [=/service worker registration=] has an associated installing worker (a [=/service worker=] or null) whose [=service worker/state=] is *installing*. It is initially set to null. A [=/service worker registration=] has an associated waiting worker (a [=/service worker=] or null) whose [=service worker/state=] is *installed*. It is initially set to null. @@ -197,6 +195,8 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe A [=/service worker registration=] has an associated last update check time. It is initially set to null. + A [=/service worker registration=] has an associated use cache (a boolean). It is initially set to false. + A [=/service worker registration=] has an associated uninstalling flag. It is initially unset. A [=/service worker registration=] has one or more task queues that back up the tasks from its active worker's event loop's corresponding [=/task queues=]. (The target task sources for this back up operation are the handle fetch task source and the handle functional event task source.) The user agent dumps the active worker's tasks to the [=/service worker registration=]'s [=service worker registration/task queues=] when the active worker is terminated and re-queues those tasks to the active worker's event loop's corresponding [=/task queues=] when the active worker spins off. Unlike the [=/task queues=] owned by event loops, the [=/service worker registration=]'s [=service worker registration/task queues=] are not processed by any event loops in and of itself. @@ -391,6 +391,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe readonly attribute ServiceWorker? active; readonly attribute USVString scope; + readonly attribute boolean useCache; [NewObject] Promise<void> update(); [NewObject] Promise<boolean> unregister(); @@ -436,6 +437,12 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe +
+

{{ServiceWorkerRegistration/useCache}}

+ + The useCache attribute *must* return [=ServiceWorkerRegistration/service worker registration=]'s [=service worker registration/use cache=]. +
+

{{ServiceWorkerRegistration/update()}}

@@ -529,6 +536,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe dictionary RegistrationOptions { USVString scope; WorkerType type = "classic"; + boolean useCache = false; }; @@ -590,7 +598,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe 1. Let |scriptURL| be the result of parsing |scriptURL| with the context object's relevant settings object's API base URL. 1. Let |scopeURL| be null. 1. If |options|.{{RegistrationOptions/scope}} is present, set |scopeURL| to the result of parsing |options|.{{RegistrationOptions/scope}} with the context object's relevant settings object's API base URL. - 1. Invoke [=Start Register=] with |scopeURL|, |scriptURL|, |p|, |client|, |client|'s creation URL and |options|.{{RegistrationOptions/type}}. + 1. Invoke [=Start Register=] with |scopeURL|, |scriptURL|, |p|, |client|, |client|'s creation URL, |options|.{{RegistrationOptions/type}}, and |options|.{{RegistrationOptions/useCache}}. 1. Return |p|.
@@ -788,7 +796,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe }; - A {{ServiceWorkerGlobalScope}} object represents the global execution context of a [=/service worker=]. A {{ServiceWorkerGlobalScope}} object has an associated service worker (a [=/service worker=]). + A {{ServiceWorkerGlobalScope}} object represents the global execution context of a [=/service worker=]. A {{ServiceWorkerGlobalScope}} object has an associated service worker (a [=/service worker=]). A {{ServiceWorkerGlobalScope}} object has an associated force bypass cache for importscripts flag. It is initially unset. Note: {{ServiceWorkerGlobalScope}} object provides generic, event-driven, time-limited script execution contexts that run at an origin. Once successfully registered, a [=/service worker=] is started, kept alive and killed by their relationship to events, not [=/service worker clients=]. Any type of synchronous requests must not be initiated inside of a [=/service worker=]. @@ -1636,7 +1644,9 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe 1. If the "scope" target attribute of the Link header is present, set |scopeURL| to the result of parsing the "scope" target attribute with |scriptURL|. 1. Let |workerType| be the "workertype" target attribute of the Link header, or "classic" if no such attribute is present. 1. If |workerType| is not a valid {{WorkerType}} value, abort these steps. - 1. Invoke [=Start Register=] with |scopeURL|, |scriptURL|, a new promise, null, |contextURL| and |workerType|. + 1. Let |useCache| be the "usecache" target attribute of the Link header, or false if no such attribute is present. + 1. If |useCache| is not a valid boolean value, abort these steps. + 1. Invoke [=Start Register=] with |scopeURL|, |scriptURL|, a new promise, null, |contextURL|, |workerType|, and |useCache|. When a serviceworker link's <{link}> element is inserted into a document, a serviceworker link is created on a <{link}> element that is already in a document tree, or the <{link/href}> or <{link/scope}> attributes of the <{link}> element of a serviceworker link is changed, the user agent *should* run these steps: @@ -1648,8 +1658,10 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe 1. If the <{link/scope}> attribute is present, set |scopeURL| to the result of parsing the <{link/scope}> attribute with the <{link}> element's node document's document base URL. 1. Let |workerType| be the <{link/workertype}> attribute, or "classic" if the <{link/workertype}> attribute is omitted. 1. If |workerType| is not a valid {{WorkerType}} value, queue a task to fire an event named error at the <{link}> element, and abort these steps. + 1. Let |useCache| be the <{link/usecache}> attribute, or false if the <{link/usecache}> attribute is omitted. + 1. If |useCache| is not a valid boolean value, queue a task to fire an event named error at the <{link}> element, and abort these steps. 1. Let |promise| be a new promise. - 1. Invoke [=Start Register=] with |scopeURL|, |scriptURL|, |promise|, |client|, |client|'s creation URL and |workerType|. + 1. Invoke [=Start Register=] with |scopeURL|, |scriptURL|, |promise|, |client|, |client|'s creation URL, |workerType|, and |useCache|. 1. Run the following substeps in parallel: 1. Wait until |promise| settles. 1. If |promise| rejected, queue a task to fire an event named error at the <{link}> element. @@ -1686,12 +1698,15 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe partial interface HTMLLinkElement { [CEReactions] attribute USVString scope; [CEReactions] attribute WorkerType workerType; + [CEReactions] attribute boolean useCache; }; The scope IDL attribute must reflect the element's scope content attribute. The workerType IDL attribute must reflect the element's workertype content attribute. + + The useCache IDL attribute must reflect the element's usecache content attribute. @@ -2136,7 +2151,13 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe 1. Let |serviceWorker| be |request|'s [=request/client=]'s [=environment settings object/global object=]'s [=ServiceWorkerGlobalScope/service worker=]. 1. If |serviceWorker|'s imported scripts updated flag is unset, then: + 1. Let |registration| be |serviceWorker|'s [=containing service worker registration=]. + 1. Set |request|'s [=request/cache mode=] to "no-cache" if any of the following are true: + * |registration|'s [=service worker registration/use cache=] is false. + * The [=current global object=]'s [=force bypass cache for importscripts flag=] is set. + * |registration|'s [=last update check time=] is not null and the time difference in seconds calculated by the current time minus |registration|’s [=last update check time=] is greater than 86400. 1. Let |response| be the result of fetching |request|. + 1. If |response|’s cache state is not "local", set |registration|’s [=service worker registration/last update check time=] to the current time. 1. If |response|'s unsafe response's [=response/type=] is not "error", and |response|'s [=response/status=] is an ok status, then: 1. [=map/Set=] script resource map[|request|'s [=request/url=]] to |response| 1. Return |response|. @@ -2247,6 +2268,8 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe A job has a worker type ("classic" or "module"). + A job has a use cache (a boolean). + A job has a client (a [=/service worker client=]). It is initially null. A job has a referrer (a [=/URL=] or null). @@ -2255,7 +2278,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe A job has a list of equivalent jobs (a list of jobs). It is initially the empty list. - A job has a force bypass cache flag It is initially unset. + A job has a force bypass cache flag. It is initially unset. @@ -2312,7 +2335,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe : Output :: none - 1. Assert: the job queue is not empty. + 1. Assert: the job queue is not empty. 1. Queue a task to run these steps: 1. Let |job| be the element in the front of the job queue. 1. If |job|'s job type is *register*, run Register with |job| in parallel. @@ -2331,7 +2354,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe : Output :: none - 1. Assert: the top element in the job queue is |job|. + 1. Assert: the top element in the job queue is |job|. 1. Pop the top element from the job queue. 1. If the job queue is not empty, invoke Run Job with the top element of the job queue. @@ -2374,6 +2397,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe :: |client|, a [=/service worker client=] :: |referrer|, a [=/URL=] :: |workerType|, a worker type + :: |useCache|, a boolean : Output :: none @@ -2388,7 +2412,8 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe 1. If |scopeURL|'s [=url/scheme=] is not one of "http" and "https", reject |promise| with a TypeError and abort these steps. 1. If any of the strings in |scopeURL|'s [=url/path=] contains either ASCII case-insensitive "%2f" or ASCII case-insensitive "%5c", reject |promise| with a TypeError and abort these steps. 1. Let |job| be the result of running [=Create Job=] with *register*, |scopeURL|, |scriptURL|, |promise|, and |client|. - 1. Set |job|'s worker type to |workerType|. + 1. Set |job|'s [=job/worker type=] to |workerType|. + 1. Set |job|'s [=job/use cache=] to |useCache|. 1. Set |job|'s [=job/referrer=] to |referrer|. 1. Invoke [=Schedule Job=] with |job|. @@ -2414,11 +2439,11 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe 1. If |registration| is not null, then: 1. If |registration|'s uninstalling flag is set, unset it. 1. Let |newestWorker| be the result of running the Get Newest Worker algorithm passing |registration| as the argument. - 1. If |newestWorker| is not null and |job|'s [=job/script url=] [=url/equals=] |newestWorker|'s [=service worker/script url=] with the *exclude fragments flag* set, then: + 1. If |newestWorker| is not null, |job|'s [=job/script url=] [=url/equals=] |newestWorker|'s [=service worker/script url=] with the *exclude fragments flag* set, and |job|'s [=job/use cache=]'s value equals |registration|'s [=service worker registration/use cache=]'s value, then: 1. Invoke Resolve Job Promise with |job| and the {{ServiceWorkerRegistration}} object which represents |registration|. 1. Invoke Finish Job with |job| and abort these steps. 1. Else: - 1. Invoke Set Registration algorithm passing |job|'s [=job/scope url=] as its argument. + 1. Invoke Set Registration algorithm with |job|'s [=job/scope url=] and |job|'s [=job/use cache=]. 1. Invoke Update algorithm passing |job| as the argument. @@ -2454,10 +2479,12 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe Note: See the definition of the Service-Worker header in Appendix B: Extended HTTP headers. 1. Set |request|'s skip-service-worker flag and |request|'s [=request/redirect mode=] to "error". - 1. If |newestWorker| is not null and |registration|'s last update check time is not null, then: - 1. If the time difference in seconds calculated by the current time minus |registration|'s last update check time is greater than 86400, or *force bypass cache flag* is set, set |request|'s [=request/cache mode=] to "reload". + 1. Set |request|'s [=request/cache mode=] to "no-cache" if any of the following are true: + * |registration|'s [=service worker registration/use cache=] is false. + * |job|'s [=force bypass cache flag=] is set. + * |newestWorker| is not null, and |registration|'s [=last update check time=] is not null and the time difference in seconds calculated by the current time minus |registration|’s [=last update check time=] is greater than 86400. - Note: Even if the cache mode is not set to "reload", the user agent obeys Cache-Control header's max-age value in the network layer to determine if it should bypass the browser cache. + Note: Even if the cache mode is not set to "no-cache", the user agent obeys Cache-Control header's max-age value in the network layer to determine if it should bypass the browser cache. 1. [=/Fetch=] |request|, and asynchronously wait to run the remaining steps as part of fetch's process response for the [=/response=] |response|. 1. Extract a MIME type from the |response|'s [=response/header list=]. If this MIME type (ignoring parameters) is not one of text/javascript, application/x-javascript, and application/javascript, then: @@ -2500,7 +2527,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe Else, continue the rest of these steps after the algorithm's asynchronous completion, with |script| being the asynchronous completion value. - 1. If |newestWorker| is not null, |newestWorker|'s [=service worker/script url=] [=url/equals=] |job|'s [=job/script url=] with the *exclude fragments flag* set, and |script| is a byte-for-byte match with |newestWorker|'s script resource, then: + 1. If |newestWorker| is not null, |newestWorker|'s [=service worker/script url=] [=url/equals=] |job|'s [=job/script url=] with the *exclude fragments flag* set, and |script|'s [=source text=] is a byte-for-byte match with |newestWorker|'s [=script resource=]'s [=source text=], if |script| is a [=classic script=], and |script|'s [=module script/module record=]'s \[[ECMAScriptCode]] is a byte-for-byte match with |newestWorker|'s [=script resource=]'s [=module script/module record=]'s \[[ECMAScriptCode]] otherwise, then: 1. Invoke Resolve Job Promise with |job| and the {{ServiceWorkerRegistration}} object which represents |registration|. 1. Invoke Finish Job with |job| and abort these steps. 1. Else: @@ -2509,7 +2536,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe 1. Set |worker|'s [=service worker/script url=] to |job|'s [=job/script url=], |worker|'s script resource to |script|, and |worker|'s type to |job|'s worker type. 1. Set |worker|'s script resource's HTTPS state to |httpsState|. 1. Set |worker|'s script resource's [=script resource/referrer policy=] to |referrerPolicy|. - 1. Invoke Run Service Worker algorithm with |worker| as the argument. + 1. Invoke Run Service Worker algorithm given |worker|, and with the *force bypass cache for importscripts flag* set if |job|'s [=job/force bypass cache flag=] is set. 1. If an uncaught runtime script error occurs during the above step, then: 1. Invoke Reject Job Promise with |job| and a TypeError. 1. If |newestWorker| is null, invoke Clear Registration algorithm passing |registration| as its argument. @@ -2554,11 +2581,11 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe 1. Let |redundantWorker| be null. 1. Run the Update Registration State algorithm passing |registration|, "installing" and |worker| as the arguments. 1. Run the Update Worker State algorithm passing |registration|'s installing worker and *installing* as the arguments. - 1. Assert: |job|'s [=job/job promise=] is not null. + 1. Assert: |job|'s [=job/job promise=] is not null. 1. Invoke Resolve Job Promise with |job| and the {{ServiceWorkerRegistration}} object which represents |registration|. 1. Queue a task to fire an event named updatefound at all the {{ServiceWorkerRegistration}} objects for all the [=/service worker clients=] whose creation URL matches |registration|'s [=service worker registration/scope url=] and all the [=/service workers=] whose containing service worker registration is |registration|. 1. Let |installingWorker| be |registration|'s installing worker. - 1. Invoke Run Service Worker algorithm with |installingWorker| as the argument. + 1. Invoke Run Service Worker algorithm given |installingWorker|, and with the *force bypass cache for importscripts flag* set if |job|'s [=job/force bypass cache flag=] is set. 1. Queue a task |task| to run the following substeps: 1. Let |e| be the result of creating an event with {{InstallEvent}}. 1. Initialize |e|’s {{Event/type}} attribute to {{install!!event}}. @@ -2641,6 +2668,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe : Input :: |serviceWorker|, a [=/service worker=] + :: *force bypass cache for importscripts flag*, an optional flag unset by default : Output :: None @@ -2678,6 +2706,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe 1. Set |workerGlobalScope|'s [=WorkerGlobalScope/HTTPS state=] to |serviceWorker|'s script resource's HTTPS state. 1. Set |workerGlobalScope|'s [=WorkerGlobalScope/referrer policy=] to |serviceWorker|'s script resource's [=script resource/referrer policy=]. 1. Set |workerGlobalScope|'s [=WorkerGlobalScope/type=] to |serviceWorker|'s type. + 1. Set |workerGlobalScope|'s [=ServiceWorkerGlobalScope/force bypass cache for importscripts flag=] if its *force bypass cache for importscripts flag* is set. 1. Create a new {{WorkerLocation}} object and associate it with |workerGlobalScope|. 1. If |serviceWorker| is an active worker, and there are any tasks queued in |serviceWorker|'s containing service worker registration's [=service worker registration/task queues=], queue them to |serviceWorker|'s event loop's [=/task queues=] in the same order using their original task sources. 1. If |script| is a classic script, then run the classic script |script|. Otherwise, it is a module script; run the module script |script|. @@ -2904,8 +2933,8 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe : Output :: None - 1. Assert: scope to registration map contains a value equal to |registration|. - 1. Assert: |registration|'s active worker is not null. + 1. Assert: scope to registration map contains a value equal to |registration|. + 1. Assert: |registration|'s active worker is not null. 1. Let |activeWorker| be |registration|'s active worker. 1. If |activeWorker|'s set of event types to handle does not contain |event|'s {{Event/type}}, then: 1. Return and continue running these steps in parallel. @@ -2989,12 +3018,13 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe : Input :: |scope|, a [=/URL=] + :: |useCache|, a boolean : Output :: |registration|, a [=/service worker registration=] 1. Run the following steps atomically. 1. Let |scopeString| be serialized |scope| with the *exclude fragment flag* set. - 1. Let |registration| be a new [=/service worker registration=] whose [=service worker registration/scope url=] is set to |scope|. + 1. Let |registration| be a new [=/service worker registration=] whose [=service worker registration/scope url=] is set to |scope| and [=service worker registration/use cache=] is set to |useCache|. 1. [=map/Set=] scope to registration map[|scopeString|] to |registration|. 1. Return |registration|. @@ -3110,7 +3140,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe : Output :: None - 1. Assert: |client| is not null. + 1. Assert: |client| is not null. 1. If |client| is a type of environment settings object, queue a task to fire an event named controllerchange at the {{ServiceWorkerContainer}} object |client| is [=ServiceWorkerContainer/service worker client|associated=] with. The task *must* use |client|'s responsible event loop and the DOM manipulation task source. diff --git a/docs/index.html b/docs/index.html index b0efff89..fe3e4992 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1177,7 +1177,7 @@ } } - + - +