From ec6f5ef5f99cb6b0dd6c701b49791810fb380b04 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Wed, 10 Aug 2016 14:09:30 +0200 Subject: [PATCH] Move 401/407 into the network realm This commit makes the following changes: * Moves 401 and 407 handling into the network realm. That way 401 and 407 responses from service worker just surface at the API level rather than potentially triggering new network activity. * That means only responses with redirect statuses have special semantics when they come from a service worker. * Only when redirects are automatically followed should we set the skip-service-worker flag, otherwise we negatively affect navigations. (Note #362 for follow up work regarding foreign fetch, which is still somewhat broken.) * This also removes the requirement that a 407 abides by the CORS protocol, which was not entirely sensical. * It makes various editorial corrections, for which I apologize as in retrospect they make this harder to review. Fixes #363 and fixes https://github.com/slightlyoff/ServiceWorker/issues/793. --- Overview.html | 290 +++++++++++++++++++++------------------------- Overview.src.html | 290 +++++++++++++++++++++------------------------- 2 files changed, 266 insertions(+), 314 deletions(-) diff --git a/Overview.html b/Overview.html index 1bf660ad6..25902e103 100644 --- a/Overview.html +++ b/Overview.html @@ -567,7 +567,7 @@

3.1.2 Headers

header and headers contains more than one, return failure. -

If different error handling is required, extract the desired +

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

  • If parsing all the headers @@ -2378,11 +2378,10 @@

    5 Fetching

    5.1 Main fetch

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

    The recursive flag is set when -main fetch is invoked recursively. The -CORS flag is a bookkeeping detail for handling redirects. +

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

    1. Let response be null. @@ -2468,11 +2467,9 @@

      5.1 Main fetch

      substeps corresponding to the first matching statement:
      -
      request's - current url's - origin is - request's origin and the - CORS flag is unset +
      request's current url's + origin is request's + origin and CORS flag is unset
      request's current url's scheme is @@ -2531,8 +2528,8 @@

      5.1 Main fetch

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

    3. If corsWithPreflightResponse is a network error, then @@ -2549,7 +2546,7 @@

      5.1 Main fetch

      "cors".
    4. Return the result of performing an HTTP fetch - using request with the CORS flag set. + using request with CORS flag set.

    @@ -2832,14 +2829,11 @@

    5.2 Basic fetch

    5.3 HTTP fetch

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

    The CORS flag is still a bookkeeping detail. The -CORS-preflight flag and authentication-fetch flag are too. The -former indicates a CORS-preflight request is required and the latter -indicates an attempt to authenticate. +

    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. @@ -2960,151 +2954,76 @@

      5.3 HTTP fetch

      CORS-preflight fetches.
    2. -

      Set request's skip-service-worker flag. +

      If request's redirect mode is + "follow", then set request's skip-service-worker flag. -

      There might be redirects. Alternatively, - request's window is an - environment settings object and the - CORS flag is unset. +

      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 credentials flag if set and - authentication-fetch flag if set. + HTTP-network-or-cache fetch using + request with CORS flag if set and credentials flag if set.

    4. -

      If the CORS flag is set and a - CORS check for request and - response returns failure, return a +

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

      There is no need to apply this to a - response from a service worker. +

      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.

  • -

    Switch on actualResponse's status: - -

    -
    redirect status -
    -
      -
    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. +

      If actualResponse's status is a + redirect status, then run these substeps: -

    2. Let location be the result of parsing - `Location` 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 the CORS flag set if set. -

      - -
    - -
    401 -
    -
      -
    1. -

      If one of the following conditions is true, return response: - -

        -
      • The CORS flag is set. -
      • The credentials flag is unset. -
      • request's window is - "no-window". -
      - -
    2. Needs testing: multiple `WWW-Authenticate` headers, - missing, parsing issues. - -

    3. -

      If request's - use-URL-credentials flag - is unset, or the authentication-fetch flag is set, run these substeps: - -

        -
      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. Return the result of performing an - HTTP fetch using request, with - the authentication-fetch flag set. - -

    - -
    407 -
    -
      -
    1. If request's window - is "no-window", return a - network error. +

        +
      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. -

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

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

      3. -

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

      4. Let location be the result of parsing + `Location` in actualResponse's + header list. -

        Remaining details surrounding proxy authentication are defined by HTTP. +

      5. If location is a value, then set + location to the result of + parsing location with + actualResponse's url. -

      6. Return the result of performing an - HTTP fetch using request. - -

      +
    2. Set actualResponse's + location URL to location. -

      Otherwise -

      Do nothing. -

    +
  • +

    Switch on request's + redirect mode: -

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

    +
    "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. +

    + +
  • Return response. Typically actualResponse's body's @@ -3157,14 +3076,14 @@

    5.4 HTTP-redirect fetch< network error.
  • -

    If the CORS flag is set and actualResponse's +

    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. -

  • If the CORS flag is set and actualResponse's +

  • If CORS flag is set and actualResponse's location URL's origin is not same origin with request's @@ -3190,7 +3109,7 @@

    5.4 HTTP-redirect fetch<
  • Return the result of performing a main fetch using - request, with the CORS flag set if set, and the recursive flag set. + request with CORS flag if set and recursive flag set.

    This has to invoke main fetch to get response tainting correct. @@ -3201,11 +3120,11 @@

    5.5 HTTP-network

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

    The authentication-fetch flag is still a bookkeeping detail. -The credentials flag is one too. +

    CORS flag is still a bookkeeping detail. As are credentials flag and +authentication-fetch flag.

    1. @@ -3372,9 +3291,8 @@

      5.5 HTTP-network
    2. Otherwise, if httpRequest's current url does - include credentials and the - authentication-fetch flag is set, set - authorizationValue to httpRequest's + include credentials and authentication-fetch flag is + set, then set authorizationValue to httpRequest's current url, converted to an `Authorization` value. @@ -3476,6 +3394,64 @@

      5.5 HTTP-network status which is most likely 200 now.

    +
  • +

    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 + 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. +

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

    + +
  • +

    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] + +

      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. +

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

  • Return response. Typically response's body's stream is still being enqueued to after returning. @@ -4450,7 +4426,7 @@

    6.2 Body mixin

    entries. -

    The above is a rough approximation of what is required for +

    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. diff --git a/Overview.src.html b/Overview.src.html index cce638ff4..b5d687394 100644 --- a/Overview.src.html +++ b/Overview.src.html @@ -495,7 +495,7 @@

    Headers

    header and headers contains more than one, return failure. -

    If different error handling is required, extract the desired +

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

  • If parsing all the headers @@ -2306,11 +2306,10 @@

    Fetching

    Main fetch

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

    The recursive flag is set when -main fetch is invoked recursively. The -CORS flag is a bookkeeping detail for handling redirects. +

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

    1. Let response be null. @@ -2396,11 +2395,9 @@

      Main fetch

      substeps corresponding to the first matching statement:
      -
      request's - current url's - origin is - request's origin and the - CORS flag is unset +
      request's current url's + origin is request's + origin and CORS flag is unset
      request's current url's scheme is @@ -2459,8 +2456,8 @@

      Main fetch

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

    3. If corsWithPreflightResponse is a network error, then @@ -2477,7 +2474,7 @@

      Main fetch

      "cors".
    4. Return the result of performing an HTTP fetch - using request with the CORS flag set. + using request with CORS flag set.

    @@ -2760,14 +2757,11 @@

    Basic fetch

    HTTP fetch

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

    The CORS flag is still a bookkeeping detail. The -CORS-preflight flag and authentication-fetch flag are too. The -former indicates a CORS-preflight request is required and the latter -indicates an attempt to authenticate. +

    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. @@ -2888,151 +2882,76 @@

      HTTP fetch

      CORS-preflight fetches.
    2. -

      Set request's skip-service-worker flag. +

      If request's redirect mode is + "follow", then set request's skip-service-worker flag. -

      There might be redirects. Alternatively, - request's window is an - environment settings object and the - CORS flag is unset. +

      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 credentials flag if set and - authentication-fetch flag if set. + HTTP-network-or-cache fetch using + request with CORS flag if set and credentials flag if set.

    4. -

      If the CORS flag is set and a - CORS check for request and - response returns failure, return a +

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

      There is no need to apply this to a - response from a service worker. +

      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.

  • -

    Switch on actualResponse's status: - -

    -
    redirect status -
    -
      -
    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. +

      If actualResponse's status is a + redirect status, then run these substeps: -

    2. Let location be the result of parsing - `Location` 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 the CORS flag set if set. -

      - -
    - -
    401 -
    -
      -
    1. -

      If one of the following conditions is true, return response: - -

        -
      • The CORS flag is set. -
      • The credentials flag is unset. -
      • request's window is - "no-window". -
      - -
    2. Needs testing: multiple `WWW-Authenticate` headers, - missing, parsing issues. - -

    3. -

      If request's - use-URL-credentials flag - is unset, or the authentication-fetch flag is set, run these substeps: - -

        -
      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. Return the result of performing an - HTTP fetch using request, with - the authentication-fetch flag set. - -

    - -
    407 -
    -
      -
    1. If request's window - is "no-window", return a - network error. +

        +
      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. -

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

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

      3. -

        Prompt the end user as appropriate in request's - window and store the result as a - proxy-authentication entry. - HTTP +

      4. Let location be the result of parsing + `Location` in actualResponse's + header list. -

        Remaining details surrounding proxy authentication are defined by HTTP. +

      5. If location is a value, then set + location to the result of + parsing location with + actualResponse's url. -

      6. Return the result of performing an - HTTP fetch using request. - -

      +
    2. Set actualResponse's + location URL to location. -

      Otherwise -

      Do nothing. -

    +
  • +

    Switch on request's + redirect mode: -

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

    +
    "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. +

    + +
  • Return response. Typically actualResponse's body's @@ -3085,14 +3004,14 @@

    HTTP-redirect fetch

    network error.
  • -

    If the CORS flag is set and actualResponse's +

    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. -

  • If the CORS flag is set and actualResponse's +

  • If CORS flag is set and actualResponse's location URL's origin is not same origin with request's @@ -3118,7 +3037,7 @@

    HTTP-redirect fetch

  • Return the result of performing a main fetch using - request, with the CORS flag set if set, and the recursive flag set. + request with CORS flag if set and recursive flag set.

    This has to invoke main fetch to get response tainting correct. @@ -3129,11 +3048,11 @@

    HTTP-network-or-cache fetch

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

    The authentication-fetch flag is still a bookkeeping detail. -The credentials flag is one too. +

    CORS flag is still a bookkeeping detail. As are credentials flag and +authentication-fetch flag.

    1. @@ -3300,9 +3219,8 @@

      HTTP-network-or-cache fetch

    2. Otherwise, if httpRequest's current url does - include credentials and the - authentication-fetch flag is set, set - authorizationValue to httpRequest's + include credentials and authentication-fetch flag is + set, then set authorizationValue to httpRequest's current url, converted to an `Authorization` value. @@ -3404,6 +3322,64 @@

      HTTP-network-or-cache fetch

      status which is most likely 200 now.
    +
  • +

    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 + 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. +

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

    + +
  • +

    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 + +

      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. +

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

  • Return response. Typically response's body's stream is still being enqueued to after returning. @@ -4378,7 +4354,7 @@

    Body mixin

    entries. -

    The above is a rough approximation of what is required for +

    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.