From 0a553aff1b0d47984816c9552703db2d2a99f323 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Tue, 28 Nov 2023 03:37:38 +0000 Subject: [PATCH 01/57] Revive of PR #1686. I used to work on the specification update to support the ServiceWorker static routing API (https://github.com/WICG/service-worker-static-routing-api) https://github.com/w3c/ServiceWorker/pull/1686 However, I accidentally closed it by force-sync to the ServiceWorker specification's repository HEAD. This CL is for reviving it. --- docs/index.bs | 134 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index a5b3635f..468c5cc9 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -133,6 +133,22 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ text: obtain a storage key; url: obtain-a-storage-key text: storage key/equals; url: storage-key-equals +spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ + type: dfn + text: parse; for: urlpattern; url: parse-a-pattern-string + text: component; for: urlpattern; url: component + text: match; for: urlpattern; url: match + text: protocol component; for: urlpattern; url: urlpattern-protocol-component + text: username component; for: urlpattern; url: urlpattern-username-component + text: password component; for: urlpattern; url: urlpattern-password-component + text: hostname component; for: urlpattern; url: urlpattern-hostname-component + text: port component; for: urlpattern; url: urlpattern-port-component + text: pathname component; for: urlpattern; url: urlpattern-pathname-component + text: search component; for: urlpattern; url: urlpattern-search-component + text: hash component; for: urlpattern; url: urlpattern-hash-component + text: pattern string; for: urlpattern-component; url: component-pattern-string + text: type; for: urlpattern-part; url: part-type +
@@ -207,6 +223,8 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
 
     A [=/service worker=] has an associated all fetch listeners are empty flag. It is initially unset.
 
+    A [=/service worker=] has an associated static router rules object. It is initially unset.
+
     A [=/service worker=] is said to be running if its [=event loop=] is running.
 
     
@@ -1545,6 +1563,46 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ Note: [=/Service workers=] delay treating the [=installing worker=] as "`installed`" until all the [=promises=] in the {{install!!event}} event's [=extend lifetime promises=] resolve successfully. (See the relevant [Install algorithm step](#install-settle-step).) If any of the promises rejects, the installation fails. This is primarily used to ensure that a [=/service worker=] is not considered "`installed`" until all of the core caches it depends on are populated. Likewise, [=/service workers=] delay treating the [=active worker=] as "`activated`" until all the [=promises=] in the {{activate!!event}} event's [=extend lifetime promises=] settle. (See the relevant [Activate algorithm step](#activate-settle-step).) This is primarily used to ensure that any [=functional events=] are not dispatched to the [=/service worker=] until it upgrades database schemas and deletes the outdated cache entries.
+
+

{{InstallEvent}}

+ +
+      [Exposed=ServiceWorker]
+      interface InstallEvent : ExtendableEvent {
+        Promise<undefined> registerRouter((RouterRule or sequence<RouterRule>) rules);
+      };
+
+      dictionary RouterRule {
+        required RouterCondition condition;
+        required RouterSourceEnum source;
+      };
+
+      dictionary RouterCondition {
+        USVString urlPattern;
+      };
+
+      enum RouterSourceEnum { "network" };
+    
+ + Each {{RouterCondition/urlPattern}} object has an associated URLPattern, a {{URLPattern}}, which is initially unset. + +
+

{{InstallEvent/registerRouter(rules)|event.registerRouter(rules)}}

+ + {{InstallEvent/registerRouter(rules)}} registers this service worker the rules to offload simple tasks that the fetch handler does. + + registerRouter(|rules|) method *must* run these steps: + + 1. Let |routerRules| be a list of {{RouterRule}} dictionaries. + 1. If |rules| is a {{RouterRule}} dictionary, set |rules| to « |rules| ». + 1. for each |rule| in |rules|: + 1. If running [=VerifyRouterRule=] algorithm with |rule| and [=/service worker=] returns false, throw a TypeError. + 1. Append |rule| to |routerRules|. + 1. Set [=/service worker=]'s [=static router rules object=] to |routerRules|. + +
+
+

{{FetchEvent}}

@@ -2822,7 +2880,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Set |installFailed| to true. 1. Else: 1. [=Queue a task=] |task| on |installingWorker|'s [=event loop=] using the [=DOM manipulation task source=] to run the following steps: - 1. Let |e| be the result of creating an event with {{ExtendableEvent}}. + 1. Let |e| be the result of creating an event with {{InstallEvent}}. 1. Initialize |e|’s {{Event/type}} attribute to {{install!!event}}. 1. Dispatch |e| at |installingWorker|'s [=service worker/global object=]. 1. *WaitForAsynchronousExtensions*: Run the following substeps in parallel: @@ -3067,6 +3125,8 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Assert: |request|'s [=request/destination=] is not "serviceworker". 1. If |request|'s [=request/destination=] is either "embed" or "object", then: 1. Return null. + 1. Else if |registration|'s active worker's [=static router rules object=] is set: + 1. If running [=GetRouterSource=] algorithm with [=static router rules object=] and |request| returns "network", return null. 1. Else if |request| is a non-subresource request, then: 1. If |reservedClient| is not null and is an environment settings object, then: 1. If |reservedClient| is not a secure context, return null. @@ -3175,6 +3235,78 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Return |response|.
+
+

VerifyRouterRule

+ + : Input + :: |rule|, a {{RouterRule}} + :: |serviceWorker|, a [=/service worker=] + : Output + :: a boolean + + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] is the empty string, return false. + 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. + 1. If |rawPattern| is a [=string=], then: + 1. Let |baseURL| be |serviceWorker|'s [=service worker/script url=]. + 1. Set |pattern| to the result of constructing a {{URLPattern}} using the {{URLPattern/URLPattern(input, baseURL)}} constructor steps given |rawPattern| and |baseURL|. If those steps throw, catch the exception and return false. + 1. Otherwise, if |rawPattern| is {{URLPatternInit}}: + 1. Set |pattern| to the result of constructing a {{URLPattern}} using the {{URLPattern/URLPattern(input)}} constructor steps given |rawPattern|. If those steps throw, catch the exception and return false. + 1. Otherwise, return false. + 1. If running the [=VerifyURLPattern=] algorithm with |pattern| returns false, return false. + 1. Set |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]'s associated {{URLPattern}} to |pattern|. + 1. Return true. +
+ +
+

VerifyURLPattern

+ + : Input + :: |pattern|, a {{URLPattern}} + : Output + :: a boolean + + 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/protocol component=] returns false, return false. + 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/username component=] returns false, return false. + 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/password component=] returns false, return false. + 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/hostname component=] returns false, return false. + 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/port component=] returns false, return false. + 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/pathname component=] returns false, return false. + 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/search component=] returns false, return false. + 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/hash component=] returns false, return false. + 1. Return true. +
+ +
+

VerifyURLPatternComponent

+ + : Input + :: |component|, a [=component=]. + : Output + :: a boolean + + 1. Let |parts| be a result of [=urlpattern/parsing=] |component|'s associated [=urlpattern-component/pattern string=]. + 1. [=list/For each=] |part| of |parts|: + 1. If |part|'s [=urlpattern-part/type=] is "regexp", return false. + + Note: Since running a user-defined regular expression has a security concern, it is prohibited. + + 1. Return true. +
+ +
+

GetRouterSource

+ : Input + :: |rules|, a list of {{RouterRule}} + :: |request|, a [=/request=] + : Output + :: {{RouterSourceEnum}} or null + + 1. [=list/For each=] |rule| of |rules|: + 1. If running [=urlpattern/match=] with |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]'s associated [=URLPattern=] and |request|'s [=request/URL=] returns null, [=continue=]. + 1. Return |rule|'s {{RouterRule/source}}. + 1. Return null. +
+

Should Skip Event

: Input From a884283b3d6816813b8eb3db8a22a5c30bcb43fe Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Tue, 28 Nov 2023 17:00:35 +0900 Subject: [PATCH 02/57] Update generate.yml Just trying to add workflows rule to run CI in static_routing_api repository. --- .github/workflows/generate.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index 6b104833..b2e253b0 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -1,9 +1,10 @@ # Create a file called .github/workflows/auto-publish.yml name: CI on: - pull_request: {} + pull_request: + branches: [static_routing_api] push: - branches: [main] + branches: [static_routing_api] jobs: main: name: Build, Validate and Deploy Locally From b650b57fab4187e3a825195563ab75ebbe36d395 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Tue, 28 Nov 2023 17:01:53 +0900 Subject: [PATCH 03/57] Update generate.yml revert --- .github/workflows/generate.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index b2e253b0..6b104833 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -1,10 +1,9 @@ # Create a file called .github/workflows/auto-publish.yml name: CI on: - pull_request: - branches: [static_routing_api] + pull_request: {} push: - branches: [static_routing_api] + branches: [main] jobs: main: name: Build, Validate and Deploy Locally From bdc2474497ca62a01eddd7180fb38486f758c8f4 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Thu, 30 Nov 2023 07:27:14 +0000 Subject: [PATCH 04/57] Introduce changes upon whatwg/urlpattern#199. --- docs/index.bs | 61 ++++++++++----------------------------------------- 1 file changed, 11 insertions(+), 50 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 468c5cc9..097f0469 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1569,7 +1569,7 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/
       [Exposed=ServiceWorker]
       interface InstallEvent : ExtendableEvent {
-        Promise<undefined> registerRouter((RouterRule or sequence<RouterRule>) rules);
+        Promise<undefined> addRoutes((RouterRule or sequence<RouterRule>) rules);
       };
 
       dictionary RouterRule {
@@ -1578,24 +1578,24 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/
       };
 
       dictionary RouterCondition {
-        USVString urlPattern;
+        URLPatternCompatible urlPattern;
       };
 
-      enum RouterSourceEnum { "network" };
+      enum RouterSource { "network" };
     
Each {{RouterCondition/urlPattern}} object has an associated URLPattern, a {{URLPattern}}, which is initially unset.
-

{{InstallEvent/registerRouter(rules)|event.registerRouter(rules)}}

+

{{InstallEvent/addRoutes(rules)|event.addRoutes(rules)}}

- {{InstallEvent/registerRouter(rules)}} registers this service worker the rules to offload simple tasks that the fetch handler does. + {{InstallEvent/addRoutes(rules)}} registers this service worker the rules to offload simple tasks that the fetch handler does. - registerRouter(|rules|) method *must* run these steps: + addRoutes(|rules|) method *must* run these steps: 1. Let |routerRules| be a list of {{RouterRule}} dictionaries. 1. If |rules| is a {{RouterRule}} dictionary, set |rules| to « |rules| ». - 1. for each |rule| in |rules|: + 1. For each |rule| of |rules|: 1. If running [=VerifyRouterRule=] algorithm with |rule| and [=/service worker=] returns false, throw a TypeError. 1. Append |rule| to |routerRules|. 1. Set [=/service worker=]'s [=static router rules object=] to |routerRules|. @@ -3244,52 +3244,13 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ : Output :: a boolean - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] is the empty string, return false. 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. If |rawPattern| is a [=string=], then: - 1. Let |baseURL| be |serviceWorker|'s [=service worker/script url=]. - 1. Set |pattern| to the result of constructing a {{URLPattern}} using the {{URLPattern/URLPattern(input, baseURL)}} constructor steps given |rawPattern| and |baseURL|. If those steps throw, catch the exception and return false. - 1. Otherwise, if |rawPattern| is {{URLPatternInit}}: - 1. Set |pattern| to the result of constructing a {{URLPattern}} using the {{URLPattern/URLPattern(input)}} constructor steps given |rawPattern|. If those steps throw, catch the exception and return false. - 1. Otherwise, return false. - 1. If running the [=VerifyURLPattern=] algorithm with |pattern| returns false, return false. - 1. Set |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]'s associated {{URLPattern}} to |pattern|. - 1. Return true. -
- -
-

VerifyURLPattern

- - : Input - :: |pattern|, a {{URLPattern}} - : Output - :: a boolean - - 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/protocol component=] returns false, return false. - 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/username component=] returns false, return false. - 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/password component=] returns false, return false. - 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/hostname component=] returns false, return false. - 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/port component=] returns false, return false. - 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/pathname component=] returns false, return false. - 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/search component=] returns false, return false. - 1. If running the [=VerifyURLPatternComponent=] algorithm with |pattern|'s [=urlpattern/hash component=] returns false, return false. - 1. Return true. -
+ 1. Let |pattern| be the result of [=building a URLPattern from a Web IDL value=] |rawPattern| given |baseURL| and |serivceWorker|'s [=service worker/global object=]'s [=relevant realm=]. If this throws an exception, catch it and return false. + 1. If |pattern| [=URLPattern/has regexp groups=] returns true, return false. -
-

VerifyURLPatternComponent

