chromium/services/network/public/mojom/url_loader_network_service_observer.mojom

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module network.mojom;

import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/time.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "services/network/public/mojom/cookie_partition_key.mojom";
import "services/network/public/mojom/ip_address.mojom";
import "services/network/public/mojom/ip_address_space.mojom";
import "services/network/public/mojom/network_param.mojom";
import "services/network/public/mojom/optional_bool.mojom";
import "url/mojom/origin.mojom";
import "url/mojom/url.mojom";

// Loading info.
struct LoadInfo {
  mojo_base.mojom.TimeTicks timestamp;
  string host;
  uint32 load_state;  // net::LoadState enum
  mojo_base.mojom.String16 state_param;
  uint64 upload_position;
  uint64 upload_size;
};

// This interface enables the UI to send client certificate selections back to
// the network service.
//
// Defining an interface for this purpose, rather than using a union in the
// response of OnCertificateRequested, enables the NetworkServiceClient to learn
// of the URLLoader destruction via the connection error handler.
interface ClientCertificateResponder {
  // Use the selected certificate and continue the URLRequest.
  //
  // - |provider_name| corresponds to the return value of
  //   net::SSLPrivateKey::GetProviderName().
  // - |algorithm_preferences| corresponds to the return value of
  //   net::SSLPrivateKey::GetAlgorithmPreferences().
  ContinueWithCertificate(network.mojom.X509Certificate x509_certificate,
                          string provider_name,
                          array<uint16> algorithm_preferences,
                          pending_remote<SSLPrivateKey> ssl_private_key);

  // Affirmatively select no certificate (this is cached and can affect future
  // URLRequests). Does not cancel the URLRequest.
  //
  // The connection is continued with no client cert.
  // net::URLRequest::ContinueWithCertificate(nullptr, nullptr) needs to be
  // called.
  ContinueWithoutCertificate();

  // Cancel the URLRequest. The request is aborted.
  // net::URLRequest::CancelWithError() needs to be called.
  CancelRequest();
};

// The content/browser implementation of this SSLPrivateKey interface wraps the
// scoped_refptr<net::SSLPrivateKey> that is received from
// SSLClientAuthDelegate::ContinueWithCertificate(), and this mojo interface is
// sent from content/browser to services/network so that services/network can
// have its own net::SSLPrivateKey implementation that internally uses this mojo
// interface.
// The |algorithm| and |input| parameters correspond to the |algorithm| and
// |input| parameters in net::SSLPrivateKey::Sign().
// The |net_error| and |signature| parameters correspond to the parameters in
// net::SSLPrivateKey::SignCallback.
interface SSLPrivateKey {
  // Sign |input| using the private key and |algorithm|.
  Sign(uint16 algorithm,
       array<uint8> input) => (int32 net_error, array<uint8> signature);
};

// The |credentials| output parameter is given to URLRequest::SetAuth()
// through this mojo interface. It is not set when URLRequest::CancelAuth()
// needs to be called.
interface AuthChallengeResponder {
   // Called in response to an authentication request. See
   // URLLoaderNetworkServiceObserver::OnAuthRequired.
   OnAuthCredentials(AuthCredentials? credentials);
};

// Shared Storage is an origin-keyed storage mechanism where the output is
// carefully guarded to mitigate the risk of cross-site correlation.
// See https://github.com/WICG/shared-storage/blob/main/README.md.
//
// Each type corresponds to one of the Shared Storage setter or deleter
// operations that can be triggered by response headers.
enum SharedStorageOperationType {
  kSet = 0,
  kAppend = 1,
  kDelete = 2,
  kClear = 3,
};

// Bundles an operation type with any needed parameters for Shared Storage
// setter/deleter operations that can be triggered by response headers. The
// raw structured headers are parsed into an array of this struct, then sent to
// the browser process.
struct SharedStorageOperation {
  SharedStorageOperationType type;
  string? key;
  string? value;
  OptionalBool ignore_if_present = kUnset;
};

// This interface is used by an URLLoaderFactory to provide notification
// of authentication and certificate events. This is typically implemented
// by a trusted process such as the browser process.
interface URLLoaderNetworkServiceObserver {
  // Called when an SSL certificate error is encountered.
  // The callback argument is a net::ERROR value. If it's net::OK, then the
  // request is resumed. Otherwise it's cancelled with the given error.
  OnSSLCertificateError(url.mojom.Url url,
                        int32 net_error,
                        SSLInfo ssl_info,
                        bool fatal) => (int32 net_error);

