diff --git a/fetch.bs b/fetch.bs index 16d9ddf59..991f6b6c2 100644 --- a/fetch.bs +++ b/fetch.bs @@ -182,12 +182,58 @@ lt="authentication entry">authentication entries (for HTTP authentication).
process request end-of-body (default null)
process response (default null)
process response end-of-body (default null) +
process response done (default null)
Null or an algorithm.
task destination (default null)
Null, a global object, or a parallel queue. + +
cross-origin isolated capability (default false) +
A boolean. + +
timing info +
A fetch timing info. +

A fetch timing info is a struct used to maintain timing +information needed by Resource Timing and Navigation Timing. It has the +following items: [[RESOURCE-TIMING]] [[NAVIGATION-TIMING]] + +

+
start time (default 0) +
redirect start time (default 0) +
redirect end time (default 0) +
post-redirect start time (default 0) +
final service worker start time (default 0) +
final network-request start time (default 0) +
final network-response start time (default 0) +
end time (default 0) +
A {{DOMHighResTimeStamp}}. + +
encoded body size (default 0) +
decoded body size (default 0) +
A number. + +
final connection timing info (default null) +
Null or a connection timing info. +
+ +

To update timing info from stored response, given a +connection timing info timingInfo and a response +response, perform the following steps: + +

    +
  1. Let storedTimingInfo be response's timing info. + +

  2. If storedTimingInfo is null, then return. + +

  3. Set timingInfo's encoded body size to + storedTimingInfo's encoded body size. + +

  4. Set timingInfo's decoded body size to + storedTimingInfo's decoded body size. +

+

To queue a fetch task, given an algorithm algorithm, a global object or a parallel queue taskDestination, run these steps: @@ -1922,6 +1968,10 @@ allowed on the resource fetched by looking at the flag of the response returned. the response of a redirect has to be set if it was set for previous responses in the redirect chain, this is also tracked internally using the request's timing allow failed flag. +

A response has an associated +timing info (null or a +fetch timing info), which is initially null. +


A response whose @@ -2139,6 +2189,66 @@ unset or keepalive is false, termi identified by a key (a network partition key), an origin (an origin), and credentials (a boolean). +

Each connection has an associated +timing info (a +connection timing info). + +

A connection timing info is a struct used to maintain timing +information pertaining to the process of obtaining a connection. It has the following +items: + +

+
domain lookup start time (default 0) +
domain lookup end time (default 0) +
connection start time (default 0) +
connection end time (default 0) +
secure connection start time (default 0) +
A {{DOMHighResTimeStamp}}. + +
ALPN negotiated protocol (default the empty + byte sequence) +
A byte sequence. +
+ +

To clamp and coarsen connection timing info, given a +connection timing info timingInfo, a {{DOMHighResTimeStamp}} +defaultStartTime, and a boolean crossOriginIsolatedCapability, run these +steps: + +

    +
  1. If timingInfo's connection start time is + less than defaultStartTime, then return a new connection timing info whose + domain lookup start time is defaultStartTime, + domain lookup end time is defaultStartTime, + connection start time is defaultStartTime, + connection end time is defaultStartTime, + secure connection start time is defaultStartTime, + and ALPN negotiated protocol is timingInfo's + ALPN negotiated protocol. + +

  2. Return a new connection timing info whose + domain lookup start time is the result of coarsen time + given timingInfo's domain lookup start time and + crossOriginIsolatedCapability, + domain lookup end time is the result of coarsen time + given timingInfo's domain lookup end time and + crossOriginIsolatedCapability, connection start time + is the result of coarsen time given timingInfo's + connection start time and + crossOriginIsolatedCapability, connection end time + is the result of coarsen time given timingInfo's + connection end time and + crossOriginIsolatedCapability, + secure connection start time is the result of + coarsen time given timingInfo's + connection end time and + crossOriginIsolatedCapability, and + ALPN negotiated protocol is timingInfo's + ALPN negotiated protocol. +

+ +
+