- - : Input - :: |component|, a [=component=]. - : Output - :: a boolean - - 1. Let |parts| be a result of [=urlpattern/parsing=] |component|'s associated [=urlpattern-component/pattern string=]. - 1. [=list/For each=] |part| of |parts|: - 1. If |part|'s [=urlpattern-part/type=] is "regexp", return false. - - Note: Since running a user-defined regular expression has a security concern, it is prohibited. + Note: Since running a user-defined regular expression has a security concern, it is prohibited. + 1. Set |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]'s associated {{URLPattern}} to |pattern|. 1. Return true.
From ef050e2ebda1757c39c63a28555c90b5791ae452 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Thu, 30 Nov 2023 08:35:17 +0000 Subject: [PATCH 05/57] Fixed the parse error. --- docs/index.bs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 097f0469..9cb17ca8 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3244,8 +3244,9 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ : Output :: a boolean + 1. Let |baseURL| be |serviceWorker|'s [=service worker/script url=]. 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of [=building a URLPattern from a Web IDL value=] |rawPattern| given |baseURL| and |serivceWorker|'s [=service worker/global object=]'s [=relevant realm=]. If this throws an exception, catch it and return false. + 1. Let |pattern| be the result of [=building a URLPattern from a Web IDL value=] |rawPattern| given |baseURL| and |serviceWorker|'s [=service worker/global object=]'s [=relevant realm=]. If this throws an exception, catch it and return false. 1. If |pattern| [=URLPattern/has regexp groups=] returns true, return false. Note: Since running a user-defined regular expression has a security concern, it is prohibited. From 39b670fcdc058c85b6ec60c50c4a75d1cf254a80 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Thu, 30 Nov 2023 08:46:48 +0000 Subject: [PATCH 06/57] clean up. --- docs/index.bs | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 9cb17ca8..b6680dab 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -135,19 +135,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ type: dfn - text: parse; for: urlpattern; url: parse-a-pattern-string - text: component; for: urlpattern; url: component text: match; for: urlpattern; url: match - text: protocol component; for: urlpattern; url: urlpattern-protocol-component - text: username component; for: urlpattern; url: urlpattern-username-component - text: password component; for: urlpattern; url: urlpattern-password-component - text: hostname component; for: urlpattern; url: urlpattern-hostname-component - text: port component; for: urlpattern; url: urlpattern-port-component - text: pathname component; for: urlpattern; url: urlpattern-pathname-component - text: search component; for: urlpattern; url: urlpattern-search-component - text: hash component; for: urlpattern; url: urlpattern-hash-component - text: pattern string; for: urlpattern-component; url: component-pattern-string - text: type; for: urlpattern-part; url: part-type
@@ -1574,7 +1562,7 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ dictionary RouterRule { required RouterCondition condition; - required RouterSourceEnum source; + required RouterSource source; }; dictionary RouterCondition { @@ -3246,7 +3234,7 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ 1. Let |baseURL| be |serviceWorker|'s [=service worker/script url=]. 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of [=building a URLPattern from a Web IDL value=] |rawPattern| given |baseURL| and |serviceWorker|'s [=service worker/global object=]'s [=relevant realm=]. If this throws an exception, catch it and return false. + 1. Let |pattern| be the result of [=URLPattern/building a URLPattern from a WebIDL value=] |rawPattern| given |baseURL| and |serviceWorker|'s [=service worker/global object=]'s [=relevant realm=]. If this throws an exception, catch it and return false. 1. If |pattern| [=URLPattern/has regexp groups=] returns true, return false. Note: Since running a user-defined regular expression has a security concern, it is prohibited. @@ -3261,7 +3249,7 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ :: |rules|, a list of {{RouterRule}} :: |request|, a [=/request=] : Output - :: {{RouterSourceEnum}} or null + :: {{RouterSource}} or null 1. [=list/For each=] |rule| of |rules|: 1. If running [=urlpattern/match=] with |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]'s associated [=URLPattern=] and |request|'s [=request/URL=] returns null, [=continue=]. From 75d848a2677154d1651057629fb37a1f4b5f799c Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Thu, 30 Nov 2023 09:06:45 +0000 Subject: [PATCH 07/57] another dfn fix. --- docs/index.bs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index b6680dab..bd567b36 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -136,6 +136,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ type: dfn text: match; for: urlpattern; url: match + text: building a urlpattern from a webidl value; for: urlpattern; url: building-a-urlpattern-from-a-webidl-value @@ -3234,7 +3235,7 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ 1. Let |baseURL| be |serviceWorker|'s [=service worker/script url=]. 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of [=URLPattern/building a URLPattern from a WebIDL value=] |rawPattern| given |baseURL| and |serviceWorker|'s [=service worker/global object=]'s [=relevant realm=]. If this throws an exception, catch it and return false. + 1. Let |pattern| be the result of [=urlpattern/building a URLPattern from a WebIDL value=] |rawPattern| given |baseURL| and |serviceWorker|'s [=service worker/global object=]'s [=relevant realm=]. If this throws an exception, catch it and return false. 1. If |pattern| [=URLPattern/has regexp groups=] returns true, return false. Note: Since running a user-defined regular expression has a security concern, it is prohibited. From 025eb824511ddfb0565b6526fd0c7fab3b7dc849 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Thu, 30 Nov 2023 09:36:11 +0000 Subject: [PATCH 08/57] Rename of static router rules object. --- docs/index.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index bd567b36..6a44b1f0 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -212,7 +212,7 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ A [=/service worker=] has an associated all fetch listeners are empty flag. It is initially unset. - A [=/service worker=] has an associated static router rules object. It is initially unset. + A [=/service worker=] has an associated list of router rules. It is initially unset. A [=/service worker=] is said to be running if its [=event loop=] is running. @@ -1587,7 +1587,7 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ 1. For each |rule| of |rules|: 1. If running [=VerifyRouterRule=] algorithm with |rule| and [=/service worker=] returns false, throw a TypeError. 1. Append |rule| to |routerRules|. - 1. Set [=/service worker=]'s [=static router rules object=] to |routerRules|. + 1. Set [=/service worker=]'s [=service worker/list of router rules=] to |routerRules|. @@ -3114,8 +3114,8 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ 1. Assert: |request|'s [=request/destination=] is not "serviceworker". 1. If |request|'s [=request/destination=] is either "embed" or "object", then: 1. Return null. - 1. Else if |registration|'s active worker's [=static router rules object=] is set: - 1. If running [=GetRouterSource=] algorithm with [=static router rules object=] and |request| returns "network", return null. + 1. Else if |registration|'s active worker's [=service worker/list of router rules=] is set: + 1. If running [=GetRouterSource=] algorithm with [=service worker/list of router rules=] and |request| returns "network", return null. 1. Else if |request| is a non-subresource request, then: 1. If |reservedClient| is not null and is an environment settings object, then: 1. If |reservedClient| is not a secure context, return null. From d90ac0badd719f9e91c3d5c5ee3702d684b2ab9a Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Thu, 30 Nov 2023 09:56:20 +0000 Subject: [PATCH 09/57] Stop associating the URLPattern and construct URLPattern on-demand. --- docs/index.bs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 6a44b1f0..fc963b41 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1573,8 +1573,6 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ enum RouterSource { "network" }; - Each {{RouterCondition/urlPattern}} object has an associated URLPattern, a {{URLPattern}}, which is initially unset. -

{{InstallEvent/addRoutes(rules)|event.addRoutes(rules)}}

@@ -3115,7 +3113,7 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ 1. If |request|'s [=request/destination=] is either "embed" or "object", then: 1. Return null. 1. Else if |registration|'s active worker's [=service worker/list of router rules=] is set: - 1. If running [=GetRouterSource=] algorithm with [=service worker/list of router rules=] and |request| returns "network", return null. + 1. If running [=GetRouterSource=] algorithm with active worker and |request| returns "network", return null. 1. Else if |request| is a non-subresource request, then: 1. If |reservedClient| is not null and is an environment settings object, then: 1. If |reservedClient| is not a secure context, return null. @@ -3224,6 +3222,18 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ 1. Return |response|.
+
+

ParseURLPattern

+ : Input + :: |rawPattern|, a {{RouterCondition/urlPattern}}" + :: |serviceWorker|, a [=/service worker=] + : Output + :: {{URLPattern}} + + 1. Let |baseURL| be |serviceWorker|'s [=service worker/script url=]. + 1. Return the result of [=urlpattern/building a URLPattern from a WebIDL value=] |rawPattern| given |baseURL| and |serviceWorker|'s [=service worker/global object=]'s [=relevant realm=]. +
+

VerifyRouterRule

@@ -3233,27 +3243,27 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ : Output :: a boolean - 1. Let |baseURL| be |serviceWorker|'s [=service worker/script url=]. 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of [=urlpattern/building a URLPattern from a WebIDL value=] |rawPattern| given |baseURL| and |serviceWorker|'s [=service worker/global object=]'s [=relevant realm=]. If this throws an exception, catch it and return false. + 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. 1. If |pattern| [=URLPattern/has regexp groups=] returns true, return false. Note: Since running a user-defined regular expression has a security concern, it is prohibited. - 1. Set |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]'s associated {{URLPattern}} to |pattern|. 1. Return true.

GetRouterSource

: Input - :: |rules|, a list of {{RouterRule}} + :: |serviceWorker|, a [=/service worker=] :: |request|, a [=/request=] : Output :: {{RouterSource}} or null - 1. [=list/For each=] |rule| of |rules|: - 1. If running [=urlpattern/match=] with |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]'s associated [=URLPattern=] and |request|'s [=request/URL=] returns null, [=continue=]. + 1. [=list/For each=] |rule| of |serviceWorker|'s [=service worker/list of router rules=]: + 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. + 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. + 1. If running [=urlpattern/match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. 1. Return |rule|'s {{RouterRule/source}}. 1. Return null.
From 65776401d7f842bbae63079fafeaa2fb79e22056 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Mon, 4 Dec 2023 07:00:32 +0000 Subject: [PATCH 10/57] Addressed some of comments. --- docs/index.bs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index fc963b41..5d375f14 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -136,7 +136,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ type: dfn text: match; for: urlpattern; url: match - text: building a urlpattern from a webidl value; for: urlpattern; url: building-a-urlpattern-from-a-webidl-value @@ -1578,7 +1577,7 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ {{InstallEvent/addRoutes(rules)}} registers this service worker the rules to offload simple tasks that the fetch handler does. - addRoutes(|rules|) method *must* run these steps: + The addRoutes(|rules|) method steps are: 1. Let |routerRules| be a list of {{RouterRule}} dictionaries. 1. If |rules| is a {{RouterRule}} dictionary, set |rules| to « |rules| ». @@ -3225,13 +3224,13 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/

ParseURLPattern

: Input - :: |rawPattern|, a {{RouterCondition/urlPattern}}" + :: |rawPattern|, a [=string=] :: |serviceWorker|, a [=/service worker=] : Output :: {{URLPattern}} 1. Let |baseURL| be |serviceWorker|'s [=service worker/script url=]. - 1. Return the result of [=urlpattern/building a URLPattern from a WebIDL value=] |rawPattern| given |baseURL| and |serviceWorker|'s [=service worker/global object=]'s [=relevant realm=]. + 1. Return the result of [=building a URLPattern from a WebIDL value=] |rawPattern| given |baseURL| and |serviceWorker|'s [=service worker/global object=]'s [=relevant realm=].
@@ -3243,9 +3242,11 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ : Output :: a boolean + 1. If |rule|["{{RouterRule/condition}}"] does not [=map/exist=], return false. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exist=], return false. 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. - 1. If |pattern| [=URLPattern/has regexp groups=] returns true, return false. + 1. If |pattern| [=URLPattern/has regexp groups=], then return false. Note: Since running a user-defined regular expression has a security concern, it is prohibited. @@ -3261,10 +3262,12 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ :: {{RouterSource}} or null 1. [=list/For each=] |rule| of |serviceWorker|'s [=service worker/list of router rules=]: - 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. - 1. If running [=urlpattern/match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. - 1. Return |rule|'s {{RouterRule/source}}. + 1. If |rule|["{{RouterRule/condition}}"] does not [=map/exist=], continue. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] [=map/exists=], then: + 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. + 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. + 1. If running [=urlpattern/match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. + 1. Return |rule|'s {{RouterRule/source}}. 1. Return null.
From cd5c86420582347652d860cd6b97c88dd05f27e1 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Mon, 4 Dec 2023 08:29:55 +0000 Subject: [PATCH 11/57] Update the case without the urlPattern condition. Considering the future update of the condition, we should mark the case handled as one of conditions. Also, we need to make it extensible. --- docs/index.bs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 5d375f14..05e1eeeb 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3242,15 +3242,18 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ : Output :: a boolean - 1. If |rule|["{{RouterRule/condition}}"] does not [=map/exist=], return false. - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exist=], return false. - 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. - 1. If |pattern| [=URLPattern/has regexp groups=], then return false. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exist=], then: + 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. + 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. + 1. If |pattern| [=URLPattern/has regexp groups=], then return false. - Note: Since running a user-defined regular expression has a security concern, it is prohibited. + Note: Since running a user-defined regular expression has a security concern, it is prohibited. - 1. Return true. + 1. Return true. + + Note: support for other conditions will be implemented here. + + 1. Return false.
@@ -3268,6 +3271,9 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. 1. If running [=urlpattern/match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. 1. Return |rule|'s {{RouterRule/source}}. + + Note: support for other conditions will be implemented here. + 1. Return null.
From 0162980cdf85f3e68f5d132def90e37f7b3363b2 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Mon, 4 Dec 2023 08:47:24 +0000 Subject: [PATCH 12/57] Fix the urlPattern existence handling. It was flipped by mistake. --- docs/index.bs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 05e1eeeb..b234ac53 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3242,7 +3242,7 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ : Output :: a boolean - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exist=], then: + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] [=map/exists=], then: 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. 1. If |pattern| [=URLPattern/has regexp groups=], then return false. @@ -3251,8 +3251,6 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ 1. Return true. - Note: support for other conditions will be implemented here. - 1. Return false. @@ -3272,8 +3270,6 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/ 1. If running [=urlpattern/match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. 1. Return |rule|'s {{RouterRule/source}}. - Note: support for other conditions will be implemented here. - 1. Return null. From 4639e6c06d0fd8bc855737df4da7bee18becf736 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Mon, 4 Dec 2023 09:00:04 +0000 Subject: [PATCH 13/57] Remove the "spec: urlpattern; ..." line. --- docs/index.bs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index b234ac53..1692ad5c 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -51,6 +51,7 @@ spec: webidl; text: resolve; spec:csp-next; type:dfn; text:enforced +spec:urlpattern; type:dfn; text:match
@@ -132,11 +133,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
         text: storage key; url: storage-key
         text: obtain a storage key; url: obtain-a-storage-key
         text: storage key/equals; url: storage-key-equals
-
-spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/
-    type: dfn
-        text: match; for: urlpattern; url: match
-
 
@@ -3267,7 +3263,7 @@ spec: urlpattern; urlPrefix: https://wicg.github.io/urlpattern/
           1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] [=map/exists=], then:
               1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"].
               1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|.
-              1. If running [=urlpattern/match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=].
+              1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=].
               1. Return |rule|'s {{RouterRule/source}}.
 
       1. Return null.

From f4f57ececba28fab79073ca42bd7ee775d2016d3 Mon Sep 17 00:00:00 2001
From: Yoshisato Yanagisawa 
Date: Mon, 4 Dec 2023 09:05:39 +0000
Subject: [PATCH 14/57] Simplified the if statement on urlPattern condition
 does not exist.

---
 docs/index.bs | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/docs/index.bs b/docs/index.bs
index 1692ad5c..8841853f 100644
--- a/docs/index.bs
+++ b/docs/index.bs
@@ -3238,16 +3238,14 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
       : Output
       :: a boolean
 
-      1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] [=map/exists=], then:
-          1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"].
-          1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false.
-          1. If |pattern| [=URLPattern/has regexp groups=], then return false.
-
-              Note: Since running a user-defined regular expression has a security concern, it is prohibited.
+      1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exiss=], Return false.
+      1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"].
+      1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false.
+      1. If |pattern| [=URLPattern/has regexp groups=], then return false.
 
-          1. Return true.
+          Note: Since running a user-defined regular expression has a security concern, it is prohibited.
 
-      1. Return false.
+      1. Return true.
   
 
   
@@ -3259,12 +3257,11 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ :: {{RouterSource}} or null 1. [=list/For each=] |rule| of |serviceWorker|'s [=service worker/list of router rules=]: - 1. If |rule|["{{RouterRule/condition}}"] does not [=map/exist=], continue. - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] [=map/exists=], then: - 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. - 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. - 1. Return |rule|'s {{RouterRule/source}}. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exist=], continue. + 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. + 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. + 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. + 1. Return |rule|'s {{RouterRule/source}}. 1. Return null.
From 0d4ed51ef4e95c4361f84e7e962f968df52ceac7 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Mon, 4 Dec 2023 09:06:47 +0000 Subject: [PATCH 15/57] Fix typo. --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 8841853f..c166754e 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3238,7 +3238,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ : Output :: a boolean - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exiss=], Return false. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exist=], Return false. 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. 1. If |pattern| [=URLPattern/has regexp groups=], then return false. From dd0590bbcb968784fe462e4b2e9f6cffbc35b870 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 6 Dec 2023 07:19:53 +0000 Subject: [PATCH 16/57] Merged the simple fixes. --- docs/index.bs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index c166754e..d8968f43 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3238,7 +3238,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ : Output :: a boolean - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exist=], Return false. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exist=], return false. 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. 1. If |pattern| [=URLPattern/has regexp groups=], then return false. @@ -3261,7 +3261,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. - 1. Return |rule|'s {{RouterRule/source}}. + 1. Return |rule|["{{RouterRule/source}}"]. 1. Return null. From 8bfef6fc8ad1260cb63f33ddd8faa4df6e236986 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 6 Dec 2023 07:21:04 +0000 Subject: [PATCH 17/57] siple fix. --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index d8968f43..f0233398 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3108,7 +3108,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |request|'s [=request/destination=] is either "embed" or "object", then: 1. Return null. 1. Else if |registration|'s active worker's [=service worker/list of router rules=] is set: - 1. If running [=GetRouterSource=] algorithm with active worker and |request| returns "network", return null. + 1. If running [=GetRouterSource=] with |registration|'s active worker and |request| returns "network", return null. 1. Else if |request| is a non-subresource request, then: 1. If |reservedClient| is not null and is an environment settings object, then: 1. If |reservedClient| is not a secure context, return null. From 0909c9c35cd55c962cad553b3185d63b87668a09 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 6 Dec 2023 07:25:53 +0000 Subject: [PATCH 18/57] Rename algorithm names to align with other algorithm names. --- docs/index.bs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index f0233398..2e3f3940 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1578,7 +1578,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |routerRules| be a list of {{RouterRule}} dictionaries. 1. If |rules| is a {{RouterRule}} dictionary, set |rules| to « |rules| ». 1. For each |rule| of |rules|: - 1. If running [=VerifyRouterRule=] algorithm with |rule| and [=/service worker=] returns false, throw a TypeError. + 1. If running [=Verify Router Rule=] algorithm with |rule| and [=/service worker=] returns false, throw a TypeError. 1. Append |rule| to |routerRules|. 1. Set [=/service worker=]'s [=service worker/list of router rules=] to |routerRules|. @@ -3108,7 +3108,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |request|'s [=request/destination=] is either "embed" or "object", then: 1. Return null. 1. Else if |registration|'s active worker's [=service worker/list of router rules=] is set: - 1. If running [=GetRouterSource=] with |registration|'s active worker and |request| returns "network", return null. + 1. If running [=Get Router Source=] with |registration|'s active worker and |request| returns "network", return null. 1. Else if |request| is a non-subresource request, then: 1. If |reservedClient| is not null and is an environment settings object, then: 1. If |reservedClient| is not a secure context, return null. @@ -3218,7 +3218,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
-

ParseURLPattern

+

Parse URL Pattern

: Input :: |rawPattern|, a [=string=] :: |serviceWorker|, a [=/service worker=] @@ -3230,7 +3230,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
-

VerifyRouterRule

+

Verify Router Rule

: Input :: |rule|, a {{RouterRule}} @@ -3240,7 +3240,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exist=], return false. 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. + 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. 1. If |pattern| [=URLPattern/has regexp groups=], then return false. Note: Since running a user-defined regular expression has a security concern, it is prohibited. @@ -3249,7 +3249,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
-

GetRouterSource

+

Get Router Source

: Input :: |serviceWorker|, a [=/service worker=] :: |request|, a [=/request=] @@ -3259,7 +3259,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. [=list/For each=] |rule| of |serviceWorker|'s [=service worker/list of router rules=]: 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exist=], continue. 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of running ParseURLPattern algorithm passing |rawPattern| and |serviceWorker|. + 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. 1. Return |rule|["{{RouterRule/source}}"]. From 2fd1936291f778aadb95a78e43b777334841cfc6 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 6 Dec 2023 07:46:00 +0000 Subject: [PATCH 19/57] Make which service worker to use clear. --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 2e3f3940..4c3eb91b 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1580,7 +1580,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. For each |rule| of |rules|: 1. If running [=Verify Router Rule=] algorithm with |rule| and [=/service worker=] returns false, throw a TypeError. 1. Append |rule| to |routerRules|. - 1. Set [=/service worker=]'s [=service worker/list of router rules=] to |routerRules|. + 1. Set the [=current global object=]'s associated [=ServiceWorkerGlobalScope/service worker=]'s [=service worker/list of router rules=] to |routerRules|.
From bef58577b17fcd712e8b88aa3b4ce940b0392ccc Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 6 Dec 2023 07:50:37 +0000 Subject: [PATCH 20/57] Put algorithm after the algorithm. --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 4c3eb91b..257e0f0f 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3108,7 +3108,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |request|'s [=request/destination=] is either "embed" or "object", then: 1. Return null. 1. Else if |registration|'s active worker's [=service worker/list of router rules=] is set: - 1. If running [=Get Router Source=] with |registration|'s active worker and |request| returns "network", return null. + 1. If running [=Get Router Source=] algorithm with |registration|'s active worker and |request| returns "network", return null. 1. Else if |request| is a non-subresource request, then: 1. If |reservedClient| is not null and is an environment settings object, then: 1. If |reservedClient| is not a secure context, return null. From 1d8cf97e0505783f191f7c1c1db677376c8b38f7 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 6 Dec 2023 09:36:35 +0000 Subject: [PATCH 21/57] Fixed typo. --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 257e0f0f..4dfe6089 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3226,7 +3226,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ :: {{URLPattern}} 1. Let |baseURL| be |serviceWorker|'s [=service worker/script url=]. - 1. Return the result of [=building a URLPattern from a WebIDL value=] |rawPattern| given |baseURL| and |serviceWorker|'s [=service worker/global object=]'s [=relevant realm=]. + 1. Return the result of [=building a URLPattern from a Web IDL value=] |rawPattern| given |baseURL| and |serviceWorker|'s [=service worker/global object=]'s [=relevant realm=].
From acdd79da3deb2a8c640fa0b4ae0bcd2dc0175ead Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 6 Dec 2023 09:42:07 +0000 Subject: [PATCH 22/57] Fix "Parse URL Pattern" argument. --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 4dfe6089..1f749e41 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3220,7 +3220,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/

