Skip to content

Commit 04d734b

Browse files
committed
Update algorithm to only share quota for direct relatives
1 parent 409aa54 commit 04d734b

File tree

1 file changed

+116
-137
lines changed

1 file changed

+116
-137
lines changed

fetch.bs

Lines changed: 116 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -6765,14 +6765,12 @@ sources, specifically task sources that can result in running scripts such as th
67656765
<a method><code>fetchLater()</code></a> call before running any scripts that might depend on it.
67666766

67676767
<div algorithm>
6768-
<p>To <dfn>queue a deferred fetch</dfn> given a
6769-
<a for=/>request</a> <var>request</var>, a null or {{DOMHighResTimeStamp}}
6768+
<p>To <dfn>queue a deferred fetch</dfn> given a <a for=/>request</a> <var>request</var>, a
6769+
<a for=fetch>fetch group</a> <var>fetchGroup</var> a null or {{DOMHighResTimeStamp}}
67706770
<var>activateAfter</var>, an <var>onActivatedWithoutTermination</var>, which is an algorithm that
67716771
takes no arguments:
67726772

67736773
<ol>
6774-
<li><p>Assert: <var>request</var>'s <a for=request>client</a> is a {{Document}}.
6775-
67766774
<li><p><a>Populate request from client</a> given <var>request</var>.
67776775

67786776
<li><p>Set <var>request</var>'s <a for=request>service-workers mode</a> to "<code>none</code>".
@@ -6782,19 +6780,9 @@ takes no arguments:
67826780
<li><p>Let <var>deferredRecord</var> be a new <a>deferred fetch record</a> whose
67836781
<a for="deferred fetch record">request</a> is <var>request</var>.
67846782

6785-
<li><p>Let <var>topMostDirectSameOriginAncestor</var> be <var>request</var>'s
6786-
<a for=request>client</a>.
6787-
6788-
<li><p>While <var>topMostDirectSameOriginAncestor</var>'s <a>node navigable</a>'s
6789-
<a>container document</a> is a {{Document}} whose <a for=Document>origin</a> is <a>same origin</a>
6790-
with <var>request</var>'s <a for=request>client</a>'s <a for=Document>origin</a>, set
6791-
<var>topMostDirectSameOriginAncestor</var> to <var>topMostDirectSameOriginAncestor</var>'s
6792-
<a>node navigable</a>'s <a>container document</a>.
6793-
67946783
<li>
6795-
<p><a for=list>Append</a> <var>deferredRecord</var> to
6796-
<var>topMostDirectSameOriginAncestor</var>'s <a>active document</a>'s
6797-
<a for=fetch>fetch group</a>'s <a for="fetch group">deferred fetch records</a>.
6784+
<p><a for=list>Append</a> <var>deferredRecord</var> to <var>fetchGroup</var>'s
6785+
<a for="fetch group">deferred fetch records</a>.
67986786

67996787
<p class=note>This prevents a case where eagerly creating and destroying nested documents would
68006788
circumvent the keepalive quota.
@@ -6873,15 +6861,15 @@ takes no arguments:
68736861

68746862
<!-- non-normative -->
68756863
<p>The deferred-fetch quota is allocated to a <a for=/>top-level traversable</a> (a "tab"),
6876-
amounting to 640 kibibytes. The top-level {{Document}} and its same-origin nested documents can
6877-
use this quota to queue deferred fetches, or delegate some of it to cross-origin nested documents,
6878-
using permissions policy.
6864+
amounting to 640 kibibytes. The top-level {{Document}} and its same-origin directly nested documents
6865+
can use this quota to queue deferred fetches, or delegate some of it to cross-origin nested
6866+
documents, using permissions policy.
68796867

68806868
<p>By default, 128 kibibytes out of these 640 kibibytes are allocated to delegating the quota to
68816869
cross-origin nested documents, each reserving 8 kibibytes.
68826870