To obtain a connection, given a key, origin, credentials, an optional boolean forceNew (default false), an optional boolean http3Only (default @@ -2169,9 +2279,10 @@ false), and an optional boolean dedic

  1. -

    Set connection to the result of establishing an HTTP connection to - origin. [[!HTTP]] [[!HTTP-SEMANTICS]] [[!HTTP-COND]] [[!HTTP-CACHING]] [[!HTTP-AUTH]] - [[!TLS]] +

    Set connection to a new connection. + Record connection timing info given connection and use + connection to establish an HTTP connection to origin. + [[!HTTP]] [[!HTTP-SEMANTICS]] [[!HTTP-COND]] [[!HTTP-CACHING]] [[!HTTP-AUTH]] [[!TLS]]

    If http3Only is true, then establish an HTTP/3 connection. [[!HTTP3]] @@ -2210,6 +2321,88 @@ clearly stipulates that connections are keyed on +


    + +

    To record connection timing info given a connection +connection, let timingInfo be connection's +timing info and observe these requirements: + +

      +
    • timingInfo's domain lookup start time + should be the unsafe shared current time immediately before starting the domain + lookup, or beginning retrieval of the information from cache. + +

    • timingInfo's domain lookup end time should + be the unsafe shared current time immediately after finishing the domain lookup, or + retrieving the information from cache. + +

    • timingInfo's connection start time should + be the unsafe shared current time immediately before establishing the connection to + the server or proxy. + +

    • +

      timingInfo's connection end time should be the + unsafe shared current time immediately after establishing the connection to the + server or proxy, as follows: + +

        +
      • The returned time must include the time interval to establish the transport connection, as + well as other time intervals such as SOCKS authentication. It must include the time interval to + complete enough of the TLS handshake to request the resource. + +

      • If the user agent used TLS False Start for this connection, this interval must not include + the time needed to receive the server's Finished message. [[RFC7918]] + +

      • If the user agent sends the request with early data without waiting for the full handshare + to complete, this interval must not include the time needed to receive the server's ServerHello + message. [[RFC8470]] + +

      • If the user agent waits for full handshake completion to send the request, this interval + includes the full TLS handshake even if other requests were sent using early data on + connection. +

      + +

      Suppose the user agent establishes an HTTP/2 + connection over TLS 1.3 to send a GET request and a POST request. It + sends the ClientHello at time t1 and then sends the GET request with early + data. The POST request is not safe ([[HTTP-SEMANTICS]], section 4.2.1), so the user + agent waits to complete the handshake at time t2 before sending it. Although both + requests used the same connection, the GET request reports a connection end time of + t1, while the POST request reports t2. + +

    • If a secure transport is used, timingInfo's + secure connection start time should be the result of calling + unsafe shared current time immmediately before starting the handshake process to + secure connection. [[!TLS]] + +

    • +

      timingInfo's ALPN negotiated protocol should be + the connection's ALPN Protocol ID, with the following caveats: [[RFC7301]] + +

        +
      • When a proxy is configured, if a tunnel connection is established then this must be the + ALPN Protocol ID of the tunneled protocol, otherwise it must be the ALPN Protocol ID of the first + hop to the proxy. + +

      • +

        In case the user agent is using an experimental, non-registered protocol, the user agent must + use the used ALPN Protocol ID, if any. If ALPN was not used for protocol negotiations, the user + agent may use another descriptive string. + +

        timingInfo's + ALPN negotiated protocol is intended to identify the network + protocol in use regardless of how it was actually negotiated; that is, even if ALPN is not used + to negotiate the network protocol, this is the ALPN Protocol IDs that indicates the protocol in + use. +

      + +

      IANA maintains a + list of ALPN Protocol IDs. +

    + +

    The clamp and coarsen connection timing info algorithm ensures that +details of reused connections are not exposed and time values are coarsened. +

    Network partition keys

    @@ -3310,15 +3503,17 @@ optional algorithm processRequestBody, an optional algorithm processRequestEndOfBody, -an optional algorithm processResponse, an -optional algorithm +an optional algorithm processResponse, +an optional algorithm processResponseEndOfBody, -and an optional boolean useParallelQueue (default false), run -the steps below. If given, processRequestBody must be an algorithm accepting an integer +an optional algorithm processResponseDone, and an optional +boolean useParallelQueue (default false), run the steps +below. If given, processRequestBody must be an algorithm accepting an integer representing the number of bytes transmitted. If given, processRequestEndOfBody must be an algorithm accepting no arguments. If given, processResponse must be an algorithm accepting a response. If given, processResponseEndOfBody must be an -algorithm accepting a response and null, failure, or a byte sequence. +algorithm accepting a response and null, failure, or a byte sequence. If +given, processResponseDone must be an algorithm accepting no arguments.

    An ongoing fetch can be terminated with flag aborted, @@ -3339,25 +3534,44 @@ the request.

    1. Let taskDestination be null. +

    2. Let crossOriginIsolatedCapability be false. + +

    3. +

      If request's client is non-null, then: + +

        +
      1. Set taskDestination to request's client's + global object. + +

      2. Set crossOriginIsolatedCapability to request's + client's + cross-origin isolated capability. +

      +
    4. If useParallelQueue is true, then set taskDestination to the result of starting a new parallel queue. -

    5. Otherwise, if request's client is non-null, set - taskDestination to request's client's - global object. - +

    6. Let timingInfo be a new fetch timing info whose + start time and + post-redirect start time are the + coarsened shared current time given crossOriginIsolatedCapability. +

    7. Let fetchParams be a new fetch params whose request is request, + timing info is timingInfo, process request body is processRequestBody, process request end-of-body is processRequestEndOfBody, process response is processResponse, - process response end-of-body is processResponseEndOfBody, and - task destination is taskDestination. + process response end-of-body is processResponseEndOfBody, + process response done is processResponseDone, + task destination is taskDestination, and + cross-origin isolated capability is + crossOriginIsolatedCapability.

    8. If request's body is a byte sequence, then set request's body to the first return value of @@ -3763,12 +3977,51 @@ steps: processBody, processBodyError, and fetchParams's task destination.

    +