Parse URL Pattern

: Input - :: |rawPattern|, a [=string=] + :: |rawPattern|, a {{URLPatternCompatible}} :: |serviceWorker|, a [=/service worker=] : Output :: {{URLPattern}} From f6472073f1f2865d1c78a8f66f92e3efe1a7c125 Mon Sep 17 00:00:00 2001 From: Takashi Nakayama Date: Mon, 11 Dec 2023 06:55:43 +0000 Subject: [PATCH 23/57] Add 'fetch-event' source --- docs/index.bs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 1f749e41..7a5f7c7c 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1565,7 +1565,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ URLPatternCompatible urlPattern; }; - enum RouterSource { "network" }; + enum RouterSource { "fetch-event", "network" };
@@ -2875,6 +2875,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Wait for |task| to have executed or been discarded. 1. Wait for the step labeled *WaitForAsynchronousExtensions* to complete. + 1. If |installingWorker|'s [=list of router rules=] contains "fetch-event" and [=set of event types to handle=] does not contain "fetch-event", then set |installFailed| to true. 1. If |installFailed| is true, then: 1. Run the Update Worker State algorithm passing |registration|'s [=installing worker=] and "`redundant`" as the arguments. 1. Run the Update Registration State algorithm passing |registration|, "installing" and null as the arguments. From df4fe986fc0c0c0876f415e91595966cf6223286 Mon Sep 17 00:00:00 2001 From: Takashi Nakayama Date: Mon, 11 Dec 2023 07:11:44 +0000 Subject: [PATCH 24/57] Fix "fetch-event" to `fetch` --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 7a5f7c7c..833a075b 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -2875,7 +2875,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Wait for |task| to have executed or been discarded. 1. Wait for the step labeled *WaitForAsynchronousExtensions* to complete. - 1. If |installingWorker|'s [=list of router rules=] contains "fetch-event" and [=set of event types to handle=] does not contain "fetch-event", then set |installFailed| to true. + 1. If |installingWorker|'s [=list of router rules=] [=list/contains=] "fetch-event" and [=set of event types to handle=] does not [=set/contain=] fetch, then set |installFailed| to true. 1. If |installFailed| is true, then: 1. Run the Update Worker State algorithm passing |registration|'s [=installing worker=] and "`redundant`" as the arguments. 1. Run the Update Registration State algorithm passing |registration|, "installing" and null as the arguments. From 538c264799941c16036152e77be7c6355aa5396f Mon Sep 17 00:00:00 2001 From: Takashi Nakayama Date: Tue, 12 Dec 2023 05:30:03 +0000 Subject: [PATCH 25/57] fxi references --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 833a075b..7d2782f3 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -2875,7 +2875,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Wait for |task| to have executed or been discarded. 1. Wait for the step labeled *WaitForAsynchronousExtensions* to complete. - 1. If |installingWorker|'s [=list of router rules=] [=list/contains=] "fetch-event" and [=set of event types to handle=] does not [=set/contain=] fetch, then set |installFailed| to true. + 1. If |installingWorker|'s [=list of router rules=] [=list/contains=] a [[RouterRule]] whose {{RouterRule/source}} is "{{RouterSource/fetch-event}}" and |installingWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, then set |installFailed| to true. 1. If |installFailed| is true, then: 1. Run the Update Worker State algorithm passing |registration|'s [=installing worker=] and "`redundant`" as the arguments. 1. Run the Update Registration State algorithm passing |registration|, "installing" and null as the arguments. From be86954fc1d8420cd4fda513a66c87208c4a5785 Mon Sep 17 00:00:00 2001 From: Takashi Nakayama Date: Tue, 12 Dec 2023 07:38:19 +0000 Subject: [PATCH 26/57] minor fix --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 7d2782f3..3719d459 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -2875,7 +2875,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Wait for |task| to have executed or been discarded. 1. Wait for the step labeled *WaitForAsynchronousExtensions* to complete. - 1. If |installingWorker|'s [=list of router rules=] [=list/contains=] a [[RouterRule]] whose {{RouterRule/source}} is "{{RouterSource/fetch-event}}" and |installingWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, then set |installFailed| to true. + 1. If |installingWorker|'s [=list of router rules=] [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSource/fetch-event}}" and |installingWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, then set |installFailed| to true. 1. If |installFailed| is true, then: 1. Run the Update Worker State algorithm passing |registration|'s [=installing worker=] and "`redundant`" as the arguments. 1. Run the Update Registration State algorithm passing |registration|, "installing" and null as the arguments. From 40eaa6981dc7608a7a058f73bf9881d7542dc88a Mon Sep 17 00:00:00 2001 From: Takashi Nakayama Date: Wed, 13 Dec 2023 02:11:16 +0000 Subject: [PATCH 27/57] move has-fetch checking to addRoutes --- docs/index.bs | 10 +++++++--- package-lock.json | 27 +++++++++++++++++++++++++++ package.json | 6 ++++++ pnpm-lock.yaml | 26 ++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 pnpm-lock.yaml diff --git a/docs/index.bs b/docs/index.bs index 3719d459..c490d23b 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1576,11 +1576,16 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ The addRoutes(|rules|) method steps are: 1. Let |routerRules| be a list of {{RouterRule}} dictionaries. + 1. Let |hasFetch| be a boolean, initially false. + 1. Let |serviceWorker| be the [=current global object=]'s associated [=ServiceWorkerGlobalScope/service worker=]. + 1. If |serviceWorker|'s [=list of router rules=] [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSource/fetch-event}}", set |hasFetch| to true. 1. If |rules| is a {{RouterRule}} dictionary, set |rules| to « |rules| ». 1. For each |rule| of |rules|: - 1. If running [=Verify Router Rule=] algorithm with |rule| and [=/service worker=] returns false, throw a TypeError. + 1. If running [=Verify Router Rule=] algorithm with |rule| and [=/service worker=] returns false, [=throw=] a {{TypeError}}. + 1. If |rule|'s {{RouterRule/source}} is "{{RouterSource/fetch-event}}", set |hasFetch| to true. 1. Append |rule| to |routerRules|. - 1. Set the [=current global object=]'s associated [=ServiceWorkerGlobalScope/service worker=]'s [=service worker/list of router rules=] to |routerRules|. + 1. If |hasFetch| is true and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, [=throw=] a {{TypeError}}. + 1. Set |serviceWorker|'s [=service worker/list of router rules=] to |routerRules|.
@@ -2875,7 +2880,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Wait for |task| to have executed or been discarded. 1. Wait for the step labeled *WaitForAsynchronousExtensions* to complete. - 1. If |installingWorker|'s [=list of router rules=] [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSource/fetch-event}}" and |installingWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, then set |installFailed| to true. 1. If |installFailed| is true, then: 1. Run the Update Worker State algorithm passing |registration|'s [=installing worker=] and "`redundant`" as the arguments. 1. Run the Update Registration State algorithm passing |registration|, "installing" and null as the arguments. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..323551a2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,27 @@ +{ + "name": "ServiceWorker", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "pnpm": "^8.11.0" + } + }, + "node_modules/pnpm": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/pnpm/-/pnpm-8.11.0.tgz", + "integrity": "sha512-nfh8FsmNsntOBR14fmfyIH7EfoCcywe/e17ErNzRYTNVg5o40LkAFEkj1qcFdwC3TSoMyxVYvrJBZHoSBqmnqw==", + "bin": { + "pnpm": "bin/pnpm.cjs", + "pnpx": "bin/pnpx.cjs" + }, + "engines": { + "node": ">=16.14" + }, + "funding": { + "url": "https://opencollective.com/pnpm" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..580e1b71 --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "pnpm": "^8.11.0", + "vnu-jar": "^23.4.11" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..0fbdaf05 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,26 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + pnpm: + specifier: ^8.11.0 + version: 8.11.0 + vnu-jar: + specifier: ^23.4.11 + version: 23.4.11 + +packages: + + /pnpm@8.11.0: + resolution: {integrity: sha512-nfh8FsmNsntOBR14fmfyIH7EfoCcywe/e17ErNzRYTNVg5o40LkAFEkj1qcFdwC3TSoMyxVYvrJBZHoSBqmnqw==} + engines: {node: '>=16.14'} + hasBin: true + dev: false + + /vnu-jar@23.4.11: + resolution: {integrity: sha512-lI5dzBYXtxhilNI7EeQ5iUduYnNBq7YWx4UjfBVLXfBQHnXYZSf3y3bpM0bSyDU6jy/+OyKV7nw4tzpR5lXSZg==} + engines: {node: '>=0.10'} + dev: false From c0033b2c9fda261f1478715282275504dd5a3955 Mon Sep 17 00:00:00 2001 From: Takashi Nakayama Date: Wed, 13 Dec 2023 05:22:59 +0000 Subject: [PATCH 28/57] delete redundant files --- package-lock.json | 27 --------------------------- package.json | 6 ------ pnpm-lock.yaml | 26 -------------------------- 3 files changed, 59 deletions(-) delete mode 100644 package-lock.json delete mode 100644 package.json delete mode 100644 pnpm-lock.yaml diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 323551a2..00000000 --- a/package-lock.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "ServiceWorker", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "pnpm": "^8.11.0" - } - }, - "node_modules/pnpm": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/pnpm/-/pnpm-8.11.0.tgz", - "integrity": "sha512-nfh8FsmNsntOBR14fmfyIH7EfoCcywe/e17ErNzRYTNVg5o40LkAFEkj1qcFdwC3TSoMyxVYvrJBZHoSBqmnqw==", - "bin": { - "pnpm": "bin/pnpm.cjs", - "pnpx": "bin/pnpx.cjs" - }, - "engines": { - "node": ">=16.14" - }, - "funding": { - "url": "https://opencollective.com/pnpm" - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 580e1b71..00000000 --- a/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dependencies": { - "pnpm": "^8.11.0", - "vnu-jar": "^23.4.11" - } -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 0fbdaf05..00000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,26 +0,0 @@ -lockfileVersion: '6.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -dependencies: - pnpm: - specifier: ^8.11.0 - version: 8.11.0 - vnu-jar: - specifier: ^23.4.11 - version: 23.4.11 - -packages: - - /pnpm@8.11.0: - resolution: {integrity: sha512-nfh8FsmNsntOBR14fmfyIH7EfoCcywe/e17ErNzRYTNVg5o40LkAFEkj1qcFdwC3TSoMyxVYvrJBZHoSBqmnqw==} - engines: {node: '>=16.14'} - hasBin: true - dev: false - - /vnu-jar@23.4.11: - resolution: {integrity: sha512-lI5dzBYXtxhilNI7EeQ5iUduYnNBq7YWx4UjfBVLXfBQHnXYZSf3y3bpM0bSyDU6jy/+OyKV7nw4tzpR5lXSZg==} - engines: {node: '>=0.10'} - dev: false From d3bad313548d084ea59fd65e5f8a678bcd8273c8 Mon Sep 17 00:00:00 2001 From: Takashi Nakayama Date: Wed, 13 Dec 2023 05:25:57 +0000 Subject: [PATCH 29/57] Rename hasFetch to hasFetchEventSource --- docs/index.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index c490d23b..110c191d 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1576,15 +1576,15 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ The addRoutes(|rules|) method steps are: 1. Let |routerRules| be a list of {{RouterRule}} dictionaries. - 1. Let |hasFetch| be a boolean, initially false. + 1. Let |hasFetchEventSource| be a boolean, initially false. 1. Let |serviceWorker| be the [=current global object=]'s associated [=ServiceWorkerGlobalScope/service worker=]. - 1. If |serviceWorker|'s [=list of router rules=] [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSource/fetch-event}}", set |hasFetch| to true. + 1. If |serviceWorker|'s [=list of router rules=] [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSource/fetch-event}}", set |hasFetchEventSource| to true. 1. If |rules| is a {{RouterRule}} dictionary, set |rules| to « |rules| ». 1. For each |rule| of |rules|: 1. If running [=Verify Router Rule=] algorithm with |rule| and [=/service worker=] returns false, [=throw=] a {{TypeError}}. - 1. If |rule|'s {{RouterRule/source}} is "{{RouterSource/fetch-event}}", set |hasFetch| to true. + 1. If |rule|'s {{RouterRule/source}} is "{{RouterSource/fetch-event}}", set |hasFetchEventSource| to true. 1. Append |rule| to |routerRules|. - 1. If |hasFetch| is true and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, [=throw=] a {{TypeError}}. + 1. If |hasFetchEventSource| is true and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, [=throw=] a {{TypeError}}. 1. Set |serviceWorker|'s [=service worker/list of router rules=] to |routerRules|. From 46a5f2e1c22730e6fe6c3632239614b66fbd8d39 Mon Sep 17 00:00:00 2001 From: Takashi Nakayama Date: Thu, 14 Dec 2023 01:53:08 +0000 Subject: [PATCH 30/57] Fix |routerRules| handling --- docs/index.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 110c191d..4a8d33fd 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1575,13 +1575,13 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ The addRoutes(|rules|) method steps are: - 1. Let |routerRules| be a list of {{RouterRule}} dictionaries. - 1. Let |hasFetchEventSource| be a boolean, initially false. 1. Let |serviceWorker| be the [=current global object=]'s associated [=ServiceWorkerGlobalScope/service worker=]. + 1. Let |routerRules| be a copy of |serviceWorker|'s [=list of router rules=]. + 1. Let |hasFetchEventSource| be a boolean, initially false. 1. If |serviceWorker|'s [=list of router rules=] [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSource/fetch-event}}", set |hasFetchEventSource| to true. 1. If |rules| is a {{RouterRule}} dictionary, set |rules| to « |rules| ». 1. For each |rule| of |rules|: - 1. If running [=Verify Router Rule=] algorithm with |rule| and [=/service worker=] returns false, [=throw=] a {{TypeError}}. + 1. If running [=Verify Router Rule=] algorithm with |rule| and |serviceWorker| returns false, [=throw=] a {{TypeError}}. 1. If |rule|'s {{RouterRule/source}} is "{{RouterSource/fetch-event}}", set |hasFetchEventSource| to true. 1. Append |rule| to |routerRules|. 1. If |hasFetchEventSource| is true and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, [=throw=] a {{TypeError}}. From e99b3573af53e7ca6bf20104797898e3391070e9 Mon Sep 17 00:00:00 2001 From: Takashi Nakayama Date: Fri, 15 Dec 2023 02:24:29 +0000 Subject: [PATCH 31/57] remove |hasFetchEventSource| --- docs/index.bs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 4a8d33fd..19f5e110 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1577,14 +1577,11 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |serviceWorker| be the [=current global object=]'s associated [=ServiceWorkerGlobalScope/service worker=]. 1. Let |routerRules| be a copy of |serviceWorker|'s [=list of router rules=]. - 1. Let |hasFetchEventSource| be a boolean, initially false. - 1. If |serviceWorker|'s [=list of router rules=] [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSource/fetch-event}}", set |hasFetchEventSource| to true. 1. If |rules| is a {{RouterRule}} dictionary, set |rules| to « |rules| ». 1. For each |rule| of |rules|: 1. If running [=Verify Router Rule=] algorithm with |rule| and |serviceWorker| returns false, [=throw=] a {{TypeError}}. - 1. If |rule|'s {{RouterRule/source}} is "{{RouterSource/fetch-event}}", set |hasFetchEventSource| to true. 1. Append |rule| to |routerRules|. - 1. If |hasFetchEventSource| is true and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, [=throw=] a {{TypeError}}. + 1. If |routerRules| [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSource/fetch-event}}" and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, [=throw=] a {{TypeError}}. 1. Set |serviceWorker|'s [=service worker/list of router rules=] to |routerRules|. From f51a2243cc4f7d68df7bf4a15e688364f35b4e82 Mon Sep 17 00:00:00 2001 From: Takashi Nakayama Date: Fri, 15 Dec 2023 02:43:23 +0000 Subject: [PATCH 32/57] fix router rule initialization --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 19f5e110..ba95fed2 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -207,7 +207,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ A [=/service worker=] has an associated all fetch listeners are empty flag. It is initially unset. - A [=/service worker=] has an associated list of router rules. It is initially unset. + A [=/service worker=] has an associated list of router rules. It is initially an empty [=list=]. A [=/service worker=] is said to be running if its [=event loop=] is running. From a44f9a4769472a757b4412907cf3844c29d7abe2 Mon Sep 17 00:00:00 2001 From: Takashi Nakayama Date: Fri, 15 Dec 2023 05:10:09 +0000 Subject: [PATCH 33/57] Update "Handle Fetch" algorithm --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index ba95fed2..4cd800e5 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3109,7 +3109,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Assert: |request|'s [=request/destination=] is not "serviceworker". 1. If |request|'s [=request/destination=] is either "embed" or "object", then: 1. Return null. - 1. Else if |registration|'s active worker's [=service worker/list of router rules=] is set: + 1. Else if |registration|'s active worker's [=service worker/list of router rules=] is [=list/is not empty=]: 1. If running [=Get Router Source=] algorithm with |registration|'s active worker and |request| returns "network", return null. 1. Else if |request| is a non-subresource request, then: 1. If |reservedClient| is not null and is an environment settings object, then: From 7b4f2d8c64b9353104576d6a1853b8229337f053 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Tue, 16 Jan 2024 06:37:33 +0000 Subject: [PATCH 34/57] Add runningStatus condition support. --- docs/index.bs | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 4cd800e5..bf4fd3c2 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1563,8 +1563,10 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ dictionary RouterCondition { URLPatternCompatible urlPattern; + RunningStatus runningStatus; }; + enum RunningStatus { "running", "not-running" }; enum RouterSource { "fetch-event", "network" }; @@ -3240,14 +3242,19 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ : Output :: a boolean - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exist=], return false. - 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. - 1. If |pattern| [=URLPattern/has regexp groups=], then return false. + 1. Let |hasCondition| be false. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] [=map/exists=], then: + 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. + 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. + 1. If |pattern| [=URLPattern/has regexp groups=], then return false. - Note: Since running a user-defined regular expression has a security concern, it is prohibited. + Note: Since running a user-defined regular expression has a security concern, it is prohibited. - 1. Return true. + 1. Set |hasCondition| to true. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] [=map/exists=], then: + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] is neither of {{RunningStatus/"running"}} nor {{RunningStatus/"not-running"}}, return false. + 1. Set |hasCondition| to true. + 1. Return |hasCondition|.
@@ -3259,10 +3266,14 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ :: {{RouterSource}} or null 1. [=list/For each=] |rule| of |serviceWorker|'s [=service worker/list of router rules=]: - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] does not [=map/exist=], continue. - 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. - 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] [=map/exists=], then: + 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. + 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. + 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] [=map/exists=], then: + 1. Let |runningStatus| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"]. + 1. If |runningStatus| is {{RunningStatus/"running"}}, and |serviceWorker| is not [=running=], continue. + 1. If |runningStatus| is {{RunningStatus/"not-running"}}, and |serviceWorker| is [=running=], continue. 1. Return |rule|["{{RouterRule/source}}"]. 1. Return null. From f9df489b66f89d11dc27679f7a040d74310e749f Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Tue, 16 Jan 2024 09:21:02 +0000 Subject: [PATCH 35/57] Addressed comments. - added a note on multiple conditions. - changed continue to [=continue=]. --- docs/index.bs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index bf4fd3c2..cbbd6866 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3266,14 +3266,17 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ :: {{RouterSource}} or null 1. [=list/For each=] |rule| of |serviceWorker|'s [=service worker/list of router rules=]: + + Note: if there are multiple conditions in a rule, all conditions should be matched to return the source. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] [=map/exists=], then: 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] [=map/exists=], then: 1. Let |runningStatus| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"]. - 1. If |runningStatus| is {{RunningStatus/"running"}}, and |serviceWorker| is not [=running=], continue. - 1. If |runningStatus| is {{RunningStatus/"not-running"}}, and |serviceWorker| is [=running=], continue. + 1. If |runningStatus| is {{RunningStatus/"running"}}, and |serviceWorker| is not [=running=], [=continue=]. + 1. If |runningStatus| is {{RunningStatus/"not-running"}}, and |serviceWorker| is [=running=], [=continue=]. 1. Return |rule|["{{RouterRule/source}}"]. 1. Return null. From 9709650dfb2bc99650b08a1fc157c770a5da0300 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Thu, 18 Jan 2024 02:35:58 +0000 Subject: [PATCH 36/57] Addressed comment. - remove checking if runningStatus is one of RunningStatus. - use "will" instead of "should". --- docs/index.bs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index cbbd6866..44cd5f47 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3251,9 +3251,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ Note: Since running a user-defined regular expression has a security concern, it is prohibited. 1. Set |hasCondition| to true. - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] [=map/exists=], then: - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] is neither of {{RunningStatus/"running"}} nor {{RunningStatus/"not-running"}}, return false. - 1. Set |hasCondition| to true. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] [=map/exists=], set |hasCondition| to true. 1. Return |hasCondition|.
@@ -3267,7 +3265,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. [=list/For each=] |rule| of |serviceWorker|'s [=service worker/list of router rules=]: - Note: if there are multiple conditions in a rule, all conditions should be matched to return the source. + Note: if there are multiple conditions in a rule, all conditions will be matched to return the source. 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] [=map/exists=], then: 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. From 768861ba07f7b406c6c869656a3a10dfdce6c181 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Fri, 19 Jan 2024 10:49:41 +0000 Subject: [PATCH 37/57] Add request{Method,Mode,Destination} support. --- docs/index.bs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/index.bs b/docs/index.bs index 44cd5f47..cef7f031 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1563,6 +1563,9 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ dictionary RouterCondition { URLPatternCompatible urlPattern; + USVString requestMethod; + RequestMode requestMode; + RequestDestination requestDestination; RunningStatus runningStatus; }; @@ -3251,6 +3254,9 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ Note: Since running a user-defined regular expression has a security concern, it is prohibited. 1. Set |hasCondition| to true. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMethod}}"] [=map/exists=], set |hasCondition| to true. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMode}}"] [=map/exists=], set |hasCondition| to true. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestDestination}}"] [=map/exists=], set |hasCondition| to true. 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] [=map/exists=], set |hasCondition| to true. 1. Return |hasCondition|. @@ -3271,6 +3277,15 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMethod}}"] [=map/exists=], then: + 1. Let |method| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMethod}}"]. + 1. If |request|'s [=request/method] is not |method|, [=continue=] + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMode}}"] [=map/exists=], then: + 1. Let |mode| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMode}}"]. + 1. If |request|'s [=request/mode] is not |mode|, [=continue=] + 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestDestination}}"] [=map/exists=], then: + 1. Let |destination| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestDestination}}"]. + 1. If |request|'s [=request/destination] is not |destination|, [=continue=] 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] [=map/exists=], then: 1. Let |runningStatus| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"]. 1. If |runningStatus| is {{RunningStatus/"running"}}, and |serviceWorker| is not [=running=], [=continue=]. From 0c966f75468fbd18eb202b923a38972efa3073cb Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Fri, 19 Jan 2024 10:52:12 +0000 Subject: [PATCH 38/57] Add "." at the end of lines. --- docs/index.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index cef7f031..cac955bd 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3279,13 +3279,13 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMethod}}"] [=map/exists=], then: 1. Let |method| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMethod}}"]. - 1. If |request|'s [=request/method] is not |method|, [=continue=] + 1. If |request|'s [=request/method] is not |method|, [=continue=]. 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMode}}"] [=map/exists=], then: 1. Let |mode| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMode}}"]. - 1. If |request|'s [=request/mode] is not |mode|, [=continue=] + 1. If |request|'s [=request/mode] is not |mode|, [=continue=]. 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestDestination}}"] [=map/exists=], then: 1. Let |destination| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestDestination}}"]. - 1. If |request|'s [=request/destination] is not |destination|, [=continue=] + 1. If |request|'s [=request/destination] is not |destination|, [=continue=]. 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] [=map/exists=], then: 1. Let |runningStatus| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"]. 1. If |runningStatus| is {{RunningStatus/"running"}}, and |serviceWorker| is not [=running=], [=continue=]. From 9c57f5fba0f3cc19cb8e10ef6aa68f057cacd523 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Mon, 22 Jan 2024 10:25:00 +0000 Subject: [PATCH 39/57] Address comments. - Use ByteString instead USVString for requestMethod. - typos on forgetting "=" in closing "=]". --- docs/index.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index cac955bd..3aad4e06 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1563,7 +1563,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ dictionary RouterCondition { URLPatternCompatible urlPattern; - USVString requestMethod; + ByteString requestMethod; RequestMode requestMode; RequestDestination requestDestination; RunningStatus runningStatus; @@ -3279,13 +3279,13 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMethod}}"] [=map/exists=], then: 1. Let |method| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMethod}}"]. - 1. If |request|'s [=request/method] is not |method|, [=continue=]. + 1. If |request|'s [=request/method=] is not |method|, [=continue=]. 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMode}}"] [=map/exists=], then: 1. Let |mode| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMode}}"]. - 1. If |request|'s [=request/mode] is not |mode|, [=continue=]. + 1. If |request|'s [=request/mode=] is not |mode|, [=continue=]. 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestDestination}}"] [=map/exists=], then: 1. Let |destination| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestDestination}}"]. - 1. If |request|'s [=request/destination] is not |destination|, [=continue=]. + 1. If |request|'s [=request/destination=] is not |destination|, [=continue=]. 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] [=map/exists=], then: 1. Let |runningStatus| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"]. 1. If |runningStatus| is {{RunningStatus/"running"}}, and |serviceWorker| is not [=running=], [=continue=]. From ca833a44d07076670c6b3b88f67d54b01208defa Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 24 Jan 2024 09:29:42 +0000 Subject: [PATCH 40/57] Add or condition support. --- docs/index.bs | 89 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 3aad4e06..85c05875 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1567,6 +1567,8 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ RequestMode requestMode; RequestDestination requestDestination; RunningStatus runningStatus; + + sequence<RouterCondition> _or; }; enum RunningStatus { "running", "not-running" }; @@ -1584,7 +1586,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |routerRules| be a copy of |serviceWorker|'s [=list of router rules=]. 1. If |rules| is a {{RouterRule}} dictionary, set |rules| to « |rules| ». 1. For each |rule| of |rules|: - 1. If running [=Verify Router Rule=] algorithm with |rule| and |serviceWorker| returns false, [=throw=] a {{TypeError}}. + 1. If running [=Verify Router Condition=] algorithm with |rule|["{{RouterRule/condition}}"] and |serviceWorker| returns false, [=throw=] a {{TypeError}}. 1. Append |rule| to |routerRules|. 1. If |routerRules| [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSource/fetch-event}}" and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, [=throw=] a {{TypeError}}. 1. Set |serviceWorker|'s [=service worker/list of router rules=] to |routerRules|. @@ -3237,30 +3239,78 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
-