6883-
<p>The top-level {{Document}}, and subsequently its nested documents, can control how much of their quota
6884-
is delegates to cross-origin/cross-agent nested documents, by using permissions policy.
6871+
<p>The top-level {{Document}}, and subsequently its nested documents, can control how much of their
6872+
quota is delegates to cross-origin/cross-agent nested documents, by using permissions policy.
68856873
By default, "{{PermissionsPolicy/deferred-fetch-minimal}}" is enabled for any origin, while
68866874
"{{PermissionsPolicy/deferred-fetch}}" is enabled for the top-level document's origin only.
68876875
By relaxing the "{{PermissionsPolicy/deferred-fetch}}" policy for particular origins and nested
@@ -6940,9 +6928,8 @@ calls would succeed and the last one would throw.
69406928
to <code>https://frame.example.com</code>, for example by serving the following header:
69416929
<pre><code class=lang-http>Permissions-Policy: deferred-fetch=(self "https://frame.example.com")</code></pre>
69426930

6943-
<p>Each nested document reserves its own quota, and all the same-origin documents in the tree share
6944-
quota with each other. So the following would work, because each frame reserve 8 kibibytes and they
6945-
share the accumulated 16 kibibytes:
6931+
<p>Each nested document reserves its own quota. So the following would work, because each frame
6932+
reserve 8 kibibytes:
69466933
<pre><code class=lang-javascript>
69476934
// In cross-origin nested document at https://frame.example.com/frame-1
69486935
fetchLater("https://a.example.com", {body: a_6kb_body});
@@ -6961,11 +6948,15 @@ share the accumulated 16 kibibytes:
69616948
| | Shares quota with the <a for=/>top-level traversable</a>, as they're same origin.
69626949
| |
69636950
| + ---- + https://x.example.com
6964-
| Shares 16 kibibytes together with one other cross-origin nested document of the same origin.
6951+
| 8 kibibytes.
69656952
|
69666953
|
69676954
+ ---- + https://x.example.com
6968-
| Shares 16 kibibytes together with one other cross-origin nested document of the same origin.
6955+
| 8 kibibytes.
6956+
| |
6957+
| + https://me.example.com
6958+
| 0. Even though it's same origin with the <a for=/>top-level traversable</a>, it does not
6959+
| automatically share its quota as they are separated by a cross-origin intermediary.
69696960
|
69706961
+ ---- + https://ok.example.com/good
69716962
| | 64 kibibytes, granted via the "{{PermissionsPolicy/deferred-fetch}}" policy.
@@ -6986,10 +6977,12 @@ descendants share a quota of 384 kibibytes. That value is computed as such:
69866977
<ul>
69876978
<li><p>640 kibibytes are initially granted to the <a for=/>top-level traversable</a>.
69886979
<li><p>128 kibibytes are reserved for the "{{PermissionsPolicy/deferred-fetch-minimal}}" policy.
6989-
<li><p>64 kibibytes are reserved for the container navigating to <code>https://ok.example/good</code>.
6990-
<li><p>64 kibibytes are reserved for the container navigating to <code>https://ok.example/redirect</code>, and lost when it navigates away.
6991-
<li><code>https://ok.example.com/back</code> did not reserve 64 kibibytes, because it navigated back to <a for=/>top-level traversable</a>'s origin.
6992-
<li><p>640 - 128 - 64 - 64 = 384 kibibytes.
6980+
<li><p>64 kibibytes are reserved for the container navigating to
6981+
<code>https://ok.example/good</code>.
6982+
<li><p>64 kibibytes are reserved for the container navigating to
6983+
<code>https://ok.example/redirect</code>, and lost when it navigates away.
6984+
<li><code>https://ok.example.com/back</code> did not reserve 64 kibibytes, because it navigated
6985+
back to <a for=/>top-level traversable</a>'s origin. <li><p>640 - 128 - 64 - 64 = 384 kibibytes.
69936986
</ul>
69946987
</div>
69956988

@@ -7002,105 +6995,75 @@ descendants share a quota of 384 kibibytes. That value is computed as such:
70026995
"<dfn for=PermissionsPolicy enum-value>deferred-fetch-minimal</dfn>". Its
70036996
<a for="policy-controlled feature">default allowlist</a> is "<code>*</code>".
70046997

7005-
<p>The <dfn>optional nested document deferred-fetch quota</dfn> is 64 kibibytes.
7006-
<p>The <dfn>minimal nested document deferred-fetch quota</dfn> is 8 kibibytes.
70076998
<p>The <dfn>max containers with minimal quota</dfn> is 16.
70086999

