Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 147 additions & 13 deletions fetch.bs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,23 @@ following <a for=struct>items</a>: [[RESOURCE-TIMING]] [[NAVIGATION-TIMING]]
<dd>An <a for=/>ASCII string</a>.
</dl>

<p>A <dfn>fetch retry params</dfn> is a <a for=/>struct</a> used to maintain bookkeeping details for
retrying <a method><code>fetch()</code></a> calls. It has the following <a for=struct>items</a>:
<dl>
<dt><dfn for="fetch retry params">expiry time</dfn>
<dd>A {{DOMHighResTimeStamp}}.

<dt><dfn for="fetch retry params">remaining attempts</dfn>
<dt><dfn for="fetch retry params">backoff factor</dfn>
<dt><dfn for="fetch retry params">next delay</dfn>
<dd>A number.

<dt><dfn for="fetch retry params">allow after unload</dfn>
<dt><dfn for="fetch retry params">allow non-idempotent methods</dfn>
<dt><dfn for="fetch retry params">allow post-connection errors</dfn>
<dd>A boolean.
</dl>

<div algorithm>
<p>To
<dfn export lt="create an opaque timing info|creating an opaque timing info">create an opaque timing info</dfn>,
Expand Down Expand Up @@ -2245,6 +2262,10 @@ Unless stated otherwise, it is unset.

<p class=note>This flag is for exclusive use by HTML's navigate algorithm. [[!HTML]]

<p>A <a for=/>request</a> has an associated
<dfn for=request>retry params</dfn> (null or a <a>fetch retry params</a>). Unless stated otherwise,
it is null.

<p>A <a for=/>request</a> has an associated boolean <dfn export for=request>user-activation</dfn>.
Unless stated otherwise, it is false.

Expand Down Expand Up @@ -2600,6 +2621,9 @@ this is also tracked internally using the request's <a for=request>timing allow
("<code>same-origin</code>", "<code>same-site</code>", or "<code>cross-site</code>"), which is
initially "<code>same-origin</code>".

<p>A <a for=/>response</a> has an associated boolean <dfn for=response>potentially transient</dfn>,
which is initially false.

<hr>

<p>A <dfn export id=concept-network-error>network error</dfn> is a <a for=/>response</a> whose
Expand Down Expand Up @@ -2884,12 +2908,22 @@ invoke a fetch at a later time, e.g., when a document is unloaded or becomes not
<dfn export for="fetch group" id=concept-fetch-group-terminate>terminated</dfn>:

<ol>
<li><p><a for=list>For each</a> <a for="fetch group">fetch record</a> <var>record</var> of
<var>fetchGroup</var>'s <a for="fetch group">fetch records</a>, if <var>record</var>'s
<a for="fetch record">controller</a> is non-null and <var>record</var>'s
<a for="fetch record">request</a>'s <a>done flag</a> is unset and <a for=request>keepalive</a> is
false, <a for="fetch controller">terminate</a> <var>record</var>'s
<a for="fetch record">controller</a>.
<li>
<p><a for=list>For each</a> <a for="fetch group">fetch record</a> <var>record</var> of
<var>fetchGroup</var>'s <a for="fetch group">fetch records</a>:

<ol>
<li>
<p>If <var>record</var>'s <a for="fetch record">controller</a> is non-null and
<var>record</var>'s <a for="fetch record">request</a>'s <a>done flag</a> is unset and <a
for=request>keepalive</a> is false,

<p><a>terminate</a> <var>record</var>'s <a for="fetch record">controller</a>.

<li><p>If <var>record</var>'s <a for="fetch record">request</a>'s <a for=request>retry params</a>
is non-null and its <a for="fetch retry params">allow after unload</a> is false, set
<var>record</var>'s <a for="fetch record">request</a>'s <a for=request>retry params</a> to null.
</ol>

<li><p><a>Process deferred fetches</a> for <var>fetchGroup</var>.
</ol>
Expand Down Expand Up @@ -5088,7 +5122,7 @@ steps:
<p>If <var>request</var>'s <a for=request>integrity metadata</a> is not the empty string, then:

<ol>
<li><p>Let <var>processBodyError</var> be this step: run <a>fetch response handover</a> given
<li><p>Let <var>processBodyError</var> be this step: <a>retry or process response</a> given
<var>fetchParams</var> and a <a>network error</a>.

<li><p>If <var>response</var>'s <a for=response>body</a> is null, then run
Expand All @@ -5105,20 +5139,83 @@ steps:
<li><p>Set <var>response</var>'s <a for=response>body</a> to <var>bytes</var>
<a for="byte sequence">as a body</a>.