Verify Router Rule

+

Verify Router Condition

: Input - :: |rule|, a {{RouterRule}} + :: |condition|, a {{RouterCondition}} :: |serviceWorker|, a [=/service worker=] : Output :: a boolean 1. Let |hasCondition| be false. - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] [=map/exists=], then: - 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. + 1. If |condition|["{{RouterCondition/urlPattern}}"] [=map/exists=], then: + 1. Let |rawPattern| be |condition|["{{RouterCondition/urlPattern}}"]. 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. 1. If |pattern| [=URLPattern/has regexp groups=], then return false. Note: Since running a user-defined regular expression has a security concern, it is prohibited. 1. Set |hasCondition| to true. - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMethod}}"] [=map/exists=], set |hasCondition| to true. - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMode}}"] [=map/exists=], set |hasCondition| to true. - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestDestination}}"] [=map/exists=], set |hasCondition| to true. - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] [=map/exists=], set |hasCondition| to true. + 1. If |condition|["{{RouterCondition/requestMethod}}"] [=map/exists=], set |hasCondition| to true. + 1. If |condition|["{{RouterCondition/requestMode}}"] [=map/exists=], set |hasCondition| to true. + 1. If |condition|["{{RouterCondition/requestDestination}}"] [=map/exists=], set |hasCondition| to true. + 1. If |condition|["{{RouterCondition/runningStatus}}"] [=map/exists=], set |hasCondition| to true. + 1. If |condition|["{{RouterCondition/_or}}"] [=map/exists=], then: + 1. If |hasCondition| is true, return false. + + Note: For ease of understanding the router rule, the "or" condition is mutual exclusive with other conditions. + + 1. Let |or conditions| be |condition|["{{RouterCondition/_or}}"]. + 1. For each |or condition| of |or conditions|: + 1. If running [=Verify Router Condition=] algorithm with |or condition| and |serviceWorker| returns false, return false. + 1. Set |hasCondition| to true. 1. Return |hasCondition|.
+
+

Match Router Condition

+ : Input + :: |condition|, a {{RouterCondition}} + :: |serviceWorker|, a [=/service worker=] + :: |request|, a [=/request=] + : Output + :: a boolean + + Note: if there are multiple conditions, all conditions will be matched to return the source. + + 1. If |condition|["{{RouterCondition/urlPattern}}"] [=map/exists=], then: + 1. Let |rawPattern| be |condition|["{{RouterCondition/urlPattern}}"]. + 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. + 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, return false. + 1. If |condition|["{{RouterCondition/requestMethod}}"] [=map/exists=], then: + 1. Let |method| be |condition|["{{RouterCondition/requestMethod}}"]. + 1. If |request|'s [=request/method=] is not |method|, return false. + 1. If |condition|["{{RouterCondition/requestMode}}"] [=map/exists=], then: + 1. Let |mode| be |condition|["{{RouterCondition/requestMode}}"]. + 1. If |request|'s [=request/mode=] is not |mode|, return false. + 1. If |condition|["{{RouterCondition/requestDestination}}"] [=map/exists=], then: + 1. Let |destination| be |condition|["{{RouterCondition/requestDestination}}"]. + 1. If |request|'s [=request/destination=] is not |destination|, return false. + 1. If |condition|["{{RouterCondition/runningStatus}}"] [=map/exists=], then: + 1. Let |runningStatus| be |condition|["{{RouterCondition/runningStatus}}"]. + 1. If |runningStatus| is {{RunningStatus/"running"}}, and |serviceWorker| is not [=running=], return false. + 1. If |runningStatus| is {{RunningStatus/"not-running"}}, and |serviceWorker| is [=running=], return false. + 1. If |condition|["{{RouterCondition/_or}}"] [=map/exists=], then: + 1. Let |or conditions| be |condition|["{{RouterCondition/_or}}"]. + 1. Let |or condition matched| be false. + 1. For each |or condition| of |or conditions|: + 1. If running [=Match Router Condition=] algorithm with |or condition|, |serviceWorker| and |request| returns true: + 1. Set |or condition matched| to true. + 1. [=break=]. + 1. If |or condition matched| is false, return false. + 1. Return true. +
+

Get Router Source