7009-
70107000
<div algorithm>
70117001
<p>To get the <dfn>available deferred-fetch quota</dfn> given a {{Document}}
7012-
<var>requestClientDocument</var> and an <a for=/>origin</a>-or-null <var>origin</var>:
7002+
<var>controlDocument</var> and an <a for=/>origin</a>-or-null <var>origin</var>:
70137003

70147004
<ol>
70157005
<li><p>Let <var>quota</var> be 0.
70167006

70177007
<li><p>Let <var>quotaForOrigin</var> be 64 kibibytes.
70187008

70197009
<li>
7020-
<p>For each <var>otherNavigable</var> of <var>requestClientDocument</var>'s <a>node navigable</a>'s
7021-
<a for=navigable>top-level traversable</a>'s <a>inclusive descendant navigables</a>:
7022-
7023-
<p class=note>This algorithm iterates over the entire navigable tree. It accumulates quota from
7024-
the <a for=/>top-level traversable</a>, and from nested documents who inherit quota. Subsequently,
7025-
it subtracts the quota delegated to cross-origin nested documents, as well as quota
7026-
spent on pending deferred fetch requests.
7010+
<p>If <var>controlDocument</var>'s <a>node navigable</a> is a
7011+
<a for=/>top-level traversable</a>, then:
70277012

70287013
<ol>
7029-
<li><p>Let <var>otherDocument</var> be <var>otherNavigable</var>'s <a>active document</a>.
7030-
<li><p>Let <var>otherContainer</var> be <var>otherNavigable</var>'s <a>navigable container</a>.
7014+
<li><p>If <var>controlDocument</var> is not <a>allowed to use</a> the
7015+
<a>policy-controlled feature</a> "{{PermissionsPolicy/deferred-fetch}}", then return 0.
70317016

70327017
<li>
7033-
<p>If <var>requestClientDocument</var>'s <a for=Document>origin</a> is <a>same origin</a> with
7034-
<var>otherDocument</var>'s <a for=Document>origin</a>, then:
7035-
<ol>
7036-
<li>
7037-
<p>If <var>otherContainer</var> is null, then:
7038-
7039-
<p class=note>Accumulate the <a for=/>top-level traversable</a>'s initial quota.
7040-
7041-
<ol>
7042-
<li><p>If <var>otherDocument</var> is not <a>allowed to use</a> the
7043-
<a>policy-controlled feature</a> "{{PermissionsPolicy/deferred-fetch}}", then return 0.
7044-
7045-
<li><p>Assert: <var>quota</var> is 0.
7046-
7047-
<li>
7048-
<p>Set <var>quota</var> be 640 kibibytes.
7049-
<p class="note allow-2119">640kb should be enough for everyone.
7050-
7051-
<li><p>If <var>otherDocument</var> is <a>allowed to use</a> the
7052-
<a>policy-controlled feature</a> "{{PermissionsPolicy/deferred-fetch-minimal}}", then
7053-
decrement <var>quota</var> by <a>max containers with minimal quota</a>, multiplied by
7054-
<a for="reserved deferred-fetch quota">minimal quota</a>.
7055-
</ol>
7018+
<p>Set <var>quota</var> be 640 kibibytes.
7019+
<p class="note allow-2119">640kb should be enough for everyone.
70567020

7057-
<li>
7058-
<p>Otherwise, if any of the following conditions is true:
7059-
7060-
<ul class=brief>
7061-
<li><p><var>otherContainer</var>'s <a>reserved deferred-fetch quota</a> is
7062-
<a for="reserved deferred-fetch quota">normal quota</a>, and <var>otherDocument</var> is
7063-
<a>allowed to use</a> the <a>policy-controlled feature</a>
7064-
"{{PermissionsPolicy/deferred-fetch}}"
7065-
7066-
<li><p><var>otherContainer</var>'s <a>reserved deferred-fetch quota</a> is
7067-
<a for="reserved deferred-fetch quota">minimal quota</a>, and <var>otherDocument</var> is
7068-
<a>allowed to use</a> the <a>policy-controlled feature</a>
7069-
"{{PermissionsPolicy/deferred-fetch-minimal}}"
7070-
</ul>
7071-
7072-
<p>then increment <var>quota</var> by <var>otherContainer</var>'s
7073-
<a>reserved deferred-fetch quota</a>.
7074-
<p class=note>Accumulate quota granted by parent documents.
7075-
7076-
<li>
7077-
<p><a for=list>For each</a> <a>deferred fetch record</a> <var>deferredRecord</var> of
7078-
<var>otherDocument</var>'s <a for=fetch>fetch group</a>'s
7079-
<a for="fetch group">deferred fetch records</a>:</p>
7021+
<li><p>If <var>controlDocument</var> is <a>allowed to use</a> the
7022+
<a>policy-controlled feature</a> "{{PermissionsPolicy/deferred-fetch-minimal}}", then
7023+
decrement <var>quota</var> by <a>max containers with minimal quota</a>, multiplied by
7024+
<a for="reserved deferred-fetch quota">minimal quota</a>.
7025+
</ol>
70807026

