Skip to content

Commit

Permalink
Specifying how media elements make and validate range requests
Browse files Browse the repository at this point in the history
  • Loading branch information
jakearchibald authored and annevk committed Jan 21, 2021
1 parent 88de068 commit dc83dde
Showing 1 changed file with 142 additions and 10 deletions.
152 changes: 142 additions & 10 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -2496,6 +2496,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li><dfn data-x-href="https://fetch.spec.whatwg.org/#http-cors-protocol">CORS protocol</dfn></li>
<li><dfn data-x="default-user-agent-value" data-x-href="https://fetch.spec.whatwg.org/#default-user-agent-value">default `<code>User-Agent</code>` value</dfn></li>
<li><dfn data-x-href="https://fetch.spec.whatwg.org/#concept-header-extract-mime-type">extract a MIME type</dfn></li>
<li><dfn data-x="extract-header-list-values" data-x-href="https://fetch.spec.whatwg.org/#extract-header-list-values">extract header list values</dfn></li>
<li><dfn data-x="concept-fetch" data-x-href="https://fetch.spec.whatwg.org/#concept-fetch">fetch</dfn></li>
<li><dfn data-x-href="https://fetch.spec.whatwg.org/#concept-http-redirect-fetch">HTTP-redirect fetch</dfn></li>
<li><dfn data-x-href="https://fetch.spec.whatwg.org/#ok-status">ok status</dfn></li>
Expand Down Expand Up @@ -2563,6 +2564,16 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li><dfn data-x="concept-request-parser-metadata" data-x-href="https://fetch.spec.whatwg.org/#concept-request-parser-metadata">parser metadata</dfn></li>
<li><dfn data-x="concept-request-reload-navigation-flag" data-x-href="https://fetch.spec.whatwg.org/#concept-request-reload-navigation-flag">reload-navigation flag</dfn></li>
<li><dfn data-x="concept-request-history-navigation-flag" data-x-href="https://fetch.spec.whatwg.org/#concept-request-history-navigation-flag">history-navigation flag</dfn></li>
<li><dfn data-x="concept-request-add-range-header" data-x-href="https://fetch.spec.whatwg.org/#concept-request-add-range-header">add a range header</dfn> algorithm</li>
</ul>
</li>
<li>
<dfn data-x="concept-header-list"
data-x-href="https://fetch.spec.whatwg.org/#concept-header-list">header list</dfn> and its
associated:
<ul class="brief">
<li><dfn data-x="concept-header-list-allow-privileged-headers" data-x-href="https://fetch.spec.whatwg.org/#concept-header-list-allow-privileged-headers">allow privileged headers flag</dfn></li>
<li><dfn data-x="concept-header-list-append" data-x-href="https://fetch.spec.whatwg.org/#concept-header-list-append">append</dfn> algorithm</li>
</ul>
</li>
</ul>
Expand Down Expand Up @@ -32818,6 +32829,25 @@ interface <dfn>HTMLMediaElement</dfn> : <span>HTMLElement</span> {

</p>

<p>A <span>media resource</span> has a <dfn
data-x="concept-media-uses-rewritten-requests-flag">uses rewritten requests flag</dfn>, which is
initially unset.</p>

<p class="note">The <span data-x="concept-media-uses-rewritten-requests-flag">uses rewritten
requests flag</span> is used to track <span>media resource</span>s that use responses that didn't
originate from their request URL, which is possible via a service worker. The aim is to prevent
developers from mixing <span>CORS-cross-origin</span> responses from different sources in a way
that could expose data through the media's duration, width, or height.</p>

<p>A <span>media resource</span> has a <dfn
data-x="concept-media-resource-uses-opaque-response-flag">uses opaque response flag</dfn>, which
is initially unset.</p>

<p class="note">The <span data-x="concept-media-resource-uses-opaque-response-flag">uses opaque
response flag</span> affects whether subtitles referenced in the <span>media data</span> are
exposed in the API and, for <code>video</code> elements, whether a <code>canvas</code> gets
tainted when the video is drawn on it.</p>

<p>A <span>media resource</span> can have multiple audio and video tracks. For the purposes of a
<span>media element</span>, the video data of the <span>media resource</span> is only that of the
currently selected track (if any) as given by the element's <code
Expand Down Expand Up @@ -33708,11 +33738,20 @@ interface <dfn>MediaError</dfn> {

<!--FETCH--><p><span data-x="concept-fetch">Fetch</span> <var>request</var>.

<p>The <var>response</var>'s <span>unsafe response</span> obtained in this fashion, if any,
contains the <span>media data</span>. It can be <span>CORS-same-origin</span> or
<span>CORS-cross-origin</span>; this affects whether subtitles referenced in the <span>media
data</span> are exposed in the API and, for <code>video</code> elements, whether a
<code>canvas</code> gets tainted when the video is drawn on it.</p>
<p>Let <var>responseUrlList</var> be <var>response</var>'s <span
data-x="concept-response-url-list">url list</span></p>

<p>If <var>responseUrlList</var>[0] does not <span data-x="list contains">exist</span>, or
<var>responseUrlList</var>[0] does not equal <var>request</var>'s <span
data-x="concept-request-url">url</span>, set <var>current media resource</var>'s <span
data-x="concept-media-uses-rewritten-requests-flag">uses rewritten requests flag</span>.</p>

<p class="note">We test the first entry of the <span data-x="concept-response-url-list">url
list</span> since that reveals if the service worker "rewrote" the request to another URL.</p>

<p>If the <var>response</var> is <span>CORS-cross-origin</span>, set the <var>current media
resource</var>'s <span data-x="concept-media-resource-uses-opaque-response-flag">uses opaque
response flag</span>.

<p>The <dfn>stall timeout</dfn> is an <span>implementation-defined</span> length of time,
which should be about three seconds. When a <span>media element</span> that is actively
Expand Down Expand Up @@ -33754,11 +33793,17 @@ interface <dfn>MediaError</dfn> {
element's <span>delaying-the-load-event flag</span> to false. This stops <span data-x="delay
the load event">delaying the load event</span>.</p>

<p>The user agent may use whatever means necessary to fetch the resource (within the constraints
put forward by this and other specifications); for example, reconnecting to the server in the
face of network errors, using HTTP range retrieval requests, or switching to a streaming
protocol. The user agent must consider a resource erroneous only if it has given up trying to
fetch it.</p>
<p>The user agent may go on to use whatever means necessary to fetch the resource (within
the constraints put forward by this and other specifications); for example, reconnecting to
the server in the face of network errors, or switching to a streaming protocol. The user
agent must consider a resource erroneous only if it has given up trying to fetch it.</p>

<p>The user agent may use the <span data-x="concept-media-ranged-fetch-steps">ranged fetch
steps</span> to perform HTTP range retrieval requests for a given start and (optional) end
range. Through its knowledge of container formats, the user agent may issue a ranged request
to gather metadata it knows to be at the end of the resource. Or, if the media is seeked,
the browser may use metadata to convert a temporal range to a byte range and make a ranged
request.</p>

<p>To determine the format of the <span>media resource</span>, the user agent must use the
<span data-x="Content-Type sniffing: video">rules for sniffing audio and video specifically</span>.</p>
Expand Down Expand Up @@ -33792,6 +33837,93 @@ interface <dfn>MediaError</dfn> {
in this situation, once <span data-x="ended playback">playback has ended</span>, the user agent
will end up firing a <code data-x="event-media-suspend">suspend</code> event, as described
earlier.</p>

<p>The <dfn data-x="concept-media-ranged-fetch-steps">ranged fetch steps</dfn> with a
<var>start</var> and optional <var>end</var> are the following steps:</p>

<ol>
<li><p>Let <var>request</var> be the result of <span
data-x="create a potential-CORS request">creating a potential-CORS request</span> given
<var>URL record</var>, "<code data-x="">media</code>", and the <var>crossorigin attribute
value</var>.</p></li>

<li><p>Set <var>request</var>'s <span data-x="concept-request-client">client</span> to the
<span>media element</span>'s <span>node document</span>'s <code>Window</code> object's
<span>environment settings object</span></p></li>

<li><p>Set <var>request</var>'s <span data-x="concept-request-type">type</span> to "<code
data-x="">audio</code>" if the <span>media element</span> is an <code>audio</code> element
and to "<code data-x="">video</code>" otherwise.</p></li>

<li><p><span data-x="concept-request-add-range-header">Add a range header</span> to
<var>request</var> with <var>start</var> and if provided, <var>end</var>.

<!--FETCH--><li><p><span data-x="concept-fetch">Fetch</span> <var>request</var>.</p></li>

<li><p>If the <var>response</var> is a <span>network error</span>, return
<var>response</var>.</p></li>

<li><p>Let <var>requestRewritten</var> be false.</p></li>

<li><p>Let <var>responseUrlList</var> be <var>response</var>'s <span
data-x="concept-response-url-list">url list</span></p></li>

<li><p>If <var>responseUrlList</var>[0] does not <span data-x="list
contains">exist</span>, or <var>responseUrlList</var>[0] does not equal
<var>request</var>'s <span data-x="concept-request-url">url</span>, set
<var>requestRewritten</var> to true</p></li>

<li>
<p>If the <var>response</var> is <span>CORS-cross-origin</span>, or the <var>current
media resource</var>'s <span
data-x="concept-media-resource-uses-opaque-response-flag">uses opaque response
flag</span> is set, then:</p>

<ol>
<li><p>If <var>requestRewritten</var> is true, or <var>current media resource</var>'s
<span data-x="concept-media-uses-rewritten-requests-flag">uses rewritten requests
flag</span> is set, then return a <span>network error</span>.</p></li>
</ol>
</li>

<li><p>If <var>response</var>'s <span data-x="concept-response-status">status</span> is
not <code data-x="">200</code> or <code data-x="">206</code>, return a <span>network
error</span>.</p></li>

<li>
<p>If <var>response</var>'s <span data-x="concept-response-status">status</span> is
<code data-x="">206</code>, then:</p>

<ol>
<li><p>Let <var>range</var> be the result of <span
data-x="extract-header-list-values">extracting</span> `<code
data-x="">Content-Range</code>` from <var>response</var>'s <span
data-x="concept-request-header-list">header list</span>.</p></li>

<li><p>If <var>range</var>'s <a
href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.16">first-byte-pos</a>
doesn't equal <var>start</var>, return a <span>network error</span>.</p></li>
</ol>
</li>

<li><p>If <var>requestRewritten</var> is true, set <var>current media resource</var>'s
<span data-x="concept-media-uses-rewritten-requests-flag">uses rewritten requests
flag</span>.</p></li>

<li><p>If the <var>response</var> is <span>CORS-cross-origin</span>, set the <var>current
media resource</var>'s <span
data-x="concept-media-resource-uses-opaque-response-flag">uses opaque data flag</span>.</p></li>

<li>
<p>Return <var>response</var>.</p>

<p class="note">How the browser consumes responses for various media types isn't covered
by this spec. However, the browser is encouraged to accept an HTTP 200 response even if
it requested a range. It could terminate fetches that are (or become) redundant, e.g. if
the returned range is already covered by a previous or in-flight response, or the media
is seeked as such that active fetches are unlikely to be useful.</p>
</li>
</ol>
</li>
</ol>
</dd>
Expand Down

0 comments on commit dc83dde

Please sign in to comment.