<li><p>Run <a>fetch response handover</a> given <var>fetchParams</var> and <var>response</var>.
<li><p><a>Retry or process response</a> given <var>fetchParams</var> and <var>response</var>.
</ol>

<li><p><a for=body>Fully read</a> <var>response</var>'s <a for=response>body</a> given
<var>processBody</var> and <var>processBodyError</var>.
</ol>

<li><p>Otherwise, run <a>fetch response handover</a> given <var>fetchParams</var> and
<var>response</var>.
<li><p><a>Retry or process response</a> given <var>fetchParams</var> and <var>response</var>.
</ol>
</div>

<hr>

<div algorithm>
<p>To <dfn>retry or process response</dfn> given <var>fetchParams</var> and <var>response</var>, run
the steps corresponding to the first matching statement:

<dl class="switch">
<dt><var>response</var> is not a <a>network error</a>
<dt><var>fetchParams</var>'s <a for="fetch params">request</a>'s <a for=request>retry params</a> is
null

<dd>Run <a>fetch response handover</a> given <var>fetchParams</var> and <var>response</var>.

<dt><var>fetchParams</var>'s <a for="fetch params">request</a>'s <a for=request>retry params</a>'s
<a for="fetch retry params">expiry time</a> is before the <a for=/>coarsened shared current
time</a> given <var>fetchParams</var>'s <a for="fetch params">cross-origin isolated capability</a>

<dt><var>fetchParams</var>'s <a for="fetch params">request</a>'s <a for=request>retry
params</a>'s <a for="fetch retry params">remaining attempts</a> is 0
<dt><var>fetchParams</var>'s <a for="fetch params">request</a>'s <a for=request>method</a> is
`<code>POST</code>`, `<code>PUT</code>`, `<code>PATCH</code>`, or `<code>DELETE</code>`, and
<var>retryParams</var>'s <a for="fetch retry params">allow non-idempotent methods</a> is false

<dt><var>response</var> is not <a for="response">potentially transient</a>

<dd>
<ol>
<li><p>Wait until the <a for=/>coarsened shared current time</a> given
<var>fetchParams</var>'s <a for="fetch params">cross-origin isolated capability</a> is
<var>fetchParams</var>'s <a for="fetch params">request</a>'s <a for=request>retry params</a>'s
<a for="fetch retry params">expiry time</a>.

<li><p>Run <a>fetch response handover</a> given <var>fetchParams</var> and <var>response</var>.
</ol>

<dt>Otherwise
<dd>
<ol>
<li><p>Let <var>retryParams</var> be <var>fetchParams</var>'s <a for="fetch params">request</a>'s
<a for=request>retry params</a>.

<li><p>Let <var>errorTime</var> be the <a for=/>coarsened shared current time</a>given
<var>fetchParams</var>'s <a for="fetch params">cross-origin isolated capability</a>.

<li><p>Let <var>expiryTime</var> be <var>errorTime</var> + <var>retryParams</var>'s <a
for="fetch retry params">next delay</a>.

<li><p>Decrement <var>retryParams</var>'s <a for="fetch retry params">remaining attempts</a> by
1.

<li><p>Multiply <var>retryParams</var>'s <a for="fetch retry params">next delay</a> by
<var>retryParams</var>'s <a for="fetch retry params">backoff factor</a>.

<li><p>Wait until the <a for=/>coarsened shared current time</a> given
<var>fetchParams</var>'s <a for="fetch params">cross-origin isolated capability</a> is
<var>expiryTime</var>.

<li><p>Run <a>main fetch</a> given <var>fetchParams</var>.
</ol>
</dl>


</div>

<hr>

<div algorithm>
<p>The <dfn id=fetch-finale>fetch response handover</dfn>, given a <a for=/>fetch params</a>
<var>fetchParams</var> and a <a for=/>response</a> <var>response</var>, run these steps:
Expand Down Expand Up @@ -6507,7 +6604,7 @@ optional boolean <var>forceNewConnection</var> (default false), run these steps:
<li><p>Let <var>request</var> be <var>fetchParams</var>'s <a for="fetch params">request</a>.

<li><p>If <var>request</var>'s <a for=request>client</a> <a>is offline</a>, then return a
<a>network error</a>.
<a>network error</a> whose <a for=response>potentially transient</a> is true.

<li><p>Let <var>response</var> be null.

Expand Down Expand Up @@ -6544,7 +6641,8 @@ optional boolean <var>forceNewConnection</var> (default false), run these steps:
<a for="fetch params">canceled</a>:

<ol>
<li><p>If <var>connection</var> is failure, then return a <a>network error</a>.
<li><p>If <var>connection</var> is failure, then return a <a>network error</a> whose <a
for=response>potentially transient</a> is true.

<li><p>Set <var>timingInfo</var>'s <a for="fetch timing info">final connection timing info</a> to
the result of calling <a>clamp and coarsen connection timing info</a> with
Expand Down Expand Up @@ -6598,8 +6696,15 @@ optional boolean <var>forceNewConnection</var> (default false), run these steps:
agent's HTTP parser receives the first byte of the response (e.g., frame header bytes for
HTTP/2 or response status line for HTTP/1.x).

<li><p>If <var>fetchParams</var>'s <a for="fetch params">request</a>'s <a for=request>retry
params</a> is non-null and its <a for="fetch retry params">allow post-connection errors</a>
is false, then set <a for="fetch params">request</a>'s <a for=request>retry params</a> to null.

<li><p>Wait until all the HTTP response headers are transmitted.

<li><p>If the connection was lost, reset, or timed out, then return a
<a>network error</a> whose <a for=response>potentially transient</a> is true.

<li><p>Let <var>status</var> be the HTTP response's status code.

<li>
Expand Down Expand Up @@ -8404,6 +8509,16 @@ interface Request {
};
Request includes Body;

dictionary RetryOptions {
[EnforceRange] required unsigned short maxAttempts;
[EnforceRange] unsigned long long initialDelay;
double backoffFactor;
[EnforceRange] unsigned long long maxAge;
boolean retryAfterUnload;
boolean retryNonIdempotent;
boolean retryOnlyIfServerUnreached;
};

dictionary RequestInit {
ByteString method;
HeadersInit headers;
Expand All @@ -8420,6 +8535,7 @@ dictionary RequestInit {
RequestDuplex duplex;
RequestPriority priority;
any window; // can only be set to null
[SecureContext] RetryOptions retryOptions;
};

enum RequestDestination { "", "audio", "audioworklet", "document", "embed", "font", "frame", "iframe", "image", "json", "manifest", "object", "paintworklet", "report", "script", "sharedworker", "style", "text", "track", "video", "worker", "xslt" };
Expand Down Expand Up @@ -8858,6 +8974,24 @@ constructor steps are:
<li><p>If <var>init</var>["{{RequestInit/keepalive}}"] <a for=map>exists</a>, then set
<var>request</var>'s <a for=request>keepalive</a> to it.

<li>
<p>If <var>init</var>["{{RequestInit/retryOptions}}"] <a for=map>exists</a>, then:

<ol>
<li><p>Let <var>options</var> be <var>init</var>["{{RequestInit/retryOptions}}"].

<li><p>Set <var>request</var>'s <a for=request>retry params</a> to a new <a>fetch retry params</a> whose
<a for="fetch retry params">remaining attempts</a> is <var>options</var>["{{RetryOptions/maxAttempts}}"],
<a for="fetch retry params">backoff factor</a> is <var>options</var>["{{RetryOptions/backoffFactor}}"] if it <a for=map>exists</a> and 1.0 otherwise,
<a for="fetch retry params">next delay</a> is <var>options</var>["{{RetryOptions/initialDelay}}"] if it <a for=map>exists</a> and 0 otherwise,
<a for="fetch retry params">allow after unload</a> is <var>options</var>["{{RetryOptions/retryAfterUnload}}"] if it <a for=map>exists</a> and false otherwise,
<a for="fetch retry params">allow non-idempotent methods</a> is <var>options</var>["{{RetryOptions/retryNonIdempotent}}"] if it <a for=map>exists</a> and false otherwise, and
<a for="fetch retry params">allow post-connection errors</a> is the negation of <var>options</var>["{{RetryOptions/retryOnlyIfServerUnreached}}"] if it <a for=map>exists</a> and true otherwise.

<li><p>If <var>options</var>["{{RetryOptions/maxAge}}"] <a for=map>exists</a>, then set
<var>request</var>'s <a for=request>retry params</a>'s <a for="fetch retry params">expiry time</a> to the result of adding <var>options</var>["{{RetryOptions/maxAge}}"] to the current time.
</ol>

<li>
<p>If <var>init</var>["{{RequestInit/method}}"] <a for=map>exists</a>, then:

Expand Down Expand Up @@ -9466,7 +9600,7 @@ method steps are:

<li>
<p><p>Set <var>controller</var> to the result of calling <a for=/>fetch</a> given
<var>request</var> and <a for=fetch><i>processResponse</i></a> given <var>response</var> being
<var>request</var>, and <a for=fetch><i>processResponse</i></a> given <var>response</var> being
these steps:

<ol>
Expand Down