7081-
<p class=note>Account for quota on deferred fetches performed by <a>same origin</a> clients.
7027+
<p>Otherwise:
70827028

7083-
<ol>
7084-
<li><p>Let <var>requestLength</var> be the <a>total request length</a> of
7085-
<var>deferredRecord</var>'s <a for="deferred fetch record">request</a>.
7029+
<ol>
7030+
<li><p>Let <var>container</var> be <var>controlDocument</var>'s <a>node navigable</a>'s
7031+
<a>navigable container</a>.
7032+
7033+
<li><p>If <var>container</var>'s <a>reserved deferred-fetch quota</a> is
7034+
<a for="reserved deferred-fetch quota">normal quota</a>, and <var>controlDocument</var> is
7035+
<a>allowed to use</a> the <a>policy-controlled feature</a>
7036+
"{{PermissionsPolicy/deferred-fetch}}", then set <var>quota</var> to
7037+
<a for="reserved deferred-fetch quota">normal quota</a>.
7038+
7039+
<li><p>Otherwise, if <var>container</var>'s <a>reserved deferred-fetch quota</a> is
7040+
<a for="reserved deferred-fetch quota">minimal quota</a>, and <var>controlDocument</var> is
7041+
<a>allowed to use</a> the <a>policy-controlled feature</a>
7042+
"{{PermissionsPolicy/deferred-fetch-minimal}}", then set <var>quota</var> to
7043+
<a for="reserved deferred-fetch quota">minimal quota</a>.
7044+
</ol>
70867045

7087-
<li><p>Decrement <var>quota</var> by <var>requestLength</var>.
7046+
<li>
7047+
<p><a for=list>For each</a> <a>deferred fetch record</a> <var>deferredRecord</var> of
7048+
<var>controlDocument</var>'s <a>fetch group</a>'s
7049+
<a for="fetch group">deferred fetch records</a>:</p>
70887050

7089-
<li><p>If <var>deferredRecord</var>'s <a for="deferred fetch record">request</a>'s
7090-
<a for=request>URL</a>'s <a for=url>origin</a> is <a>same origin</a> with <var>origin</var>,
7091-
then decrement <var>quotaForOrigin</var> by <var>requestLength</var>.
7092-
</ol>
7093-
</ol>
7051+
<ol>
7052+
<li><p>Let <var>requestLength</var> be the <a>total request length</a> of
7053+
<var>deferredRecord</var>'s <a for="deferred fetch record">request</a>.
70947054

7095-
<li>
7096-
<p>If <var>otherDocument</var>'s <a>container document</a> is a {{Document}} whose
7097-
<a for=Document>origin</a> is <a>same origin</a> with <var>requestClientDocument</var>'s
7098-
<a for=Document>origin</a>, then decrement <var>quota</var> by <var>otherContainer</var>'s
7099-
<a>reserved deferred-fetch quota</a>.
7055+
<li><p>Decrement <var>quota</var> by <var>requestLength</var>.
71007056

7101-
<p class=note>Account for quota granted to child documents.
7057+
<li><p>If <var>deferredRecord</var>'s <a for="deferred fetch record">request</a>'s
7058+
<a for=request>URL</a>'s <a for=url>origin</a> is <a>same origin</a> with <var>origin</var>,
7059+
then decrement <var>quotaForOrigin</var> by <var>requestLength</var>.
71027060
</ol>
71037061

