firstDaisy Diff compare report.
Click on the changed parts for a detailed description. Use the left and right arrow keys to walk through the modifications.
last 

Fetch

Living Standard — Last Updated

Participate:
GitHub whatwg/fetch (file an issue, open issues)
IRC: #whatwg on Freenode
Commits:
GitHub whatwg/fetch/commits
LOCAL COPY
@fetchstandard
Tests:
web-platform-tests fetch/ (ongoing work)
Translation (non-normative):
日本語

Abstract

The Fetch standard defines requests, responses, and the process that binds them: fetching.

Goals

To unify fetching across the web platform this specification supplants a number of algorithms and specifications:

Unifying fetching provides consistent handling of:

1. Preface

At a high level, fetching a resource is a fairly simple operation. A request goes in, a response comes out. The details of that operation are however quite involved and used to not be written down carefully and differ from one API to the next.

Numerous APIs provide the ability to fetch a resource, e.g. HTML’s img and script element, CSS' cursor and list-style-image, the navigator.sendBeacon() and self.importScripts() JavaScript APIs. The Fetch Standard provides a unified architecture for these features so they are all consistent when it comes to various aspects of fetching, such as redirects and the CORS protocol.

The Fetch Standard also defines the fetch() JavaScript API, which exposes most of the networking functionality at a fairly low level of abstraction.

2. Infrastructure

This specification depends on the Infra Standard. [INFRA]

This specification uses terminology from the ABNF, Encoding, HTML, HTTP, IDL, Streams, and URL Standards. [ABNF] [ENCODING] [HTML] [HTTP][WEBIDL] [STREAMS] [URL] ABNF

