Skip to content

Commit 4c07c9c

Browse files
committed
Update algorithm to only share quota for direct relatives
1 parent ef6c324 commit 4c07c9c

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
@@ -6761,14 +6761,12 @@ sources, specifically task sources that can result in running scripts such as th
67616761
<a method><code>fetchLater()</code></a> call before running any scripts that might depend on it.
67626762

67636763
<div algorithm>
6764-
<p>To <dfn>queue a deferred fetch</dfn> given a
6765-
<a for=/>request</a> <var>request</var>, a null or {{DOMHighResTimeStamp}}
6764+
<p>To <dfn>queue a deferred fetch</dfn> given a <a for=/>request</a> <var>request</var>, a
6765+
<a for=fetch>fetch group</a> <var>fetchGroup</var> a null or {{DOMHighResTimeStamp}}
67666766
<var>activateAfter</var>, an <var>onActivatedWithoutTermination</var>, which is an algorithm that
67676767
takes no arguments:
67686768

67696769
<ol>
6770-
<li><p>Assert: <var>request</var>'s <a for=request>client</a> is a {{Document}}.
6771-
67726770
<li><p><a>Populate request from client</a> given <var>request</var>.
67736771

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

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

67956783
<p class=note>This prevents a case where eagerly creating and destroying nested documents would
67966784
circumvent the keepalive quota.
@@ -6869,15 +6857,15 @@ takes no arguments:
68696857

68706858
<!-- non-normative -->
68716859
<p>The deferred-fetch quota is allocated to a <a for=/>top-level traversable</a> (a "tab"),
6872-
amounting to 640 kibibytes. The top-level {{Document}} and its same-origin nested documents can
6873-
use this quota to queue deferred fetches, or delegate some of it to cross-origin nested documents,
6874-
using permissions policy.
6860+
amounting to 640 kibibytes. The top-level {{Document}} and its same-origin directly nested documents
6861+
can use this quota to queue deferred fetches, or delegate some of it to cross-origin nested
6862+
documents, using permissions policy.
68756863

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

6879-
<p>The top-level {{Document}}, and subsequently its nested documents, can control how much of their quota
6880-
is delegates to cross-origin/cross-agent nested documents, by using permissions policy.
6867+
<p>The top-level {{Document}}, and subsequently its nested documents, can control how much of their
6868+
quota is delegates to cross-origin/cross-agent nested documents, by using permissions policy.
68816869
By default, "{{PermissionsPolicy/deferred-fetch-minimal}}" is enabled for any origin, while
68826870
"{{PermissionsPolicy/deferred-fetch}}" is enabled for the top-level document's origin only.
68836871
By relaxing the "{{PermissionsPolicy/deferred-fetch}}" policy for particular origins and nested
@@ -6936,9 +6924,8 @@ calls would succeed and the last one would throw.
69366924
to <code>https://frame.example.com</code>, for example by serving the following header:
69376925
<pre><code class=lang-http>Permissions-Policy: deferred-fetch=(self "https://frame.example.com")</code></pre>
69386926

6939-
<p>Each nested document reserves its own quota, and all the same-origin documents in the tree share
6940-
quota with each other. So the following would work, because each frame reserve 8 kibibytes and they
6941-
share the accumulated 16 kibibytes:
6927+
<p>Each nested document reserves its own quota. So the following would work, because each frame
6928+
reserve 8 kibibytes:
69426929
<pre><code class=lang-javascript>
69436930
// In cross-origin nested document at https://frame.example.com/frame-1
69446931
fetchLater("https://a.example.com", {body: a_6kb_body});
@@ -6957,11 +6944,15 @@ share the accumulated 16 kibibytes:
69576944
| | Shares quota with the <a for=/>top-level traversable</a>, as they're same origin.
69586945
| |
69596946
| + ---- + https://x.example.com
6960-
| Shares 16 kibibytes together with one other cross-origin nested document of the same origin.
6947+
| 8 kibibytes.
69616948
|
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.
6952+
| |
6953+
| + https://me.example.com
6954+
| 0. Even though it's same origin with the <a for=/>top-level traversable</a>, it does not
6955+
| automatically share its quota as they are separated by a cross-origin intermediary.
69656956
|
69666957
+ ---- + https://ok.example.com/good
69676958
| | 64 kibibytes, granted via the "{{PermissionsPolicy/deferred-fetch}}" policy.
@@ -6982,10 +6973,12 @@ descendants share a quota of 384 kibibytes. That value is computed as such:
69826973
<ul>
69836974
<li><p>640 kibibytes are initially granted to the <a for=/>top-level traversable</a>.
69846975
<li><p>128 kibibytes are reserved for the "{{PermissionsPolicy/deferred-fetch-minimal}}" policy.
6985-
<li><p>64 kibibytes are reserved for the container navigating to <code>https://ok.example/good</code>.
6986-
<li><p>64 kibibytes are reserved for the container navigating to <code>https://ok.example/redirect</code>, and lost when it navigates away.
6987-
<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.
6988-
<li><p>640 - 128 - 64 - 64 = 384 kibibytes.
6976+
<li><p>64 kibibytes are reserved for the container navigating to
6977+
<code>https://ok.example/good</code>.
6978+
<li><p>64 kibibytes are reserved for the container navigating to
6979+
<code>https://ok.example/redirect</code>, and lost when it navigates away.
6980+
<li><code>https://ok.example.com/back</code> did not reserve 64 kibibytes, because it navigated
6981+
back to <a for=/>top-level traversable</a>'s origin. <li><p>640 - 128 - 64 - 64 = 384 kibibytes.
69896982
</ul>
69906983
</div>
69916984

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