7062+
<li><p><a for=list>For each</a> <var>navigable</var> in <var>controlDocument</var>'s
7063+
<a>node navigable</a>'s <a>descendant navigables</a> whose <a>container document</a>'s
7064+
<a>deferred-fetch control document</a> is <var>controlDocument</var>, decrement <var>quota</var> by
7065+
<var>navigable</var>'s <a>navigable container</a>'s <a>reserved deferred-fetch quota</a>.
7066+
71047067
<li><p>If <var>quota</var> is less than 0, then return 0.
71057068
<li><p>If <var>quota</var> is less than <var>quotaForOrigin</var>, then return <var>quota</var>.
71067069
<li><p>Return <var>quotaForOrigin</var>.
@@ -7123,32 +7086,36 @@ shared.
71237086
<ol>
71247087
<li><p>Set <var>container</var>'s <a>reserved deferred-fetch quota</a> to 0.
71257088

7089+
<li><p>Let <var>controlDocument</var> be <var>container</var>'s <a>node document</a>'s
7090+
<a>deferred-fetch control document</a>.
7091+
71267092
<li><p>If the <a data-lt="define an inherited policy for feature in container">inherited policy</a>
71277093
for "{{PermissionsPolicy/deferred-fetch}}", <var>container</var> and <var>originToNavigateTo</var>
71287094
is <code>Enabled</code>, and the <a>available deferred-fetch quota</a> for
7129-
<var>container</var>'s <a>container document</a> is equal or greater than
7095+
<var>controlDocument</var> is equal or greater than
71307096
<a for="reserved deferred-fetch quota">normal quota</a>, then set <var>container</var>'s
71317097
<a>reserved deferred-fetch quota</a> to <a for="reserved deferred-fetch quota">normal quota</a> and
71327098
return.
71337099

7134-
<li><p>If the <a data-lt="define an inherited policy for feature in container">inherited policy</a>
7135-
for "{{PermissionsPolicy/deferred-fetch-minimal}}", <var>container</var> and
7136-
<var>originToNavigateTo</var> is <code>Disabled</code>, then return.
7137-
7138-
<li><p>If <var>container</var>'s <a>node document</a>'s <a for=Document>origin</a> is not
7139-
<a>same origin</a> with <var>container</var>'s <a>node navigable</a>'s
7140-
<a for=navigable>top-level traversable</a>'s <a>active document</a>'s <a for=Document>origin</a>,
7141-
then return.
7142-
7143-
<li><p>Let <var>containersWithReservedMinimalQuota</var> be <var>container</var>'s
7144-
<a>node navigable</a>'s <a for=navigable>top-level traversable</a>'s
7145-
<a>descendant navigables</a>, <a for=list data-lt=remove>removing</a> any <a for=/>navigable</a>
7146-
whose <a>navigable container</a>'s <a>reserved deferred-fetch quota</a> is not
7147-
<a for="reserved deferred-fetch quota">minimal quota</a> .
7148-
7149-
<li><p>If <var>containersWithReservedMinimalQuota</var>'s <a for=list>size</a> is less
7150-
than <a>max containers with minimal quota</a>, then set <var>container</var>'s
7151-
<a>reserved deferred-fetch quota</a> to <a for="reserved deferred-fetch quota">minimal quota</a>.
7100+
<li>
7101+
<p>If all of the following conditions are true:
7102+
7103+
<ul class=brief>
7104+
<li><p><var>controlDocument</var>'s <a>node navigable</a> is a <a for=/>top-level traversable</a>
7105+
7106+
<li><p>The <a data-lt="define an inherited policy for feature in container">inherited policy</a>
7107+
for "{{PermissionsPolicy/deferred-fetch-minimal}}", <var>container</var> and
7108+
<var>originToNavigateTo</var> is <code>Enabled</code>
7109+
7110+
<li><p>The <a for=list>size</a> of <var>controlDocument</var>'s <a>node navigable</a>'s
7111+
<a>descendant navigables</a>, <a for=list data-lt=remove>removing</a> any <a for=/>navigable</a>
7112+
whose <a>navigable container</a>'s <a>reserved deferred-fetch quota</a> is not
7113+
<a for="reserved deferred-fetch quota">minimal quota</a>, is less than
7114+
<a>max containers with minimal quota</a>
7115+
</ul>
7116+
7117+
<p>then set <var>container</var>'s <a>reserved deferred-fetch quota</a> to
7118+
<a for="reserved deferred-fetch quota">minimal quota</a>.
71527119
</ol>
71537120
</div>
71547121

