@@ -2777,7 +2777,7 @@ not <a for=Document>fully active</a>. It has the following <a for=struct>items</
2777
2777
false, <a for="fetch controller">terminate</a> <var> record</var> 's
2778
2778
<a for="fetch record">controller</a> .
2779
2779
2780
- <li><p> <a>Process or propagate deferred fetches</a> for <var> fetchGroup</var> .
2780
+ <li><p> <a>Process deferred fetches</a> for <var> fetchGroup</var> .
2781
2781
</ol>
2782
2782
2783
2783
@@ -6768,6 +6768,8 @@ sources, specifically task sources that can result in running scripts such as th
6768
6768
takes no arguments:
6769
6769
6770
6770
<ol>
6771
+ <li><p> Assert: <var> request</var> 's <a for=request>client</a> is a {{Document}} .
6772
+
6771
6773
<li><p> <a>Populate request from client</a> given <var> request</var> .
6772
6774
6773
6775
<li><p> Set <var> request</var> 's <a for=request>service-workers mode</a> to "<code> none</code> ".
@@ -6777,9 +6779,22 @@ takes no arguments:
6777
6779
<li><p> Let <var> deferredRecord</var> be a new <a>deferred fetch record</a> whose
6778
6780
<a for="deferred fetch record">request</a> is <var> request</var> .
6779
6781
6780
- <li><p> <a for=list>Append</a> <var> deferredRecord</var> to <var> request</var> 's
6781
- <a for=request>client</a> 's <a for=fetch>fetch group</a>' s
6782
- <a for="fetch group">deferred fetch records</a> .
6782
+ <li><p> Let <var> topMostDirectSameOriginAncestor</var> be var>request</var> 's
6783
+ <a for=request>client</a> .
6784
+
6785
+ <li><p> While <var> topMostDirectSameOriginAncestor</var> 's <a>node navigable</a>' s
6786
+ <a>container document</a> is a {{Document}} whose <a for=Document>origin</a> is <a>same origin</a>
6787
+ with <var> request</var> 's <a for=request>client</a>' s <a for=Document>origin</a> , set
6788
+ <var> topMostDirectSameOriginAncestor</var> to <var> topMostDirectSameOriginAncestor</var> 's
6789
+ <a>node navigable</a> 's <a>container document</a> .
6790
+
6791
+ <li>
6792
+ <p> <a for=list>Append</a> <var> deferredRecord</var> to
6793
+ <var> topMostDirectSameOriginAncestor</var> 's <a>active document</a>' s
6794
+ <a for=fetch>fetch group</a> 's <a for="fetch group">deferred fetch records</a> .
6795
+
6796
+ <p class=note> This prevents a case where eagerly creating and destroying nested documents would
6797
+ circumvent the keepalive quota.
6783
6798
6784
6799
<li>
6785
6800
<p> If <var> activateAfter</var> is non-null, then run the following steps <a>in parallel</a> :</p>
@@ -6829,26 +6844,11 @@ takes no arguments:
6829
6844
</div>
6830
6845
6831
6846
<div algorithm>
6832
- <p> To <dfn>process or propagate deferred fetches</dfn> given a <a>fetch group</a>
6847
+ <p> To <dfn>process deferred fetches</dfn> given a <a>fetch group</a>
6833
6848
<var> fetchGroup</var> , <a for=list>for each</a> <a for="fetch group">deferred fetch record</a>
6834
6849
<var> deferredRecord</var> of <var> fetchGroup</var> 's
6835
- <a for="fetch group">deferred fetch records</a> :
6836
-
6837
- <ol>
6838
- <li><p> Let <var> document</var> be <var> deferredRecord</var> 's
6839
- <a for="deferred fetch record">request</a> 's <a for=request>client</a> .
6840
-
6841
- <li><p> Let <var> parent</var> be <var> document</var> 's <a>node navigable</a>' s
6842
- <a>container document</a> .
6843
-
6844
- <li><p> If <var> parent</var> is a <a>fully active</a> {{Document}} whose
6845
- <a for=Document>origin</a> is <a>same origin</a> with <var> document</var> 's
6846
- <a for=Document>origin</a> , then set <var> deferredRecord</var> 's
6847
- <a for="deferred fetch record">request</a> 's <a for=request>client</a> to <var> parent</var> and
6848
- <a for=list>append</a> <var> deferredRecord</var> to <var> parent</var> 's
6849
- <a for=fetch>fetch group</a> 's <a for="fetch group">deferred fetch records</a> .
6850
-
6851
- <li><p> Otherwise, .
6850
+ <a for="fetch group">deferred fetch records</a> <a>process a deferred fetch</a>
6851
+ <var> deferredRecord</var> .
6852
6852
</ol>
6853
6853
</div>
6854
6854
@@ -6897,13 +6897,14 @@ opportunistically, before they have data to send.
6897
6897
<div class=example id=deferred-fetch-quota-examples>
6898
6898
<p> Any of the following calls to <a method><code>fetchLater()</code></a> would throw due to
6899
6899
the request itself exceeding the 64 kibibytes quota allocated to a reporting origin. Note that the
6900
- size of the request includes the <a for=request>URL</a> itself, the <a for=request>body</a> , and the
6901
- <a for=request>header list</a> .
6900
+ size of the request includes the <a for=request>URL</a> itself, the <a for=request>body</a> , the
6901
+ <a for=request>header list</a> , and the <a for=request>referrer</a> .
6902
6902
<pre><code class=lang-javascript>
6903
- fetchLater(a_64_kb_url );
6903
+ fetchLater(a_72_kb_url );
6904
6904
fetchLater("https://origin.example.com", {headers: headers_exceeding_64kb});
6905
6905
fetchLater(a_32_kb_url, {headers: headers_exceeding_32kb});
6906
6906
fetchLater("https://origin.example.com", {method: "POST", body: body_exceeding_64_kb});
6907
+ fetchLater(a_62_kb_url /* with a 3kb referrer */);
6907
6908
</code></pre>
6908
6909
6909
6910
<p> In the following sequence, the first two requests would succeed, but the third one would throw.
@@ -6923,125 +6924,69 @@ calls would succeed and the last one would throw.
6923
6924
// In main page
6924
6925
fetchLater("https://a.example.com", {method: "POST", body: a_64kb_body});
6925
6926
6926
- // In same-origin iframe
6927
+ // In same-origin nested document
6927
6928
fetchLater("https://b.example.com", {method: "POST", body: a_64kb_body});
6928
6929
6929
- // In cross-origin iframe at https://frame.example.com
6930
+ // In cross-origin nested document at https://frame.example.com
6930
6931
fetchLater("https://a.example.com", {body: a_5kb_body});
6931
6932
fetchLater("https://a.example.com", {body: a_12kb_body});
6932
6933
</code></pre>
6933
6934
6935
+
6934
6936
<p> To make the previous example not throw, the top-level {{Document}} can delegate some of its quota
6935
6937
to <code> https://frame.example.com</code> , for example by serving the following header:
6936
6938
<pre><code class=lang-http> Permissions-Policy: deferred-fetch=(self "https://frame.example.com")</code></pre>
6937
6939
6938
- <p> The following tables illustrates how quota is distributed to different iframes, each table
6939
- representing a different <a for=/>top-level traversable</a> ("tab").
6940
-
6941
- <p> For a tree with its top-level <code> Permissions-Policy</code> header set to
6942
- <code class=lang-http> deferred-fetch=(self "https://ok.example.com")</code> :
6943
-
6944
- <table>
6945
- <tr>
6946
- <th> Window name
6947
- <th> Parent
6948
- <th> Initial origin
6949
- <th> Current origin
6950
- <th> Quota
6951
- <tr>
6952
- <td><code> top</code>
6953
- <td><code> null</code>
6954
- <td><code> https://me.example.com</code>
6955
- <td><code> https://me.example.com</code>
6956
- <td> 384 kibibytes (512 - 64 - 64). <code> d</code> and frame <code> g</code> were granted
6957
- 64 kibibytes each, even though for <code> g</code> this quota ended up being unavailable.
6958
- <tr>
6959
- <td><code> a</code>
6960
- <td><code> top</code>
6961
- <td><code> https://me.example.com</code>
6962
- <td><code> https://me.example.com</code>
6963
- <td> Shared with <code> top</code> 's quota.
6964
- <tr>
6965
- <td><code> b</code>
6966
- <td><code> a</code>
6967
- <td><code> https://x.example.com</code>
6968
- <td><code> https://x.example.com</code>
6969
- <td> 8 kibibytes, due to the default "{{PermissionsPolicy/deferred-fetch-minimal}} " policy.
6970
- <tr>
6971
- <td><code> c</code>
6972
- <td><code> top</code>
6973
- <td><code> https://x.example.com</code>
6974
- <td><code> https://x.example.com</code>
6975
- <td> 8 kibibytes, due to the default "{{PermissionsPolicy/deferred-fetch-minimal}} " policy.
6976
- <tr>
6977
- <td><code> d</code>
6978
- <td><code> top</code>
6979
- <td><code> https://ok.example.com</code>
6980
- <td><code> https://ok.example.com</code>
6981
- <td> 64 kibibytes, due to the "{{PermissionsPolicy/deferred-fetch}} " policy.
6982
- <tr>
6983
- <td><code> e</code>
6984
- <td><code> d</code>
6985
- <td><code> https://x.example.com</code>
6986
- <td><code> https://x.example.com</code>
6987
- <td> 0, as its parent doesn't share the quota with the top-level document.
6988
- <tr>
6989
- <td><code> f</code>
6990
- <td><code> d</code>
6991
- <td><code> https://me.example.com</code>
6992
- <td><code> https://me.example.com</code>
6993
- <td> Shared with <code> top</code> 's quota.
6994
- <tr>
6995
- <td><code> g</code>
6996
- <td><code> top</code>
6997
- <td><code> https://ok.example.com</code>
6998
- <td><code> https://x.example.com</code>
6999
- <td> 0, as the reserved quota when navigating doesn't match the current {{PermissionsPolicy}} .
7000
- <tr>
7001
- <td><code> h</code>
7002
- <td><code> top</code>
7003
- <td><code> https://ok.example.com</code>
7004
- <td><code> https://me.example.com</code>
7005
- <td> Shared with <code> top</code> 's quota.
7006
- </table>
6940
+ <p> Each nested document reserves its own quota, and all the same-origin documents in the tree share
6941
+ quota with each other. So the following would work, because each frame reserve 8 kibibytes and they
6942
+ share the accumulated 16 kibibytes:
6943
+ <pre><code class=lang-javascript>
6944
+ // In cross-origin nested document at https://frame.example.com/frame-1
6945
+ fetchLater("https://a.example.com", {body: a_6kb_body});
7007
6946
7008
- <p> For a tree with its top-level <code> Permissions-Policy</code> header set to
7009
- <code class=lang-http> deferred-fetch-minimal=(); deferred-fetch=(self https://ok.example.com)</code> :
6947
+ // In cross-origin nested document at https://frame.example.com/frame-2
6948
+ fetchLater("https://a.example.com", {body: a_6kb_body});
6949
+ </code></pre>
7010
6950
7011
- <table>
7012
- <tr>
7013
- <th> Window name
7014
- <th> Parent
7015
- <th> Initial origin
7016
- <th> Current origin
7017
- <th> Quota
7018
- <tr>
7019
- <td><code> top</code>
7020
- <td><code> null</code>
7021
- <td><code> https://me.example.com</code>
7022
- <td><code> https://me.example.com</code>
7023
- <td> 576kb (640kb - 64kb). <code> c</code> was granted 64kb. Since "{{PermissionsPolicy/deferred-fetch-minimal}} "
7024
- was explicitly disabled, the initial top-level quota is 640kb instead of 512kb.
7025
- <tr>
7026
- <td><code> a</code>
7027
- <td><code> top</code>
7028
- <td><code> https://me.example.com</code>
7029
- <td><code> https://me.example.com</code>
7030
- <td> Shared with <code> top</code> 's quota.
7031
- <tr>
7032
- <td><code> b</code>
7033
- <td><code> a</code>
7034
- <td><code> https://x.example.com</code>
7035
- <td><code> https://x.example.com</code>
7036
- <td> 0, due to the "{{PermissionsPolicy/deferred-fetch-minimal}} " being explicitly disabled.
7037
- <tr>
7038
- <td><code> c</code>
7039
- <td><code> top</code>
7040
- <td><code> https://ok.example.com</code>
7041
- <td><code> https://ok.example.com</code>
7042
- <td> 64kb, due to the "{{PermissionsPolicy/deferred-fetch}} " policy.
7043
- </table>
6951
+ <p> The following chart illustrates how quota is distributed to different nested documents in a tree:
6952
+
6953
+ <pre><code>
6954
+ + https://me.example.com with Permissions-policy: deferred-fetch=(self "https://ok.example.com")
6955
+ |
6956
+ + ---- + https://me.example.com
6957
+ | | Shares quota with the <a for=/>top-level traversable</a> , as they're same origin.
6958
+ | |
6959
+ | + ---- + https://x.example.com
6960
+ | Shares 16 kibibytes together with one other cross-origin nested document of the same origin.
6961
+ |
6962
+ |
6963
+ + ---- + https://x.example.com
6964
+ | Shares 16 kibibytes together with one other cross-origin nested document of the same origin.
6965
+ |
6966
+ + ---- + https://ok.example.com/good
6967
+ | | 64 kibibytes, granted via the "{{PermissionsPolicy/deferred-fetch}} " policy.
6968
+ | |
6969
+ | + ---- + https://x.example.com
6970
+ | 0. Only documents with the same originas the <a for=/>top-level traversable</a> can grant
6971
+ | the 8 kibibytes
6972
+ |
6973
+ + ---- + https://ok.example.com/redirect, navigated to https://x.example.com
6974
+ | 0. The reserved 64 kibibytes for https://ok.example.com are not available for https://x.example.com.
6975
+ |
6976
+ + ---- + https://ok.example.com/back, navigated to https://me.example.com
6977
+ Shares quota with the <a for=/>top-level traversable</a> , as they're same origin.
6978
+ </code></pre>
7044
6979
6980
+ <p> In the above example, the <a for=/>top-level traversable</a> and its <a>same origin</a>
6981
+ descendants share a quota of 384 kibibytes. That value is computed as such:
6982
+ <ul>
6983
+ <li><p> 640 kibibytes are initially granted to the <a for=/>top-level traversable</a> .
6984
+ <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.
6989
+ </ul>
7045
6990
</div>
7046
6991
7047
6992
0 commit comments