  // Called when an SSL certificate requested message is received for client
  // authentication.
  //
  // Rather than using one response for multiple purposes, the caller expects
  // exactly one response (or disconnect) to be sent back via |cert_responder|.
  //
  // |window_id| indicates the frame making the request, see
  // network::ResourceRequest::fetch_window_id. This parameter is only set
  // when the request is from a service worker to identify the origin window.
  // The is not needed for frame based requests because they have their own
  // URLLoaderFactory and a unique URLLoaderNetworkServiceObserver for each
  // frame.
  OnCertificateRequested(
      mojo_base.mojom.UnguessableToken? window_id,
      network.mojom.SSLCertRequestInfo cert_info,
      pending_remote<ClientCertificateResponder> cert_responder);

  // Called when we receive an authentication failure.
  // The |auth_challenge_responder| will respond to auth challenge with
  // credentials. |head_headers| can provide response headers for the response
  // which has elicited this auth request, if applicable.
  //
  // |window_id| indicates the frame making the request, see
  // network::ResourceRequest::fetch_window_id. This parameter is only set
  // when the request is from a service worker to identify the origin window.
  // The is not needed for frame based requests because they have their own
  // URLLoaderFactory and a unique URLLoaderNetworkServiceObserver for each
  // frame.
  OnAuthRequired(
      mojo_base.mojom.UnguessableToken? window_id,
      int32 request_id,
      url.mojom.Url url,
      bool first_auth_attempt,
      AuthChallengeInfo auth_info,
      HttpResponseHeaders? head_headers,
      pending_remote<AuthChallengeResponder> auth_challenge_responder);

  // Asks the URL loader observer if the caller has permission to access a
  // device on the private network.
  //
  // `url` is the request's URL.
  // `ip_address` is the remote IP address from which headers were fetched.
  // `private_network_device_id` and `private_network_device_name` are the
  // values of the `Private-Network-Access-ID` and `Private-Network-Access-Name`
  // headers.
  //
  // `permission_granted` is a bool specifying whether the user granted private
  // network access permission.
  OnPrivateNetworkAccessPermissionRequired(
      url.mojom.Url url,
      network.mojom.IPAddress ip_address,
      string? private_network_device_id,
      string? private_network_device_name) => (bool permission_granted);

  // Called when the Clear-Site-Data header has been received. The callback
  // should be run after the data is deleted.
  // https://www.w3.org/TR/clear-site-data/
  // TODO(crbug.com/41409604): We might want to move header parsing work to
  // Network Service for security concerns (e.g. |header_value| => booleans).
  OnClearSiteData(url.mojom.Url url,
                  string header_value,
                  int32 load_flags,
                  CookiePartitionKey? cookie_partition_key,
                  bool partitioned_state_allowed_only) => ();

  // Called periodically to update the client about progress of the current
  // loads. To avoid flooding the client, it has to ack the update before it can
  // receive the next update. This will only be called if the
  // URLLoaderFactory has requested it in the URLLoaderFactoryParams.
  OnLoadingStateUpdate(LoadInfo info) => ();

  // Called on every request completion to update the network traffic annotation
  // ID, and the total bytes received and sent.
  // |network_traffic_annotation_id_hash| represents the hash of unique tag that
  // identifies the annotation of the request.
  OnDataUseUpdate(int32 network_traffic_annotation_id_hash, int64 recv_bytes,
                  int64 sent_bytes);

  // The syntactic parsing of "Shared-Storage-Write" response headers occurs in
  // the network service for security and privacy; this method then notifies
  // the browser process or other observer implementers that the raw headers
  // have been parsed into an array of `SharedStorageOperation` structs.
  //
  // The order of the operations as listed in the header(s) is preserved, so
  // that the browser process (the main implementer of this API) can guarantee
  // that it will invoke the corresponding operations in their originally
  // specified order.
  //
  // Note that any structured header list items that are not parsed as valid
  // `SharedStorageOperation`s will simply be omitted. Moreover, if the header
  // does not parse as a valid structured header list, or if the parsed list is
  // empty, then this method will not be invoked.
  //
  // Unlike with calls to Shared Storage from the renderer, we don't check the
  // the length requirements for keys and values using mojom traits, in order
  // to avoid a dependency on blink. Instead, we must check these lengths in
  // the implementation (e.g. in the browser process) before invoking the
  // actual Shared Storage operations.
  //
  // TODO(crbug.com/40064101): Make the `OnSharedStorageHeaderReceived()` call
  // synchronous so that we can guarantee that order is preserved between calls
  // triggered by response headers and Shared Storage calls from the same
  // renderer process where this request originated.
  OnSharedStorageHeaderReceived(url.mojom.Origin request_origin,
                 array<SharedStorageOperation> operations) => ();

  // Used by the NetworkService to create a copy of this observer.
  // (e.g. when creating an observer for URLLoader from URLLoaderFactory's
  // observer).
  Clone(pending_receiver<URLLoaderNetworkServiceObserver> listener);

  // Called when a WebSocket is connected to a private or local IP address
  // space.
  OnWebSocketConnectedToPrivateNetwork(IPAddressSpace ip_address_space);
};