@@ -7165,6 +7132,17 @@ document creation, as the <a for=Document>origin</a> of the {{Document}} is only
71657132
redirects are handled.
71667133
</div>
71677134

7135+
<div algorithm>
7136+
<p>To get the <dfn>deferred-fetch control document</dfn> of a {{Document}} <var>document</var>:
7137+
7138+
<ol>
7139+
<li><p>If <var>document</var>' <a>node navigable</a>'s <a>container document</a> is null or a
7140+
{{Document}} whose <a for=Document>origin</a> is not <a>same origin</a> with <var>document</var>,
7141+
return <var>document</var>; Otherwise return the <a>deferred-fetch control document</a> given
7142+
<var>document</var>' <a>node navigable</a>'s <a>container document</a>.
7143+
</ol>
7144+
</div>
7145+
71687146

71697147
<h2 id=fetch-api>Fetch API</h2>
71707148

@@ -9084,22 +9062,24 @@ method steps are:
90849062
then throw a {{TypeError}}.
90859063

90869064
<li>
9087-
<p>If <var>request</var>'s
9088-
<a for=request>body</a> is not null, and <var>request</var>'s <a for=request>body</a>
9089-
<a for=body>length</a> is null, then throw a {{TypeError}}.
9065+
<p>If <var>request</var>'s <a for=request>body</a> is not null, and <var>request</var>'s
9066+
<a for=request>body</a> <a for=body>length</a> is null, then throw a {{TypeError}}.
90909067

90919068
<p class=note>Requests whose <a for=request>body</a> is a {{ReadableStream}} cannot be deferred.
90929069

9093-
<li><p>If the <a>available deferred-fetch quota</a> given <var>request</var>'s
9094-
<a for=request>client</a> and <var>request</var>'s <a for=request>URL</a>'s <a for=url>origin</a>
9095-
is less than <var>request</var>'s <a>total request length</a>, then throw a
9096-
"{{QuotaExceededError}}" {{DOMException}}.
9070+
<li><p>Let <var>controlDocument</var> be <var>request</var>'s <a for=request>client</var>'s
9071+
<a>deferred-fetch control document</a>.
9072+
9073+
<li><p>If the <a>available deferred-fetch quota</a> given <var>controlDocument</var> and
9074+
<var>request</var>'s <a for=request>URL</a>'s <a for=url>origin</a> is less than
9075+
<var>request</var>'s <a>total request length</a>, then throw a "{{QuotaExceededError}}"
9076+
{{DOMException}}.
90979077

90989078
<li><p>Let <var>activated</var> be false.
90999079

9100-
<li><p>Let <var>deferredRecord</var> be the result of calling
9101-
<a>queue a deferred fetch</a> given <var>request</var>, <var>activateAfter</var>, and the
9102-
following step: set <var>activated</var> to true.
9080+
<li><p>Let <var>deferredRecord</var> be the result of calling <a>queue a deferred fetch</a> given
9081+
<var>request</var>, <var>controlDocument</var>'s <a>fetch group</a>, <var>activateAfter</var>, and
9082+
the following step: set <var>activated</var> to true.
91039083

91049084
<li>
91059085
<p><a for=AbortSignal lt=add>Add the following abort steps</a> to <var>requestObject</var>'s
@@ -9108,9 +9088,8 @@ method steps are:
91089088
<ol>
91099089
<li><p>Set <var>deferredRecord</var>'s <a for="deferred fetch record">done</a> to true.
91109090

9111-
<li><p><a for=list>Remove</a> <var>deferredRecord</var> from
9112-
<var>request</var>'s <a for=request>client</a>'s <a for=fetch>fetch group</a>'s
9113-
<a for="fetch group">deferred fetch records</a>.
9091+
<li><p><a for=list>Remove</a> <var>deferredRecord</var> from <var>controlDocument</var>'s
9092+
<a for=fetch>fetch group</a>'s <a for="fetch group">deferred fetch records</a>.
91149093
</ol>
91159094

91169095
<li><p>Return a new {{FetchLaterResult}} whose

0 commit comments

Comments
 (0)