-
  • Wait for either response's body to be null, or - response's body's stream to be - closed or errored, and then set - request's done flag. - +

    To finalize response given a fetch params fetchParams and a +response response, run these steps: + +

      +
    1. Set fetchParams's request's + done flag. + +

    2. If fetchParams's process response done is not null, + then queue a fetch task given fetchParams's + process response done and fetchParams's + task destination. +

    + +

    To finalize and report timing given a response +response, a global object global, and a string +initiatorType (default "other"), run these steps: + +

      +
    1. If response's URL list is null or + empty, then return. + +

    2. Let originalURL be response's URL list[0]. + +

    3. Let timingInfo be response's timing info. + +

    4. If timingInfo is null, then return. + +

    5. If response's timing allow passed flag is not set, then set + timingInfo to a new fetch timing info whose + start time and + post-redirect start time are timingInfo's + start time. + +

    6. Set timingInfo's end time to the + coarsened shared current time given global's + relevant settings object's + cross-origin isolated capability. + +

    7. Set response's timing info to timingInfo. + +

    8. Mark resource timing for + timingInfo, originalURL, initiatorType, and global. +

    @@ -3894,6 +4147,8 @@ these steps:
  • Let actualResponse be null. +

  • Let timingInfo be fetchParams's timing info. +

  • If request's service-workers mode is "all", then: @@ -3901,6 +4156,9 @@ these steps:

  • Let requestForServiceWorker be a clone of request. +

  • Let serviceWorkerStartTime be the coarsened shared current time + given fetchParams's cross-origin isolated capability. +

  • Set response to the result of invoking handle fetch for requestForServiceWorker. [[!HTML]] [[!SW]] @@ -3908,6 +4166,13 @@ these steps:

    If response is not null, then:

      +
    1. Set fetchParams's timing info's + final service worker start time to + serviceWorkerStartTime. + +

    2. Update timing info from stored response given fetchParams's + timing info and response. +

    3. If request's body is non-null, then cancel request's body with undefined. @@ -4040,6 +4305,15 @@ these steps:
    +
  • +

    Set response's timing info to timingInfo. + +

    Attaching the timing info to a response is what makes it exposed to the web as a + Resource Timing entry later. This step is done here, as resource-timing entries are available only + for HTTP fetches, including ones that are handled by service-workers or HTTP cache, and not for, + e.g., data:, blob: URL fetches, and are only available after all the + relevant security checks have succeeded. +

  • Return response. Typically actualResponse's body's stream is still being enqueued to after returning. @@ -4125,6 +4399,17 @@ run these steps:

    request's body's source's nullity has already been checked. +

  • Let timingInfo be fetchParams's timing info. + +

  • Set timingInfo's redirect end time and + post-redirect start time to the + coarsened shared current time given fetchParams's + cross-origin isolated capability. + +

  • If timingInfo's redirect start time is 0, then set + timingInfo's redirect start time to + timingInfo's start time. +

  • Append locationURL to request's URL list. @@ -4428,6 +4713,8 @@ steps. They return a response.

    1. +

      Let timingInfo be fetchParams's timing info. +

      Set storedResponse to the result of selecting a response from the httpCache, possibly needing validation, as per the "Constructing Responses from Caches" @@ -4552,6 +4839,8 @@ steps. They return a response.

    2. Set response to storedResponse. +

    3. Update timing info from stored response given fetchParams's + timing info and response.

  • @@ -4567,6 +4856,9 @@ steps. They return a response.

    If forwardResponse is a network error, this effectively caches the network error, which is sometimes known as "negative caching". + +

    The associated timing info is stored in the cache + alongside the response. @@ -4712,6 +5004,8 @@ optional boolean forceNewConnection (default false), run these steps:

  • Let response be null. +

  • Let timingInfo be fetchParams's timing info. +

  • Let httpCache be the result of determining the HTTP cache partition, given httpRequest. @@ -4737,6 +5031,12 @@ optional boolean forceNewConnection (default false), run these steps: includeCredentials, and forceNewConnection. +

  • Set timingInfo's final connection timing info to the + result of calling clamp and coarsen connection timing info with connection's + timing info, timingInfo's + post-redirect start time, and fetchParams's + cross-origin isolated capability. +
  • Run these steps, but abort when the ongoing fetch is terminated: @@ -4750,6 +5050,10 @@ optional boolean forceNewConnection (default false), run these steps: `Transfer-Encoding`/`chunked` to request's header list. +

  • Set timingInfo's final network-request start time + to the coarsened shared current time given fetchParams's + cross-origin isolated capability. +
  • Set response to the result of making an HTTP request over connection using request with the following caveats: @@ -4757,11 +5061,19 @@ optional boolean forceNewConnection (default false), run these steps: