Skip to content

Commit

Permalink
enforce payload limits via Fetch API
Browse files Browse the repository at this point in the history
Beacon requests are allowed to continue while/if a fetch group is being
terminated - e.g. as the page unloads. To ensure that such requests do
not negatively affect the consequent navigation, or incur high costs for
the user, we limit the amount of data that can be queued via this
method.

The enforcement is applied within Fetch API, which tracks the amount of
in-flight data queued with the `keepalive` flag set, and returns a
network error if the limit is exceeded.

Background: #38
  • Loading branch information
igrigorik committed Nov 11, 2016
1 parent ff26009 commit cf2d0ac
Showing 1 changed file with 81 additions and 75 deletions.
156 changes: 81 additions & 75 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,16 @@ <h2>Introduction</h2>
request and may be combined with [[SERVICE-WORKERS]] to provide offline
functionality where necessary.</li>
<li>The <code>sendBeacon</code> method is not intended to provide
background synchronization or transfer capabilities. The user agent is
allowed to restrict the maximum accepted payload size to ensure that
background synchronization or transfer capabilities. The user agent
restricts the maximum accepted payload size to ensure that
beacon requests are able to complete quickly and in a timely manner.</li>
<li>The <code>sendBeacon</code> method does not provide ability to customize the request method, provide custom request headers, or change other <a href="#sec-processing-model">processing properties</a> of the request and response. Applications that require non-default settings for such requests should use the [[FETCH]] API with <a href="#concept-keep-alive-flag">keepalive flag</a> set to <code>true</code>.</li>
<li>The <code>sendBeacon</code> method does not provide ability to
customize the request method, provide custom request headers, or change
other <a href="#sec-processing-model">processing properties</a> of the
request and response. Applications that require non-default settings for
such requests should use the [[FETCH]] API with
<a href="#concept-keep-alive-flag">keepalive flag</a> set to
<code>true</code>.</li>
</ul>
</section>
<section id="conformance-requirements">
Expand Down Expand Up @@ -358,9 +364,14 @@ <h2><code>sendBeacon</code> Method</h2>
"#data-parameter"><code>data</code></a> parameter to the URL provided by
the <a href="#url-parameter"><code>url</code></a> parameter:</p>
<ul>
<li>The user agent SHOULD restrict the maximum <code>data</code> size
<li>The user agent MUST restrict the maximum <code>data</code> size
to ensure that beacon requests are able to complete quickly and in a
timely manner.</li>
<li>The user agent MUST schedule immediate transmission of all beacon
requests when the document <code>visiblityState</code>
([[!PAGE-VISIBILITY]]) transitions to <code>hidden</code>, and must
allow all such requests to run to completion without blocking other
time-critical and high-priority work.</li>
<li>The user agent SHOULD schedule transmission of provided data to
minimize resource (CPU and network) contention with other time-critical
and high priority work.</li>
Expand All @@ -370,15 +381,10 @@ <h2><code>sendBeacon</code> Method</h2>
agent SHOULD NOT delay transmission indefinitely and ensure that
pending transmissions are periodically flushed even if there is no
other network activity.</li>
<li>The user agent MUST schedule immediate transmission of all beacon
requests when the document <code>visiblityState</code>
([[!PAGE-VISIBILITY]]) transitions to <code>hidden</code>, and must
allow all such requests to run to completion without blocking other
time-critical and high-priority work.</li>
</ul>

<div class="note">Beacon API does not provide a response callback. The server is encouraged to omit returning a response body for such requests (e.g. respond with <code>204 No Content</code>).</div>

<div class="note">Beacon API does not provide a response callback. The
server is encouraged to omit returning a response body for such requests
(e.g. respond with <code>204 No Content</code>).</div>
<div class="parameters">
<h4 id="parameters">Parameters</h4>
<h4 id="url-parameter"><code>url</code></h4>
Expand All @@ -393,13 +399,15 @@ <h4 id="return-values">Return Value</h4>
<p>The <a href="#dom-navigator-sendbeacon"><code>sendBeacon</code></a>
method returns true if the user agent is able to successfully queue the
data for transfer. Otherwise it returns false.</p>
<p class="note">If the user agent limits the amount of data that can be
queued to be sent using this API and the size of <var>data</var> causes
that limit to be exceeded, this method returns false. A return value of
true implies the browser has queued the data for transfer. However,
since the actual data transfer happens asynchronously, this method does
not provide any information whether the data transfer has succeeded or
not.</p>
<p class="note">The user agent imposes limits on the amount of data that
can be sent via this API: this helps ensure that such requests are
delivered successfully and with minimal impact on other user and browser
activity. If the amount of <var>data</var> to be queued exceeds the
user agent limit, this method returns <code>false</code>; a return
value of <code>true</code> implies the browser has queued the data for
transfer. However, since the actual data transfer happens
asynchronously, this method does not provide any information whether
the data transfer has succeeded or not.</p>
</div>
</section>
<section id="sec-processing-model">
Expand Down Expand Up @@ -430,13 +438,7 @@ <h2>Processing Model</h2>
"<code><a>TypeError</a></code>" exception and terminate these
steps.</p>
</li>
<li>
<p>If <var>data</var> is not null and if the user agent limits the
amount of data that can be queued to be sent using this API and the
size of <var>data</var> causes that limit to be exceeded, terminate
these steps and set the return value to false.</p>
</li>
<li>Otherwise, create the following temporary variables:
<li>If <var>data</var> is not <code>null</code>:
<ul>
<li>
<a href=
Expand All @@ -445,7 +447,7 @@ <h2>Processing Model</h2>
(<var>mimeType</var>).
</li>
<li>Let <var>corsMode</var> be "<code>cors</code>".</li>
<li>Let <var>headerList</var> be null.</li>
<li>Let <var>headerList</var> be <code>null</code>.</li>
</ul>
</li>
<li>If <var>mimeType</var> is not null:
Expand All @@ -459,54 +461,58 @@ <h2>Processing Model</h2>
<var>mimeType</var> to <var>headerList</var>.</li>
</ul>
</li>
<li>Set the return value to true and return the
<code>sendBeacon()</code> call, but continue to runs the following
steps. These steps may be run even after the document has
unloaded.</li>
<li>
<p>Let <var>req</var> be a new <a>request</a>, initialized as
follows:</p>
<dl>
<dt>
<a>method</a>
</dt>
<dd><code>POST</code></dd>
<dt>
<a>url</a>
</dt>
<dd><var>parsedUrl</var></dd>
<dt>
<a>header list</a>
</dt>
<dd><var>headerList</var></dd>
<dt>
<a>origin</a>
</dt>
<dt>
<a>referrer</a>
</dt>
<dd><var>referrer</var></dd>
<dt>
<a>keep-alive flag</a>
</dt>
<dd><code>true</code></dd>
<dt>
<a>body</a>
</dt>
<dd><var>transmittedData</var></dd>
<dt>
<a>mode</a>
</dt>
<dd><var>corsMode</var></dd>
<dt>
<a>credentials mode</a>
</dt>
<dd><i>include</i></dd>
</dl>
</li>
<li>
<a>Fetch</a> <var>req</var>.
</li>
<li>Run the following <a href="https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel">
in parallel</a> (TODO: this doesn't work...):</li>
<ol>
<li>
<p>Let <var>req</var> be a new <a>request</a>, initialized as
follows:</p>
<dl>
<dt>
<a>method</a>
</dt>
<dd><code>POST</code></dd>
<dt>
<a>url</a>
</dt>
<dd><var>parsedUrl</var></dd>
<dt>
<a>header list</a>
</dt>
<dd><var>headerList</var></dd>
<dt>
<a>origin</a>
</dt>
<dt>
<a>referrer</a>
</dt>
<dd><var>referrer</var></dd>
<dt>
<a>keep-alive flag</a>
</dt>
<dd><code>true</code></dd>
<dt>
<a>body</a>
</dt>
<dd><var>transmittedData</var></dd>
<dt>
<a>mode</a>
</dt>
<dd><var>corsMode</var></dd>
<dt>
<a>credentials mode</a>
</dt>
<dd><i>include</i></dd>
</dl>
</li>
<li>
<a>Fetch</a> <var>req</var>.
</li>
<li>(TODO) Fetch, as specced, will retun a network error if the size of
the payload exceeds some UA defined limit (which we can recommend) to
be &lt;64KB. However, if we're below limit it'll continue running...
How/can we get a return code without blocking on fetch?</li>
</ol>
</ol>
</section>
<section id="privacy" class="informative">
Expand Down

0 comments on commit cf2d0ac

Please sign in to comment.