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