: Input @@ -3270,26 +3320,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ :: {{RouterSource}} or null 1. [=list/For each=] |rule| of |serviceWorker|'s [=service worker/list of router rules=]: - - Note: if there are multiple conditions in a rule, all conditions will be matched to return the source. - - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"] [=map/exists=], then: - 1. Let |rawPattern| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. - 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, [=continue=]. - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMethod}}"] [=map/exists=], then: - 1. Let |method| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMethod}}"]. - 1. If |request|'s [=request/method=] is not |method|, [=continue=]. - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMode}}"] [=map/exists=], then: - 1. Let |mode| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestMode}}"]. - 1. If |request|'s [=request/mode=] is not |mode|, [=continue=]. - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestDestination}}"] [=map/exists=], then: - 1. Let |destination| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/requestDestination}}"]. - 1. If |request|'s [=request/destination=] is not |destination|, [=continue=]. - 1. If |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"] [=map/exists=], then: - 1. Let |runningStatus| be |rule|["{{RouterRule/condition}}"]["{{RouterCondition/runningStatus}}"]. - 1. If |runningStatus| is {{RunningStatus/"running"}}, and |serviceWorker| is not [=running=], [=continue=]. - 1. If |runningStatus| is {{RunningStatus/"not-running"}}, and |serviceWorker| is [=running=], [=continue=]. + 1. If running [=Match Router Condition=] with |rule|["{{RouterRule/condition}}"], |serviceWorker| and |request| returns false, [=continue=]. 1. Return |rule|["{{RouterRule/source}}"]. 1. Return null. From 42d01eba7cacd95e61fdfc97b562a7fb563f7c3f Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Thu, 25 Jan 2024 06:56:41 +0000 Subject: [PATCH 41/57] Reflect comments. - mutual to mutually. - |or condition| or |or conditions| to |orCondition| or |orConditions|. - simplify the for loop upon WICG/service-worker-static-routing-api#9. --- docs/index.bs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 85c05875..b82a2769 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3263,11 +3263,11 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |condition|["{{RouterCondition/_or}}"] [=map/exists=], then: 1. If |hasCondition| is true, return false. - Note: For ease of understanding the router rule, the "or" condition is mutual exclusive with other conditions. + Note: For ease of understanding the router rule, the "or" condition is mutually exclusive with other conditions. - 1. Let |or conditions| be |condition|["{{RouterCondition/_or}}"]. - 1. For each |or condition| of |or conditions|: - 1. If running [=Verify Router Condition=] algorithm with |or condition| and |serviceWorker| returns false, return false. + 1. Let |orConditions| be |condition|["{{RouterCondition/_or}}"]. + 1. For each |orCondition| of |orConditions|: + 1. If running [=Verify Router Condition=] algorithm with |orCondition| and |serviceWorker| returns false, return false. 1. Set |hasCondition| to true. 1. Return |hasCondition|.
@@ -3301,13 +3301,10 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |runningStatus| is {{RunningStatus/"running"}}, and |serviceWorker| is not [=running=], return false. 1. If |runningStatus| is {{RunningStatus/"not-running"}}, and |serviceWorker| is [=running=], return false. 1. If |condition|["{{RouterCondition/_or}}"] [=map/exists=], then: - 1. Let |or conditions| be |condition|["{{RouterCondition/_or}}"]. - 1. Let |or condition matched| be false. - 1. For each |or condition| of |or conditions|: - 1. If running [=Match Router Condition=] algorithm with |or condition|, |serviceWorker| and |request| returns true: - 1. Set |or condition matched| to true. - 1. [=break=]. - 1. If |or condition matched| is false, return false. + 1. Let |orConditions| be |condition|["{{RouterCondition/_or}}"]. + 1. For each |orCondition| of |orConditions|: + 1. If running [=Match Router Condition=] algorithm with |orCondition|, |serviceWorker| and |request| returns true, then return true. + 1. Return false. 1. Return true. From 2d0d848ce0291bd71b9d2d437e2c148cfe7975bb Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Thu, 25 Jan 2024 07:05:51 +0000 Subject: [PATCH 42/57] Revised note to make it match with the moved location. --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index b82a2769..21b308c1 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3281,7 +3281,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ : Output :: a boolean - Note: if there are multiple conditions, all conditions will be matched to return the source. + Note: if there are multiple conditions (e.g. `urlPattern`, `runningStatus`, and `requestMethod` are set), all conditions will be matched to return true. 1. If |condition|["{{RouterCondition/urlPattern}}"] [=map/exists=], then: 1. Let |rawPattern| be |condition|["{{RouterCondition/urlPattern}}"]. From 8304676120a0df213afa07cf04eb1c3d26edfdc8 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 31 Jan 2024 13:20:55 +0900 Subject: [PATCH 43/57] Add "cache" source support. (#4) * Add "cache" source support. * Use |client| as settingsObject to evaluate COEP. When the ServiceWorker static routing API is used and source other than "fetch-event" is used, results are directly returned without running ServiceWorker. In that case, we use the request's COEP instead of ServiceWorker's COEP. --- docs/index.bs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 21b308c1..50718095 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1572,7 +1572,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ }; enum RunningStatus { "running", "not-running" }; - enum RouterSource { "fetch-event", "network" }; + enum RouterSource { "cache", "fetch-event", "network" };
@@ -3117,7 +3117,16 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |request|'s [=request/destination=] is either "embed" or "object", then: 1. Return null. 1. Else if |registration|'s active worker's [=service worker/list of router rules=] is [=list/is not empty=]: - 1. If running [=Get Router Source=] algorithm with |registration|'s active worker and |request| returns "network", return null. + 1. Let |source| be the result of running [=Get Router Source=] algorithm with |registration|'s active worker and |request|. + 1. If |source| is {{RouterSource/"network"}}, return null. + 1. Else if |source| is {{RouterSource/"cache"}}, then: + 1. Let |requestResponses| be the result of running [=Query Cache=] with |request|. + 1. If |requestResponses| is an empty [=list=], return null. + 1. Else: + 1. Let |requestResponse| be the first element of |requestResponses|. + 1. Let |response| be |requestResponse|'s response. + 1. If |client| is not null, |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |request|'s [=request/origin=], |client|, "", and |response|'s [=filtered response/internal response=] returns blocked, then return null. + 1. Return |response|. 1. Else if |request| is a non-subresource request, then: 1. If |reservedClient| is not null and is an environment settings object, then: 1. If |reservedClient| is not a secure context, return null. From bde360bc67643c294566db5822fd63e78c06ed31 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 31 Jan 2024 15:04:08 +0900 Subject: [PATCH 44/57] Bug fix: Make |registration| has a meaningful value. (#8) * Make |registration| set. In the previous specification, |registration| looks null when the ServiceWorker static routing API is used. Let me fix that by moving the step after configuring the registration. * Remove unnecessary blank line. --- docs/index.bs | 66 +++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 50718095..c0b3f441 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3116,17 +3116,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Assert: |request|'s [=request/destination=] is not "serviceworker". 1. If |request|'s [=request/destination=] is either "embed" or "object", then: 1. Return null. - 1. Else if |registration|'s active worker's [=service worker/list of router rules=] is [=list/is not empty=]: - 1. Let |source| be the result of running [=Get Router Source=] algorithm with |registration|'s active worker and |request|. - 1. If |source| is {{RouterSource/"network"}}, return null. - 1. Else if |source| is {{RouterSource/"cache"}}, then: - 1. Let |requestResponses| be the result of running [=Query Cache=] with |request|. - 1. If |requestResponses| is an empty [=list=], return null. - 1. Else: - 1. Let |requestResponse| be the first element of |requestResponses|. - 1. Let |response| be |requestResponse|'s response. - 1. If |client| is not null, |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |request|'s [=request/origin=], |client|, "", and |response|'s [=filtered response/internal response=] returns blocked, then return null. - 1. Return |response|. 1. Else if |request| is a non-subresource request, then: 1. If |reservedClient| is not null and is an environment settings object, then: 1. If |reservedClient| is not a secure context, return null. @@ -3138,28 +3127,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Set |registration| to the result of running Match Service Worker Registration given |storage key| and |request|'s [=request/url=]. 1. If |registration| is null or |registration|'s active worker is null, return null. 1. If |request|'s [=request/destination=] is not {{RequestDestination/"report"}}, set |reservedClient|'s active service worker to |registration|'s active worker. - 1. If |request| is a [=navigation request=], |registration|'s [=navigation preload enabled flag=] is set, |request|'s [=request/method=] is \`GET\`, |registration|'s [=active worker=]'s [=set of event types to handle=] [=set/contains=] fetch, and |registration|'s [=active worker=]'s [=all fetch listeners are empty flag=] is not set then: - - Note: If the above is true except |registration|'s [=active worker=]'s set of event types to handle **does not** contain fetch, then the user agent may wish to show a console warning, as the developer's intent isn't clear. - - 1. Let |preloadRequest| be the result of [=request/cloning=] the request |request|. - 1. Let |preloadRequestHeaders| be |preloadRequest|'s [=request/header list=]. - 1. Let |preloadResponseObject| be a new {{Response}} object associated with a new {{Headers}} object whose [=guard=] is "`immutable`". - 1. [=header list/Append=] to |preloadRequestHeaders| a new [=header=] whose [=header/name=] is \`Service-Worker-Navigation-Preload\` and [=header/value=] is |registration|'s [=navigation preload header value=]. - 1. Set |preloadRequest|'s [=service-workers mode=] to "`none`". - 1. Let |preloadFetchController| be null. - 1. Run the following substeps [=in parallel=], but [=abort when=] |controller|'s [=fetch controller/state=] is "terminated" or "aborted": - 1. Set |preloadFetchController| to the result of [=Fetch|fetching=] |preloadRequest|. - - To [=fetch/processResponse=] for |navigationPreloadResponse|, run these substeps: - - 1. If |navigationPreloadResponse|'s [=response/type=] is "`error`", reject |preloadResponse| with a `TypeError` and terminate these substeps. - 1. Associate |preloadResponseObject| with |navigationPreloadResponse|. - 1. Resolve |preloadResponse| with |preloadResponseObject|. - 1. [=If aborted=], then: - 1. Let |deserializedError| be the result of [=deserialize a serialized abort reason=] given null and |workerRealm|. - 1. [=fetch controller/Abort=] |preloadFetchController| with |deserializedError|. - 1. Else, resolve |preloadResponse| with undefined. Note: From this point, the [=/service worker client=] starts to use its active service worker's containing service worker registration. @@ -3167,6 +3134,39 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |client|'s active service worker is non-null, set |registration| to |client|'s active service worker's containing service worker registration. 1. Else, return null. 1. Let |activeWorker| be |registration|'s active worker. + 1. If |activeWorker|'s [=service worker/list of router rules=] is [=list/is not empty=]: + 1. Let |source| be the result of running [=Get Router Source=] algorithm with |registration|'s active worker and |request|. + 1. If |source| is {{RouterSource/"network"}}, return null. + 1. Else if |source| is {{RouterSource/"cache"}}, then: + 1. Let |requestResponses| be the result of running [=Query Cache=] with |request|. + 1. If |requestResponses| is an empty [=list=], return null. + 1. Else: + 1. Let |requestResponse| be the first element of |requestResponses|. + 1. Let |response| be |requestResponse|'s response. + 1. If |client| is not null, |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |request|'s [=request/origin=], |client|, "", and |response|'s [=filtered response/internal response=] returns blocked, then return null. + 1. Return |response|. + 1. If |request| is a non-subresource request, |request| is a [=navigation request=], |registration|'s [=navigation preload enabled flag=] is set, |request|'s [=request/method=] is \`GET\`, |registration|'s [=active worker=]'s [=set of event types to handle=] [=set/contains=] fetch, and |registration|'s [=active worker=]'s [=all fetch listeners are empty flag=] is not set then: + + Note: If the above is true except |registration|'s [=active worker=]'s set of event types to handle **does not** contain fetch, then the user agent may wish to show a console warning, as the developer's intent isn't clear. + + 1. Let |preloadRequest| be the result of [=request/cloning=] the request |request|. + 1. Let |preloadRequestHeaders| be |preloadRequest|'s [=request/header list=]. + 1. Let |preloadResponseObject| be a new {{Response}} object associated with a new {{Headers}} object whose [=guard=] is "`immutable`". + 1. [=header list/Append=] to |preloadRequestHeaders| a new [=header=] whose [=header/name=] is \`Service-Worker-Navigation-Preload\` and [=header/value=] is |registration|'s [=navigation preload header value=]. + 1. Set |preloadRequest|'s [=service-workers mode=] to "`none`". + 1. Let |preloadFetchController| be null. + 1. Run the following substeps [=in parallel=], but [=abort when=] |controller|'s [=fetch controller/state=] is "terminated" or "aborted": + 1. Set |preloadFetchController| to the result of [=Fetch|fetching=] |preloadRequest|. + + To [=fetch/processResponse=] for |navigationPreloadResponse|, run these substeps: + + 1. If |navigationPreloadResponse|'s [=response/type=] is "`error`", reject |preloadResponse| with a `TypeError` and terminate these substeps. + 1. Associate |preloadResponseObject| with |navigationPreloadResponse|. + 1. Resolve |preloadResponse| with |preloadResponseObject|. + 1. [=If aborted=], then: + 1. Let |deserializedError| be the result of [=deserialize a serialized abort reason=] given null and |workerRealm|. + 1. [=fetch controller/Abort=] |preloadFetchController| with |deserializedError|. + 1. Else, resolve |preloadResponse| with undefined. 1. Let |shouldSoftUpdate| be true if any of the following are true, and false otherwise: * |request| is a [=non-subresource request=]. * |request| is a [=subresource request=] and |registration| is [=stale=]. From 55f93603fa478cdd6a9964be4db28db40a14f0a8 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Mon, 5 Feb 2024 19:22:57 +0900 Subject: [PATCH 45/57] Add cacheName support. (#9) With this change, cacheName is supported. It means that if there is multiple cache storage and developers want to choose which storage to use, they can specify the storage by cacheName. --- docs/index.bs | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index c0b3f441..4979e20b 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1571,8 +1571,14 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ sequence<RouterCondition> _or; }; + typedef (RouterSourceDict or RouterSourceEnum) RouterSource; + + dictionary RouterSourceDict { + DOMString cacheName; + }; + enum RunningStatus { "running", "not-running" }; - enum RouterSource { "cache", "fetch-event", "network" }; + enum RouterSourceEnum { "cache", "fetch-event", "network" };
@@ -1588,7 +1594,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. For each |rule| of |rules|: 1. If running [=Verify Router Condition=] algorithm with |rule|["{{RouterRule/condition}}"] and |serviceWorker| returns false, [=throw=] a {{TypeError}}. 1. Append |rule| to |routerRules|. - 1. If |routerRules| [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSource/fetch-event}}" and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, [=throw=] a {{TypeError}}. + 1. If |routerRules| [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSourceEnum/fetch-event}}" and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, [=throw=] a {{TypeError}}. 1. Set |serviceWorker|'s [=service worker/list of router rules=] to |routerRules|.
@@ -3136,15 +3142,18 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |activeWorker| be |registration|'s active worker. 1. If |activeWorker|'s [=service worker/list of router rules=] is [=list/is not empty=]: 1. Let |source| be the result of running [=Get Router Source=] algorithm with |registration|'s active worker and |request|. - 1. If |source| is {{RouterSource/"network"}}, return null. - 1. Else if |source| is {{RouterSource/"cache"}}, then: - 1. Let |requestResponses| be the result of running [=Query Cache=] with |request|. - 1. If |requestResponses| is an empty [=list=], return null. - 1. Else: - 1. Let |requestResponse| be the first element of |requestResponses|. - 1. Let |response| be |requestResponse|'s response. - 1. If |client| is not null, |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |request|'s [=request/origin=], |client|, "", and |response|'s [=filtered response/internal response=] returns blocked, then return null. - 1. Return |response|. + 1. If |source| is {{RouterSourceEnum/"network"}}, return null. + 1. Else if |source| is {{RouterSourceEnum/"cache"}}, or |source|["{{RouterSourceDict/cacheName}}"] [=map/exists=], then: + 1. [=map/For each=] |cacheName| → |cache| of the [=relevant name to cache map=]: + 1. If |source|["{{RouterSourceDict/cacheName}}"] [=map/exists=] and |source|["{{RouterSourceDict/cacheName}}"] does not match |cacheName|, [=continue=]. + 1. Let |requestResponses| be the result of running [=Query Cache=] with |request|, a new {{CacheQueryOptions}}, and |cache|. + 1. If |requestResponses| is an empty [=list=], return null. + 1. Else: + 1. Let |requestResponse| be the first element of |requestResponses|. + 1. Let |response| be |requestResponse|'s response. + 1. If |client| is not null, |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |request|'s [=request/origin=], |client|, "", and |response|'s [=filtered response/internal response=] returns blocked, then return null. + 1. Return |response|. + 1. Return null. 1. If |request| is a non-subresource request, |request| is a [=navigation request=], |registration|'s [=navigation preload enabled flag=] is set, |request|'s [=request/method=] is \`GET\`, |registration|'s [=active worker=]'s [=set of event types to handle=] [=set/contains=] fetch, and |registration|'s [=active worker=]'s [=all fetch listeners are empty flag=] is not set then: Note: If the above is true except |registration|'s [=active worker=]'s set of event types to handle **does not** contain fetch, then the user agent may wish to show a console warning, as the developer's intent isn't clear. From 5a48d558660f38a23c8eff0b6260cf5fb3627047 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Fri, 9 Feb 2024 18:24:41 +0900 Subject: [PATCH 46/57] Use ServiceWorkerGlobalScope instead of request's settingsObject for COEP. (#11) When we designed the ServiceWorker static routing API, it was designed to be offloading simple things ServiceWorkers do. With that concept, if we evaluate the cache COEP, it should not be a request's COEP, but to be a ServiceWorker's COEP to make it behave as an offload. To make it happen, we set up the ServiceWorkerGlobalScope to be used for the COEP check. Since we only need ServiceWorkerGlobalScope for CSP checks, this PR separated the Run ServiceWorker algorithm to ServiceWorkerGlobalScope setup and others, and make it called before the static routing's cache COEP check if ServiceWorkerGlobalScope is not ready. --- docs/index.bs | 63 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 4979e20b..14559349 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -211,6 +211,8 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ A [=/service worker=] is said to be running if its [=event loop=] is running. + A [=/service worker=] has an associated ServiceWorkerGlobalScope is ready. It is initially unset. +

Lifetime

@@ -2973,23 +2975,27 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
-

Run Service Worker

+

Setup ServiceWorkerGlobalScope

: Input :: |serviceWorker|, a [=/service worker=] - :: |forceBypassCache|, an optional boolean, false by default : Output - :: a [=Completion=] or *failure* + :: a boolean - Note: This algorithm blocks until the service worker is [=running=] or fails to start. + Note: This algorithm returns true if |serviceWorker| has a {{ServiceWorkerGlobalScope}} usable for a CSP check. + +
+ This algorithm does the minimal setup for the service worker that is necessary to create something usable for security checks like CSP and COEP. This specification ensures that this algorithm is called before any such checks are performed. + + In specifications, such security checks require creating a {{ServiceWorkerGlobalScope}}, a [=relevant settings object=], a [=realm=], and an [=agent=]. In implementations, the amount of work required might be much less. Therefore, implementations could do less work in their equivalent of this algorithm, and more work in [=Run Service Worker=], as long as the results are observably equivalent. (And in particular, as long as all security checks have the same result.) +
1. Let |unsafeCreationTime| be the [=unsafe shared current time=]. - 1. If |serviceWorker| is [=running=], then return |serviceWorker|'s [=start status=]. - 1. If |serviceWorker|'s [=service worker/state=] is "`redundant`", then return *failure*. + 1. If |serviceWorker| is [=running=], then return true. + 1. If |serviceWorker|'s [=service worker/state=] is "`redundant`", then return false. + 1. If |serviceWorker|'s [=ServiceWorkerGlobalScope is ready=] is set, then return true. 1. Assert: |serviceWorker|'s [=start status=] is null. - 1. Let |script| be |serviceWorker|'s [=service worker/script resource=]. - 1. Assert: |script| is not null. - 1. Let |startFailed| be false. + 1. Let |setupFailed| be false. 1. Let |agent| be the result of [=obtain a service worker agent|obtaining a service worker agent=], and run the following steps in that context: 1. Let |realmExecutionContext| be the result of [=creating a new realm=] given |agent| and the following customizations: * For the global object, create a new {{ServiceWorkerGlobalScope}} object. Let |workerGlobalScope| be the created object. @@ -3013,9 +3019,36 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Set |workerGlobalScope|'s [=WorkerGlobalScope/url=] to |serviceWorker|'s [=service worker/script url=]. 1. Set |workerGlobalScope|'s [=WorkerGlobalScope/policy container=] to |serviceWorker|'s script resource's [=script resource/policy container=]. 1. Set |workerGlobalScope|'s [=WorkerGlobalScope/type=] to |serviceWorker|'s [=service worker/type=]. - 1. Set |workerGlobalScope|'s [=ServiceWorkerGlobalScope/force bypass cache for import scripts flag=] if |forceBypassCache| is true. 1. Create a new {{WorkerLocation}} object and associate it with |workerGlobalScope|. - 1. If the [=run CSP initialization for a global object=] algorithm returns "Blocked" when executed upon |workerGlobalScope|, set |startFailed| to true and abort these steps. + 1. If the [=run CSP initialization for a global object=] algorithm returns "Blocked" when executed upon |workerGlobalScope|, set |setupFailed| to true and abort these steps. + 1. Set |serviceWorker|'s [=ServiceWorkerGlobalScope is ready=]. + 1. Wait for |serviceWorker|'s [=ServiceWorkerGlobalScope is ready=] is set, or for |setupFailed| to be true. + 1. If |setupFailed| is true, then return false. + 1. Return true. +
+ +
+

Run Service Worker

+ + : Input + :: |serviceWorker|, a [=/service worker=] + :: |forceBypassCache|, an optional boolean, false by default + : Output + :: a [=Completion=] or *failure* + + Note: This algorithm blocks until the service worker is [=running=] or fails to start. + + 1. If |serviceWorker| is [=running=], then return |serviceWorker|'s [=start status=]. + 1. If |serviceWorker|'s [=service worker/state=] is "`redundant`", then return *failure*. + 1. Assert: |serviceWorker|'s [=start status=] is null. + 1. Let |script| be |serviceWorker|'s [=service worker/script resource=]. + 1. Assert: |script| is not null. + 1. Let |startFailed| be false. + 1. If |serviceWorker|'s [=ServiceWorkerGlobalScope is ready=] is not set: + 1. If run the [=Setup ServiceWorkerGlobalScope=] algorithm with |serviceWorker| returns false, then return *failure*. + 1. Obtain agent for |serviceWorker|'s [=service worker/global object=]'s [=environment settings object/realm execution context=], and run the following steps in that context: + 1. Let |workerGlobalScope| be |serviceWorker|'s [=service worker/global object=]. + 1. Set |workerGlobalScope|'s [=ServiceWorkerGlobalScope/force bypass cache for import scripts flag=] if |forceBypassCache| is true. 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. Let |evaluationStatus| be null. 1. If |script| is a [=classic script=], then: @@ -3151,7 +3184,13 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Else: 1. Let |requestResponse| be the first element of |requestResponses|. 1. Let |response| be |requestResponse|'s response. - 1. If |client| is not null, |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |request|'s [=request/origin=], |client|, "", and |response|'s [=filtered response/internal response=] returns blocked, then return null. + 1. If |activeWorker| is not [=running=] or |activeWorker|'s [=ServiceWorkerGlobalScope is ready=] is not set: + 1. If the result of running the [=Setup ServiceWorkerGlobalScope=] algorithm with |activeWorker| is false, then return null. + + Note: If this step succeeds, then |activeWorker|'s [=relevant settings object=] is now ready to use. + + 1. Let |settingsObject| be |activeWorker|'s [=relevant settings object=]. + 1. If |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |settingsObject|'s [=environment settings object/origin=], |settingsObject|, "", and |response|'s [=filtered response/internal response=] returns blocked, then return null. 1. Return |response|. 1. Return null. 1. If |request| is a non-subresource request, |request| is a [=navigation request=], |registration|'s [=navigation preload enabled flag=] is set, |request|'s [=request/method=] is \`GET\`, |registration|'s [=active worker=]'s [=set of event types to handle=] [=set/contains=] fetch, and |registration|'s [=active worker=]'s [=all fetch listeners are empty flag=] is not set then: From 59e1de9c945a456f85bf83992b20799627a2d910 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Fri, 16 Feb 2024 08:42:24 +0900 Subject: [PATCH 47/57] Address comments in the main PR. (#12) * Reflect some of comments in https://github.com/w3c/ServiceWorker/pull/1701 * Clarified the cache name matching. * Run soft update during the router is selected. * Explicitly unset the flag on terminate. * add definition for agent. * Use registration's cache map instead of this's. * renamed to add "flag", but I still need to find a better name. --- docs/index.bs | 94 ++++++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 14559349..b0db5169 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -66,6 +66,7 @@ spec: ecma-262; urlPrefix: http://tc39.github.io/ecma262/ text: IsCallable; url: sec-iscallable text: Get; url: sec-get-o-p type: dfn + text: agent; text: Assert; url: sec-algorithm-conventions text: \[[Call]]; url: sec-ecmascript-function-objects-call-thisargument-argumentslist text: promise; url: sec-promise-objects @@ -207,11 +208,11 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ A [=/service worker=] has an associated all fetch listeners are empty flag. It is initially unset. - A [=/service worker=] has an associated list of router rules. It is initially an empty [=list=]. + A [=/service worker=] has an associated list of router rules (a [=list=] of {{RouterRule}}s). It is initially an empty [=list=]. A [=/service worker=] is said to be running if its [=event loop=] is running. - A [=/service worker=] has an associated ServiceWorkerGlobalScope is ready. It is initially unset. + A [=/service worker=] has an associated ServiceWorkerGlobalScope is ready flag. It is initially unset.

Lifetime

@@ -1594,10 +1595,11 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |routerRules| be a copy of |serviceWorker|'s [=list of router rules=]. 1. If |rules| is a {{RouterRule}} dictionary, set |rules| to « |rules| ». 1. For each |rule| of |rules|: - 1. If running [=Verify Router Condition=] algorithm with |rule|["{{RouterRule/condition}}"] and |serviceWorker| returns false, [=throw=] a {{TypeError}}. + 1. If running [=Verify Router Condition=] algorithm with |rule|["{{RouterRule/condition}}"] and |serviceWorker| returns false, return [=a promise rejected with=] a {{TypeError}}. 1. Append |rule| to |routerRules|. - 1. If |routerRules| [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSourceEnum/fetch-event}}" and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, [=throw=] a {{TypeError}}. + 1. If |routerRules| [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSourceEnum/fetch-event}}" and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, return [=a promise rejected with=] a {{TypeError}}. 1. Set |serviceWorker|'s [=service worker/list of router rules=] to |routerRules|. + 1. Return [=a promise resolved with=] undefined.
@@ -2987,13 +2989,13 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
This algorithm does the minimal setup for the service worker that is necessary to create something usable for security checks like CSP and COEP. This specification ensures that this algorithm is called before any such checks are performed. - In specifications, such security checks require creating a {{ServiceWorkerGlobalScope}}, a [=relevant settings object=], a [=realm=], and an [=agent=]. In implementations, the amount of work required might be much less. Therefore, implementations could do less work in their equivalent of this algorithm, and more work in [=Run Service Worker=], as long as the results are observably equivalent. (And in particular, as long as all security checks have the same result.) + In specifications, such security checks require creating a {{ServiceWorkerGlobalScope}}, a [=relevant settings object=], a [=global object/realm=], and an [=agent=]. In implementations, the amount of work required might be much less. Therefore, implementations could do less work in their equivalent of this algorithm, and more work in [=Run Service Worker=], as long as the results are observably equivalent. (And in particular, as long as all security checks have the same result.)
1. Let |unsafeCreationTime| be the [=unsafe shared current time=]. 1. If |serviceWorker| is [=running=], then return true. 1. If |serviceWorker|'s [=service worker/state=] is "`redundant`", then return false. - 1. If |serviceWorker|'s [=ServiceWorkerGlobalScope is ready=] is set, then return true. + 1. If |serviceWorker|'s [=ServiceWorkerGlobalScope is ready flag=] is set, then return true. 1. Assert: |serviceWorker|'s [=start status=] is null. 1. Let |setupFailed| be false. 1. Let |agent| be the result of [=obtain a service worker agent|obtaining a service worker agent=], and run the following steps in that context: @@ -3021,8 +3023,8 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Set |workerGlobalScope|'s [=WorkerGlobalScope/type=] to |serviceWorker|'s [=service worker/type=]. 1. Create a new {{WorkerLocation}} object and associate it with |workerGlobalScope|. 1. If the [=run CSP initialization for a global object=] algorithm returns "Blocked" when executed upon |workerGlobalScope|, set |setupFailed| to true and abort these steps. - 1. Set |serviceWorker|'s [=ServiceWorkerGlobalScope is ready=]. - 1. Wait for |serviceWorker|'s [=ServiceWorkerGlobalScope is ready=] is set, or for |setupFailed| to be true. + 1. Set |serviceWorker|'s [=ServiceWorkerGlobalScope is ready flag=]. + 1. Wait for |serviceWorker|'s [=ServiceWorkerGlobalScope is ready flag=] is set, or for |setupFailed| to be true. 1. If |setupFailed| is true, then return false. 1. Return true.
@@ -3044,7 +3046,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |script| be |serviceWorker|'s [=service worker/script resource=]. 1. Assert: |script| is not null. 1. Let |startFailed| be false. - 1. If |serviceWorker|'s [=ServiceWorkerGlobalScope is ready=] is not set: + 1. If |serviceWorker|'s [=ServiceWorkerGlobalScope is ready flag=] is not set: 1. If run the [=Setup ServiceWorkerGlobalScope=] algorithm with |serviceWorker| returns false, then return *failure*. 1. Obtain agent for |serviceWorker|'s [=service worker/global object=]'s [=environment settings object/realm execution context=], and run the following steps in that context: 1. Let |workerGlobalScope| be |serviceWorker|'s [=service worker/global object=]. @@ -3127,6 +3129,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. [=Abort a running script|Abort the script=] currently running in |serviceWorker|. 1. Set |serviceWorker|'s [=start status=] to null. + 1. Unset |serviceWorker|'s [=ServiceWorkerGlobalScope is ready flag=].
@@ -3173,18 +3176,24 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |client|'s active service worker is non-null, set |registration| to |client|'s active service worker's containing service worker registration. 1. Else, return null. 1. Let |activeWorker| be |registration|'s active worker. - 1. If |activeWorker|'s [=service worker/list of router rules=] is [=list/is not empty=]: - 1. Let |source| be the result of running [=Get Router Source=] algorithm with |registration|'s active worker and |request|. - 1. If |source| is {{RouterSourceEnum/"network"}}, return null. + 1. Let |shouldSoftUpdate| be true if any of the following are true, and false otherwise: + * |request| is a [=non-subresource request=]. + * |request| is a [=subresource request=] and |registration| is [=stale=]. + 1. If |activeWorker|'s [=service worker/list of router rules=] [=list/is not empty=]: + 1. Let |source| be the result of running the [=Get Router Source=] algorithm with |registration|'s active worker and |request|. + 1. If |source| is {{RouterSourceEnum/"network"}}: + 1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|. + 1. Return null. 1. Else if |source| is {{RouterSourceEnum/"cache"}}, or |source|["{{RouterSourceDict/cacheName}}"] [=map/exists=], then: - 1. [=map/For each=] |cacheName| → |cache| of the [=relevant name to cache map=]: - 1. If |source|["{{RouterSourceDict/cacheName}}"] [=map/exists=] and |source|["{{RouterSourceDict/cacheName}}"] does not match |cacheName|, [=continue=]. + 1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|. + 1. [=map/For each=] |cacheName| → |cache| of the |registration|'s [=service worker registration/storage key=]'s [=name to cache map=]. + 1. If |source|["{{RouterSourceDict/cacheName}}"] [=map/exists=] and |source|["{{RouterSourceDict/cacheName}}"] [=string/is=] not |cacheName|, [=continue=]. 1. Let |requestResponses| be the result of running [=Query Cache=] with |request|, a new {{CacheQueryOptions}}, and |cache|. 1. If |requestResponses| is an empty [=list=], return null. 1. Else: 1. Let |requestResponse| be the first element of |requestResponses|. 1. Let |response| be |requestResponse|'s response. - 1. If |activeWorker| is not [=running=] or |activeWorker|'s [=ServiceWorkerGlobalScope is ready=] is not set: + 1. If |activeWorker| is not [=running=] or |activeWorker|'s [=ServiceWorkerGlobalScope is ready flag=] is not set: 1. If the result of running the [=Setup ServiceWorkerGlobalScope=] algorithm with |activeWorker| is false, then return null. Note: If this step succeeds, then |activeWorker|'s [=relevant settings object=] is now ready to use. @@ -3193,7 +3202,8 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |settingsObject|'s [=environment settings object/origin=], |settingsObject|, "", and |response|'s [=filtered response/internal response=] returns blocked, then return null. 1. Return |response|. 1. Return null. - 1. If |request| is a non-subresource request, |request| is a [=navigation request=], |registration|'s [=navigation preload enabled flag=] is set, |request|'s [=request/method=] is \`GET\`, |registration|'s [=active worker=]'s [=set of event types to handle=] [=set/contains=] fetch, and |registration|'s [=active worker=]'s [=all fetch listeners are empty flag=] is not set then: + 1. Assert: |source| is "{{RouterSourceEnum/fetch-event}}" + 1. If |request| is a [=navigation request=], |registration|'s [=navigation preload enabled flag=] is set, |request|'s [=request/method=] is \`GET\`, |registration|'s [=active worker=]'s [=set of event types to handle=] [=set/contains=] fetch, and |registration|'s [=active worker=]'s [=all fetch listeners are empty flag=] is not set then: Note: If the above is true except |registration|'s [=active worker=]'s set of event types to handle **does not** contain fetch, then the user agent may wish to show a console warning, as the developer's intent isn't clear. @@ -3215,9 +3225,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |deserializedError| be the result of [=deserialize a serialized abort reason=] given null and |workerRealm|. 1. [=fetch controller/Abort=] |preloadFetchController| with |deserializedError|. 1. Else, resolve |preloadResponse| with undefined. - 1. Let |shouldSoftUpdate| be true if any of the following are true, and false otherwise: - * |request| is a [=non-subresource request=]. - * |request| is a [=subresource request=] and |registration| is [=stale=]. 1. If the result of running the [=Should Skip Event=] algorithm with "fetch" and |activeWorker| is true, then: 1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|. 1. Return null. @@ -3338,31 +3345,35 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ : Output :: a boolean - Note: if there are multiple conditions (e.g. `urlPattern`, `runningStatus`, and `requestMethod` are set), all conditions will be matched to return true. + Note: if there are multiple conditions (e.g. `urlPattern`, `runningStatus`, and `requestMethod` are set), all conditions need to match for true to be returned. - 1. If |condition|["{{RouterCondition/urlPattern}}"] [=map/exists=], then: - 1. Let |rawPattern| be |condition|["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. - 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, return false. - 1. If |condition|["{{RouterCondition/requestMethod}}"] [=map/exists=], then: - 1. Let |method| be |condition|["{{RouterCondition/requestMethod}}"]. - 1. If |request|'s [=request/method=] is not |method|, return false. - 1. If |condition|["{{RouterCondition/requestMode}}"] [=map/exists=], then: - 1. Let |mode| be |condition|["{{RouterCondition/requestMode}}"]. - 1. If |request|'s [=request/mode=] is not |mode|, return false. - 1. If |condition|["{{RouterCondition/requestDestination}}"] [=map/exists=], then: - 1. Let |destination| be |condition|["{{RouterCondition/requestDestination}}"]. - 1. If |request|'s [=request/destination=] is not |destination|, return false. - 1. If |condition|["{{RouterCondition/runningStatus}}"] [=map/exists=], then: - 1. Let |runningStatus| be |condition|["{{RouterCondition/runningStatus}}"]. - 1. If |runningStatus| is {{RunningStatus/"running"}}, and |serviceWorker| is not [=running=], return false. - 1. If |runningStatus| is {{RunningStatus/"not-running"}}, and |serviceWorker| is [=running=], return false. - 1. If |condition|["{{RouterCondition/_or}}"] [=map/exists=], then: - 1. Let |orConditions| be |condition|["{{RouterCondition/_or}}"]. + 1. If |condition|["{{RouterCondition/or}}"] [=map/exists=], then: + 1. Let |orConditions| be |condition|["{{RouterCondition/or}}"]. 1. For each |orCondition| of |orConditions|: 1. If running [=Match Router Condition=] algorithm with |orCondition|, |serviceWorker| and |request| returns true, then return true. 1. Return false. - 1. Return true. + 1. Else: + + Note: The [=Verify Router Condition=] algorithm guarantees that {{RouterCondition/or}} and other conditions are mutual exclusive. + + 1. If |condition|["{{RouterCondition/urlPattern}}"] [=map/exists=], then: + 1. Let |rawPattern| be |condition|["{{RouterCondition/urlPattern}}"]. + 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. + 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, return false. + 1. If |condition|["{{RouterCondition/requestMethod}}"] [=map/exists=], then: + 1. Let |method| be |condition|["{{RouterCondition/requestMethod}}"]. + 1. If |request|'s [=request/method=] is not |method|, return false. + 1. If |condition|["{{RouterCondition/requestMode}}"] [=map/exists=], then: + 1. Let |mode| be |condition|["{{RouterCondition/requestMode}}"]. + 1. If |request|'s [=request/mode=] is not |mode|, return false. + 1. If |condition|["{{RouterCondition/requestDestination}}"] [=map/exists=], then: + 1. Let |destination| be |condition|["{{RouterCondition/requestDestination}}"]. + 1. If |request|'s [=request/destination=] is not |destination|, return false. + 1. If |condition|["{{RouterCondition/runningStatus}}"] [=map/exists=], then: + 1. Let |runningStatus| be |condition|["{{RouterCondition/runningStatus}}"]. + 1. If |runningStatus| is {{RunningStatus/"running"}}, and |serviceWorker| is not [=running=], return false. + 1. If |runningStatus| is {{RunningStatus/"not-running"}}, and |serviceWorker| is [=running=], return false. + 1. Return true.
@@ -3374,8 +3385,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ :: {{RouterSource}} or null 1. [=list/For each=] |rule| of |serviceWorker|'s [=service worker/list of router rules=]: - 1. If running [=Match Router Condition=] with |rule|["{{RouterRule/condition}}"], |serviceWorker| and |request| returns false, [=continue=]. - 1. Return |rule|["{{RouterRule/source}}"]. + 1. If running the [=Match Router Condition=] algorithm with |rule|["{{RouterRule/condition}}"], |serviceWorker| and |request| returns true, then return |rule|["{{RouterRule/source}}"]. 1. Return null.
From c32426084bb36b053362bb4270d4b35c02b9397e Mon Sep 17 00:00:00 2001 From: Shunya Shishido Date: Fri, 16 Feb 2024 13:31:11 +0900 Subject: [PATCH 48/57] Add `race-network-and-fetch-handler` source race-network-and-fetch-handler is a source to allow request to do competition between a network fetch and a fetch handler. To implement the feature, this CL factored out the process to run a fetch handler in agent. It is called from both the ServiceWorker static routing API part and the original part. In the static routing API part, a fetch controller also runs in parallel, and the Handle Fetch algorithm returns a response coming earlier to the queue. --- docs/index.bs | 94 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 86 insertions(+), 8 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index b0db5169..a27c39d5 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1082,7 +1082,9 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ }; - 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 import scripts flag. It is initially unset. + 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 import scripts flag. A {{ServiceWorkerGlobalScope}} object has an associated race response map which is an [=ordered map=] where the [=map/keys=] are [=/requests=] and the [=map/values=] are [=race response=]. It is initially unset. + + A race response is a [=struct=] used to contain the network response when {{RouterSourceEnum/"race-network-and-fetch-handler"}} performs. It has a value, which is a [=/response=], "pending", or null. 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=]. @@ -1581,7 +1583,12 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ }; enum RunningStatus { "running", "not-running" }; - enum RouterSourceEnum { "cache", "fetch-event", "network" }; + enum RouterSourceEnum { + "cache", + "fetch-event", + "network", + "race-network-and-fetch-handler" + };
@@ -3142,19 +3149,15 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ :: |controller|, a [=fetch controller=] :: |useHighResPerformanceTimers|, a boolean : Output - :: |response|, a [=/response=] + :: a [=/response=] - 1. Let |handleFetchFailed| be false. - 1. Let |respondWithEntered| be false. - 1. Let |eventCanceled| be false. - 1. Let |response| be null. 1. Let |registration| be null. 1. Let |client| be |request|'s [=request/client=]. 1. Let |reservedClient| be |request|'s [=request/reserved client=]. 1. Let |preloadResponse| be a new [=promise=]. 1. Let |workerRealm| be null. - 1. Let |eventHandled| be null. 1. Let |timingInfo| be a new [=service worker timing info=]. + 1. Let |raceResponse| be a [=race response=] whose [=race response/value=] is null. 1. Assert: |request|'s [=request/destination=] is not "serviceworker". 1. If |request|'s [=request/destination=] is either "embed" or "object", then: 1. Return null. @@ -3202,6 +3205,26 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |settingsObject|'s [=environment settings object/origin=], |settingsObject|, "", and |response|'s [=filtered response/internal response=] returns blocked, then return null. 1. Return |response|. 1. Return null. + 1. Else if |source| is {{RouterSourceEnum/"race-network-and-fetch-handler"}}, and |request|'s [=request/method=] is \`GET\` then: + 1. Let |queue| be an empty [=queue=] of [=/response=]. + 1. Let |raceFetchController| be null. + 1. Set |raceResponse|'s [=race response/value=] to "pending". + 1. Run the following substeps [=in parallel=], but [=abort when=] |controller|'s [=fetch controller/state=] is "terminated" or "aborted": + 1. Set |raceFetchController| to the result of calling [=fetch=] given |request|, with [=fetch/processResponse=] set to the following steps given a [=/response=] |raceNetworkRequestResponse|: + 1. If |raceNetworkRequestResponse|'s [=response/status=] is [=ok status=], then: + 1. Set |raceResponse|'s [=race response/value=] to |raceNetworkRequestResponse|. + 1. [=queue/Enqueue=] |raceNetworkRequestResponse| to |queue|. + 1. Otherwise, set |raceResponse|'s [=race response/value=] to a [=network error=]. + 1. [=If aborted=] and |raceFetchController| is not null, then: + 1. [=fetch controller/Abort=] |raceFetchController|. + 1. Set |raceResponse| to a [=race response=] whose [=race response/value=] is null. + 1. Resolve |preloadResponse| with undefined. + 1. Run the following substeps [=in parallel=]: + 1. Let |fetchHandlerResponse| be the result of [=Create Fetch Event and Dispatch=] with |request|, |registration|, |useHighResPerformanceTimers|, |timingInfo|, |workerRealm|, |reservedClient|, |preloadResponse|, and |raceResponse|. + 1. If |fetchHandlerResponse| is not null and not a [=network error=], and |raceFetchController| is not null, [=fetch controller/abort=] |raceFetchController|. + 1. [=queue/Enqueue=] |fetchHandlerResponse| to |queue|. + 1. Wait until |queue| is not empty. + 1. Return the result of [=dequeue=] |queue|. 1. Assert: |source| is "{{RouterSourceEnum/fetch-event}}" 1. If |request| is a [=navigation request=], |registration|'s [=navigation preload enabled flag=] is set, |request|'s [=request/method=] is \`GET\`, |registration|'s [=active worker=]'s [=set of event types to handle=] [=set/contains=] fetch, and |registration|'s [=active worker=]'s [=all fetch listeners are empty flag=] is not set then: @@ -3225,6 +3248,34 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |deserializedError| be the result of [=deserialize a serialized abort reason=] given null and |workerRealm|. 1. [=fetch controller/Abort=] |preloadFetchController| with |deserializedError|. 1. Else, resolve |preloadResponse| with undefined. + 1. Return the result of [=Create Fetch Event and Dispatch=] with |request|, |registration|, |useHighResPerformanceTimers|, |timingInfo|, |workerRealm|, |reservedClient|, |preloadResponse|, and |raceResponse|. +
+ +
+

Create Fetch Event and Dispatch

+ : Input + :: |request|, a [=/request=] + :: |registration|, a [=/service worker registration=] + :: |useHighResPerformanceTimers|, a boolean + :: |timingInfo|, a [=service worker timing info=] + :: |workerRealm|, a [=relevant realm=] of the [=service worker/global object=] + :: |reservedClient|, a [=request/reserved client=] + :: |preloadResponse|, a [=promise=] + :: |raceResponse|, a [=race response=] + : Output + :: a [=/response=] + + 1. Let |response| be null. + 1. Let |eventCanceled| be false. + 1. Let |client| be |request|'s [=request/client=]. + 1. Let |activeWorker| be |registration|'s active worker. + 1. Let |eventHandled| be null. + 1. Let |handleFetchFailed| be false. + 1. Let |respondWithEntered| be false. + 1. Let |shouldSoftUpdate| be true if any of the following are true, and false otherwise: + * |request| is a [=non-subresource request=]. + * |request| is a [=subresource request=] and |registration| is [=stale=]. + 1. Let |raceResponseMap| be |activeWorker|'s [=service worker/global object=]'s [=race response map=]. 1. If the result of running the [=Should Skip Event=] algorithm with "fetch" and |activeWorker| is true, then: 1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|. 1. Return null. @@ -3241,6 +3292,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Else: 1. Set |workerRealm| to the [=relevant realm=] of the |activeWorker|'s [=service worker/global object=]. 1. Set |eventHandled| to [=a new promise=] in |workerRealm|. + 1. If |raceResponse| is not null, [=map/set=] |raceResponseMap|[|request|] to |raceResponse|. 1. [=Queue a task=] |task| to run the following substeps: 1. Let |e| be the result of creating an event with {{FetchEvent}}. 1. Let |controller| be a [=new=] {{AbortController}} object with |workerRealm|. @@ -3277,11 +3329,15 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Wait for |task| to have executed or for |handleFetchFailed| to be true. 1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|. + 1. If |raceResponseMap|[|request|] [=map/exists=], [=map/remove=] |raceResponseMap|[|request|]. 1. If |respondWithEntered| is false, then: 1. If |eventCanceled| is true, then: 1. If |eventHandled| is not null, then [=reject=] |eventHandled| with a "{{NetworkError}}" {{DOMException}} in |workerRealm|. 2. Return a [=network error=]. 1. If |eventHandled| is not null, then [=resolve=] |eventHandled|. + 1. If |raceResponse|'s [=race response/value=] is not null, then: + 1. Wait until |raceResponse|'s [=race response/value=] is not "pending". + 1. If |raceResponse|'s [=race response/value=] is a [=/response=], return |raceResponse|'s [=race response/value=]. 1. Return null. 1. If |handleFetchFailed| is true, then: 1. If |eventHandled| is not null, then [=reject=] |eventHandled| with a "{{NetworkError}}" {{DOMException}} in |workerRealm|. @@ -3922,6 +3978,28 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Return true. 1. Return false.
+ +
+

Lookup Race Response

+ + : Input + :: |request|, a [=/request=] + : Output + :: a [=/response=] or null + + 1. If |request|'s [=request/reserved client=] is null, return null. + 1. Let |storage key| be the result of running [=obtain a storage key=] given |request|'s [=request/reserved client=]. + 1. Let |registration| be the result of running Match Service Worker Registration given |storage key| and |url|. + 1. If |registration| is null or |registration|'s active worker is null, return null. + 1. Else, let |activeWorker| be |registration|'s active worker. + 1. Let |map| be |activeWorker|'s [=service worker/global object=]'s [=race response map=]. + 1. If |map|[|request|] [=map/exists=], then: + 1. Let |entry| be |map|[|request|]. + 1. [=map/Remove=] |map|[|request|]. + 1. Wait until |entry|'s [=race response/value=] is not "pending" + 1. If |entry|'s [=race response/value=] is [=/response=], return |entry|'s [=race response/value=]. + 1. Return null. +
From e67a439c84ea86233e5a401a4531684723bf6732 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Fri, 16 Feb 2024 05:00:35 +0000 Subject: [PATCH 49/57] Go with the XXX algorithm form In the previous CLs, there was a mix of the X algorithm and X algorithm. This CL changes all to the X algorithm when calling the algorithm defined in this PR. --- docs/index.bs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index a27c39d5..b30acfb9 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1602,7 +1602,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |routerRules| be a copy of |serviceWorker|'s [=list of router rules=]. 1. If |rules| is a {{RouterRule}} dictionary, set |rules| to « |rules| ». 1. For each |rule| of |rules|: - 1. If running [=Verify Router Condition=] algorithm with |rule|["{{RouterRule/condition}}"] and |serviceWorker| returns false, return [=a promise rejected with=] a {{TypeError}}. + 1. If running the [=Verify Router Condition=] algorithm with |rule|["{{RouterRule/condition}}"] and |serviceWorker| returns false, return [=a promise rejected with=] a {{TypeError}}. 1. Append |rule| to |routerRules|. 1. If |routerRules| [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is "{{RouterSourceEnum/fetch-event}}" and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, return [=a promise rejected with=] a {{TypeError}}. 1. Set |serviceWorker|'s [=service worker/list of router rules=] to |routerRules|. @@ -3370,7 +3370,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |hasCondition| be false. 1. If |condition|["{{RouterCondition/urlPattern}}"] [=map/exists=], then: 1. Let |rawPattern| be |condition|["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. + 1. Let |pattern| be the result of running the Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. If this throws an exception, catch it and return false. 1. If |pattern| [=URLPattern/has regexp groups=], then return false. Note: Since running a user-defined regular expression has a security concern, it is prohibited. @@ -3387,7 +3387,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |orConditions| be |condition|["{{RouterCondition/_or}}"]. 1. For each |orCondition| of |orConditions|: - 1. If running [=Verify Router Condition=] algorithm with |orCondition| and |serviceWorker| returns false, return false. + 1. If running the [=Verify Router Condition=] algorithm with |orCondition| and |serviceWorker| returns false, return false. 1. Set |hasCondition| to true. 1. Return |hasCondition|.
@@ -3406,7 +3406,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |condition|["{{RouterCondition/or}}"] [=map/exists=], then: 1. Let |orConditions| be |condition|["{{RouterCondition/or}}"]. 1. For each |orCondition| of |orConditions|: - 1. If running [=Match Router Condition=] algorithm with |orCondition|, |serviceWorker| and |request| returns true, then return true. + 1. If running the [=Match Router Condition=] algorithm with |orCondition|, |serviceWorker| and |request| returns true, then return true. 1. Return false. 1. Else: @@ -3414,7 +3414,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |condition|["{{RouterCondition/urlPattern}}"] [=map/exists=], then: 1. Let |rawPattern| be |condition|["{{RouterCondition/urlPattern}}"]. - 1. Let |pattern| be the result of running Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. + 1. Let |pattern| be the result of running the Parse URL Pattern algorithm passing |rawPattern| and |serviceWorker|. 1. If running [=match=] with |pattern| and |request|'s [=request/URL=] returns null, return false. 1. If |condition|["{{RouterCondition/requestMethod}}"] [=map/exists=], then: 1. Let |method| be |condition|["{{RouterCondition/requestMethod}}"]. From 9635f8aaf166fd92480359985cbe340416b0d9c2 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Fri, 16 Feb 2024 05:17:13 +0000 Subject: [PATCH 50/57] Omit "ServiceWorkerGlobalScope is ready flag" --- docs/index.bs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index b30acfb9..bd698770 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -212,8 +212,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ A [=/service worker=] is said to be running if its [=event loop=] is running. - A [=/service worker=] has an associated ServiceWorkerGlobalScope is ready flag. It is initially unset. -

Lifetime

@@ -3002,13 +3000,12 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |unsafeCreationTime| be the [=unsafe shared current time=]. 1. If |serviceWorker| is [=running=], then return true. 1. If |serviceWorker|'s [=service worker/state=] is "`redundant`", then return false. - 1. If |serviceWorker|'s [=ServiceWorkerGlobalScope is ready flag=] is set, then return true. + 1. If |serviceWorker|'s [=service worker/global object=] is not null, then return true. 1. Assert: |serviceWorker|'s [=start status=] is null. 1. Let |setupFailed| be false. 1. Let |agent| be the result of [=obtain a service worker agent|obtaining a service worker agent=], and run the following steps in that context: 1. Let |realmExecutionContext| be the result of [=creating a new realm=] given |agent| and the following customizations: * For the global object, create a new {{ServiceWorkerGlobalScope}} object. Let |workerGlobalScope| be the created object. - 1. Set |serviceWorker|'s [=service worker/global object=] to |workerGlobalScope|. 1. Let |settingsObject| be a new environment settings object whose algorithms are defined as follows: : The [=environment settings object/realm execution context=] @@ -3030,8 +3027,8 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Set |workerGlobalScope|'s [=WorkerGlobalScope/type=] to |serviceWorker|'s [=service worker/type=]. 1. Create a new {{WorkerLocation}} object and associate it with |workerGlobalScope|. 1. If the [=run CSP initialization for a global object=] algorithm returns "Blocked" when executed upon |workerGlobalScope|, set |setupFailed| to true and abort these steps. - 1. Set |serviceWorker|'s [=ServiceWorkerGlobalScope is ready flag=]. - 1. Wait for |serviceWorker|'s [=ServiceWorkerGlobalScope is ready flag=] is set, or for |setupFailed| to be true. + 1. Set |serviceWorker|'s [=service worker/global object=] to |workerGlobalScope|. + 1. Wait for |serviceWorker|'s [=service worker/global object=] is not null, or for |setupFailed| to be true. 1. If |setupFailed| is true, then return false. 1. Return true.
@@ -3053,7 +3050,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |script| be |serviceWorker|'s [=service worker/script resource=]. 1. Assert: |script| is not null. 1. Let |startFailed| be false. - 1. If |serviceWorker|'s [=ServiceWorkerGlobalScope is ready flag=] is not set: + 1. If |serviceWorker|'s [=service worker/global object=] is null: 1. If run the [=Setup ServiceWorkerGlobalScope=] algorithm with |serviceWorker| returns false, then return *failure*. 1. Obtain agent for |serviceWorker|'s [=service worker/global object=]'s [=environment settings object/realm execution context=], and run the following steps in that context: 1. Let |workerGlobalScope| be |serviceWorker|'s [=service worker/global object=]. @@ -3136,7 +3133,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. [=Abort a running script|Abort the script=] currently running in |serviceWorker|. 1. Set |serviceWorker|'s [=start status=] to null. - 1. Unset |serviceWorker|'s [=ServiceWorkerGlobalScope is ready flag=].
@@ -3196,7 +3192,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Else: 1. Let |requestResponse| be the first element of |requestResponses|. 1. Let |response| be |requestResponse|'s response. - 1. If |activeWorker| is not [=running=] or |activeWorker|'s [=ServiceWorkerGlobalScope is ready flag=] is not set: + 1. If |activeWorker|'s [=service worker/global object=] is null: 1. If the result of running the [=Setup ServiceWorkerGlobalScope=] algorithm with |activeWorker| is false, then return null. Note: If this step succeeds, then |activeWorker|'s [=relevant settings object=] is now ready to use. From 088bb7bd864df8eb6577878f70c6811c1347558b Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Fri, 16 Feb 2024 07:52:05 +0000 Subject: [PATCH 51/57] Add note. --- docs/index.bs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/index.bs b/docs/index.bs index bd698770..695a1567 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3352,6 +3352,9 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |baseURL| be |serviceWorker|'s [=service worker/script url=]. 1. Return the result of [=building a URLPattern from a Web IDL value=] |rawPattern| given |baseURL| and |serviceWorker|'s [=service worker/global object=]'s [=relevant realm=]. + + Note: Since the [=building a URLPattern from a Web IDL value=] algorithm actually do not depend on the realm, it is fine to call the algorithm here even if the [=service worker/global object=] may not be ready. +
From d237b4ab477e623ce675865d9b6d618c6c1c79dc Mon Sep 17 00:00:00 2001 From: Shunya Shishido Date: Wed, 21 Feb 2024 10:45:51 +0900 Subject: [PATCH 52/57] Remove |raceResponseMap| --- docs/index.bs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 695a1567..193c79c5 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3271,7 +3271,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |shouldSoftUpdate| be true if any of the following are true, and false otherwise: * |request| is a [=non-subresource request=]. * |request| is a [=subresource request=] and |registration| is [=stale=]. - 1. Let |raceResponseMap| be |activeWorker|'s [=service worker/global object=]'s [=race response map=]. 1. If the result of running the [=Should Skip Event=] algorithm with "fetch" and |activeWorker| is true, then: 1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|. 1. Return null. @@ -3288,7 +3287,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Else: 1. Set |workerRealm| to the [=relevant realm=] of the |activeWorker|'s [=service worker/global object=]. 1. Set |eventHandled| to [=a new promise=] in |workerRealm|. - 1. If |raceResponse| is not null, [=map/set=] |raceResponseMap|[|request|] to |raceResponse|. + 1. If |raceResponse| is not null, [=map/set=] |activeWorker|'s [=service worker/global object=]'s [=race response map=][|request|] to |raceResponse|. 1. [=Queue a task=] |task| to run the following substeps: 1. Let |e| be the result of creating an event with {{FetchEvent}}. 1. Let |controller| be a [=new=] {{AbortController}} object with |workerRealm|. @@ -3325,7 +3324,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Wait for |task| to have executed or for |handleFetchFailed| to be true. 1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|. - 1. If |raceResponseMap|[|request|] [=map/exists=], [=map/remove=] |raceResponseMap|[|request|]. + 1. If |activeWorker|'s [=service worker/global object=]'s [=race response map=][|request|] [=map/exists=], [=map/remove=] |activeWorker|'s [=service worker/global object=]'s [=race response map=][|request|]. 1. If |respondWithEntered| is false, then: 1. If |eventCanceled| is true, then: 1. If |eventHandled| is not null, then [=reject=] |eventHandled| with a "{{NetworkError}}" {{DOMException}} in |workerRealm|. From 7791260b4a5afff27e5ce004a025c8aa4f0ada06 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 21 Feb 2024 10:49:22 +0900 Subject: [PATCH 53/57] Update docs/index.bs Co-authored-by: Marijn Kruisselbrink --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 193c79c5..353d62aa 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1592,7 +1592,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/

{{InstallEvent/addRoutes(rules)|event.addRoutes(rules)}}

- {{InstallEvent/addRoutes(rules)}} registers this service worker the rules to offload simple tasks that the fetch handler does. + Note: {{InstallEvent/addRoutes(rules)}} registers rules for this service worker to offload simple tasks that the fetch event handler ordinarily does. The addRoutes(|rules|) method steps are: From 16c38c1f8be2bdba7346cb8e8166630de06d2c5a Mon Sep 17 00:00:00 2001 From: Shunya Shishido Date: Wed, 21 Feb 2024 11:09:57 +0900 Subject: [PATCH 54/57] Re-format {{ServiceWorkerGlobalScope}} part and move `It is initially unset` phrase (#14) * Remove |raceResponseMap| * Re-format {{ServiceWorkerGlobalScope}} part and move `It is initially unset` phrase --- docs/index.bs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 353d62aa..c43094e4 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -1080,7 +1080,13 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ }; - 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 import scripts flag. A {{ServiceWorkerGlobalScope}} object has an associated race response map which is an [=ordered map=] where the [=map/keys=] are [=/requests=] and the [=map/values=] are [=race response=]. It is initially unset. + 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 import scripts flag. It is initially unset. + + A {{ServiceWorkerGlobalScope}} object has an associated race response map which is an [=ordered map=] where the [=map/keys=] are [=/requests=] and the [=map/values=] are [=race response=]. A race response is a [=struct=] used to contain the network response when {{RouterSourceEnum/"race-network-and-fetch-handler"}} performs. It has a value, which is a [=/response=], "pending", or null. From c96dba032160eec0c306366d2ba7081276f06bd0 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 21 Feb 2024 02:56:02 +0000 Subject: [PATCH 55/57] Not to modify |activeWorker| for handling the static routing API Upon the review request, this CL makes |activeWorker| not modified in the Setup ServiceWorkerGlobalScope algorithm. It is the caller's responsibility to update the active service worker's global scope. With this change, an effemeral ServiceWorkerGlobalScope can be used for a cache source in the static routing API. --- docs/index.bs | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index c43094e4..81888892 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -2993,9 +2993,9 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ : Input :: |serviceWorker|, a [=/service worker=] : Output - :: a boolean + :: a {{ServiceWorkerGlobalScope}} object or null - Note: This algorithm returns true if |serviceWorker| has a {{ServiceWorkerGlobalScope}} usable for a CSP check. + Note: This algorithm returns a {{ServiceWorkerGlobalScope}} usable for a CSP check, or null. If |serviceWorker| has an active {{ServiceWorkerGlobalScope}}, then it is returned. Otherwise, the object will be newly created.
This algorithm does the minimal setup for the service worker that is necessary to create something usable for security checks like CSP and COEP. This specification ensures that this algorithm is called before any such checks are performed. @@ -3004,11 +3004,12 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
1. Let |unsafeCreationTime| be the [=unsafe shared current time=]. - 1. If |serviceWorker| is [=running=], then return true. - 1. If |serviceWorker|'s [=service worker/state=] is "`redundant`", then return false. - 1. If |serviceWorker|'s [=service worker/global object=] is not null, then return true. + 1. If |serviceWorker| is [=running=], then return |serviceWorker|'s [=service worker/global object=]. + 1. If |serviceWorker|'s [=service worker/state=] is "`redundant`", then return null. + 1. If |serviceWorker|'s [=service worker/global object=] is not null, then return |serviceWorker|'s [=service worker/global object=]. 1. Assert: |serviceWorker|'s [=start status=] is null. 1. Let |setupFailed| be false. + 1. Let |globalObject| be null. 1. Let |agent| be the result of [=obtain a service worker agent|obtaining a service worker agent=], and run the following steps in that context: 1. Let |realmExecutionContext| be the result of [=creating a new realm=] given |agent| and the following customizations: * For the global object, create a new {{ServiceWorkerGlobalScope}} object. Let |workerGlobalScope| be the created object. @@ -3033,10 +3034,10 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Set |workerGlobalScope|'s [=WorkerGlobalScope/type=] to |serviceWorker|'s [=service worker/type=]. 1. Create a new {{WorkerLocation}} object and associate it with |workerGlobalScope|. 1. If the [=run CSP initialization for a global object=] algorithm returns "Blocked" when executed upon |workerGlobalScope|, set |setupFailed| to true and abort these steps. - 1. Set |serviceWorker|'s [=service worker/global object=] to |workerGlobalScope|. - 1. Wait for |serviceWorker|'s [=service worker/global object=] is not null, or for |setupFailed| to be true. - 1. If |setupFailed| is true, then return false. - 1. Return true. + 1. Set |globalObject| to |workerGlobalScope|. + 1. Wait for |globalObject| is not null, or for |setupFailed| to be true. + 1. If |setupFailed| is true, then return null. + 1. Return |globalObject|.
@@ -3056,10 +3057,12 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |script| be |serviceWorker|'s [=service worker/script resource=]. 1. Assert: |script| is not null. 1. Let |startFailed| be false. - 1. If |serviceWorker|'s [=service worker/global object=] is null: - 1. If run the [=Setup ServiceWorkerGlobalScope=] algorithm with |serviceWorker| returns false, then return *failure*. - 1. Obtain agent for |serviceWorker|'s [=service worker/global object=]'s [=environment settings object/realm execution context=], and run the following steps in that context: - 1. Let |workerGlobalScope| be |serviceWorker|'s [=service worker/global object=]. + 1. Let |workerGlobalScope| be |serviceWorker|'s [=service worker/global object=]. + 1. If |workerGlobalScope| is null: + 1. Set |workerGlobalScope| to be the result of running the [=Setup ServiceWorkerGlobalScope=] algorithm with |serviceWorker|. + 1. If |workerGlobalScope| is null, then return *failure*. + 1. Set |serviceWorker|'s [=service worker/global object=] to |workerGlobalScope|. + 1. Obtain agent for |workerGlobalScope|'s [=environment settings object/realm execution context=], and run the following steps in that context: 1. Set |workerGlobalScope|'s [=ServiceWorkerGlobalScope/force bypass cache for import scripts flag=] if |forceBypassCache| is true. 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. Let |evaluationStatus| be null. @@ -3198,13 +3201,14 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Else: 1. Let |requestResponse| be the first element of |requestResponses|. 1. Let |response| be |requestResponse|'s response. - 1. If |activeWorker|'s [=service worker/global object=] is null: - 1. If the result of running the [=Setup ServiceWorkerGlobalScope=] algorithm with |activeWorker| is false, then return null. + 1. Let |globalObject| be |activeWorker|'s [=service worker/global object=]. + 1. If |globalObject| is null: + 1. Set |globalObject| to the result of running [=Setup ServiceWorkerGlobalScope=] with |activeWorker|. + 1. If |globalObject| is null, return null. - Note: If this step succeeds, then |activeWorker|'s [=relevant settings object=] is now ready to use. + Note: This only creates a ServiceWorkerGlobalScope because CORS checks require that. It is not expected that implementations will actually create a ServiceWorkerGlobalScope here. - 1. Let |settingsObject| be |activeWorker|'s [=relevant settings object=]. - 1. If |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |settingsObject|'s [=environment settings object/origin=], |settingsObject|, "", and |response|'s [=filtered response/internal response=] returns blocked, then return null. + 1. If |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |globalObject|'s [=environment settings object/origin=], |globalObject|, "", and |response|'s [=filtered response/internal response=] returns blocked, then return null. 1. Return |response|. 1. Return null. 1. Else if |source| is {{RouterSourceEnum/"race-network-and-fetch-handler"}}, and |request|'s [=request/method=] is \`GET\` then: From 9a0f50dcf3052d2365de965b403038f4da31019a Mon Sep 17 00:00:00 2001 From: Shunya Shishido Date: Wed, 21 Feb 2024 13:35:20 +0900 Subject: [PATCH 56/57] Fix |url| in Lookup Race Response (#15) --- docs/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.bs b/docs/index.bs index 81888892..628aed89 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3997,7 +3997,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If |request|'s [=request/reserved client=] is null, return null. 1. Let |storage key| be the result of running [=obtain a storage key=] given |request|'s [=request/reserved client=]. - 1. Let |registration| be the result of running Match Service Worker Registration given |storage key| and |url|. + 1. Let |registration| be the result of running Match Service Worker Registration given |storage key| and |request|'s [=request/url=]. 1. If |registration| is null or |registration|'s active worker is null, return null. 1. Else, let |activeWorker| be |registration|'s active worker. 1. Let |map| be |activeWorker|'s [=service worker/global object=]'s [=race response map=]. From 31f3b947c75d8d1c351cd6f70b044d3b5ec2c453 Mon Sep 17 00:00:00 2001 From: Shunya Shishido Date: Thu, 22 Feb 2024 09:13:15 +0900 Subject: [PATCH 57/57] Update race handling, lookup race response algorithm (#16) * Remove |raceResponseMap| * Re-format {{ServiceWorkerGlobalScope}} part and move `It is initially unset` phrase * Fix |url| in Lookup Race Response * Update race handling, lookup race response algorithm --- docs/index.bs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 628aed89..baa047ed 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -3162,7 +3162,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |preloadResponse| be a new [=promise=]. 1. Let |workerRealm| be null. 1. Let |timingInfo| be a new [=service worker timing info=]. - 1. Let |raceResponse| be a [=race response=] whose [=race response/value=] is null. 1. Assert: |request|'s [=request/destination=] is not "serviceworker". 1. If |request|'s [=request/destination=] is either "embed" or "object", then: 1. Return null. @@ -3212,9 +3211,10 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Return |response|. 1. Return null. 1. Else if |source| is {{RouterSourceEnum/"race-network-and-fetch-handler"}}, and |request|'s [=request/method=] is \`GET\` then: + 1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|. 1. Let |queue| be an empty [=queue=] of [=/response=]. 1. Let |raceFetchController| be null. - 1. Set |raceResponse|'s [=race response/value=] to "pending". + 1. Let |raceResponse| be a [=race response=] whose [=race response/value=] is "pending". 1. Run the following substeps [=in parallel=], but [=abort when=] |controller|'s [=fetch controller/state=] is "terminated" or "aborted": 1. Set |raceFetchController| to the result of calling [=fetch=] given |request|, with [=fetch/processResponse=] set to the following steps given a [=/response=] |raceNetworkRequestResponse|: 1. If |raceNetworkRequestResponse|'s [=response/status=] is [=ok status=], then: @@ -3254,7 +3254,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Let |deserializedError| be the result of [=deserialize a serialized abort reason=] given null and |workerRealm|. 1. [=fetch controller/Abort=] |preloadFetchController| with |deserializedError|. 1. Else, resolve |preloadResponse| with undefined. - 1. Return the result of [=Create Fetch Event and Dispatch=] with |request|, |registration|, |useHighResPerformanceTimers|, |timingInfo|, |workerRealm|, |reservedClient|, |preloadResponse|, and |raceResponse|. + 1. Return the result of [=Create Fetch Event and Dispatch=] with |request|, |registration|, |useHighResPerformanceTimers|, |timingInfo|, |workerRealm|, |reservedClient|, |preloadResponse|, and null.
@@ -3267,7 +3267,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ :: |workerRealm|, a [=relevant realm=] of the [=service worker/global object=] :: |reservedClient|, a [=request/reserved client=] :: |preloadResponse|, a [=promise=] - :: |raceResponse|, a [=race response=] + :: |raceResponse|, a [=race response=] or null : Output :: a [=/response=] @@ -3995,11 +3995,17 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ : Output :: a [=/response=] or null - 1. If |request|'s [=request/reserved client=] is null, return null. - 1. Let |storage key| be the result of running [=obtain a storage key=] given |request|'s [=request/reserved client=]. - 1. Let |registration| be the result of running Match Service Worker Registration given |storage key| and |request|'s [=request/url=]. - 1. If |registration| is null or |registration|'s active worker is null, return null. - 1. Else, let |activeWorker| be |registration|'s active worker. + 1. Let |registration| be null. + 1. If |request| is a [=non-subresource request=], then: + 1. If |request|'s [=request/reserved client=] is null, return null. + 1. Let |storage key| be the result of running [=obtain a storage key=] given |request|'s [=request/reserved client=]. + 1. Set |registration| to the result of running [=Match Service Worker Registration=] given |storage key| and |request|'s [=request/url=]. + 1. Else if |request| is a [=subresource request=], then: + 1. Let |client| be |request|'s [=request/client=]. + 1. If |client|'s [=active service worker=] is null, return null. + 1. Set |registration| to |client|'s [=active service worker=]'s [=containing service worker registration=]. + 1. Otherwise, return null. + 1. Let |activeWorker| be |registration|'s [=active worker=]. 1. Let |map| be |activeWorker|'s [=service worker/global object=]'s [=race response map=]. 1. If |map|[|request|] [=map/exists=], then: 1. Let |entry| be |map|[|request|].