7001-
<p>The <dfn>optional nested document deferred-fetch quota</dfn> is 64 kibibytes.
7002-
<p>The <dfn>minimal nested document deferred-fetch quota</dfn> is 8 kibibytes.
70036994
<p>The <dfn>max containers with minimal quota</dfn> is 16.
70046995

7005-
70066996
<div algorithm>
70076997
<p>To get the <dfn>available deferred-fetch quota</dfn> given a {{Document}}
7008-
<var>requestClientDocument</var> and an <a for=/>origin</a>-or-null <var>origin</var>:
6998+
<var>controlDocument</var> and an <a for=/>origin</a>-or-null <var>origin</var>:
70096999

70107000
<ol>
70117001
<li><p>Let <var>quota</var> be 0.
70127002

70137003
<li><p>Let <var>quotaForOrigin</var> be 64 kibibytes.
70147004

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

70247009
<ol>
7025-
<li><p>Let <var>otherDocument</var> be <var>otherNavigable</var>'s <a>active document</a>.
7026-
<li><p>Let <var>otherContainer</var> be <var>otherNavigable</var>'s <a>navigable container</a>.
7010+
<li><p>If <var>controlDocument</var> is not <a>allowed to use</a> the
7011+
<a>policy-controlled feature</a> "{{PermissionsPolicy/deferred-fetch}}", then return 0.
70277012

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

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

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

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

7083-
<li><p>Decrement <var>quota</var> by <var>requestLength</var>.
7042+
<li>
7043+
<p><a for=list>For each</a> <a>deferred fetch record</a> <var>deferredRecord</var> of
7044+
<var>controlDocument</var>'s <a>fetch group</a>'s
7045+
<a for="fetch group">deferred fetch records</a>:</p>
70847046

7085-
<li><p>If <var>deferredRecord</var>'s <a for="deferred fetch record">request</a>'s
7086-
<a for=request>URL</a>'s <a for=url>origin</a> is <a>same origin</a> with <var>origin</var>,
7087-
then decrement <var>quotaForOrigin</var> by <var>requestLength</var>.
7088-
</ol>
7089-
</ol>
7047+
<ol>
7048+
<li><p>Let <var>requestLength</var> be the <a>total request length</a> of
7049+
<var>deferredRecord</var>'s <a for="deferred fetch record">request</a>.
70907050

7091-
<li>
7092-
<p>If <var>otherDocument</var>'s <a>container document</a> is a {{Document}} whose
7093-
<a for=Document>origin</a> is <a>same origin</a> with <var>requestClientDocument</var>'s
7094-
<a for=Document>origin</a>, then decrement <var>quota</var> by <var>otherContainer</var>'s
7095-
<a>reserved deferred-fetch quota</a>.
7051+
<li><p>Decrement <var>quota</var> by <var>requestLength</var>.
70967052

7097-
<p class=note>Account for quota granted to child documents.
7053+
<li><p>If <var>deferredRecord</var>'s <a for="deferred fetch record">request</a>'s
7054+
<a for=request>URL</a>'s <a for=url>origin</a> is <a>same origin</a> with <var>origin</var>,
7055+
then decrement <var>quotaForOrigin</var> by <var>requestLength</var>.
70987056
</ol>
70997057

7058+
<li><p><a for=list>For each</a> <var>navigable</var> in <var>controlDocument</var>'s
7059+
<a>node navigable</a>'s <a>descendant navigables</a> whose <a>container document</a>'s
7060+
<a>deferred-fetch control document</a> is <var>controlDocument</var>, decrement <var>quota</var> by
7061+
<var>navigable</var>'s <a>navigable container</a>'s <a>reserved deferred-fetch quota</a>.
7062+
71007063
<li><p>If <var>quota</var> is less than 0, then return 0.
71017064
<li><p>If <var>quota</var> is less than <var>quotaForOrigin</var>, then return <var>quota</var>.
71027065
<li><p>Return <var>quotaForOrigin</var>.
@@ -7119,32 +7082,36 @@ shared.
71197082
<ol>
71207083
<li><p>Set <var>container</var>'s <a>reserved deferred-fetch quota</a> to 0.
71217084

7085+
<li><p>Let <var>controlDocument</var> be <var>container</var>'s <a>node document</a>'s
7086+
<a>deferred-fetch control document</a>.
7087+
71227088
<li><p>If the <a data-lt="define an inherited policy for feature in container">inherited policy</a>
71237089
for "{{PermissionsPolicy/deferred-fetch}}", <var>container</var> and <var>originToNavigateTo</var>
71247090
is <code>Enabled</code>, and the <a>available deferred-fetch quota</a> for
7125-
<var>container</var>'s <a>container document</a> is equal or greater than
7091+
<var>controlDocument</var> is equal or greater than
71267092
<a for="reserved deferred-fetch quota">normal quota</a>, then set <var>container</var>'s
71277093
<a>reserved deferred-fetch quota</a> to <a for="reserved deferred-fetch quota">normal quota</a> and
71287094
return.
71297095

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

@@ -7161,6 +7128,17 @@ document creation, as the <a for=Document>origin</a> of the {{Document}} is only
71617128
redirects are handled.
71627129
</div>
71637130

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

71657143
<h2 id=fetch-api>Fetch API</h2>
71667144

@@ -9076,22 +9054,24 @@ method steps are:
90769054
then throw a {{TypeError}}.
90779055

90789056
<li>
9079-
<p>If <var>request</var>'s
9080-
<a for=request>body</a> is not null, and <var>request</var>'s <a for=request>body</a>
9081-
<a for=body>length</a> is null, then throw a {{TypeError}}.
9057+
<p>If <var>request</var>'s <a for=request>body</a> is not null, and <var>request</var>'s
9058+
<a for=request>body</a> <a for=body>length</a> is null, then throw a {{TypeError}}.
90829059

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

9085-
<li><p>If the <a>available deferred-fetch quota</a> given <var>request</var>'s
9086-
<a for=request>client</a> and <var>request</var>'s <a for=request>URL</a>'s <a for=url>origin</a>
9087-
is less than <var>request</var>'s <a>total request length</a>, then throw a
9088-
"{{QuotaExceededError}}" {{DOMException}}.
9062+
<li><p>Let <var>controlDocument</var> be <var>request</var>'s <a for=request>client</var>'s
9063+
<a>deferred-fetch control document</a>.
9064+
9065+
<li><p>If the <a>available deferred-fetch quota</a> given <var>controlDocument</var> and
9066+
<var>request</var>'s <a for=request>URL</a>'s <a for=url>origin</a> is less than
9067+
<var>request</var>'s <a>total request length</a>, then throw a "{{QuotaExceededError}}"
9068+
{{DOMException}}.
90899069

90909070
<li><p>Let <var>activated</var> be false.
90919071

9092-
<li><p>Let <var>deferredRecord</var> be the result of calling
9093-
<a>queue a deferred fetch</a> given <var>request</var>, <var>activateAfter</var>, and the
9094-
following step: set <var>activated</var> to true.
9072+
<li><p>Let <var>deferredRecord</var> be the result of calling <a>queue a deferred fetch</a> given
9073+
<var>request</var>, <var>controlDocument</var>'s <a>fetch group</a>, <var>activateAfter</var>, and
9074+
the following step: set <var>activated</var> to true.
90959075

90969076
<li>
90979077
<p><a for=AbortSignal lt=add>Add the following abort steps</a> to <var>requestObject</var>'s
@@ -9100,9 +9080,8 @@ method steps are:
91009080
<ol>
91019081
<li><p>Set <var>deferredRecord</var>'s <a for="deferred fetch record">done</a> to true.
91029082

9103-
<li><p><a for=list>Remove</a> <var>deferredRecord</var> from
9104-
<var>request</var>'s <a for=request>client</a>'s <a for=fetch>fetch group</a>'s
9105-
<a for="fetch group">deferred fetch records</a>.
9083+
<li><p><a for=list>Remove</a> <var>deferredRecord</var> from <var>controlDocument</var>'s
9084+
<a for=fetch>fetch group</a>'s <a for="fetch group">deferred fetch records</a>.
91069085
</ol>
91079086

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

0 commit comments

Comments
 (0)