means ABNF as modified by HTTP (in particular the addition #). Comparing two byte sequences in a byte-case-insensitive manner means comparing them exactly, byte for byte, except that the bytes in the range 0x41 to 0x5A, inclusive, are considered to also match their corresponding byte in the range 0x61 to 0x7A, inclusive.

A case-insensitive byte sequence is a byte sequence that when compared to another byte sequence does so in a byte-case-insensitive manner.

The case-insensitive byte sequences `Content-Type` and `content-TYPE` are equal.


A response URL is a URL for which implementations need not store the fragment as it is never exposed. When serialized, the exclude fragment flag is set, meaning implementations can store the fragment nonetheless.


Credentials are HTTP cookies, TLS client certificates, and authentication entries.


Tasks that are queued by this standard are annotated as one of:

To queue a fetch task on request request to run an operation, run these steps:

  1. If request’s client is null, terminate these steps.

  2. Queue a task to run an operation on request’s client’s responsible event loop using the networking task source.

To queue a fetch-request-done task, given a request, queue a fetch task on request to process request end-of-body for request.

2.1. HTTP

While fetching encompasses more than just HTTP, it borrows a number of concepts from HTTP and applies these to resources obtained via other means (e.g., data URLs).

The HTTP whitespace bytes are 0x09, 0x0A, 0x0D, and 0x20.

An HTTPS state value is "none", "deprecated", or "modern".

A response delivered over HTTPS will typically have its HTTPS state set to "modern". A user agent can use "deprecated" in a transition period. E.g., while removing support for a hash function, weak cypher suites, certificates for an "Internal Name", or certificates with an overly long validity period. How exactly a user agent can use "deprecated" is not defined by this specification. An environment settings object typically derives its HTTPS state from a response.

2.1.1. Methods

A method is a byte sequence that matches the method token production.

A CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.

A forbidden method is a method that is a byte-case-insensitive match for `CONNECT`, `TRACE`, or `TRACK`. [HTTPVERBSEC1], [HTTPVERBSEC2], [HTTPVERBSEC3]

To normalize a method, if it is a byte-case-insensitive match for `DELETE`, `GET`, `HEAD`, `OPTIONS`, `POST`, or `PUT`, byte-uppercase it.

Normalization is done for backwards compatibility and consistency across APIs as methods are actually "case-sensitive".

Using `patch` is highly likely to result in a `405 Method Not Allowed`. `PATCH` is much more likely to succeed.

There are no restrictions on methods. `CHICKEN` is perfectly acceptable (and not a misspelling of `CHECKIN`). Other than those that are normalized there are no casing restrictions either. `Egg` or `eGg` would be fine, though uppercase is encouraged for consistency.

2.1.2. Headers

A header list consists of zero or more headers.

A header list is essentially a specialized multimap. An ordered list of key-value pairs with potentially duplicate keys.

A header list (list) contains a name (name) if list contains a header whose name is a byte-case-insensitive match for name. To append a name/value (name/value) pair to a header list (list), run these steps:

  • If list contains name, then set name to the first such header’s name.

    This reuses the casing of the name of the header already in the header list, if any. If there are multiple matched headers their names will all be identical.

  • Append

    append a new header whose name is name, byte-lowercased, and value is value, to list.

    To delete a name (name) from a header list (list), remove all headers whose name is

    a

    name, byte-

    case-insensitive match for name

    lowercased, from list.

    To set a name/value (name/value) pair in a header list (list), run these steps:

    1. Byte-lowercase name.

    2. If there are any headers in list

      contains

      whose name is name,

      then

      set the value of the first such header to value and remove the others.

    3. Otherwise, append a new header whose name is name and value is value, to list.

    To combine a name/value (name/value) pair in a header list (list), run these steps:

    1. Byte-lowercase name.

    2. If there are any headers in list

      contains

      whose name is name,

      then

      set the value of the first such header to its value, followed by `,`, followed by value.

    3. Otherwise, append a new header whose name is name and value is value, to list.

    Combine is used by XMLHttpRequest and the WebSocket protocol handshake.

    To sort and combine a header list (list), run these steps:

    1. Let headers be an empty list of name-value pairs with the key being the name and value the value.

    2. Let names be all the names of the headers in list,

      byte-lowercased,

      with duplicates removed, and

      finally

      sorted lexicographically.

    3. For each name in names, run these substeps:

      1. Let value be the combined value given name and list.

      2. Append name-value to headers.

    4. Return headers.


    A header consists of a name and value.

    A name is a case-insensitive byte sequence that matches the field-name token production.

    A value is a byte sequence that matches the following conditions:

    The definition of value is not defined in terms of an HTTP token production as it is broken.

    To normalize a potentialValue, remove any leading and trailing HTTP whitespace bytes from potentialValue.

    A combined value, given a name (name) and header list (list), is the values of all headers in list whose name is

    a byte-case-insensitive match for

    name, separated from each other by `,`, in order.


    A CORS-safelisted request-header is a header whose name is

    a byte-case-insensitive match for

    one of

    extracted

    or whose name is

    a byte-case-insensitive match for

    one of

    and whose value, once

    extracted

    parsed, is not a failure.

    A CORS non-wildcard request-header name is

    a byte-case-insensitive match for

    `Authorization`.

    A CORS-safelisted response-header name, given a CORS-exposed header-name list list, is a header name that is

    a byte-case-insensitive match for

    one of

    A forbidden header name is a header name that is

    a byte-case-insensitive match for

    one of

    or a header name that starts with

    a byte-case-insensitive match for

    `Proxy-` or `Sec-` (including being

    a byte-case-insensitive match for

    just `Proxy-` or `Sec-`).

    These are forbidden so the user agent remains in full control over them. Names starting with `Sec-` are reserved to allow new headers to be minted that are safe from APIs using fetch that allow control over headers by developers, such as XMLHttpRequest. [XHR]

    A forbidden response-header name is a header name that is

    a byte-case-insensitive match for

    one of:


    To

    extract header values given

    parse a header

    header, run these steps: If parsing header’s

    value

    , per the ABNF for header’s name, fails, then return failure.
  • Return one or more values resulting from parsing header’s value, per the ABNF for header’s name.

  • To extract header list values

    given a name (name) and a header or a header list (

    list

    headers), run these steps:

    1. If

      list does not contain name, then

      name is not in headers, return null.

    2. If the ABNF for name allows a single header and

      list

      headers contains more than one,

      then

      return failure.

      If different error handling is needed, extract the desired header first.

    3. Let values be an empty list.

    4. For each header header list contains whose name is name, run these substeps:

      1. Let extract be the result of extracting header values from header.

      2. If extract is failure, then return failure.

      3. Append each value in extract, in order, to values.

    5. Return values.

    6. If parsing all the headers named name in headers, per the ABNF for name, failed, return failure.

    7. Return one or more values resulting from parsing all the headers named name in headers, per the ABNF for name.

    To extract a MIME type from a header list (headers), run these steps:

    1. Let MIMEType be the result of

      extracting header list values given

      parsing `Content-Type`

      and

      in headers.

    2. If MIMEType is null or failure, return the empty byte sequence.

    3. Return MIMEType, byte-lowercased.


    A default `User-Agent` value is a user-agent-defined value for the `User-Agent` header.

    2.1.3. Statuses

    A status is a code.

    A null body status is a status that is 101, 204, 205, or 304.

    An ok status is any status in the range 200 to 299, inclusive.

    A redirect status is a status that is 301, 302, 303, 307, or 308.

    2.1.4. Bodies

    A body consists of:

    A body body is said to be done if body is null or body’s stream is closed or errored.

    To wait for a body body, wait for body to be done.

    To clone a body body, run these steps:

    1. Let «out1, out2» be the result of teeing body’s stream. Rethrow any exceptions.

    2. Set body’s stream to out1.

    3. Return a body whose stream is out2 and other members are copied from body.

    To handle content codings given codings and bytes, run these substeps:

    1. If codings are not supported, return bytes.

    2. Return the result of decoding bytes with the given codings as explained in HTTP. [HTTP] [HTTP-SEMANTICS] [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH]

    2.1.5. Requests

    The input to fetch is a request.

    A request has an associated method (a method). Unless stated otherwise it is `GET`.

    This can be updated during redirects to `GET` as described in HTTP fetch.

    A request has an associated url (a URL).

    Implementations are encouraged to make this a pointer to the first URL in request’s url list. It is provided as a distinct field solely for the convenience of other standards hooking into Fetch.

    A request has an associated local-URLs-only flag. Unless stated otherwise it is unset.

    A request has an associated sandboxed-storage-area-URLs flag. Unless stated otherwise it is unset.

    A request has an associated header list (a header list). Unless stated otherwise it is empty.

    A request has an associated unsafe-request flag. Unless stated otherwise it is unset.

    The unsafe-request flag is set by APIs such as fetch() and XMLHttpRequest to ensure a CORS-preflight fetch is done based on the supplied method and header list. It does not free an API from outlawing forbidden methods and forbidden header names.

    A request has an associated body (null or a body). Unless stated otherwise it is null.

    This can be updated during redirects to null as described in HTTP fetch.


    A request has an associated client (null or an environment settings object).

    A request has an associated reserved client (null, an environment, or an environment settings object). Unless stated otherwise it is null.

    This is only used by navigation requests and worker requests, but not service worker requests. It references an environment for a navigation request and an environment settings object for a worker request.

    A request has an associated target client id (a string). Unless stated otherwise it is the empty string.

    This is only used by navigation requests. It is the id of the target browsing context’s active document’s environment settings object.

    A request has an associated window ("no-window", "client", or an environment settings object whose global object is a Window object). Unless stated otherwise it is "client".

    The "client" value is changed to "no-window" or request’s client during fetching. It provides a convenient way for standards to not have to explicitly set request’s window.

    A request has an associated keepalive flag. Unless stated otherwise it is unset.

    This can be used to allow the request to outlive the environment settings object, e.g., navigator.sendBeacon and the HTML img element set this flag. Requests with this flag set are subject to additional processing requirements.

    A request has an associated skip-service-

    workers mode, that is "all", "foreign", or "none"

    worker flag. Unless stated otherwise it is

    "all".

    This determines which service workers will receive a fetch event for this fetch.

    "all"
    Relevant local and foreign service workers will get a fetch or foreignfetch event for this fetch.
    "foreign"
    Only relevant foreign service workers will get a foreignfetch event for this fetch. fetch(input) uses this to bypass the current service worker if the global is a ServiceWorkerGlobalScope.
    "none"
    Neither local nor foreign service workers will get events for this fetch.

    unset.

    A request has an associated initiator, which is the empty string, "download", "imageset", "manifest", or "xslt". Unless stated otherwise it is the empty string.

    A request’s initiator is not particularly granular for the time being as other specifications do not require it to. It is primarily a specification device to assist defining CSP and Mixed Content. It is not exposed to JavaScript. [CSP] [MIX]

    A request has an associated type, which is the empty string, "audio", "font", "image", "script", "style", "track", or "video". Unless stated otherwise it is the empty string.

    A request has an associated destination, which is the empty string, "

    audio", "

    document", "embed", "font", "image", "manifest", "media", "object", "report", "script", "serviceworker", "sharedworker", "style", "

    track", "video", "

    worker", or "xslt". Unless stated otherwise it is the empty string.

    The following table illustrates the relationship between a request’s initiator, type, destination, CSP directives, and features.

    Initiator Type Destination CSP directive Features
    "" "" "report" ? CSP, NEL reports.
    "document" HTML’s navigate algorithm.
    "document" child-src HTML’s <iframe> and <frame>
    "" connect-src navigator.sendBeacon(), EventSource, HTML’s ping="", fetch(), XMLHttpRequest, WebSocket, Cache API?
    "object" object-src HTML’s <object>
    "embed" object-src HTML’s <embed>
    "audio" "
    audio
    media" media-src HTML’s <audio>
    "font" "font" font-src CSS' @font-face
    "image" "image" img-src HTML’s <img src>, /favicon.ico resource, SVG’s <image>, CSS' background-image, CSS' cursor, CSS' list-style-image, …
    "script" "script" script-src HTML’s <script>, importScripts()
    "serviceworker" ? navigator.serviceWorker.register()
    "sharedworker" child-src SharedWorker
    "worker" child-src Worker
    "style" "style" style-src HTML’s <link rel=stylesheet>, CSS' @import
    "track" "
    track
    media" media-src HTML’s <track>
    "video" "
    video
    media" media-src HTML’s <video> element
    "download" "" "" ? HTML’s download="", "Save Link As…" UI
    "imageset" "image" "image" img-src HTML’s <img srcset> and <picture>
    "manifest" "" "manifest" manifest-src HTML’s <link rel=manifest>
    "xslt" "xslt" script-src <?xml-stylesheet>

    CSP’s form-action needs to be a hook directly in HTML’s navigate or form submission algorithm.

    CSP will also need to check request’s client’s responsible browsing context’s ancestor browsing contexts for various CSP directives.


    A request has an associated priority (null or a user-agent-defined object). Unless otherwise stated it is null.

    A request has an associated origin, which is "client" or an origin. Unless stated otherwise it is "client".

    "client" is changed to an origin during fetching. It provides a convenient way for standards to not have to set request’s origin. Request’s origin can be changed during redirects too.

    A request has an associated referrer, which is "no-referrer", "client", or a URL. Unless stated otherwise it is "client".

    "client" is changed to "no-referrer" or a URL during fetching. It provides a convenient way for standards to not have to set request’s referrer.

    A request has an associated referrer policy, which is a referrer policy. Unless stated otherwise it is the empty string. [REFERRER]

    This can be used to override a referrer policy associated with an environment settings object.

    A request has an associated client hints list, which is a client-hints list. Unless stated otherwise, it is the empty list.

    This will be used to override a client hints list associated with an environment settings object. [CLIENT-HINTS]

    A request has an associated synchronous flag. Unless stated otherwise it is unset.

    A request has an associated mode, which is "same-origin", "cors", "no-cors", "navigate", or "websocket". Unless stated otherwise, it is "no-cors".

    Even though the default request mode is "no-cors", standards are highly discouraged from using it for new features. It is rather unsafe. "navigate" and "websocket" are special values for the HTML Standard. [HTML]

    A request has an associated use-CORS-preflight flag. Unless stated otherwise, it is unset.

    A request has an associated credentials mode, which is "omit", "same-origin", or "include". Unless stated otherwise, it is "omit".

    Request’s credentials mode controls the flow of credentials during a fetch. When request’s mode is "navigate", its credentials mode is assumed to be "include" and fetch does not currently account for other values. If HTML changes here, this standard will need corresponding changes.

    A request has an associated use-URL-credentials flag. Unless stated otherwise, it is unset.

    A request has an associated use-token-binding flag. Unless stated otherwise, it is unset.

    Request’s use-token-binding flag controls whether the user agent will send the token binding ID for the origin of the request’s url when it transmits the request to the server. The token binding ID can be used by the server to, e.g., bind HTTP cookies or OAuth tokens that it issues to the user agent.

    A request has an associated use-referred-token-binding flag. Unless stated otherwise, it is unset.

    Request’s use-referred-token-binding flag controls whether the user agent will send the token binding ID used by the user agent for an alternate origin, in addition to the token binding ID used by the user agent for the origin of the request’s url, when it transmits the request to the server. This is used, e.g., by a relying party to indicate (via the user agent) to the server receiving the request that it wants the credential issued by the server to be bound to the token binding ID for the relying party’s origin. (Without this, a credential issued by the server in response to a request would be bound to request’s origin’s token binding ID).

    A request has an associated referred-token-binding origin, which is an origin. Unless stated otherwise, it is null.

    Request’s referred-token-binding origin specifies the origin used to determine the referred-token-binding ID, when its use-referred-token-binding flag is set.

    A request has an associated cache mode, which is "default", "no-store", "reload", "no-cache", "force-cache", or "only-if-cached". Unless stated otherwise, it is "default".

    "default"
    Fetch will inspect the HTTP cache on the way to the network. If there is a fresh response it will be used. If there is a stale response a conditional request will be created, and a normal request otherwise. It then updates the HTTP cache with the response. [HTTP] [HTTP-SEMANTICS] [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH]
    "no-store"
    Fetch behaves as if there is no HTTP cache at all.
    "reload"
    Fetch behaves as if there is no HTTP cache on the way to the network. Ergo, it creates a normal request and updates the HTTP cache with the response.
    "no-cache"
    Fetch creates a conditional request if there is a response in the HTTP cache and a normal request otherwise. It then updates the HTTP cache with the response.
    "force-cache"
    Fetch uses any response in the HTTP cache matching the request, not paying attention to staleness. If there was no response, it creates a normal request and updates the HTTP cache with the response.
    "only-if-cached"
    Fetch uses any response in the HTTP cache matching the request, not paying attention to staleness. If there was no response, it returns a network error. (Can only be used when request’s mode is "same-origin". Any cached redirects will be followed assuming request’s redirect mode is "follow" and the redirects do not violate request’s mode.)

    If header list contains a header whose name is one of `If-Modified-Since`, `If-None-Match`, `If-Unmodified-Since`, `If-Match`,

    or

    and `If-Range`, fetch will set cache mode to "no-store" if it is "default".

    A request has an associated redirect mode, which is "follow", "error", or "manual". Unless stated otherwise, it is "follow".

    A request has associated integrity metadata (a string). Unless stated otherwise, it is the empty string.

    A request has associated cryptographic nonce metadata (a string). Unless stated otherwise, it is the empty string.

    A request has associated parser metadata which is the empty string, "parser-inserted", or "not-parser-inserted". Unless otherwise stated, it is the empty string.

    A request’s cryptographic nonce metadata and parser metadata are generally populated from attributes and flags on the HTML element responsible for triggering a fetch. They are used by various algorithms in [CSP] to determine whether requests or responses should be blocked in a given context.


    A request has an associated url list (a list of one or more URLs). Unless stated otherwise, it is a list containing a copy of request’s url.

    A request has an associated current url. It is a pointer to the last URL in request’s url list.

    A request has an associated redirect count. Unless stated otherwise, it is zero.

    A request has an associated response tainting, which is "basic", "cors", or "opaque". Unless stated otherwise, it is "basic".

    A request has an associated done flag. Unless stated otherwise, it is unset.

    A request’s url list, current url, redirect count, response tainting, and done flag are used as bookkeeping details by the fetch algorithm.


    A subresource request is a request whose destination is "

    audio", "

    font", "image", "manifest", "

    script

    media", "

    style

    script", "

    track

    style", "

    video", "

    xslt", or the empty string.

    A potential-navigation-or-subresource request is a request whose destination is "object" or "embed".

    A non-subresource request is a request whose destination is "document", "report", "serviceworker", "sharedworker", or "worker".

    A navigation request is a request whose destination is "document".

    See handle fetch for usage of these terms. [SW]


    To clone a request request, run these steps:

    1. Let newRequest be a copy of request, except for its body.

    2. If request’s body is non-null, set newRequest’s body to the result of cloning request’s body. Rethrow any exceptions.

    3. Return newRequest.


    To transmit body for a request request, run these steps:

    1. Let body be request’s body.
    2. If body is null, then queue a fetch task on request to process request end-of-body for request and abort these steps.

    3. Let read be the result of reading a chunk from body’s stream.

      • When read is fulfilled with an object whose done property is false and whose value property is a Uint8Array object, run these substeps:

        1. Let bytes be the byte sequence represented by the Uint8Array object.

        2. Transmit bytes.

        3. Increase body’s transmitted bytes by bytes’s length.

        4. Run the above step again.

      • When read is fulfilled with an object whose done property is true, queue a fetch task on request to process request end-of-body for request.

      • When read is fulfilled with a value that matches with neither of the above patterns, or read is rejected, terminate the ongoing fetch with reason fatal.

    2.1.6. Responses

    The result of fetch is a response. A response evolves over time. That is, not all its fields are available straight away.

    A response has an associated type which is "basic", "cors", "default", "error", "opaque", or "opaqueredirect". Unless stated otherwise, it is "default".

    A response can have an associated termination reason which is end-user abort, fatal, or timeout.

    A response has an associated url. It is a pointer to the last response URL in response’s url list and null if response’s url list is the empty list.

    A response has an associated url list (a list of zero or more response URLs). Unless stated otherwise, it is the empty list.

    Except for the last response URL, if any, a response’s url list cannot be exposed to script. That would violate atomic HTTP redirect handling.

    A response has an associated status, which is a status. Unless stated otherwise it is 200.

    A response has an associated status message. Unless stated otherwise it is `OK`.

    A response has an associated header list (a header list). Unless stated otherwise it is empty.

    A response has an associated body (null or a body). Unless stated otherwise it is null.

    A response has an associated trailer (a header list). Unless stated otherwise it is empty.

    A response has an associated HTTPS state (an HTTPS state value). Unless stated otherwise, it is "none".

    A response has an associated CSP list, which is a list of Content Security Policy objects for the response. The list is empty unless otherwise specified. [CSP]

    A response has an associated CORS-exposed header-name list (a list of zero or more header names). The list is empty unless otherwise specified.

    A response will typically get its CORS-exposed header-name list set by

    extracting header values from

    parsing the `Access-Control-Expose-Headers` header. This list is used by a CORS filtered response to determine which headers to expose.

    A response can have an associated location URL (null, failure, or a URL). Unless specified otherwise, response has no location URL.

    This concept is used for redirect handling in Fetch and in HTML’s navigate algorithm. It ensures `Location`

    has its value extracted

    is parsed consistently and only once. [HTML]


    A response whose type is "error" is known as a network error.

    A network error is a response whose status is always 0, status message is always the empty byte sequence, header list is always empty, body is always null, and trailer is always empty.


    A filtered response is a limited view on a response that is not a network error. This response is referred to as the filtered response’s associated internal response.

    The fetch algorithm returns such a view to ensure APIs do not accidentally leak information. If the information is required, e.g., to feed image data to a decoder, the associated internal response can be used, which is only "accessible" to internal specification algorithms.

    A basic filtered response is a filtered response whose type is "basic" and header list excludes any headers in internal response’s header list whose name is a forbidden response-header name.

    A CORS filtered response is a filtered response whose type is "cors", header list excludes any headers in internal response’s header list whose name is not a CORS-safelisted response-header name, given internal response’s CORS-exposed header-name list, and trailer is empty.

    An opaque filtered response is a filtered response whose type is "opaque", url list is the empty list, status is 0, status message is the empty byte sequence, header list is empty, body is null, and trailer is empty.

    An opaque-redirect filtered response is a filtered response whose type is "opaqueredirect", status is 0, status message is the empty byte sequence, header list is empty, body is null, and trailer is empty.

    Exposing the url list for opaque-redirect filtered responses is harmless since no redirects are followed.

    In other words, an opaque filtered response and an opaque-redirect filtered response are nearly indistinguishable from a network error. When introducing new APIs, do not use the internal response for internal specification algorithms as that will leak information.

    This also means that JavaScript APIs, such as response.ok, will return rather useless results.

    To clone a response response, run these steps:

    1. If response is a filtered response, return a new identical filtered response whose internal response is a clone of response’s internal response. Rethrow any exceptions.

    2. Let newResponse be a copy of response, except for its body.

    3. If response’s body is non-null, set newResponse’s body to the result of cloning response’s body. Rethrow any exceptions.

    4. Return newResponse.

    2.2. Authentication entries

    An authentication entry and a proxy-authentication entry are tuples of username, password, and realm, associated with one or more requests.

    User agents should allow both to be cleared together with HTTP cookies and similar tracking functionality.

    Further details are defined by HTTP. [HTTP] [HTTP-SEMANTICS] [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH]

    2.3. Fetch groups

    Each environment settings object has an associated fetch group.

    A fetch group holds an ordered list of fetch records.

    A fetch record has an associated request (a request).

    A fetch record has an associated fetch (a fetch algorithm or null).


    When a fetch group is terminated, for each associated fetch record whose request’s done flag or keepalive flag is unset, terminate the fetch record’s fetch with reason fatal.

    2.4. Connections

    A user agent has an associated connection pool. A connection pool consists of zero or more connections. Each connection is identified by an origin (an origin) and credentials (a boolean).

    2.4.1. HTTP/2 Connection Reuse

    HTTP/2 allows connections to be reused for multiple origin servers, as described in Section 9.1 of HTTP/2. [HTTP2]

    HTTPS connections can be reused for a request if the TLS certificate for the connection is valid for the host in the URI. This happens when the certificate has multiple "subjectAltName" attributes or names with wildcards, one of which is valid for the authority in the URI.

    2.4.2. Obtaining a Connection

    To obtain a connection, given an origin and credentials, run these steps:

    1. If connection pool contains a connection whose origin is origin or whose origin is authoritative for origin, and credentials is credentials, return that connection.

    2. Let connection be the result of establishing an HTTP connection to origin. [HTTP] [HTTP2] [HTTP-SEMANTICS] [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH] [TLS]

      If credentials is true and if the user agent supports Token Binding, propose the use of Token Binding while setting up a TLS connection by sending the highest supported Token Binding protocol version and supported cryptographic algorithms and parameters (the token-binding key parameters) in a token_binding Client Hello Extension, as described in section 2 of the Token Binding Negotiation spec [TOKBIND-NEGOTIATION]. If Token Binding Negotiation succeeds, indicating client-server agreement on protocol version and token-binding key parameters, update metadata for the TLS connection with the results of the negotiation.

      The user agent will use Token Binding for any request sent over a TLS connection for which Token Binding Negotiation was successful. Since Token Binding is used only when credentials is true, such a connection will not be pooled with connections that have credentials is false. Also, Token Binding is compatible with connection reuse - HTTP/2 requests to different origin servers coalesced over the same connection will use different token-binding keys if needed.

      If credentials is false, do not send a TLS client certificate.

      If establishing a connection does not succeed (e.g., a DNS, TCP, or TLS error), return failure.

    3. Add connection to the connection pool with origin being origin and credentials being credentials.

    4. Return connection.

    This is intentionally a little vague as the finer points are still evolving. Describing this helps explain the <link rel=preconnect> feature and clearly stipulates that connections are keyed on credentials. The latter clarifies that e.g., TLS session identifiers are not reused across connections whose credentials are false with connections whose credentials are true.

    2.5. Port blocking

    To determine whether fetching a request request should be blocked due to a bad port, run these steps:

    1. Let url be request’s current url.

    2. Let scheme be url’s scheme.

    3. Let port be url’s port.

    4. If scheme is "ftp" and port is 20 or 21, then return allowed.

    5. Otherwise, if scheme is a network scheme and port is a bad port, then return blocked.

    6. Return allowed.

    A port is a bad port if it is listed in the first column of the following table.

    Port Typical service
    1 tcpmux
    7 echo
    9 discard
    11 systat
    13 daytime
    15 netstat
    17 qotd
    19 chargen
    20 ftp-data
    21 ftp
    22 ssh
    23 telnet
    25 smtp
    37 time
    42 name
    43 nicname
    53 domain
    77 priv-rjs
    79 finger
    87 ttylink
    95 supdup
    101 hostriame
    102 iso-tsap
    103 gppitnp
    104 acr-nema
    109 pop2
    110 pop3
    111 sunrpc
    113 auth
    115 sftp
    117 uucp-path
    119 nntp
    123 ntp
    135 loc-srv / epmap
    139 netbios
    143 imap2
    179 bgp
    389 ldap
    465 smtp+ssl
    512 print / exec
    513 login
    514 shell
    515 printer
    526 tempo
    530 courier
    531 chat
    532 netnews
    540 uucp
    556 remotefs
    563 nntp+ssl
    587 smtp
    601 syslog-conn
    636 ldap+ssl
    993 ldap+ssl
    995 pop3+ssl
    2049 nfs
    3659 apple-sasl
    4045 lockd
    6000 x11
    6665 irc (alternate)
    6666 irc (alternate)
    6667 irc (default)
    6668 irc (alternate)
    6669 irc (alternate)

    2.6. Should response to request be blocked due to its MIME type?

    Run these steps:

    1. Let MIMEType be the result of extracting a MIME type from response’s header list.

    2. Let type be request’s type.

    3. If type is "script" and one of the following is true, then return blocked:

      • MIMEType starts with `audio/`, `image/`, or `video/`.
      • MIMEType is `text/csv`.
    4. Return allowed.

    2.7. Client hints list

    This section will be integrated into HTTP Client Hints. [CLIENT-HINTS]

    A client hints list is a list of Client hint tokens, each of which is one of `dpr`, `save-data`, `viewport-width`, or `width`.

    2.8. Streams

    This section might be integrated into other standards, such as IDL.

    2.8.1. ReadableStream

    A ReadableStream object represents a stream of data. In this section, we define common operations for ReadableStream objects. [STREAMS]

    To enqueue chunk into a ReadableStream object stream, run these steps:

    1. Call ReadableStreamDefaultControllerEnqueue(stream.[[readableStreamController]], chunk). Rethrow any exceptions.

    To close a ReadableStream object stream, run these steps:

    1. Call ReadableStreamDefaultControllerClose(stream.[[readableStreamController]]). Rethrow any exceptions.

    To error a ReadableStream object stream with given reason, run these steps:

    1. Call ReadableStreamDefaultControllerError(stream.[[readableStreamController]]). reason). Rethrow any exceptions.

    To construct a ReadableStream object with given strategy, pull action and cancel action, all of which are optional, run these steps:

    1. Let init be a new object.

    2. Set init["pull"] to a function that runs pull if pull is given.

    3. Set init["cancel"] to a function that runs cancel if cancel is given.

    4. Let stream be the result of calling the initial value of ReadableStream as constructor with init and strategy if given. Rethrow any exceptions.

    5. Return stream.

    To construct a fixed ReadableStream object with given chunks, run these steps:

    1. Let stream be the result of constructing a ReadableStream object. Rethrow any exceptions.

    2. For each chunk in chunks, enqueue chunk into stream. Rethrow any exceptions.

    3. Close stream. Rethrow any exceptions.

    4. Return stream.

    To get a reader from a ReadableStream object stream, run these steps:

    1. Let reader be the result of calling AcquireReadableStreamDefaultReader(stream). Rethrow any exceptions.

    2. Return reader.

    To read a chunk from a ReadableStream object with reader, return the result of calling ReadableStreamDefaultReaderRead(reader).

    To read all bytes from a ReadableStream object with reader, run these steps:

    1. Let promise be a new promise.

    2. Let bytes be an empty byte sequence.

    3. Let read be the result of calling ReadableStreamDefaultReaderRead(reader).

      • When read is fulfilled with an object whose done property is false and whose value property is a Uint8Array object, append the value property to bytes and run the above step again.

      • When read is fulfilled with an object whose done property is true, resolve promise with bytes.

      • When read is fulfilled with a value that matches with neither of the above patterns, reject promise with a TypeError.

      • When read is rejected with an error, reject promise with that error.

    4. Return promise.

    To cancel a ReadableStream object with reader and reason, return the result of calling ReadableStreamCancel(reader, reason).

    Because the reader grants exclusive access, the actual mechanism of how to read cannot be observed. Implementations could use more direct mechanism if convenient.

    To tee a ReadableStream object stream, run these steps:

    1. Return the result of calling ReadableStreamTee(stream, true). Rethrow any exception.

    An empty ReadableStream object is the result of constructing a fixed ReadableStream object with an empty list.

    Constructing an empty ReadableStream object will not throw an exception.

    A ReadableStream object stream is said to be readable if stream.[[state]] is "readable".

    A ReadableStream object stream is said to be closed if stream.[[state]] is "closed".

    A ReadableStream object stream is said to be errored if stream.[[state]] is "errored".

    A ReadableStream object stream is said to be locked if the result of calling IsReadableStreamLocked(stream) is true.

    A ReadableStream object stream is said to need more data if the following conditions hold:

    A ReadableStream object stream is said to be disturbed if the result of calling IsReadableStreamDisturbed(stream) is true.

    3. HTTP extensions

    3.1. `Origin` header

    The `Origin` request header indicates where a fetch originates from.

    The `Origin` header is a version of the `Referer` [sic] header that does not reveal a path. It is used for all HTTP fetches whose CORS flag is set as well as those where request’s method is neither `GET` nor `HEAD`. Due to compatibility constraints it is not included in all fetches.

    Its value ABNF:

    Origin                           = origin-or-null
    
    origin-or-null                   = origin / %x6E.75.6C.6C ; "null", case-sensitive
    origin                           = scheme "://" host [ ":" port ]
    

    This supplants the `Origin` header. [ORIGIN]

    3.2. CORS protocol

    To allow sharing responses cross-origin and allow for more versatile fetches than possible with HTML’s form element, the CORS protocol exists. It is layered on top of HTTP and allows responses to declare they can be shared with other origin.

    It needs to be an opt-in mechanism to prevent leaking data from responses behind a firewall (intranets). Additionally, for requests including credentials it needs to be opt-in to prevent leaking potentially-sensitive data.

    This section explains the CORS protocol as it pertains to server developers. Requirements for user agents are part of the fetch algorithm, except for the new HTTP header syntax.

    3.2.1. General

    The CORS protocol consists of a set of headers that indicates whether a response can be shared cross-origin.

    For requests that are more involved than what is possible with HTML’s form element, a CORS-preflight request is performed, to ensure request’s current url supports the CORS protocol.

    3.2.2. HTTP requests

    A CORS request is an HTTP request that includes an `Origin` header. It cannot be reliably identified as participating in the CORS protocol as the `Origin` header is also included for all requests whose method is neither `GET` nor `HEAD`.

    A CORS-preflight request is a CORS request that checks to see if the CORS protocol is understood. It uses `OPTIONS` as method and includes these headers:

    `Access-Control-Request-Method`

    Indicates which method a future CORS request to the same resource might use.

    `Access-Control-Request-Headers`

    Indicates which headers a future CORS request to the same resource might use.

    3.2.3. HTTP responses

    An HTTP response to a CORS request can include the following headers:

    `Access-Control-Allow-Origin`

    Indicates whether the response can be shared, via returning the literal value of the `Origin` request header (which can be `null`) or `*` in a response.

    `Access-Control-Allow-Credentials`

    Indicates whether the response can be shared when request’s credentials mode is "include".

    For a CORS-preflight request, request’s credentials mode is always "omit", but for any subsequent CORS requests it might not be. Support therefore needs to be indicated as part of the HTTP response to the CORS-preflight request as well.

    An HTTP response to a CORS-preflight request can include the following headers:

    `Access-Control-Allow-Methods`

    Indicates which methods are supported by the response’s url for the purposes of the CORS protocol.

    The `Allow` header is not relevant for the purposes of the CORS protocol.

    `Access-Control-Allow-Headers`

    Indicates which headers are supported by the response’s url for the purposes of the CORS protocol.

    `Access-Control-Max-Age`

    Indicates how long the information provided by the `Access-Control-Allow-Methods` and `Access-Control-Allow-Headers` headers can be cached.

    An HTTP response to a CORS request that is not a CORS-preflight request can also include the following header:

    `Access-Control-Expose-Headers`

    Indicates which headers can be exposed as part of the response by listing their names.

    3.2.4. HTTP new-header syntax

    ABNF for the values of the headers used by the CORS protocol:

    Access-Control-Request-Method    = method
    Access-Control-Request-Headers   = 1#field-name
    
    wildcard                         = "*"
    Access-Control-Allow-Origin      = origin-or-null / wildcard
    Access-Control-Allow-Credentials = %x74.72.75.65 ; "true", case-sensitive
    Access-Control-Expose-Headers    = #field-name / wildcard
    Access-Control-Max-Age           = delta-seconds
    Access-Control-Allow-Methods     = #method / wildcard
    Access-Control-Allow-Headers     = #field-name-or-wildcard
    field-name-or-wildcard           = field-name / wildcard
    

    The difference between the Access-Control-Expose-Headers and Access-Control-Allow-Headers production is that the latter needs to be able to handle `*, Authorization` as header value whereas the former does not.

    3.2.5. CORS protocol and credentials

    When request’s credentials mode is "include" it has an impact on the functioning of the CORS protocol other than including credentials in the fetch.

    In the old days, XMLHttpRequest could be used to set request’s credentials mode to "include":

    var client = new XMLHttpRequest()
    client.open("GET", "./")
    client.withCredentials = true
    /* … */
    

    Nowadays, fetch("./", { credentials:"include" }).then(/* … */) suffices.

    A request’s credentials mode is not necessarily observable on the server; only when credentials exist for a request can it be observed by virtue of the credentials being included. Note that even so, a CORS-preflight request never includes credentials.

    The server developer therefore needs to decide whether or not responses "tainted" with credentials can be shared. And also needs to decide if requests necessitating a CORS-preflight request can include credentials. Generally speaking, both sharing responses and allowing requests with credentials is rather unsafe, and extreme care has to be taken to avoid the confused deputy problem.

    To share responses with credentials, the `Access-Control-Allow-Origin` and `Access-Control-Allow-Credentials` headers are important. The following table serves to illustrate the various legal and illegal combinations for a request to https://rabbit.invalid/:

    Request’s credentials mode `Access-Control-Allow-Origin` `Access-Control-Allow-Credentials` Shared? Notes
    "omit" `*` Omitted
    "omit" `*` `true` If credentials mode is not "include", then `Access-Control-Allow-Credentials` is ignored.
    "omit" `https://rabbit.invalid/` Omitted A serialized origin has no trailing slash.
    "omit" `https://rabbit.invalid` Omitted
    "include" `*` `true` If credentials mode is "include", then `Access-Control-Allow-Origin` cannot be `*`.
    "include" `https://rabbit.invalid` `true`
    "include" `https://rabbit.invalid` `True` `true` is (byte) case-sensitive.

    Similarly, `Access-Control-Expose-Headers`, `Access-Control-Allow-Methods`, and `Access-Control-Allow-Headers` response headers can only use `*` as value when request’s credentials mode is not "include".

    3.2.6. Examples

    A script at https://foo.invalid/ wants to fetch some data from https://bar.invalid/. (Neither credentials nor response header access is important.)

    var url = "https://bar.invalid/api?key=730d67a37d7f3d802e96396d00280768773813fbe726d116944d814422fc1a45&data=about:unicorn";
    fetch(url).then(success, failure)
    

    This will use the CORS protocol, though this is entirely transparent to the developer from foo.invalid. As part of the CORS protocol, the user agent will include the `Origin` header in the request:

    Origin: https://foo.invalid
    

    Upon receiving a response from bar.invalid, the user agent will verify the `Access-Control-Allow-Origin` response header. If its value is either `https://foo.invalid` or `*`, the user agent will invoke the success callback. If it has any other value, or is missing, the user agent will invoke the failure callback.

    The developer of foo.invalid is back, and now wants to fetch some data from bar.invalid while also accessing a response header.

    fetch(url).then(response => {
      var hsts = response.headers.get("strict-transport-security"),
          csp = response.headers.get("content-security-policy")
      log(hsts, csp)
    })
    

    bar.invalid provides a correct `Access-Control-Allow-Origin` response header per the earlier example. The values of hsts and csp will depend on the `Access-Control-Expose-Headers` response header. For example, if the response included the following headers

    Content-Security-Policy: default-src 'self'
    Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
    Access-Control-Expose-Headers: Content-Security-Policy
    

    then hsts would be null and csp would be "default-src 'self'", even though the response did include both headers. This is because bar.invalid needs to explicitly share each header by listing their names in the `Access-Control-Expose-Headers` response header.

    Alternatively, if bar.invalid wanted to share all its response headers, for requests that do not include credentials, it could use `*` as value for the `Access-Control-Expose-Headers` response header. If the request would have included credentials, the response header names would have to be listed explicitly and `*` could not be used.

    The developer of foo.invalid returns, now fetching some data from bar.invalid while including credentials. This time around the CORS protocol is no longer transparent to the developer as credentials require an explicit opt-in:

    fetch(url, { credentials:"include" }).then(success, failure)
    

    This also makes any `Set-Cookie` response headers bar.invalid includes fully functional (they are ignored otherwise).

    The user agent will make sure to include any relevant credentials in the request. It will also put stricter requirements on the response. Not only will bar.invalid be required to list `https://foo.invalid` as value for `Access-Control-Allow-Origin` (`*` is not allowed when credentials are involved), the `Access-Control-Allow-Credentials` has to be present too:

    Access-Control-Allow-Origin: https://foo.invalid
    Access-Control-Allow-Credentials: true
    

    If the response does not include those two headers with those values, the failure callback will be invoked and any `Set-Cookie` response headers will end up being ignored.

    3.3. `X-Content-Type-Options` header

    The `X-Content-Type-Options` response header can be used to require checking of a response’s `Content-Type` header against the type of a request.

    Its value ABNF:

    X-Content-Type-Options           = "nosniff" ; case-insensitive
    

    3.3.1. Should response to request be blocked due to nosniff?

    Run these steps:

    1. If response’s header list

      does not contain

      has no header whose name is `X-Content-Type-Options`, then return allowed.

    2. Let nosniff be the result of

      extracting header values from

      parsing the first header whose name is

      a byte-case-insensitive match for

      `X-Content-Type-Options` in response’s header list.

    3. If nosniff is failure, then return allowed.

    4. Let MIMEType be the result of extracting a MIME type from response’s header list.

    5. Let type be request’s type.

    6. If type is "script", and MIMEType (ignoring parameters) is not a JavaScript MIME type, then return blocked.

    7. If type is "style" and MIMEType (ignoring parameters) is not `text/css`, then return blocked.

    8. Return allowed.

    Only "script" and "style" are considered as any exploits pertain to those types. Also, considering "image" was not compatible with deployed content.

    3.4. Token Binding

    In order to protect security tokens like HTTP cookies and OAuth tokens, user agents and servers can use a technique known as Token Binding to cryptographically associate a given token with a secret (a token-binding key) known only to a specific user agent. This association mitigates the risk that attackers can steal the token and use it themselves, as they will not be able to easily replicate the user agent’s secret, and therefore cannot replicate the cryptographic binding of the token.

    Details are described in TOKBIND-NEGOTIATION, TOKBIND-PROTOCOL and TOKBIND-HTTPS and integration is defined here. [TOKBIND-NEGOTIATION], [TOKBIND-PROTOCOL], and [TOKBIND-HTTPS].

    A token binding ID is the non-secret representation of a token-binding key, as described in section 3.2 of [TOKBIND-PROTOCOL].

    At a very high level, a user agent negotiates the use of Token Binding with the server when it sets up a TLS connection to the server, and saves metadata (the Token Binding protocol version and token-binding key parameters resulting from the Token Binding negotiation) for the TLS connection. The user agent maintains a token-binding key store, where it saves different token-binding keys to be used with different servers. Whenever a token-binding key is needed, the user agent looks it up in the token-binding key store (creating it if needed).

    The user agent uses a `Sec-Token-Binding` HTTP request header to transmit token binding metadata to the server. When a user agent sends a request to a server over a TLS connection for which Token Binding has been negotiated, it proves possession of the private key via data sent in the `Sec-Token-Binding` header. The server associates ('binds') credentials that it issues to that user agent with a token binding ID in that header. The server also verifies if bound credentials presented to it by a user agent match a token binding ID in that header.

    The value of the `Sec-Token-Binding` header is a base64url-encoded string [RFC4648]:

    Sec-Token-Binding       = 1*( ALPHA / DIGIT / "-" / "_" ) *2( "=" )
    
    

    The data in a `Sec-Token-Binding` header is a Token Binding Message as specified in section 2 of the Token Binding over HTTP spec [TOKBIND-HTTPS]. A token binding message is a list of token bindings, where each token binding consists of a token binding ID, a token binding type and a cryptographic signature.

    3.4.1. Federated Token Binding

    In the scenario described above, servers bind tokens to be used by user agents with those servers. To enable existing web authorization protocols to use bound credentials, there is a need to support scenarios where bound credentials issued by one server (e.g., an identity provider) are presented by the user agent to a different server (e.g., a relying party). [TOKBIND-PROTOCOL] and [TOKBIND-HTTPS] describe support for Federated Token Binding.

    A referred-token-binding ID is the token binding ID for a server other than the server to which the request is being sent.

    Script code from an origin can set a request’s use-referred-token-binding flag to ask the user agent to send the token binding ID for that origin as a referred-token-binding ID in the Token Binding Message sent to a target server.

    Alternately, servers that redirect a user agent to a different server can use the `Include-Referred-Token-Binding-ID` header.

    Include-Referred-Token-Binding-ID = %x74.72.75.65 ; "true", case-sensitive
    
    

    The value of this header is specified in section 5.3 of the Token Binding over HTTP spec [TOKBIND-HTTPS].

    By setting the `Include-Referred-Token-Binding-ID` header to `true` in the redirect response, the origin that sends the redirect response (the "referring origin" in the Token Binding sense) tells the user agent to disclose the token binding ID used by the user agent for that origin to the target origin. The user agent does this while processing the `Include-Referred-Token-Binding-ID` header in the redirect response, by adding a referred-token-binding ID in the Token Binding Message that is created when the request is sent to the target server.

    3.4.2. Getting a Token Binding Key

    Get the token-binding key for an origin tokenBindingOrigin and token-binding key parameters tokenBindingKeyParameters, using the user agent’s token-binding key store, by running these substeps:

    1. Let keyDomainName be null.

    2. If tokenBindingOrigin’s host is an IP address, set keyDomainName to tokenBindingOrigin’s host.

      Otherwise, set keyDomainName to the registrable domain of tokenBindingOrigin’s host, determined by running the steps in the Algorithm section of Public Suffix List [PUBLIC-SUFFIX]

    3. Let tokenBindingKeyPair be null.

    4. Set tokenBindingKeyPair to the result of looking up the token-binding key pair for keyDomainName in the token-binding key store.

    5. If tokenBindingKeyPair is null, create a new key pair for keyDomainName using tokenBindingKeyParameters, save it in the token-binding key store, and set tokenBindingKeyPair to that new key pair.

    6. Return tokenBindingKeyPair.

    3.4.3. Computing a Token Binding Header Value

    If the user agent supports Token Binding, build the value that can be passed in a `Sec-Token-Binding` header for a request httpRequest and a connection tlsConnection, using the token-binding key store and the connection pool, by running these substeps:

    1. If httpRequest’s use-token-binding flag is not set, then return null.

    2. Initialize tokenBindingMessage to null.

    3. If Token Binding was not negotiated for tlsConnection, return null.

    4. Let providedTokenBindingKeyPair be the result of getting the token-binding key for the origin of httpRequest’s current url and tlsConnection’s token-binding key parameters metadata, obtained by following the steps in the Getting a Token Binding Key section of this document.

    5. Let providedTokenBindingId be the result of computing a token binding ID from providedTokenBindingKeyPair, as described in section 3.2 of [TOKBIND-PROTOCOL].

    6. Let providedTokenBinding be the result of computing a token binding using providedTokenBindingId and type provided_token_binding, containing a signature (using providedTokenBindingKeyPair) over the providedTokenBindingId as well as tlsConnection’s Exported Keying Material, as described in section 3.3 of [TOKBIND-PROTOCOL].

    7. Set tokenBindingMessage to a list containing providedTokenBinding as the only token binding.

    8. If httpRequest’s use-referred-token-binding flag is set, then run these substeps:

      1. Let referredTlsConnection be the result of getting a TLS connection for httpRequest’s referred-token-binding origin with credentials true from the connection pool.

      2. If Token Binding was not negotiated for referredTlsConnection, set referredTokenBinding to null.

      3. If Token Binding was negotiated for referredTlsConnection then:

        1. Let referredTokenBindingKeyPair be the result of getting the Token Binding key for httpRequest’s referred-token-binding origin and referredTlsConnection’s token-binding key parameters metadata, obtained by following the steps in the Getting a Token Binding Key section of this document.

        2. Let referredTokenBindingId be the result of computing a token binding ID from referredTokenBindingKeyPair, as described in section 3.2 of [TOKBIND-PROTOCOL].

        3. Let referredTokenBinding be the result of computing a token binding using referredTokenBindingId and type referred_token_binding, containing a signature (using referredTokenBindingKeyPair) over the referredTokenBindingId as well as tlsConnection’s Exported Keying Material, as described in section 3.3 of [TOKBIND-PROTOCOL].

      4. If referredTokenBinding is not null, add it to tokenBindingMessage.

    9. If tokenBindingMessage is not null, compute and return its base64url-encoding [RFC4648]. Otherwise return null.

    Details of how to create a Token Binding Messsage are described in section 3 of [TOKBIND-PROTOCOL].

    4. Fetching

    The algorithm below defines fetching. In broad strokes, it takes a request and outputs a response.

    That is, it either returns a response if request’s synchronous flag is set, or it queues tasks annotated process response, process response end-of-body, and process response done for the response.

    To capture uploads, if request’s synchronous flag is unset, tasks annotated process request body and process request end-of-body for the request can be queued.

    To perform a fetch using request, run the steps below. An ongoing fetch can be terminated with reason reason, which must be end-user abort, fatal, timeout, or garbage collection.

    The user agent may be asked to suspend the ongoing fetch. The user agent may either accept or ignore the suspension request. The suspended fetch can be resumed. The user agent should ignore the suspension request if the ongoing fetch is updating the response in the HTTP cache for the request.

    The user agent does not update the entry in the HTTP cache for a request if request’s cache mode is "no-store" or a `Cache-Control: no-store` header appears in the response. [HTTP-CACHING]

    1. If request’s window is "client", set request’s window to request’s client, if request’s client’s global object is a Window object, and to "no-window" otherwise.

    2. If request’s origin is "client", set request’s origin to request’s client’s origin.

    3. If request’s header list does not contain a header whose name is `Accept`,

      then

      run these substeps:

      1. Let value be `*/*`.

      2. If request is a navigation request, a user agent should set value to `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8`.

      3. Otherwise, a user agent should set value to the first matching statement, if any, switching on request’s type:

        "image"
        `image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5`
        "style"
        `text/css,*/*;q=0.1`
      4. Append `Accept`/value to request’s header list.

    4. If request’s header list does not contain a header whose name is `Accept-Language`, user agents should append `Accept-Language`/an appropriate value to request’s header list.

    5. If request’s priority is null, use request’s initiator, type, and destination appropriately in setting it to a user-agent-defined object.

      The user-agent-defined object could encompass stream weight and dependency for HTTP/2, and equivalent information used to prioritize dispatch and processing of HTTP/1 fetches.

    6. If request is a navigation request, a user agent should, for each header name (

      hintName

      hint-name) in the first column of the following table, if hint-name is not in request’s header list

      does not contain hintName

      ,

      then

      append

      hintName/the

      hint-name/hint-value given in the same row on the second column, to request’s header list.

      Name Value
      hint-name hint-value
      `dpr` a suitable dpr value
      `save-data` a suitable save-data value
      `viewport-width` a suitable viewport-width value
    7. If request is a subresource request, run these substeps:

      1. If the request’s client hints list is not empty, then run these substeps for each

        hintName

        hint-name in the list:

        1. Set value to the first matching statement, if any, switching on

          hintName

          hint-name:

          "dpr"
          a suitable dpr value
          "save-data"
          a suitable save-data value
          "viewport-width"
          a suitable viewport-width value
          "width"
          a suitable width value
        2. Append

          hintName

          hint-name/value to request’s header list.

      2. Let record be a new fetch record consisting of request and this instance of the fetch algorithm.

      3. Append record to request’s client’s fetch group list of fetch records.

    8. Return the result of performing a main fetch using request.

    4.1. Main fetch

    To perform a main fetch using request, optionally with a CORS flag and recursive flag, run these steps:

    When main fetch is invoked recursively recursive flag is set. CORS flag is a bookkeeping detail for handling redirects.

    1. Let response be null.

    2. If request’s local-URLs-only flag is set and request’s current url is not local, set response to a network error.

    3. Execute Report Content Security Policy violations for request. [CSP]

    4. Upgrade request to a potentially secure URL, if appropriate. [UPGRADE]

    5. If should fetching request be blocked due to a bad port, should fetching request be blocked as mixed content, or should fetching request be blocked by Content Security Policy returns blocked, set response to a network error. [MIX] [CSP]

    6. If request’s referrer policy is the empty string and request’s client is non-null, then set request’s referrer policy to request’s client’s referrer policy. [REFERRER]

    7. If request’s referrer policy is the empty string, then set request’s referrer policy to "no-referrer-when-downgrade".

      We use "no-referrer-when-downgrade" because it is the historical default.

    8. If request’s referrer is not "no-referrer", set request’s referrer to the result of invoking determine request’s referrer. [REFERRER]

      As stated in Referrer Policy, user agents can provide the end user with options to override request’s referrer to "no-referrer" or have it expose less sensitive information.

    9. If request’s current URL’s scheme is "ftp", request’s client’s creation URL’s scheme is not "ftp", and request’s reserved client is either null or an environment whose target browsing context is a nested browsing context, then set response to a network error.

    10. Set request’s current url’s scheme to "https" if all of the following conditions are true:

    11. If request’s synchronous flag is unset and recursive flag is unset, run the remaining steps in parallel.

    12. If response is null, then set response to the result of running the substeps corresponding to the first matching statement:

      request’s current url’s origin is same origin with request’s origin and CORS flag is unset
      request’s current url’s scheme is "data"
      request’s mode is "navigate" or "websocket"
      1. Set request’s response tainting to "basic".

      2. Return the result of performing a basic fetch using request.

      HTML assigns any documents and workers created from URLs whose scheme is "data" a unique opaque origin. Service workers can only be created from URLs whose scheme is an HTTP(S) scheme. [HTML] [SW]

      request’s mode is "same-origin"

      Return a network error.

      request’s mode is "no-cors"
      1. Set request’s response tainting to "opaque".

      2. Return the result of performing a basic fetch using request.

      request’s current url’s scheme is not an HTTP(S) scheme

      Return a network error.

      request’s use-CORS-preflight flag is set
      request’s unsafe-request flag is set and either request’s method is not a CORS-safelisted method or a header in request’s header list is not a CORS-safelisted request-header
      1. Set request’s response tainting to "cors".

      2. Let corsWithPreflightResponse be the result of performing an HTTP fetch using request with CORS flag and CORS-preflight flag set.

      3. If corsWithPreflightResponse is a network error, then clear cache entries using request.

      4. Return corsWithPreflightResponse.

      Otherwise
      1. Set request’s response tainting to "cors".

      2. Return the result of performing an HTTP fetch using request with CORS flag set.

    13. If the recursive flag is set, return response.

    14. If response is not a network error and response is not a filtered response, then run these substeps:

      1. If request’s response tainting is "cors", then run these substeps:

        1. Let headerNames be the result of

          extracting header list values given

          parsing `Access-Control-Expose-Headers`

          and

          in response’s header list.

        2. If headerNames is `*` and request’s credentials mode is not "include", then set response’s CORS-exposed header-name list to all unique header names in response’s header list.

        3. Otherwise, if headerNames is not null, failure, or `*`, then set response’s CORS-exposed header-name list to headerNames.

      2. Set response to the following filtered response with response as its internal response, depending on request’s response tainting:

        "basic"
        basic filtered response
        "cors"
        CORS filtered response
        "opaque"
        opaque filtered response
    15. Let internalResponse be response, if response is a network error, and response’s internal response otherwise.

    16. If internalResponse’s url list is empty, then set it to a copy of request’s url list.

      A response’s url list will typically be empty at this point, unless it came from a service worker, in which case it will only be empty if it was created through new Response().

    17. If response is not a network error and any of the following algorithms returns blocked, then set response and internalResponse to a network error:

    18. If response is not a network error and either request’s method is `HEAD` or `CONNECT`, or internalResponse’s status is a null body status, set internalResponse’s body to null and disregard any enqueuing toward it (if any).

      This standardizes the error handling for servers that violate HTTP.

    19. If response is not a network error and request’s integrity metadata is not the empty string, run these substeps:

      1. Wait for response’s body.

      2. If response does not have a termination reason and response does not match request’s integrity metadata, set response and internalResponse to a network error. [SRI]

      This operates on response as this algorithm is not supposed to observe internalResponse. That would allow an attacker to use hashes as an oracle.

    20. If request’s synchronous flag is set, wait for internalResponse’s body, and then return response.

      This terminates fetch.

    21. If request’s current url’s scheme is an HTTP(S) scheme, then run these substeps:

      1. If request’s body is done, queue a fetch-request-done task for request.

      2. Otherwise, in parallel, wait for request’s body, and then queue a fetch-request-done task for request.

    22. Queue a fetch task on request to process response for response.

    23. Wait for internalResponse’s body.

    24. Queue a fetch task on request to process response end-of-body for response.

    25. Wait for internalResponse’s trailer, if any. See section 4.1.2 of [HTTP].

    26. Set request’s done flag.

    27. Queue a fetch task on request to process response done for response.

    4.2. Basic fetch

    To perform a basic fetch using request, switch on request’s current url’s scheme, and run the associated steps:

    "about"

    If request’s current url’s cannot-be-a-base-URL flag is set and path contains a single string "blank", return a response whose header list consist of a single header whose name is `Content-Type` and value is `text/html;charset=utf-8`, body is the empty byte sequence, and HTTPS state is request’s client’s HTTPS state if request’s client is non-null.

    Otherwise, return a network error.

    URLs such as "about:config" are handled during navigation and result in a network error in the context of fetching.

    "blob"
    1. Let blob be request’s current url’s object.

    2. If request’s method is not `GET` or blob is null, then return a network error.

      The `GET` method restriction serves no useful purpose other than being interoperable.

    3. Let response be a new response.

    4. Append `Content-Length`/blob’s size attribute value to response’s header list.

    5. Append `Content-Type`/blob’s type attribute value to response’s header list.

    6. Set response’s HTTPS state to request’s client’s HTTPS state if request’s client is non-null.

    7. Set response’s body to the result of performing the read operation on blob.

    8. Return response.

    "data"

    If obtaining a resource from request’s current url does not return failure, then return a response whose header list consist of a single header whose name is `Content-Type` and value is the MIME type and parameters returned from obtaining a resource, body is the data returned from obtaining a resource, and HTTPS state is request’s client’s HTTPS state if request’s client is non-null. [DATAURL]

    Otherwise, return a network error.

    "file"
    "ftp"

    For now, unfortunate as it is, file and ftp URLs are left as an exercise for the reader.

    When in doubt, return a network error.

    "filesystem"

    If request’s sandboxed-storage-area-URLs flag is set, return a network error.

    Otherwise, … this scheme still needs to be defined.

    HTTP(S) scheme

    Return the result of performing an HTTP fetch using request.

    Otherwise

    Return a network error.

    4.3. HTTP fetch

    To perform an HTTP fetch using request with an optional CORS flag and CORS-preflight flag, run these steps:

    CORS flag is still a bookkeeping detail. As is CORS-preflight flag; it indicates a CORS-preflight request is needed.

    1. Let response be null.

    2. Let actualResponse be null.

    3. If request’s skip-service-

      workers mode is not "none"

      worker flag is unset, then run these substeps:

      1. If request’s

        service-workers mode is "all"

        client is null or request’s client’s global object is not a ServiceWorkerGlobalScope object, then set response to the result of invoking handle fetch for request. [HTML] [SW]

      2. If response is null, request is a subresource request, and request’s origin is not same origin with request’s url’s origin, then set response to the result of invoking handle foreign fetch for request. [SW]

      3. If response is not null, then run these substeps:

        1. Transmit body for request.

        2. Set actualResponse to response, if response is not a filtered response, and to response’s internal response otherwise.

        3. If one of the following conditions is true, then return a network error:

          • response’s type is "error".
          • request’s mode is not "no-cors" and response’s type is "opaque".
          • request’s redirect mode is not "manual" and response’s type is "opaqueredirect".
          • request’s redirect mode is not "follow" and response’s url list has more than one item.
        4. Execute set response’s CSP list on actualResponse. [CSP]

    4. If response is null, run these substeps:

      1. If the CORS-preflight flag is set and one of these conditions is true:

        Then run these subsubsteps:

        1. Let preflightResponse be the result of performing a CORS-preflight fetch using request.

        2. If preflightResponse is a network error, return preflightResponse.

        This step checks the CORS-preflight cache and if there is no suitable entry it performs a CORS-preflight fetch which, if successful, populates the cache. The purpose of the CORS-preflight fetch is to ensure the fetched resource is familiar with the CORS protocol. The cache is there to minimize the number of CORS-preflight fetches.

      2. If request’s redirect mode is "follow", then set request’s skip-service-

        workers mode to "foreign"

        worker flag.

        Redirects coming from the network (as opposed to from a service worker) are not to be exposed to a service worker.

      3. Set response and actualResponse to the result of performing an HTTP-network-or-cache fetch using request with CORS flag if set.

      4. If CORS flag is set and a CORS check for request and response returns failure, then return a network error.

        As the CORS check is not to be applied to responses whose status is 304 or 407, or responses from a service worker for that matter, it is applied here.

    5. If actualResponse’s status is a redirect status, then run these substeps:

      1. If actualResponse’s status is not 303, request’s body is not done, and the connection uses HTTP/2, then user agents may, and are even encouraged to, transmit an RST_STREAM frame.

        303 is excluded as certain communities ascribe special status to it.

      2. Let location be the result of

        extracting header list values given

        parsing `Location`

        and

        in actualResponse’s header list.

      3. If location is a value, then set location to the result of parsing location with actualResponse’s url.

      4. Set actualResponse’s location URL to location.

      5. Switch on request’s redirect mode:

        "error"

        Set response to a network error.

        "manual"

        Set response to an opaque-redirect filtered response whose internal response is actualResponse.

        "follow"

        Set response to the result of performing HTTP-redirect fetch using request and response with CORS flag if set.

    6. Return response. Typically actualResponse’s body’s stream is still being enqueued to after returning.

    4.4. HTTP-redirect fetch

    This algorithm will be used by HTML’s "navigate" algorithm in addition to HTTP fetch above. [HTML]

    To perform an HTTP-redirect fetch using request and response, with an optional CORS flag, run these steps:

    1. Let actualResponse be response, if response is not a filtered response, and response’s internal response otherwise.

    2. If actualResponse’s location URL is null, then return response.

    3. If actualResponse’s location URL is failure, then return a network error.

    4. If actualResponse’s location URL’s scheme is not an HTTP(S) scheme, then return a network error.

    5. If request’s redirect count is twenty, return a network error.

    6. Increase request’s redirect count by one.

    7. If request’s mode is "cors", request’s origin is not same origin with actualResponse’s location URL’s origin, and actualResponse’s location URL includes credentials, then return a network error.

    8. If actualResponse’s status is not 303, request’s body is non-null, and request’s body’s source is null, then return a network error.

    9. If CORS flag is set and actualResponse’s location URL includes credentials, then return a network error.

      This catches a cross-origin resource redirecting to a same-origin URL.

    10. If CORS flag is set and actualResponse’s location URL’s origin is not same origin with request’s current url’s origin, set request’s origin to a globally unique identifier.

    11. If either actualResponse’s status is 301 or 302 and request’s method is `POST`, or actualResponse’s status is 303, set request’s method to `GET` and request’s body to null.

    12. If request’s body is non-null, then set request’s body to the first part of extracting request’s body’s source.

      request’s body’s source’s nullity has already been checked. The extracting operation cannot throw as it was called for the same source before.

    13. Let useReferredTokenBinding be the result of parsing `Include-Referred-Token-Binding-ID` in actualResponse’s header list.

    14. Unset the request’s use-referred-token-binding flag.

    15. If useReferredTokenBinding is `true` and the request’s use-token-binding flag is set, then perform the following substeps:

      1. Set the request’s use-referred-token-binding flag.

      2. Set the request’s referred-token-binding origin to request’s origin.

      By causing the use-referred-token-binding flag to be set for the subsequent request via the `Include-Referred-Token-Binding-ID` header in its redirect response, the referring origin tells the user agent to disclose to the target server the token binding ID used by the user agent with the referring origin. Importantly, only the referring origin can cause the user agent to disclose the token binding ID for that origin to a target server - a third party cannot do that. Also, every redirect in a redirect chain is handled independently - the server that sends a redirect response controls whether the user agent receiving that response will disclose its token binding id for that server to the target server to which the user agent is being redirected.

    16. Append actualResponse’s location URL to request’s url list.

    17. Invoke set request’s referrer policy on redirect on request and actualResponse. [REFERRER]

    18. Return the result of performing a main fetch using request with CORS flag if set and recursive flag set.

      This has to invoke main fetch to get response tainting correct.

    4.5. HTTP-network-or-cache fetch

    To perform an HTTP-network-or-cache fetch using request with an optional CORS flag and authentication-fetch flag, run these steps:

    CORS flag is still a bookkeeping detail. As is authentication-fetch flag.

    1. Let httpRequest be null.

    2. If request’s window is "no-window" and request’s redirect mode is "error", then set httpRequest to request.

    3. Otherwise, run these substeps:

      1. Set httpRequest to a copy of request except for its body.

      2. Let body be request’s body.

      3. Set httpRequest’s body to body.

      4. If body is non-null, then set request’s body to a new body whose stream is null and whose source is body’s source.

      request is copied as httpRequest here as we need to be able to add headers to httpRequest and read its body without affecting request. Namely, request can be reused with redirects, authentication, and proxy authentication. We copy rather than clone in order to reduce memory consumption. In case request’s body’s source is null, redirects and authentication will end up failing the fetch.

    4. Let credentials flag be set if one of

      is true, and unset otherwise.

    5. Let contentLengthValue be null.

    6. If httpRequest’s body is null and httpRequest’s method is `POST` or `PUT`, then set contentLengthValue to `0`.

    7. If httpRequest’s body is non-null and httpRequest’s body’s source is non-null, then set contentLengthValue to httpRequest’s body’s total bytes, UTF-8 encoded.

    8. If contentLengthValue is non-null, append `Content-Length`/contentLengthValue to httpRequest’s header list.

    9. If contentLengthValue is non-null

      and

      , httpRequest’s keepalive flag is set,

      then:
    10. Let inflightKeepaliveBytes be zero.

    11. Let group be httpRequest’s client’s fetch group.

    12. Let inflightRecords be the set of fetch records in group whose request has its keepalive flag set

      and

      done flag unset.
    13. For each fetchRecord in inflightRecords:

      1. Let inflightRequest be fetchRecord’s request.

      2. Increment inflightKeepaliveBytes by inflightRequest’s body’s total bytes.

    14. If the sum of

      contentLengthValue

      and inflightKeepaliveBytes

      is greater than

      64 kibibytes

      a user-agent-defined maximum, then return a network error.

      The above

      limit

      user-agent-defined maximum ensures that requests that are allowed to outlive the environment settings object and contain a body, have a bounded size and are not allowed to stay alive indefinitely.

    15. If httpRequest’s referrer is a URL, then append `Referer`/httpRequest’s referrer, serialized and UTF-8 encoded, to httpRequest’s header list.

    16. If the CORS flag is set or httpRequest’s method is neither `GET` nor `HEAD`, then append `Origin`/httpRequest’s origin, serialized and UTF-8 encoded, to httpRequest’s header list.

    17. If httpRequest’s header list does not contain a header whose name is `User-Agent`,

      then

      user agents should append `User-Agent`/default `User-Agent` value to httpRequest’s header list.

    18. If httpRequest’s cache mode is "default" and httpRequest’s header list contains a header named `If-Modified-Since`, `If-None-Match`, `If-Unmodified-Since`, `If-Match`, or `If-Range`,

      then

      set httpRequest’s cache mode to "no-store".

    19. If httpRequest’s cache mode is "no-cache" and httpRequest’s header list does not contain a header whose name is `Cache-Control`,

      then

      append `Cache-Control`/`max-age=0` to httpRequest’s header list.

    20. If httpRequest’s cache mode is "no-store" or "reload", run these substeps:

      1. If httpRequest’s header list does not contain a header whose name is `Pragma`,

        then

        append `Pragma`/`no-cache` to httpRequest’s header list.

      2. If httpRequest’s header list does not contain a header whose name is `Cache-Control`,

        then

        append `Cache-Control`/`no-cache` to httpRequest’s header list.

    21. Modify httpRequest’s header list per HTTP.

      It would be great if we could make this more normative somehow. At this point headers such as `Accept-Encoding`, `Connection`, `DNT`, and `Host`, are to be appended if necessary.

      `Accept`, `Accept-Charset`, and `Accept-Language` must not be included at this point.

      `Accept` and `Accept-Language` are already included (unless fetch() is used, which does not include the latter by default), and `Accept-Charset` is a waste of bytes. See HTTP header layer division for more details.

    22. If credentials flag is not set or if the user agent is configured to block cookies for httpRequest (see section 7 of [COOKIES]), then unset the httpRequest’s use-token-binding flag.

    23. If credentials flag is set, run these substeps:

      1. If the user agent is not configured to block cookies for httpRequest (see section 7 of [COOKIES]), then run these substeps:

        1. Let cookies be the result of running the "cookie-string" algorithm (see section 5.4 of [COOKIES]) with the user agent’s cookie store and httpRequest’s current url.

        2. If cookies is not the empty string, append `Cookie`/cookies to httpRequest’s header list.
        3. If the user agent supports Token Binding, set httpRequest’s use-token-binding flag.

      2. If httpRequest’s header list contains a header whose name is `Authorization`,

        then

        terminate these substeps.

      3. Let authorizationValue be null.

      4. If there’s an authentication entry for httpRequest and either httpRequest’s use-URL-credentials flag is unset or httpRequest’s current url does not include credentials, set authorizationValue to authentication entry.

      5. Otherwise, if httpRequest’s current url does include credentials and authentication-fetch flag is set, then set authorizationValue to httpRequest’s current url, converted to an `Authorization` value.

      6. If authorizationValue is non-null, append `Authorization`/authorizationValue to httpRequest’s header list.

    24. If there’s a proxy-authentication entry, use it as appropriate.

      This intentionally does not depend on httpRequest’s credentials mode.

    25. Let response be null.

    26. If httpRequest’s cache mode is neither "no-store" nor "reload", and there is a complete response in the HTTP cache for httpRequest run these substeps:

      1. If httpRequest’s cache mode is "force-cache" or "only-if-cached", then set response to the response in the HTTP cache for httpRequest.

        As mandated by HTTP, this still takes the `Vary` header into account.

      2. Otherwise, if httpRequest’s cache mode is "default" and the response in the HTTP cache for httpRequest does not require revalidation, then set response to that response.

      3. Otherwise, if httpRequest’s cache mode is either "default" or "no-cache", modify httpRequest’s header list with revalidation headers.

    27. Otherwise, if httpRequest’s cache mode is either "default" or "force-cache", and there is a partial response in the HTTP cache for httpRequest, modify httpRequest’s header list with resume headers.

    28. If response is null, run these substeps:

      1. If httpRequest’s cache mode is "only-if-cached", then return a network error.

      2. Set response to the result of making an HTTP-network fetch using httpRequest with credentials flag if set.

    29. If response’s status is 304 and httpRequest’s cache mode is either "default" or "no-cache", run these substeps:

      1. Set cachedResponse to the result of selecting a stored response from the HTTP cache using httpRequest, as per the "Freshening Stored Responses upon Validation" chapter of HTTP Caching. [HTTP-CACHING]

      2. If cachedResponse is null (i.e., one cannot be selected), return a network error.

      3. Update cachedResponse’s header list using response’s header list, as per the "Freshening Stored Responses upon Validation" chapter of HTTP Caching. [HTTP-CACHING]

      4. Set response to the cachedResponse.

        This changes response entirely, including its status which is most likely 200 now.

    30. If response’s status is 401, CORS flag is unset, credentials flag is set, and request’s window is an environment settings object, then run these substeps:

      1. Needs testing: multiple `WWW-Authenticate` headers, missing, parsing issues.

      2. If request’s body is non-null, then run these subsubsteps:

        1. If request’s body’s source is null, then return a network error.

        2. Set request’s body to the first part of extracting request’s body’s source.

          The extracting operation cannot throw as it was called for the same source before.

      3. If request’s use-URL-credentials flag is unset or authentication-fetch flag is set, then run these subsubsteps:

        1. Let username and password be the result of prompting the end user for a username and password, respectively, in request’s window.

        2. Set the username given request’s current url and username.

        3. Set the password given request’s current url and password.

      4. Set response to the result of performing an HTTP-network-or-cache fetch using request with authentication-fetch flag set.

    31. If response’s status is 407, then run these substeps:

      1. If request’s window is "no-window", then return a network error.

      2. Needs testing: multiple `Proxy-Authenticate` headers, missing, parsing issues.

      3. Prompt the end user as appropriate in request’s window and store the result as a proxy-authentication entry. [HTTP-AUTH]

        Remaining details surrounding proxy authentication are defined by HTTP.

      4. Set response to the result of performing an HTTP-network-or-cache fetch using request with CORS flag if set.

    32. If authentication-fetch flag is set, then create an authentication entry for request and the given realm.

    33. Return response. Typically response’s body’s stream is still being enqueued to after returning.

    4.6. HTTP-network fetch

    To perform an HTTP-network fetch using request with an optional credentials flag, run these steps:

    1. Let credentials be true if credentials flag is set, and false otherwise.

    2. Switch on request’s mode:

      "websocket"

      Let connection be the result of obtaining a WebSocket connection, given request’s current url.

      Otherwise

      Let connection be the result of obtaining a connection, given request’s current url’s origin and credentials.

    3. If connection is failure, return a network error.

    4. If the user agent supports Token Binding, and request’s use-token-binding flag is set, build and add a Sec-Token-Binding header by running the following substeps:

      1. Let tokenBindingMessage be the result of running the steps in the Computing a Token Binding Header Value section of this document for request and connection, using the user agent’s token-binding key store and connection pool.

      2. If tokenBindingMessage is not null, append `Sec-Token-Binding`/tokenBindingMessage to request’s header list.

    5. If connection is not an HTTP/2 connection, request’s body is non-null, and request’s body’s source is null, then append `Transfer-Encoding`/`chunked` to request’s header list.

    6. Let response be the result of making an HTTP request over connection using request with the following caveats:

      The exact layering between Fetch and HTTP still needs to be sorted through and therefore response represents both a response and an HTTP response here.

      If request’s header list contains `Transfer-Encoding`/`chunked` and response is transferred via HTTP/1.0 or older, then return a network error.

      If the HTTP request results in a TLS client certificate dialog, run these substeps:

      1. If request’s window is an environment settings object, make the dialog available in request’s window.

      2. Otherwise, return a network error.

      If response was retrieved over HTTPS, set its HTTPS state to either "deprecated" or "modern". [TLS]

      The exact determination here is up to user agents for the time being. User agents are strongly encouraged to only succeed HTTPS connections with strong security properties and return network errors otherwise. Using the "deprecated" state value ought to be a temporary and last resort kind of option.

      Transmit body for request.

    7. Let strategy be an object. The user agent may choose any object.

      strategy is used to control the queuing strategy of stream constructed below.

    8. Let pull be an action that resumes the ongoing fetch if it is suspended.

    9. Let cancel be an action that terminates the ongoing fetch with reason end-user abort.

    10. Let stream be the result of constructing a ReadableStream object with strategy, pull and cancel.

      This construction operation will not throw an exception.

    11. Set response’s body to a new body whose stream is stream.

    12. If response has a payload body length, then set response’s body’s total bytes to that payload body length.

    13. Delete `Content-Encoding` from response’s header list if one of the following conditions is true:

      Extracting header list values given and ,
      • and
      extracting header list values given and
      • in response’s header list returns `application/gzip`, `application/x-gunzip`, or `application/x-gzip`.
      Extracting header list values given and ,
      • and
      extracting header list values given and
      • in response’s header list returns `application/compress` or `application/x-compress.

      This deals with broken Apache configurations. Ideally HTTP would define this.

      Gecko bug 1030660 looks into whether this quirk can be removed.

    14. Execute set response’s CSP list on response. [CSP]

    15. If response is not a network error and request’s cache mode is not "no-store", update response in the HTTP cache for request.

    16. If credentials flag is set and the user agent is not configured to block cookies for request (see section 7 of [COOKIES]), then run the "set-cookie-string" parsing algorithm (see section 5.2 of [COOKIES]) on the value of each header

      whose name is a byte-case-insensitive match for

      named `Set-Cookie` in response’s header list, if any, and request’s current url.

      This is a fingerprinting vector.

    17. Run these substeps in parallel:

      1. Whenever one or more bytes are transmitted from response’s message body, let bytes be the transmitted bytes and run these subsubsteps:

        1. Increase response’s body’s transmitted bytes with bytes’ length.

        2. Let codings be the result of

          extracting header list values given

          parsing `Content-Encoding`

          and

          in response’s header list.

        3. Set bytes to the result of handling content codings given codings and bytes.

          This makes the `Content-Length` header unreliable to the extent that it was reliable to begin with.

        4. Enqueue a Uint8Array object wrapping an ArrayBuffer containing bytes to stream. If that threw an exception, terminate the ongoing fetch with fatal, error stream with that exception and abort these subsubsteps.

        5. If stream doesn’t need more data and request’s synchronous flag is unset, ask the user agent to suspend the ongoing fetch.

      2. If at any point the bytes transmission for response’s message body is done normally and stream is readable, then close stream.

      3. If at any point fetch is terminated with reason reason, run these subsubsteps:

        1. Set response’s termination reason to reason.

        2. If stream is readable, error stream with a TypeError.

      These are run in parallel as at this point it is unclear whether response’s body is relevant (response might be a redirect).

    18. Return response. Typically response’s body’s stream is still being enqueued to after returning.

    4.7. CORS-preflight fetch

    This is effectively the user agent implementation of the check to see if the CORS protocol is understood. The so-called CORS-preflight request. If successful it populates the CORS-preflight cache to minimize the number of these fetches.

    To perform a CORS-preflight fetch using request, run these steps:

    1. Let preflight be a new request whose method is `OPTIONS`, url is request’s current url, initiator is request’s initiator, type is request’s type, destination is request’s destination, origin is request’s origin, referrer is request’s referrer, and referrer policy is request’s referrer policy.

    2. Set `Access-Control-Request-Method` to request’s method in preflight’s header list.

    3. Let headers be the names of request’s header list’s headers, excluding CORS-safelisted request-headers and duplicates, sorted lexicographically, and byte-lowercased.

    4. If headers is not empty, then:

      1. Let value be the items in headers separated from each other by `,`.

      2. Set `Access-Control-Request-Headers` to value in preflight’s header list.

    5. Let response be the result of performing an HTTP-network-or-cache fetch using preflight.

    6. If a CORS check for request and response returns success and response’s status is an ok status, run these substeps:

      The CORS check is done on request rather than preflight to ensure the correct credentials mode is used.

      1. Let methods be the result of

        extracting header list values given

        parsing `Access-Control-Allow-Methods`

        and

        in response’s header list.

      2. If methods is `*`, then set methods to a new list containing `*`.

      3. Let headerNames be the result of

        extracting header list values given

        parsing `Access-Control-Allow-Headers`

        and

        in response’s header list.

      4. If either methods or headerNames is failure, return a network error.

      5. If methods or headerNames contains `*`, and request’s credentials mode is "include", then return a network error.

      6. If methods is null and request’s use-CORS-preflight flag is set, then set methods to a new list containing request’s method.

        This ensures that a CORS-preflight fetch that happened due to request’s use-CORS-preflight flag being set is cached.

      7. If request’s method is not in methods, is not a CORS-safelisted method, and methods does not contain `*`, then return a network error.

      8. If one of request’s header list’s names is a CORS non-wildcard request-header name and is not

        a byte-case-insensitive match for an item

        in headerNames, then return a network error.

      9. If one of request’s header list' names is not

        a byte-case-insensitive match for an item

        in headerNames, its corresponding header is not a CORS-safelisted request-header, and headerNames does not contain `*`, then return a network error.

      10. Let max-age be the result of

        extracting header list values given

        parsing `Access-Control-Max-Age`

        and

        in response’s header list.

      11. If max-age is failure or null, then set max-age to zero.

      12. If max-age is greater than an imposed limit on max-age, then set max-age to the imposed limit.

      13. If the user agent does not provide for a cache, then return response.

      14. For each method in methods for which there is a method cache match using request, set matching entry’s max-age to max-age.

      15. For each method in methods for which there is no method cache match using request, create a new entry with request, max-age, method, and null.

      16. For each headerName in headerNames for which there is a header-name cache match using request, set matching entry’s max-age to max-age.

      17. For each headerName in headerNames for which there is no header-name cache match using request, create a new entry with request, max-age, null, and headerName.

      18. Return response.

    7. Otherwise, return a network error.

    4.8. CORS-preflight cache

    A CORS-preflight cache consists of a collection of entries where each entry has these fields:

    Entries must be removed after the seconds specified in the max-age field have passed since storing the entry. Entries may be removed before that moment arrives.

    To create a new entry in the CORS-preflight cache, given request, max-age, method, and headerName, do so as follows:

    origin
    request’s origin
    url
    request’s current url
    max-age
    max-age
    credentials
    True if request’s credentials mode is "include", and false otherwise
    method
    method
    header name
    headerName

    To clear cache entries, given a request, remove any entries in the CORS-preflight cache whose origin is request’s origin and whose url is request’s current url.

    There is a cache match for request if origin is request’s origin, url is request’s current url, and one of

    is true.

    There is a method cache match for method using request when there is an entry in CORS-preflight cache for which there is a cache match for request and its method is method or `*`.

    There is a header-name cache match for headerName using request when there is an entry in CORS-preflight cache for which there is a cache match for request and one of

    a byte-case-insensitive match for

    is true.

    4.9. CORS check

    To perform a CORS check for a request and response, run these steps:

    1. Let origin be the result of

      extracting header list values given

      parsing `Access-Control-Allow-Origin`

      and

      in response’s header list.

    2. If origin is null or failure, return failure.

      Null is not `null`.

    3. If request’s credentials mode is not "include" and origin is `*`, return success.

    4. If request’s origin, serialized and UTF-8 encoded, is not origin, return failure.

    5. If request’s credentials mode is not "include", return success.

    6. Let credentials be the result of

      extracting header list values given

      parsing `Access-Control-Allow-Credentials`

      and

      in response’s header list.

    7. If credentials is `true`, return success.

      It has been suggested to check for origin not being `null` here as that would be equal to allowing credentials and `*` which is also forbidden.

    8. Return failure.

    5. Fetch API

    The fetch() method is relatively low-level API for fetching resources. It covers slightly more ground than XMLHttpRequest, although it is currently lacking when it comes to request progression (not response progression).

    The fetch() method makes it quite straightforward to fetch a resource and extract its contents as a Blob:

    fetch("/music/pk/altes-kamuffel.flac")
      .then(res => res.blob()).then(playBlob)
    

    If you just care to log a particular response header:

    fetch("/", {method:"HEAD"})
      .then(res => log(res.headers.get("strict-transport-security")))
    

    If you want to check a particular response header and then process the response of a cross-origin resources:

    fetch("https://pk.example/berlin-calling.json", {mode:"cors"})
      .then(res => {
        if(res.headers.get("content-type") &&
           res.headers.get("content-type").toLowerCase().indexOf("application/json") >= 0) {
          return res.json()
        } else {
          throw new TypeError()
        }
      }).then(processJSON)
    

    If you want to work with URL query parameters:

    var url = new URL("https://geo.example.org/api"),
        params = {lat:35.696233, long:139.570431}
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))
    fetch(url).then(/* … */)
    

    If you want to receive the body data progressively:

    function consume(reader) {
      var total = 0
      return pump()
      function pump() {
        return reader.read().then(({done, value}) => {
          if (done) {
            return
          }
          total += value.byteLength
          log(`received ${value.byteLength} bytes (${total} bytes in total)`)
          return pump()
        })
      }
    }
    
    fetch("/music/pk/altes-kamuffel.flac")
      .then(res => consume(res.body.getReader()))
      .then(() => log("consumed the entire body without keeping the whole thing in memory!"))
      .catch(e => log("something went wrong: " + e))
    

    5.1. Headers class

    typedef (sequence<sequence<ByteString>> or record<ByteString, ByteString>) HeadersInit;
    
    [Constructor(optional HeadersInit init),
     Exposed=(Window,Worker)]
    interface Headers {
      void append(ByteString name, ByteString value);
      void delete(ByteString name);
      ByteString? get(ByteString name);
      boolean has(ByteString name);
      void set(ByteString name, ByteString value);
      iterable<ByteString, ByteString>;
    };
    

    Constructing a Headers object from scratch is fairly straightforward. You could pass in a JavaScript object representing a header hash map, or an array of ordered pairs:

    var meta = { "Content-Type": "text/xml", "Breaking-Bad": "<3" }
    new Headers(meta)
    
    // The above is equivalent to
    var meta = [
      [ "Content-Type", "text/xml" ],
      [ "Breaking-Bad", "<3" ]
    ]
    new Headers(meta)
    

    A Headers object has an associated header list (a header list), which is initially empty. This can be a pointer to the header list of something else, e.g., of a request as demonstrated by Request objects.

    A Headers object also has an associated guard, which is "immutable", "request", "request-no-cors", "response" or "none".

    "immutable" exists for service workers. [SW]

    To append a name/value (name/value) pair to a Headers object (headers), run these steps:

    1. Normalize value.

    2. If name is not a name or value is not a value, then throw a TypeError.

    3. If guard is "immutable", then throw a TypeError.

    4. Otherwise, if guard is "request" and name is a forbidden header name, return.

    5. Otherwise, if guard is "request-no-cors" and name/value is not a CORS-safelisted request-header, return.

    6. Otherwise, if guard is "response" and name is a forbidden response-header name, return.

    7. Append name/value to header list.

    To fill a Headers object (headers) with a given object (object), run these steps:

    1. If object is a sequence, then for each header in object, run these substeps:

      1. If header does not contain exactly two items, then throw a TypeError.

      2. Append header’s first item/header’s second item to headers. Rethrow any exception.

    2. Otherwise, object is a record, then for each mapping (key

      , value) in object, append key/value to headers. Rethrow any exception.

    The Headers(init) constructor, when invoked, must run these steps:

    1. Let headers be a new Headers object whose guard is "none".

    2. If init is given, fill headers with init. Rethrow any exception.

    3. Return headers.

    The append(name, value) method, when invoked, must append name/value to context object and rethrow any exception.

    The delete(name) method, when invoked, must run these steps:

    1. If name is not a name, then throw a TypeError.

    2. If guard is "immutable", then throw a TypeError.

    3. Otherwise, if guard is "request" and name is a forbidden header name, return.

    4. Otherwise, if guard is "request-no-cors" and name/`invalid` is not a CORS-safelisted request-header, then return.

      `invalid` is used because delete() is not passed a value as argument.

    5. Otherwise, if guard is "response" and name is a forbidden response-header name, return.

    6. Delete name from header list.

    The get(name) method, when invoked, must run these steps:

    1. If name is not a name, then throw a TypeError.

    2. If there is no header in header list

      does not contain

      whose name is name,

      then

      return null.

    3. Return the combined value given name and header list.

    The has(name) method, when invoked, must run these steps:

    1. If name is not a name, then throw a TypeError.

    2. Return true if there is a header in header list

      contains

      whose name is name, and false otherwise.

    The set(name, value) method, when invoked, must run these steps:

    1. Normalize value.

    2. If name is not a name or value is not a value, then throw a TypeError.

    3. If guard is "immutable", then throw a TypeError.

    4. Otherwise, if guard is "request" and name is a forbidden header name, return.

    5. Otherwise, if guard is "request-no-cors" and name/value is not a CORS-safelisted request-header, return.

    6. Otherwise, if guard is "response" and name is a forbidden response-header name, return.

    7. Set name/value in header list.

    The value pairs to iterate over are the return value of running sort and combine with the header list.

    5.2. Body mixin

    typedef (Blob or BufferSource or FormData or URLSearchParams or ReadableStream or USVString) BodyInit;
    

    To extract a body and a `Content-Type` value from object, with an optional keepalive flag, run these steps:

    1. Let stream be the result of constructing a ReadableStream object.

    2. Let Content-Type be null.

    3. Let action be null.

    4. Let source be null.

    5. Switch on object’s type:

      Blob

      Set action to an action that reads object.

      If object’s type attribute is not the empty byte sequence, set Content-Type to its value.

      Set source to object.

      BufferSource

      Enqueue a Uint8Array object wrapping an ArrayBuffer containing a copy of the bytes held by object to stream and close stream. If that threw an exception, error stream with that exception.

      Set source to object.

      FormData

      Set action to an action that runs the multipart/form-data encoding algorithm, with object as form data set and with UTF-8 as the explicit character encoding.

      Set Content-Type to `multipart/form-data; boundary=`, followed by the multipart/form-data boundary string generated by the multipart/form-data encoding algorithm.

      Set source to object.

      URLSearchParams

      Set action to an action that runs the application/x-www-form-urlencoded serializer with object’s list.

      Set Content-Type to `application/x-www-form-urlencoded;charset=UTF-8`.

      Set source to object.

      USVString

      Set action to an action that runs UTF-8 encode on object.

      Set Content-Type to `text/plain;charset=UTF-8`.

      Set source to object.

      ReadableStream

      Set stream to object.

    6. If keepalive flag is set and object’s type is a ReadableStream object, then throw a TypeError.

    7. If action is non-null, run action in parallel:

      1. Whenever one or more bytes are available, let bytes be the bytes and enqueue a Uint8Array object wrapping an ArrayBuffer containing bytes to stream. If creating the ArrayBuffer threw an exception, error stream with that exception and cancel running action.

      2. When running action is done, close stream.

    8. Let body be a body whose stream is stream and whose source is source.

    9. Return body and Content-Type.

    [NoInterfaceObject, Exposed=(Window,Worker)]
    interface Body {
      readonly attribute ReadableStream? body;
      readonly attribute boolean bodyUsed;
      [NewObject] Promise<ArrayBuffer> arrayBuffer();
      [NewObject] Promise<Blob> blob();
      [NewObject] Promise<FormData> formData();
      [NewObject] Promise<any> json();
      [NewObject] Promise<USVString> text();
    };
    

    Formats you would not want a network layer to be dependent upon, such as HTML, will likely not be exposed here. Rather, an HTML parser API might accept a stream in due course.

    Objects implementing the Body mixin gain an associated body (null or a body) and a MIME type (initially the empty byte sequence).

    An object implementing the Body mixin is said to be disturbed if body is non-null and its stream is disturbed.

    An object implementing the Body mixin is said to be locked if body is non-null and its stream is locked.

    The body attribute’s getter must return null if body is null and body’s stream otherwise.

    The bodyUsed attribute’s getter must return true if disturbed, and false otherwise.

    Objects implementing the Body mixin also have an associated package data algorithm, given bytes, a type and a MIME type, switches on type, and runs the associated steps:

    ArrayBuffer

    Return an ArrayBuffer whose contents are bytes. Rethrow any exceptions.

    Blob

    Return a Blob whose contents are bytes and type attribute is MIME type.

    FormData

    If MIME type (ignoring parameters) is `multipart/form-data`, run these substeps:

    1. Parse bytes, using the value of the `boundary` parameter from MIME type, per the rules set forth in Returning Values from Forms: multipart/form-data. [RFC7578]

      Each part whose `Content-Disposition` header contains a `filename` parameter must be parsed into an entry whose value is a File whose content is the content of the part. The name attribute of the File must have the value of the `filename` parameter of the part. The type attribute of the File must have the value of the `Content-Type` header of the part if the part has such header, and `text/plain` (the default defined by [RFC7578] section 4.4) otherwise.

      Each part whose `Content-Disposition` header does not contain a `filename` parameter must be parsed into an entry whose value is the UTF-8 decoded content of the part. This is done regardless of the presence or the value of a `Content-Type` header and regardless of the presence or the value of a `charset` parameter.

      A part whose `Content-Disposition` header contains a `name` parameter whose value is `_charset_` is parsed like any other part. It does not change the encoding.

    2. If that fails for some reason, then throw a TypeError.

    3. Return a new FormData object, appending each entry, resulting from the parsing operation, to entries.

    The above is a rough approximation of what is needed for `multipart/form-data`, a more detailed parsing specification is to be written. Volunteers welcome.

    Otherwise, if MIME type (ignoring parameters) is `application/x-www-form-urlencoded`, run these substeps:

    1. Let entries be the result of parsing bytes.

    2. If entries is failure, then throw a TypeError.

    3. Return a new FormData object whose entries are entries.

    Otherwise, throw a TypeError.

    JSON

    Return the result of invoking the initial value of the parse property of the JSON object with the result of running UTF-8 decode on bytes as argument. Rethrow any exceptions.

    text

    Return the result of running UTF-8 decode on bytes.

    Objects implementing the Body mixin also have an associated consume body algorithm, given a type, runs these steps:

    1. If this object is disturbed or locked, return a new promise rejected with a TypeError.

    2. Let stream be body’s stream if body is non-null, or an empty ReadableStream object otherwise.

    3. Let reader be the result of getting a reader from stream. If that threw an exception, return a new promise rejected with that exception.

    4. Let promise be the result of reading all bytes from stream with reader.

    5. Return the result of transforming promise by a fulfillment handler that returns the result of the package data algorithm with its first argument, type and this object’s MIME type.

    The arrayBuffer() method, when invoked, must return the result of running consume body with ArrayBuffer.

    The blob() method, when invoked, must return the result of running consume body with Blob.

    The formData() method, when invoked, must return the result of running consume body with FormData.

    The json() method, when invoked, must return the result of running consume body with JSON.

    The text() method, when invoked, must return the result of running consume body with text.

    5.3. Request class

    typedef (Request or USVString) RequestInfo;
    
    [Constructor(RequestInfo input, optional RequestInit init),
     Exposed=(Window,Worker)]
    interface Request {
      readonly attribute ByteString method;
      readonly attribute USVString url;
      [SameObject] readonly attribute Headers headers;
    
      readonly attribute RequestType type;
      readonly attribute RequestDestination destination;
      readonly attribute USVString referrer;
      readonly attribute ReferrerPolicy referrerPolicy;
      readonly attribute RequestMode mode;
      readonly attribute RequestCredentials credentials;
      readonly attribute boolean useReferredTokenBinding;
      readonly attribute RequestCache cache;
      readonly attribute RequestRedirect redirect;
      readonly attribute DOMString integrity;
      readonly attribute boolean keepalive;
    
      [NewObject] Request clone();
    };
    Request implements Body;
    dictionary RequestInit {
      ByteString method;
      HeadersInit headers;
      BodyInit? body;
      USVString referrer;
      ReferrerPolicy referrerPolicy;
      RequestMode mode;
      RequestCredentials credentials;
      boolean useReferredTokenBinding;
      RequestCache cache;
      RequestRedirect redirect;
      DOMString integrity;
      boolean keepalive;
      any window; // can only be set to null
    };
    
    enum RequestType { "", "audio", "font", "image", "script", "style", "track", "video" };
    enum RequestDestination { "", "
    
    audio", "
    document", "embed", "font", "image", "manifest", "media", "object", "report", "script", "serviceworker", "sharedworker", "style",  "
    
    track", "video", "
    worker", "xslt" };
    enum RequestMode { "navigate", "same-origin", "no-cors", "cors" };
    enum RequestCredentials { "omit", "same-origin", "include" };
    enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" };
    enum RequestRedirect { "follow", "error", "manual" };
    

    "serviceworker" is omitted from RequestDestination as it cannot be observed from JavaScript. Implementations will still need to support it as a destination. "websocket" is omitted from RequestMode as it cannot be used nor observed from JavaScript.

    A Request object has an associated request (a request).

    A Request object also has an associated Headers object which is itself associated with request’s header list.

    A Request object’s body is its request’s body.


    The Request(input, init) constructor must run these steps:

    1. Let request be null.

    2. Let fallbackMode be null.

    3. Let fallbackCredentials be null.

    4. Let baseURL be current settings object’s API base URL.

    5. If input is a string, then run these substeps:

      1. Let parsedURL be the result of parsing input with baseURL.

      2. If parsedURL is failure, then throw a TypeError.

      3. If parsedURL includes credentials, then throw a TypeError.

      4. Set request to a new request whose url is parsedURL.

      5. Set fallbackMode to "cors".

      6. Set fallbackCredentials to "omit".

    6. Otherwise (input is a Request object), run these substeps:

      1. If input is disturbed or locked, then throw a TypeError.

      2. Set request to input’s request.

    7. Let origin be current settings object’s origin.

    8. Let window be "client".

    9. If request’s window is an environment settings object and its origin is same origin with origin, set window to request’s window.

    10. If init’s window member is present and it is non-null, then throw a TypeError.

    11. If init’s window member is present, set window to "no-window".

    12. Set request to a new request whose url is request’s current url, method is request’s method, header list is a copy of request’s header list, unsafe-request flag is set, client is current settings object, window is window, origin is "client", referrer is request’s referrer, referrer policy is request’s referrer policy, mode is request’s mode, credentials mode is request’s credentials mode, use-referred-token-binding flag is request’s use-referred-token-binding flag, cache mode is request’s cache mode, redirect mode is request’s redirect mode, integrity metadata is request’s integrity metadata, and keepalive flag is request’s keepalive flag.

    13. If any of init’s members are present, run these substeps:

      1. If request’s mode is "navigate", then set it to "same-origin".

      2. Set request’s referrer to "client"

      3. Set request’s referrer policy to the empty string.

      This is done to ensure that when a service worker "redirects" a request, .e.g., from an image in a cross-origin stylesheet, and makes modifications, it no longer appears to come from the original source (i.e., the cross-origin stylesheet), but instead from the service worker that "redirected" the request. This is important as the original source might not even be able to generate the same kind of requests as the service worker. Services that trust the original source could therefore be exploited were this not done, although that is somewhat farfetched.

    14. If init’s referrer member is present, run these substeps:

      1. Let referrer be init’s referrer member.

      2. If referrer is the empty string, set request’s referrer to "no-referrer" and terminate these substeps.

      3. Let parsedReferrer be the result of parsing referrer with baseURL.

      4. If parsedReferrer is failure, then throw a TypeError.

      5. If one of the following conditions is true, then set request’s referrer to "client":

      6. Otherwise, set request’s referrer to parsedReferrer.

    15. If init’s referrerPolicy member is present, set request’s referrer policy to it.

    16. Let mode be init’s mode member if it is present, and fallbackMode otherwise.

    17. If mode is "navigate", then throw a TypeError.

    18. If mode is non-null, set request’s mode to mode.

    19. Let credentials be init’s credentials member if it is present, and fallbackCredentials otherwise.

    20. If credentials is non-null, set request’s credentials mode to credentials.

    21. If useReferredTokenBinding is non-null, set request’s use-referred-token-binding flag to useReferredTokenBinding. Also, set request’s referred-token-binding origin to origin.

    22. If init’s cache member is present, set request’s cache mode to it.

    23. If request’s cache mode is "only-if-cached" and request’s mode is not "same-origin", then throw a TypeError.

    24. If init’s redirect member is present, set request’s redirect mode to it.

    25. If init’s integrity member is present, set request’s integrity metadata to it.

    26. If init’s keepalive member is present, then set request’s keepalive flag if init’s keepalive member is true, and unset it otherwise.

    27. If init’s method member is present, let method be it and run these substeps:

      1. If method is not a method or method is a forbidden method, then throw a TypeError.

      2. Normalize method.

      3. Set request’s method to method.

    28. Let r be a new Request object associated with request and a new associated Headers object whose guard is "request".

    29. Let headers be a copy of r’s Headers object and its associated header list.

    30. If init’s headers member is present, set headers to init’s headers member.

    31. Empty r’s Headers object’s header list.

    32. If r’s request’s mode is "no-cors", run these substeps:

      1. If r’s request’s method is not a CORS-safelisted method, then throw a TypeError.

      2. If request’s integrity metadata is not the empty string, then throw a TypeError.

      3. Set r’s Headers object’s guard to "request-no-cors".

    33. Fill r’s Headers object with headers. Rethrow any exceptions.

    34. Let inputBody be input’s request’s body if input is a Request object, and null otherwise.

    35. If either init’s body member is present and is non-null or inputBody is non-null, and request’s method is `GET` or `HEAD`, then throw a TypeError.

    36. Let body be inputBody.

    37. If init’s body member is present and is non-null, run these substeps:

      1. Let Content-Type be null.

      2. If init’s keepalive member is present and is true, then set body and Content-Type to the result of extracting init’s body member, with keepalive flag set. Rethrow any exceptions.

      3. Otherwise, set body and Content-Type to the result of extracting init’s body member. Rethrow any exceptions.

      4. If Content-Type is non-null and r’s Headers object’s header list

        does not contain

        contains no header named `Content-Type`, then append `Content-Type`/Content-Type to r’s Headers object. Rethrow any exception.

    38. If body is non-null and body’s source is null, then run these substeps:

      1. If r’s request’s mode is neither "same-origin" nor "cors", then throw a TypeError.

      2. Set r’s request’s use-CORS-preflight flag.

    39. If inputBody is non-null, then run these substeps:

      1. Let rs bs a ReadableStream object from which one can read the exactly same data as one could read from inputBody’s stream.

        This will be specified more precisely once transform stream and piping are precisely defined. See the issue.

        This makes inputBody’s stream locked and disturbed immediately.

      2. If inputBody is body, then set body to a new body whose stream is rs, whose source is inputBody’s source and whose total bytes is inputBody’s total bytes.

    40. Set r’s request’s body to body.

    41. Set r’s MIME type to the result of extracting a MIME type from r’s request’s header list.

    42. Return r.

    The method attribute’s getter must return request’s method.

    The url attribute’s getter must return request’s url, serialized.

    The headers attribute’s getter must return the associated Headers object.

    The type attribute’s getter must return request’s type.

    The destination attribute’s getter must return request’s destination.

    The referrer attribute’s getter must return the empty string if request’s referrer is "no-referrer", "about:client" if request’s referrer is "client", and request’s referrer, serialized, otherwise.

    The referrerPolicy attribute’s getter must return request’s referrer policy.

    The mode attribute’s getter must return request’s mode.

    The credentials attribute’s getter must return request’s credentials mode.

    The useReferredTokenBinding attribute’s getter must return true if request’s use-referred-token-binding flag is set, and false otherwise.

    The cache attribute’s getter must return request’s cache mode.

    The redirect attribute’s getter must return request’s redirect mode.

    The integrity attribute’s getter must return request’s integrity metadata.

    The keepalive attribute’s getter must return true if request’s keepalive flag is set, and false otherwise.


    The clone() method, when invoked, must run these steps:

    1. If this Request object is disturbed or locked, then throw a TypeError.

    2. Return a new Request object associated with the result of cloning request and a new associated Headers object whose guard is context object’s Headers object’s guard.

    5.4. Response class

    [Constructor(optional BodyInit? body = null, optional ResponseInit init), Exposed=(Window,Worker)]
    interface Response {
      [NewObject] static Response error();
      [NewObject] static Response redirect(USVString url, optional unsigned short status = 302);
    
      readonly attribute ResponseType type;
    
      readonly attribute USVString url;
      readonly attribute boolean redirected;
      readonly attribute unsigned short status;
      readonly attribute boolean ok;
      readonly attribute ByteString statusText;
      [SameObject] readonly attribute Headers headers;
      [SameObject] readonly attribute Promise<Headers> trailer;
    
      [NewObject] Response clone();
    };
    Response implements Body;
    
    dictionary ResponseInit {
      unsigned short status = 200;
      ByteString statusText = "OK";
      HeadersInit headers;
    };
    
    enum ResponseType { "basic", "cors", "default", "error", "opaque", "opaqueredirect" };
    

    A Response object has an associated response (a response).

    A Response object also has an associated Headers object which is itself associated with response’s header list.

    A Response object also has an associated trailer promise (a promise). Used for the trailer attribute.

    A Response object’s body is its response’s body.

    The Response(body, init) constructor, when invoked, must run these steps:

    1. If init’s status member is not in the range 200 to 599, inclusive, then throw a RangeError.

    2. If init’s statusText member does not match the reason-phrase token production, then throw a TypeError.

    3. Let r be a new Response object, associated with a new response and a new associated Headers object whose guard is "response".

    4. Set r’s response’s status to init’s status member.

    5. Set r’s response’s status message to init’s statusText member.

    6. If init’s headers member is present,

      then fill r’s

      run these substeps:

      1. Empty r’s response’s header list.

      2. Fill r’s Headers object with init’s headers member. Rethrow any exceptions.

    7. If body is non-null, run these substeps:

      1. If init’s status member is a null body status, then throw a TypeError.

        101 is included in null body status due to its use elsewhere. It does not affect this step.

      2. Let Content-Type be null.

      3. Set r’s response’s body and Content-Type to the result of extracting body. Rethrow any exceptions.

      4. If Content-Type is non-null and r’s response’s header list

        does not contain

        contains no header named `Content-Type`,

        then

        append `Content-Type`/Content-Type to r’s response’s header list.

    8. Set r’s MIME type to the result of extracting a MIME type from r’s response’s header list.

    9. Set r’s response’s HTTPS state to current settings object’s HTTPS state.

    10. Resolve r’s trailer promise with a new Headers object whose guard is "immutable".

    11. Return r.

    The static error() method, when invoked, must return a new Response object, associated with a new network error and a new associated Headers object whose guard is "immutable".

    The static redirect(url, status) method, when invoked, must run these steps:

    1. Let parsedURL be the result of parsing url with current settings object’s API base URL.

    2. If parsedURL is failure, then throw a TypeError.

    3. If status is not a redirect status, then throw a RangeError.

    4. Let r be a new Response object, associated with a new response and a new associated Headers object whose guard is "immutable".

    5. Set r’s response’s status to status.

    6. Set `Location` to parsedURL, serialized and UTF-8 encoded, in r’s response’s header list.

    7. Return r.

    The type attribute’s getter must return response’s type.

    The url attribute’s getter must return the empty string if response’s url is null and response’s url, serialized with the exclude-fragment flag set, otherwise. [URL]

    The redirected attribute’s getter must return true if response’s url list has more than one item, and false otherwise.

    To filter out responses that are the result of a redirect, do this directly through the API, e.g., fetch(url, { redirect:"error" }). This way a potentially unsafe response cannot accidentally leak.

    The status attribute’s getter must return response’s status.

    The ok attribute’s getter must return true if response’s status is an ok status, and false otherwise.

    The statusText attribute’s getter must return response’s status message.

    The headers attribute’s getter must return the associated Headers object.

    The trailer attribute’s getter must return the associated trailer promise.


    The clone() method, when invoked, must run these steps:

    1. If context object is disturbed or locked, then throw a TypeError.

    2. Let clonedResponse be a new Response object associated with the result of cloning context object’s response and a new associated Headers object whose guard is context object’s Headers object’s guard.

    3. Upon fulfillment of context object’s trailer promise, resolve clonedResponse’s trailer promise with a new Headers object whose guard is "immutable" that is associated with clonedResponse’s trailer.

    4. Return clonedResponse.

    5.5. Fetch method

    partial interface WindowOrWorkerGlobalScope {  
    
    [NewObject] Promise<Response> fetch(RequestInfo input, optional RequestInit init);
    };
    

    The fetch(input, init) method, must run these steps:

    1. Let p be a new promise.

    2. Let request be the associated request of the result of invoking the initial value of Request as constructor with input and init as arguments. If this throws an exception, reject p with it and return p.

    3. If request’s client’s global object is a ServiceWorkerGlobalScope object, set request’s service-workers mode to "foreign".
    4. Let responseObject be a new Response object and a new associated Headers object whose guard is "immutable".

    5. Run the following in parallel:

      Fetch request.

      To process response for response, run these substeps:

      1. If response’s type is "error", reject p with a TypeError and terminate these substeps.

      2. Associate responseObject with response.

      3. Resolve p with responseObject.

      To process response done for response, run these substeps:

      1. Let trailerObject be a new Headers object whose guard is "immutable".

      2. Associate trailerObject with response’s trailer.

      3. Resolve responseObject’s trailer promise with trailerObject.

    6. Return p.

    5.6. Garbage collection

    The user agent may terminate an ongoing fetch with reason garbage collection if that termination is not observable through script.

    "Observable through script" means observable through fetch()’s arguments and return value. Other ways, such as communicating with the server through a side-channel are not included.

    The server being able to observe garbage collection has precedent, e.g., with WebSocket and XMLHttpRequest objects.

    The user agent can terminate the fetch because the termination cannot be observed.

    fetch("https://www.example.com/")
    

    The user agent cannot terminate the fetch because the termination can be observed through the promise.

    window.promise = fetch("https://www.example.com/")
    

    The user agent can terminate the fetch because the associated body is not observable.

    window.promise = fetch("https://www.example.com/").then(res => res.headers)
    

    The user agent can terminate the fetch because the termination cannot be observed.

    fetch("https://www.example.com/").then(res => res.body.getReader().closed)
    

    The user agent cannot terminate the fetch because one can observe the termination by registering a handler for the promise object.

    window.promise = fetch("https://www.example.com/")
      .then(res => res.body.getReader().closed)
    

    The user agent cannot terminate the fetch as termination would be observable via the registered handler.

    fetch("https://www.example.com/")
      .then(res => {
        res.body.getReader().closed.then(() => console.log("stream closed!"))
      })
    

    6. WebSocket protocol alterations

    This section replaces part of the WebSocket protocol opening handshake client requirement to integrate it with algorithms defined in Fetch. This way CSP, cookies, HSTS, and other Fetch-related protocols are handled in a single location. Ideally the RFC would be updated with this language, but it is never that easy. The WebSocket API, defined in the HTML Standard, has been updated to use this language. [WSP] [HTML]

    The way this works is by replacing The WebSocket Protocol’s "establish a WebSocket connection" algorithm with a new one that integrates with Fetch. "Establish a WebSocket connection" consists of three algorithms: setting up a connection, creating and transmiting a handshake request, and validating the handshake response. That layering is different from Fetch, which first creates a handshake, then sets up a connection and transmits the handshake, and finally validates the response. Keep that in mind while reading these alterations.

    6.1. Connections

    To obtain a WebSocket connection, given a url, run these steps:

    1. Let host be url’s host.

    2. Let port be url’s port.

    3. Let secure be false, if url’s scheme is "http", and true otherwise.

    4. Follow the requirements stated in step 2 to 5, inclusive, of the first set of steps in section 4.1 of The WebSocket Protocol to establish a WebSocket connection. [WSP]

    5. If that established a connection, return it, and return failure otherwise.

    Although structured a little differently, carrying different properties, and therefore not shareable, a WebSocket connection is very close to identical to an "ordinary" connection.

    6.2. Opening handshake

    To establish a WebSocket connection, given a url, protocols, and client, run these steps:

    1. Let requestURL be a copy of url, with its scheme set to "http", if url’s scheme is "ws", and to "https" otherwise.

      This change of scheme is essential to integrate well with fetching. E.g., HSTS would not work without it. There is no real reason for WebSocket to have distinct schemes, it’s a legacy artefact. [HSTS]

    2. Let request be a new request, whose url is requestURL, client is client, skip-service-

      workers mode is "none"

      worker flag is set, synchronous flag is set, mode is "websocket", credentials mode is "include", cache mode is "no-store", and redirect mode is "error".

    3. Append `Upgrade`/`websocket` to request’s header list.

    4. Append `Connection`/`Upgrade` to request’s header list.

    5. Let keyValue be a nonce consisting of a randomly selected 16-byte value that has been base64-encoded (see section 4 of [RFC4648]).

      If the randomly selected value was the byte sequence 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10, keyValue would be `AQIDBAUGBwgJCgsMDQ4PEC==`.

    6. Append `Sec-WebSocket-Key`/keyValue to request’s header list.

    7. Append `Sec-WebSocket-Version`/`13` to request’s header list.

    8. For each protocol in protocols, combine `Sec-WebSocket-Protocol`/protocol in request’s header list.

    9. Let permessageDeflate be a user-agent defined "permessage-deflate" extension header value. [WSP]

      `permessage-deflate; client_max_window_bits`

    10. Append `Sec-WebSocket-Extensions`/permessageDeflate to request’s header list.

    11. Let response be the result of fetching request.

    12. If response is a network error or its status is not 101, fail the WebSocket connection.

    13. If protocols is not the empty list and

      extracting header list values given

      parsing `Sec-WebSocket-Protocol`

      and

      in response’s header list results in null, failure, or the empty byte sequence,

      then

      fail the WebSocket connection.

      This is different from the check on this header defined by The WebSocket Protocol. That only covers a subprotocol not requested by the client. This covers a subprotocol requested by the client, but not acknowledged by the server.

    14. Follow the requirements stated step 2 to step 6, inclusive, of the last set of steps in section 4.1 of The WebSocket Protocol to validate response. This either results in fail the WebSocket connection or the WebSocket connection is established.

    Fail the WebSocket connection and the WebSocket connection is established are defined by The WebSocket Protocol. [WSP]

    The reason redirects are not followed, HTTP authentication will not function, and this handshake is generally restricted is because that could introduce serious security problems in a web browser context. For example, consider a host with a WebSocket server at one path and an open HTTP redirector at another. Suddenly, any script that can be given a particular WebSocket URL can be tricked into communicating to (and potentially sharing secrets with) any host on the internet, even if the script checks that the URL has the right hostname.

    Background reading

    This section and its subsections are informative only.

    HTTP header layer division

    For the purposes of fetching, there is an API layer (HTML’s img, CSS' background-image), early fetch layer, service worker layer, and network & cache layer. `Accept` and `Accept-Language` are set in the early fetch layer (typically by the user agent). Most other headers controlled by the user agent, such as `Accept-Encoding`, `Host`, and `Referer`, are set in the network & cache layer. Developers can set headers either at the API layer or in the service worker layer (typically through a Request object). Developers have almost no control over forbidden headers, but can control `Accept` and have the means to constrain and omit `Referer` for instance.

    Atomic HTTP redirect handling

    Redirects (a response whose status or internal response’s (if any) status is a redirect status) are not exposed to APIs. Exposing redirects might leak information not otherwise available through a cross-site scripting attack.

    A fetch to https://example.org/auth that includes a Cookie marked HttpOnly could result in a redirect to https://other-origin.invalid/4af955781ea1c84a3b11. This new URL contains a secret. If we expose redirects that secret would be available through a cross-site scripting attack.

    Basic safe CORS protocol setup

    For resources where data is protected through IP authentication or a firewall (unfortunately relatively common still), using the CORS protocol is unsafe. (This is the reason why the CORS protocol had to be invented.)

    However, otherwise using the following header is safe:

    Access-Control-Allow-Origin: *
    

    Even if a resource exposes additional information based on cookie or HTTP authentication, using the above header will not reveal it. It will share the resource with APIs such as XMLHttpRequest, much like it is already shared with curl and wget.

    Thus in other words, if a resource cannot be accessed from a random device connected to the web using curl and wget the aforementioned header is not to be included. If it can be accessed however, it is perfectly fine to do so.

    CORS protocol and HTTP caches

    If CORS protocol requirements are more complicated than setting `Access-Control-Allow-Origin` to * or a static origin, `Vary` is to be used. [HTML] [HTTP] [HTTP-SEMANTICS] [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH]

    Vary: Origin
    

    Acknowledgments

    Thanks to Adam Barth, Adam Lavin, Alan Jeffrey, Alexey Proskuryakov,

    Andrés Gutiérrez,

    Andrew Sutherland, Ángel González, Anssi Kostiainen, Arkadiusz Michalski, Arne Johannessen, Arthur Barstow, Axel Rauschmayer, Ben Kelly, Benjamin Hawkes-Lewis, Bert Bos, Björn Höhrmann, Boris Zbarsky, Brad Hill, Brad Porter, Bryan Smith, Caitlin Potter, Cameron McCormack, Clement Pellerin, Collin Jackson, Daniel Robertson, Daniel Veditz, David Håsäther, David Orchard, Dean Jackson, Domenic Denicola, Dominique Hazaël-Massieux, Doug Turner, Eero Häkkinen, Ehsan Akhgari, Emily Stark, Eric Lawrence, François Marier, Frank Ellerman, Frederick Hirsch, Gavin Carothers, Glenn Maynard, Graham Klyne, Hal Lockhart, Hallvord R. M. Steen, Henri Sivonen, Henry Story, Hiroshige Hayashizaki, Honza Bambas, Ian Hickson, Ilya Grigorik, isonmad, Jake Archibald, James Graham, Janusz Majnert, Jeena Lee, Jeff Carpenter, Jeff Hodges, Jeffrey Yasskin, Jesse M. Heines, Jochen Eisinger, Jonas Sicking, Jonathan Kingston, Jonathan Watt, 최종찬 (Jongchan Choi), Jörn Zaefferer,

    Joseph Pecoraro,

    Josh Matthews, Julian Krispel-Samsel, Julian Reschke, 송정기 (Jungkee Song), Jussi Kalliokoski, Jxck, Keith Yeung, Kenji Baheux, Lachlan Hunt, Liam Brummitt, Louis Ryan, Lucas Gonze, 呂康豪 (Kang-Hao Lu), Maciej Stachowiak, Malisa, Manfred Stock, Manish Goregaokar, Marc Silbey, Marcos Caceres, Marijn Kruisselbrink, Mark Nottingham, Mark S. Miller, Martin Dürst, Matt Andrews, Matt Falkenhagen, Matt Oshry, Matt Seddon, Matt Womer, Mhano Harkness, Michael Kohler, Michael™ Smith, Mike West, Mohamed Zergaoui, Ms2ger, Nico Schlömer, Nikhil Marathe, Nikki Bee, Nikunj Mehta, Odin Hørthe Omdal, Ondřej Žára, Philip Jägenstedt, R. Auburn, Raphael Kubo da Costa, Ryan Sleevi, Rory Hewitt, Sébastien Cevey, Sendil Kumar N, Shao-xuan Kang, Sharath Udupa, Shivakumar Jagalur Matt, Sigbjørn Finne, Simon Pieters, Srirama Chandra Sekhar Mogali, Steven Salat, Sunava Dutta, Surya Ismail, 吉野剛史 (Takeshi Yoshino), Thomas Roessler, Thomas Wisniewski, Tiancheng "Timothy" Gu, Tobie Langel, Tom Schuster, Tomás Aparicio, 保呂毅 (Tsuyoshi Horo), Tyler Close, Vignesh Shanmugam, Vinod Anupam, Vladimir Dzhuvinov, Wayne Carr, Xabier Rodríguez, Yoav Weiss, Youenn Fablet, 平野裕 (Yutaka Hirano), and Zhenbin Xu for being awesome.

    This standard is written by Anne van Kesteren (Mozilla, annevk@annevk.nl).

    Per CC0, to the extent possible under law, the editor has waived all copyright and related or neighboring rights to this work.

    References

    Normative References

    [ABNF]
    D. Crocker, Ed.; P. Overell. Augmented BNF for Syntax Specifications: ABNF. January 2008. Internet Standard. URL: https://tools.ietf.org/html/rfc5234
    [CLIENT-HINTS]
    Ilya Grigorik. HTTP Client Hints. URL: https://tools.ietf.org/html/draft-ietf-httpbis-client-hints
    [COOKIES]
    A. Barth. HTTP State Management Mechanism. April 2011. Proposed Standard. URL: https://tools.ietf.org/html/rfc6265
    [CSP]
    Mike West. Content Security Policy Level 3. URL: https://w3c.github.io/webappsec-csp/
    [DATAURL]
    Simon Sapin. The data URL scheme. URL: https://simonsapin.github.io/data-urls/
    [DOM]
    Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
    [ENCODING]
    Anne van Kesteren. Encoding Standard. Living Standard. URL: https://encoding.spec.whatwg.org/
    [FileAPI]
    Arun Ranganathan; Jonas Sicking. File API. URL: https://w3c.github.io/FileAPI/
    [HSTS]
    J. Hodges; C. Jackson; A. Barth. HTTP Strict Transport Security (HSTS). November 2012. Proposed Standard. URL: https://tools.ietf.org/html/rfc6797
    [HTML]
    Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
    [HTTP]
    R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7230
    [HTTP-AUTH]
    R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Authentication. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7235
    [HTTP-CACHING]
    R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Caching. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7234
    [HTTP-COND]
    R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7232
    [HTTP-SEMANTICS]
    R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7231
    [HTTP2]
    M. Belshe; R. Peon; M. Thomson, Ed.. Hypertext Transfer Protocol Version 2 (HTTP/2). May 2015. Proposed Standard. URL: https://tools.ietf.org/html/rfc7540
    [INFRA]
    Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
    [MIX]
    Mike West. Mixed Content. URL: https://w3c.github.io/webappsec-mixed-content/
    [REFERRER]
    Jochen Eisinger; Emily Stark. Referrer Policy. URL: https://w3c.github.io/webappsec-referrer-policy/
    [RFC4648]
    S. Josefsson. The Base16, Base32, and Base64 Data Encodings. October 2006. Proposed Standard. URL: https://tools.ietf.org/html/rfc4648
    [RFC7578]
    L. Masinter. Returning Values from Forms: multipart/form-data. July 2015. Proposed Standard. URL: https://tools.ietf.org/html/rfc7578
    [SRI]
    Devdatta Akhawe; et al. Subresource Integrity. URL: https://w3c.github.io/webappsec-subresource-integrity/
    [STREAMS]
    Domenic Denicola; 吉野剛史 (Takeshi Yoshino). Streams Standard. Living Standard. URL: https://streams.spec.whatwg.org/
    [SW]
    Alex Russell; et al. Service Workers 1. URL: https://w3c.github.io/ServiceWorker/
    [TLS]
    T. Dierks; E. Rescorla. The Transport Layer Security (TLS) Protocol Version 1.2. August 2008. Proposed Standard. URL: https://tools.ietf.org/html/rfc5246
    [TOKBIND-HTTPS]
    Andrei Popov; et al. Token Binding over HTTP. URL: https://tools.ietf.org/html/draft-ietf-tokbind-https
    [TOKBIND-NEGOTIATION]
    Andrei Popov; et al. Transport Layer Security (TLS) Extension for Token Binding Protocol Negotiation. URL: https://tools.ietf.org/html/draft-ietf-tokbind-negotiation
    [TOKBIND-PROTOCOL]
    Andrei Popov; et al. The Token Binding Protocol Version 1.0. URL: https://tools.ietf.org/html/draft-ietf-tokbind-protocol
    [UPGRADE]
    Mike West. Upgrade Insecure Requests. URL: https://w3c.github.io/webappsec-upgrade-insecure-requests/
    [URL]
    Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
    [WEBIDL]
    Cameron McCormack; Boris Zbarsky; Tobie Langel. Web IDL. URL: https://heycam.github.io/webidl/
    [WSP]
    C. Holmberg, S. Hakansson, G. Eriksson. The WebSocket protocol. URL: https://tools.ietf.org/id/draft-ietf-hybi-thewebsocketprotocol-09.txt
    [XHR]
    Anne van Kesteren. XMLHttpRequest Standard. Living Standard. URL: https://xhr.spec.whatwg.org/

    Informative References

    [CORS]
    Anne van Kesteren. Cross-Origin Resource Sharing. 16 January 2014. REC. URL: https://www.w3.org/TR/cors/
    [HTTPVERBSEC1]
    Multiple vendors' web servers enable HTTP TRACE method by default.. URL: https://www.kb.cert.org/vuls/id/867593
    [HTTPVERBSEC2]
    Microsoft Internet Information Server (IIS) vulnerable to cross-site scripting via HTTP TRACK method.. URL: https://www.kb.cert.org/vuls/id/288308
    [HTTPVERBSEC3]
    HTTP proxy default configurations allow arbitrary TCP connections.. URL: https://www.kb.cert.org/vuls/id/150227
    [ORIGIN]
    A. Barth. The Web Origin Concept. December 2011. Proposed Standard. URL: https://tools.ietf.org/html/rfc6454
    [PUBLIC-SUFFIX]
    Public Suffix List. URL: https://publicsuffix.org/list/