// Copyright 2018 The Chromium Authors. All rights reserved.
// 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/file_path.mojom";
import "mojo/public/mojom/base/time.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "mojo/public/mojom/base/values.mojom";
import "services/network/public/mojom/address_list.mojom";
import "services/network/public/mojom/cookie_manager.mojom";
import "services/network/public/mojom/cors_origin_pattern.mojom";
import "services/network/public/mojom/host_resolver.mojom";
import "services/network/public/mojom/http_request_headers.mojom";
import "services/network/public/mojom/ip_endpoint.mojom";
import "services/network/public/mojom/mdns_responder.mojom";
import "services/network/public/mojom/mutable_network_traffic_annotation_tag.mojom";
import "services/network/public/mojom/net_log.mojom";
import "services/network/public/mojom/network_param.mojom";
import "services/network/public/mojom/p2p.mojom";
import "services/network/public/mojom/p2p_trusted.mojom";
import "services/network/public/mojom/proxy_config.mojom";
import "services/network/public/mojom/proxy_config_with_annotation.mojom";
import "services/network/public/mojom/proxy_lookup_client.mojom";
import "services/network/public/mojom/proxy_resolving_socket.mojom";
import "services/network/public/mojom/restricted_cookie_manager.mojom";
import "services/network/public/mojom/ssl_config.mojom";
import "services/network/public/mojom/tcp_socket.mojom";
import "services/network/public/mojom/udp_socket.mojom";
import "services/network/public/mojom/url_loader.mojom";
import "services/network/public/mojom/url_loader_factory.mojom";
import "services/network/public/mojom/websocket.mojom";
import "services/proxy_resolver/public/mojom/proxy_resolver.mojom";
import "url/mojom/origin.mojom";
import "url/mojom/url.mojom";

[EnableIf=is_ct_supported]
import "services/network/public/mojom/ct_log_info.mojom";

// Config for setting a custom proxy config that will be used if a request
// matches the proxy rules and would otherwise be direct. This config allows
// headers to be set on requests to the proxies from the config before and/or
// after the caching layer. Currently only supports proxying http requests.
struct CustomProxyConfig {
  // The custom proxy rules to use. Right now this is limited to proxies for
  // http requests.
  ProxyRules rules;

  // List of proxies that will be used if
  // ResourceRequest::custom_proxy_use_alternate_proxy_list is set.
  ProxyList alternate_proxy_list;

  // The custom proxy can set these headers in this config which will be added
  // to all requests using the proxy. This allows setting headers that may be
  // privacy/security sensitive which we don't want to send to the renderer.
  // Headers that require per-request logic can be added through the
  // |custom_proxy_pre_cache_headers| and |custom_proxy_post_cache_headers|
  // fields in ResourceRequest.
  //
  // Headers that will be set before the cache for http requests. If the request
  // does not use a custom proxy, these headers will be removed before sending
  // to the network. If a request already has one of these headers set, it may
  // be overwritten if a custom proxy is used, or removed if a custom proxy is
  // not used.
  HttpRequestHeaders pre_cache_headers;

  // Headers that will be set after the cache for requests that are issued
  // through a custom proxy. Headers here will overwrite matching headers on the
  // request if a custom proxy is used.
  HttpRequestHeaders post_cache_headers;
};

// Client to update the custom proxy config.
interface CustomProxyConfigClient {
  OnCustomProxyConfigUpdated(CustomProxyConfig proxy_config);

  // Marks the custom proxies in |bad_proxies| as temporarily bad, so they are
  // not layered onto the proxy resolution results for subsequent requests.
  MarkProxiesAsBad(mojo_base.mojom.TimeDelta bypass_duration,
                   ProxyList bad_proxies) => ();

  // Clears the list of bad proxy servers that has been cached in the proxy
  // resolution service.
  ClearBadProxiesCache();
};

[EnableIf=is_chromeos]
struct AdditionalCertificates {
  // List of all additional certificates.
  array<X509Certificate> all_certificates;

  // List of additional trust anchors.
  array<X509Certificate> trust_anchors;
};

// Interface to allow modifying the full request and response headers. This
// interface exposes sensitive headers such as set-cookie, so should only be
// sent to trusted processes.
interface TrustedURLLoaderHeaderClient {
  // Allows modifying request headers before the request is sent.
  OnBeforeSendHeaders(int32 request_id, HttpRequestHeaders headers) =>
      (int32 result, HttpRequestHeaders? headers);

  // Allows modifying response headers, including sensitive headers such as
  // set-cookie. This should only be used from a trusted process.
  OnHeadersReceived(int32 request_id, string headers) =>
      (int32 result,
       string? headers,
       url.mojom.Url allowed_unsafe_redirect_url);
};

// Parameters for constructing a network context.
struct NetworkContextParams {
  // Name used by memory tools to identify the context.
  string? context_name;

  // The user agent string.
  string user_agent;

  // String to send as the Accept-Language header. This can be changed later
  // by calling SetAcceptLanguage on the NetworkContext. If empty, the header
  // will not be added.
  string accept_language;

  // Whether Brotli content-encoding should be enabled for HTTPS responses.
  bool enable_brotli = true;

  // QUIC user agent.
  string quic_user_agent_id;

  // If false, the referrer of requests is never populated.
  bool enable_referrers = true;

  // If true, requests initiated with referrers that don't match their referrer
  // policy will fail.
  bool validate_referrer_policy_on_initial_request = true;

  // Handles PAC script execution. If not populated, will attempt to use
  // platform implementation to execute PAC scripts, if available (Only
  // available on Windows and Mac).
  proxy_resolver.mojom.ProxyResolverFactory? proxy_resolver_factory;

  // Points to the cookie file. An in-memory cookie store is used if it's empty.
  mojo_base.mojom.FilePath? cookie_path;

  // If true, cookies will be stored encrypted.
  bool enable_encrypted_cookies = true;

  // If the cookie file is given, this controls whether previously written
  // session cookies are restored. Otherwise it should be false.
  bool restore_old_session_cookies = false;

  // If the cookie file is given, this controls whether to persist session
  // cookies. Otherwise it should be false.
  bool persist_session_cookies = false;

  // Points to the channel ID file. If a cookie file is specified, this must be
  // specified as well. Otherwise an in-memory store is used.
  mojo_base.mojom.FilePath? channel_id_path;

  // True if an HTTP cache should be used.
  bool http_cache_enabled = true;
  // Maximum size of the HTTP cache. 0 means to use the default size.
  // Ignored if the cache is disabled.
  int32 http_cache_max_size = 0;
  // Points to the HTTP cache directory. Ignored if the cache is disabled.
  // If null and the cache is enabled, an in-memory database is used.
  mojo_base.mojom.FilePath? http_cache_path;

  // The file to store cached server properties (Like HTTP2 and QUIC support).
  // This information is used as a performance optimization in connection
  // logic. If null, an in-memory cache will be used instead.
  mojo_base.mojom.FilePath? http_server_properties_path;

  // The directory in which to store cached transport security properties (like
  // HSTS). The file itself will be called "TransportSecurity". If null, or the
  // file can't be opened, an in-memory store will be used instead.
  mojo_base.mojom.FilePath? transport_security_persister_path;

  // Enabled protocols. Note that these apply to all fetches, including those
  // used to fetch PAC scripts.

  // True if data URLs should be supported.
  bool enable_data_url_support = false;
  // True if file URLs should be supported.
  // Must be false if built without file support.
  bool enable_file_url_support = false;
  // True if ftp URLs should be supported.
  // Must be false if built without FTP support.
  bool enable_ftp_url_support = false;

  // True if the "Certificate Transparency in Chrome" policy (see
  // https://github.com/chromium/ct-policy/blob/master/ct_policy.md) should
  // be enforced for certificates and connections.
  //
  // See //net/docs/certificate-transparency.md before setting this flag to
  // true.
  [EnableIf=is_ct_supported]
  bool enforce_chrome_ct_policy = false;

  // Enables HTTP/0.9 on ports other than 80 for HTTP and 443 for HTTPS.
  bool http_09_on_non_default_ports_enabled = false;

  // SSL configuration. |initial_proxy_config| is the initial SSL configuration
  // to use. If nullptr, uses the default configuration. Updated SSL
  // configurations can be passed in via |ssl_config_client_request|.
  SSLConfig? initial_ssl_config;
  SSLConfigClient&? ssl_config_client_request;

  // Proxy configuration. If |initial_proxy_config| is set, it's the initial
  // proxy configuration. Updated proxy configuration can be passed in via
  // |proxy_config_client_request|. If |initial_proxy_config| is not set,
  // proxy lookups will be deferred until a configuration is received via
  // |proxy_config_client_request|.
  //
  // If both are null, the NetworkContext will not use a proxy.
  ProxyConfigWithAnnotation? initial_proxy_config;
  ProxyConfigClient&? proxy_config_client_request;

  // If |custom_proxy_config_client_request| is set, this context will listen
  // for updates to the custom proxy config, and use it if applicable for
  // requests which would otherwise be made direct.
  // |initial_custom_proxy_config| is the initial config settings.
  CustomProxyConfig? initial_custom_proxy_config;
  CustomProxyConfigClient&? custom_proxy_config_client_request;

  // If |proxy_config_client_request| is non-null, this is called during
  // periods of network activity, and can be used as a signal for polling-based
  // logic to determine the proxy config.
  //
  // TODO(mmenke): Can the consumer piggy back on other network events through
  // other channels (navigation, issuing requests, etc)? Or can
  // ProxyConfigServices be modified not to need this notification?
  ProxyConfigPollerClient? proxy_config_poller_client;

  // Optional client that will be notified of errors related to the proxy
  // settings.
  ProxyErrorClient? proxy_error_client;

  // When PAC quick checking is enabled, DNS lookups for PAC script's host are
  // timed out aggressively. This prevents hanging all network request on DNS
  // lookups that are slow or are blockholed, at the cost of making it more
  // likely that the network service erroneously fails to fetch a PAC file.
  bool pac_quick_check_enabled = true;

  // When enabled, exposes full URLs to PAC scripts. This setting will be
  // removed in the future.
  // See https://crbug.com/619087
  bool dangerously_allow_pac_access_to_secure_urls = false;

  // Enables reporting certain SSL errors, such as HTTP Public Key Pinning, to
  // servers, so they can discover misconfigurations.
  bool enable_certificate_reporting = false;

  // Enables Expect CT reporting, which sends reports for opted-in sites that
  // don't serve sufficient Certificate Transparency information.
  [EnableIf=is_ct_supported]
  bool enable_expect_ct_reporting = false;

  // The Certificate Transparency logs that are known to the client. SCTs from
  // these logs will be extracted and verified; other SCTs will be treated as
  // unrecognized.
  [EnableIf=is_ct_supported]
  array<CTLogInfo> ct_logs;

  // Specifies the path to the directory where NSS will store its database.
  [EnableIf=is_chromeos]
  mojo_base.mojom.FilePath? nss_path;

  // This is used in combination with nss_path, to ensure that the NSS database
  // isn't opened multiple times for NetworkContexts in the same profie.
  [EnableIf=is_chromeos]
  string username_hash;

  // Initial additional certificates that will be used for certificate
  // validation.
  [EnableIf=is_chromeos]
  AdditionalCertificates? initial_additional_certificates;

  // Parameters for constructing the cookie manager.
  CookieManagerParams? cookie_manager_params;

  // Whether to enable Domain Reliability.
  bool enable_domain_reliability = false;

  // The uploader reporter name to use for Domain Reliability uploads.
  string domain_reliability_upload_reporter;

  // Whether to discard Domain Reliability uploads.
  bool discard_domain_reliablity_uploads = false;

  // Sets whether the NetworkContext should be used for globally scoped tasks
  // that need to make network requests. Currently this includes DNS over HTTPS
  // requests and certain cert validation requests (OCSP, AIA, etc) on some
  // platforms. May only be set to true the first NetworkContext created using
  // the NetworkService.  Destroying a NetworkContext created with this set to
  // true will destroy all other NetworkContexts.
  //
  // A failure to mark a NetworkContext as being used by certificate
  // verification may result in incorrect certificate validation behaviors,
  // such as the inability to verify EV certificates, to build paths when
  // intermediates are missing, and to enforce revocation checking when it was
  // requested via policy.
  //
  // TODO(mmenke): Once NSS is not used on any platform for certificate
  // verification, we should consider using each URLRequestContext to do its own
  // validation.
  bool primary_network_context = false;

  // Specifies the initial set of allowed and blocked origins for the
  // URLLoaderFactory consumers to access beyond the same-origin-policy.
  array<CorsOriginAccessPatterns> cors_origin_access_list;
};

struct NetworkConditions {
  // If set, the offline state is simulated and other fields are ignored.
  bool offline;

  // Channel round-trip latency, i.e. minimum time between request sent and
  // response received.
  mojo_base.mojom.TimeDelta latency;

  // Maximal aggregated download throughput (bytes/sec). 0 disables download
  // throttling.
  double download_throughput;

  // Maximal aggregated upload throughput (bytes/sec). 0 disables upload
  // throttling.
  double upload_throughput;
};

// Used in some clearing methods of URL-keyed data to specify the resources to
// keep/delete.
struct ClearDataFilter {
  enum Type {DELETE_MATCHES, KEEP_MATCHES};

  Type type;

  // A list of registrable domains (e.g. google.com), internal hostnames
  // (e.g. localhost), or IP addresses (e.g. 127.0.0.1). Other domains, such as
  // third and lower level domains (e.g. www.google.com) are not accepted.
  // Formally, it must hold that GetDomainAndRegistry(|domain|, _) is |domain|
  // itself or an empty string.
  array<string> domains;

  // List of URL origins.
  array<url.mojom.Origin> origins;
};

// Represents the accumulated network usage for a consumer.
struct NetworkUsage {
  // |process_id| is 0 for the browser process, otherwise it's the child process
  // ID.
  uint32 process_id;

  // The ID of the IPC route for the consumer, which identifies the RenderFrame
  // or like-thing.
  uint32 routing_id;

  // Raw bytes received from the network since the start/restart of the service.
  int64 total_bytes_received;

  // Raw bytes sent to the network since the start/restart of the service.
  int64 total_bytes_sent;
};

const uint32 kBrowserProcessId = 0;
const uint32 kInvalidProcessId = 0xffffffff;

struct URLLoaderFactoryParams {
  // Process requesting the URLLoaderFactory.
  // Set to kBrowserProcessId to indicate the browser process.
  uint32 process_id = kInvalidProcessId;

  // If specified, then |request_initiator_site_lock| locks
  // |ResourceRequest::request_initiator| to the specified origin.
  // TODO(lukasza): https://crbug.com/891872: Make this non-optional.
  // TODO(lukasza, nasko): https://crbug.com/888079: Make this an *origin* lock
  // (rather than just a site lock).
  url.mojom.Origin? request_initiator_site_lock;

  // Cross-origin read blocking (CORB) configuration.
  bool is_corb_enabled = true;
  // TODO(lukasza): The field below in practice is always set to
  // RESOURCE_TYPE_PREFETCH by the //content layer, but in the long-term we want
  // to avoid using resource types (even as an opaque int) in
  // //services/network.  See also the TODO comment for
  // network::ResourceRequest::resource_type.
  int32 corb_detachable_resource_type = -1;
  // TODO(lukasza): https://crbug.com/846339: Remove the field below and instead
  // make plugins use a separate URLoaderFactory. Note requests of this type are
  // only excluded if ResourceRequest::fetch_request_mode is kNoCors. The field
  // below in practice is always set to RESOURCE_TYPE_PLUGIN_RESOURCE by the
  //  content layer, but in the long-term we want to avoid using resource types
  // (even as an opaque int) in //services/network.  See also the TODO comment
  // for network::ResourceRequest::resource_type.
  int32 corb_excluded_resource_type = -1;

  // True if web related security (e.g., CORS) should be disabled. This is
  // mainly used by people testing their sites, via a command line switch.
  bool disable_web_security = false;

  // If this is set, requests with the kURLLoadOptionUseHeaderClient option will
  // callback to the |header_client|, allowing the Cookie/Referrer request
  // headers and Cookie response headers to be modified. This has a performance
  // impact because of the extra process hops, so use should be minimized.
  TrustedURLLoaderHeaderClient? header_client;
};

// Callback interface for NetworkContext when routing identifiers aren't
// available. Otherwise generally callbacks from the network service go on
// NetworkServiceClient.
interface NetworkContextClient {
  // Checks if network error reports could be sent for the given origins.
  // Replies with the origins that are allowed.
  OnCanSendReportingReports(array<url.mojom.Origin> origins) =>
      (array<url.mojom.Origin> origins);

  // Checks if a Domain Reliability report can be uploaded for the given origin.
  OnCanSendDomainReliabilityUpload(url.mojom.Url origin) => (bool allowed);
};

// Represents a distinct context for making network requests, with its own
// storage (e.g. cookies and cache).
interface NetworkContext {
  // Sets a client for this network context.
  SetClient(NetworkContextClient client);

  // Creates a new URLLoaderFactory with the given |params|.
  CreateURLLoaderFactory(URLLoaderFactory& url_loader_factory,
                         URLLoaderFactoryParams params);

  // Destroys all URLLoaderFactory bindings, which should then be regenerated.
  // This should be called if there is a change to the proxies which should be
  // used on URLLoaders.
  ResetURLLoaderFactories();

  // Gets the CookieManager associated with this network context.
  //
  // The CookieManager must only be passed to trusted processes. Whenever
  // possible, a RestrictedCookieManager should be handed out instead.
  GetCookieManager(CookieManager& cookie_manager);

  // Gets a RestrictedCookieManager scoped to a given origin.
  //
  // This interface can be safely handed out to a process that is known to
  // represent the given origin, such as a renderer process.
  GetRestrictedCookieManager(RestrictedCookieManager& restricted_cookie_manager,
                             url.mojom.Origin origin);

  // Clears network objects with implicit URL history information. Data related
  // to events that happened prior to |start_time| may be retained. Only applies
  // to network objects without more specific methods (Channel ID, Cookies,
  // and the cache have, or will have, their own clearing APIs). This currently
  // only covers server properties and transport security state.
  //
  // The callback will be invoked once the data has been deleted.
  ClearNetworkingHistorySince(mojo_base.mojom.Time start_time) => ();

  // Clears content from the HTTP cache. A specific range of time can be
  // specified with |start_time| and |end_time|. This supports unbounded deletes
  // in either direction by using null Time values for either argument.
  // If a non-null |filter| is specified, will clear only entries matching the
  // filter.
  ClearHttpCache(mojo_base.mojom.Time start_time,
                 mojo_base.mojom.Time end_time,
                 ClearDataFilter? filter) => ();

  // Computes the size of cache objects last accessed between |start_time| and
  // |end_time|.
  //
  // If you don't want a lower bound, pass base::Time() for |start_time|.
  // If you don't want an upper bound, pass base::Time::Max()
  //
  // |upper_bound| will be returned as true if the implementation had to
  // overestimate; this may be as bad as giving the size of the entire cache.
  //
  // |size_or_error|, if non-negative, is the result in bytes; and a net error
  // code if negative.
  ComputeHttpCacheSize(mojo_base.mojom.Time start_time,
                       mojo_base.mojom.Time end_time)
      => (bool is_upper_bound, int64 size_or_error);

  // Notifies the HttpCache of a renderer-level cache hit with |url|
  // and |http_method|, with the top-level frame of the containing page
  // being on origin |top_frame_origin|.
  //
  // This is being proxied by the browser because the renderer is unable to
  // directly interact with NetworkContext.
  NotifyExternalCacheHit(url.mojom.Url url, string http_method,
                         url.mojom.Origin? top_frame_origin);

  // Caches |data| associated with |url| and |expected_response_time| in the
  // HttpCache related to this NetworkContext.
  WriteCacheMetadata(url.mojom.Url url,
                     RequestPriority priority,
                     mojo_base.mojom.Time expected_response_time,
                     array<uint8> data);

  // Clears channel IDs. A specific range of time can be specified with
  // |start_time| and |end_time|. This supports unbounded deletes in either
  // direction by using null Time values for either argument.
  //
  // If a non-null |filter| is specified, will clear only IDs matching the
  // filter. Filtering by origins is not supported. If |filter| is non-null,
  // |filter.origins| must be empty.
  ClearChannelIds(mojo_base.mojom.Time start_time,
                  mojo_base.mojom.Time end_time,
                  ClearDataFilter? filter) => ();

  // Clears the host cache. This will affect all NetworkContexts that share the
  // same HostResolved as the NetworkContext this is called on.
  //
  // If a non-null |filter| is specified, will clear only entries for domains
  // matching the filter. Filtering by origins is not supported. If |filter| is
  // non-null, |filter.origins| must be empty.
  ClearHostCache(ClearDataFilter? filter) => ();

  // Clears all entries from the HTTP Auth cache that were added since
  // |start_time|. Supports unbounded delete using null Time value.
  ClearHttpAuthCache(mojo_base.mojom.Time start_time) => ();

  // Clears all report entries from the reporting cache. Should not be called if
  // the ENABLE_REPORTING build flag is false.
  //
  // If a non-null |filter| is specified, will clear only entries matching the
  // filter.
  ClearReportingCacheReports(ClearDataFilter? filter) => ();

  // Clears all client entries from the reporting cache. Should not be called if
  // the ENABLE_REPORTING build flag is false.
  //
  // If a non-null |filter| is specified, will clear only entries matching the
  // filter.
  ClearReportingCacheClients(ClearDataFilter? filter) => ();

  // Clears policy entries from the NetworkErrorLoggingService. Should not be
  // called if the ENABLE_REPORTING build flag is false.
  //
  // If a non-null |filter| is specified, will clear only entries matching the
  // filter.
  ClearNetworkErrorLogging(ClearDataFilter? filter) => ();

  // Mirror of domain_reliability::DomainReliabilityClearMode.
  enum DomainReliabilityClearMode {CLEAR_CONTEXTS, CLEAR_BEACONS};
  // Clears Domain Reliability entries, specified by |mode|.
  ClearDomainReliability(ClearDataFilter? filter,
                         DomainReliabilityClearMode mode) => ();

  // Returns a JSON value containing data for displaying on a debugging page.
  GetDomainReliabilityJSON() => (mojo_base.mojom.Value data);

  // Queues a report via the Reporting API. |type| describes the type of report
  // (as well as what data will contained in |body|). |group| specifies the
  // endpoint group that the report will be delivered to. |url| indicates the
  // URL of the resource that the report describes; |user_agent| may be
  // provided, or will be automatically generated if omitted; |body| holds the
  // contents of the report.
  //
  // Note that this queued report will never be delivered if no reporting
  // endpoint is registered for this |url|.
  //
  // Spec: https://w3c.github.io/reporting/#concept-reports
  QueueReport(string type,
              string group,
              url.mojom.Url url,
              string? user_agent,
              mojo_base.mojom.DictionaryValue body);

  // Closes all open connections within this context.
  CloseAllConnections() => ();

  // Close all idle connections for the HTTP network session used by
  // this context.
  CloseIdleConnections() => ();

  // Configures network conditions for the specified throttling profile.
  // The throttling will be applied only to requests that have matching
  // throttling_profile_id.
  // Passing null NetworkConditions disables the throttling.
  SetNetworkConditions(mojo_base.mojom.UnguessableToken throttling_profile_id,
                       NetworkConditions? conditions);

  // Updates the Accept-Language header to be used for requests.
  SetAcceptLanguage(string new_accept_language);

  // If false, the referrer of requests is never populated.
  SetEnableReferrers(bool enable_referrers);

  // Updates the additional trust anchors for certificate verification.
  [EnableIf=is_chromeos]
  UpdateAdditionalCertificates(AdditionalCertificates? additional_certificates);

  // Updates the CT policy to be used for requests. Only applies if the
  // NetworkContextParams set enforce_chrome_ct_policy to true.
  // TODO(rsleevi): Remove this once Chrome-specific policies are moved out
  // of the network service.
  [EnableIf=is_ct_supported]
  SetCTPolicy(array<string> required_hosts,
              array<string> excluded_hosts,
              array<string> excluded_spkis,
              array<string> excluded_legacy_spkis);

  // Adds explicitly-specified data as if it was processed from an Expect-CT
  // header.
  [EnableIf=is_ct_supported]
  AddExpectCT(string host, mojo_base.mojom.Time expiry,
              bool enforce, url.mojom.Url report_uri) => (bool success);

  // Send a test CT report with dummy data for test purposes.
  [EnableIf=is_ct_supported]
  SetExpectCTTestReport(url.mojom.Url report_uri) => (bool success);

  // Retrieves the expect CT state from the associated network context
  // transport security state.
  [EnableIf=is_ct_supported]
  GetExpectCTState(string domain) => (mojo_base.mojom.DictionaryValue state);

  // Creates a UDP socket. Caller can supply a |receiver| interface pointer
  // to listen for incoming datagrams. A null |receiver| is acceptable if caller
  // is not interested in incoming data.
  // Any sockets that are created but are yet to be destroyed will be destroyed
  // when NetworkContext goes away.
  CreateUDPSocket(UDPSocket& request, UDPSocketReceiver? receiver);

  // Creates a TCP server socket that listens on |local_addr|. The socket
  // created can only be used for the purpose specified in |traffic_annotation|,
  // and cannot be re-used for other purposes. Caller must specify an address
  // family in |local_addr| to be either IPv4 or IPv6. If port in |local_addr|
  // is 0, the OS will pick an available port. If address bytes are 0, the OS
  // will pick a local address of the specified address family. |backlog| will
  // be passed to the OS to set the size of accept queue.
  // On success, the resulting local address will be written to |local_addr_out|
  // and |result| is net::OK. On failure, |result| is a network error code.
  //
  // Any sockets that are created but are yet to be destroyed will be destroyed
  // when NetworkContext goes away.
  CreateTCPServerSocket(IPEndPoint local_addr,
                        uint32 backlog,
                        MutableNetworkTrafficAnnotationTag traffic_annotation,
                        TCPServerSocket& socket)
      => (int32 result, IPEndPoint? local_addr_out);

  // Creates a TCP socket connected to |remote_addr|. |observer| if non-null
  // will be used to listen for any network connection error on the newly
  // established connection. The socket created can only be used for the purpose
  // specified in |traffic_annotation|, and cannot be re-used for other
  // purposes. |local_addr| should be set to null unless the caller wants to
  // bind the socket to a specific address and port. On success, |result| is
  // net::OK. Caller is to use |send_stream| to send data and |receive_stream|
  // to receive data over the connection. On failure, |result| is a network
  // error code.
  //
  // If the client closes |socket| before this completes, the callback will be
  // invoked with net::ERR_ABORTED.
  //
  // Any sockets that are created but are yet to be destroyed will be destroyed
  // when NetworkContext goes away.
  CreateTCPConnectedSocket(
      IPEndPoint? local_addr,
      AddressList remote_addr_list,
      TCPConnectedSocketOptions? tcp_connected_socket_options,
      MutableNetworkTrafficAnnotationTag traffic_annotation,
      TCPConnectedSocket& socket,
      SocketObserver? observer)
      => (int32 result,
          IPEndPoint? local_addr,
          IPEndPoint? peer_addr,
          handle<data_pipe_consumer>? receive_stream,
          handle<data_pipe_producer>? send_stream);

  // Creates a TCPSocket bound to |local_addr|. The socket created can only be
  // used for the purpose specified in |traffic_annotation|, and cannot be
  // re-used for other purposes. |local_addr| is treated the same as in
  // CreateTCPServerSocket().
  //
  // On success, the resulting local address will be written to |local_addr_out|
  // and |result| is net::OK. On failure, |result| is a network error code.
  //
  // It's recommended consumers use CreateTCPServerSocket() or
  // CreateTCPConnectedSocket(). This method is just provided so legacy
  // consumers can mimic Berkeley sockets semantics.
  CreateTCPBoundSocket(IPEndPoint local_addr,
                       MutableNetworkTrafficAnnotationTag traffic_annotation,
                       TCPBoundSocket& socket)
      => (int32 result, IPEndPoint? local_addr);

  // Creates a ProxyResolvingSocketFactory that shares some configuration params
  // with this NetworkContext, but uses separate socket pools.
  //
  // Any sockets that are created but are yet to be destroyed will be destroyed
  // when NetworkContext goes away.
  CreateProxyResolvingSocketFactory(ProxyResolvingSocketFactory& factory);

  // Looks up what proxy to use for a particular URL.
  LookUpProxyForURL(url.mojom.Url url,
                    ProxyLookupClient proxy_lookup_client);

  // Forces refetching the proxy configuration, and applying it.
  ForceReloadProxyConfig() => ();

  // Clears the list of bad proxy servers that has been cached.
  ClearBadProxiesCache() => ();

  // Creates a WebSocket connection.
  CreateWebSocket(WebSocket& request,
                  int32 process_id,
                  int32 render_frame_id,
                  url.mojom.Origin origin,
                  AuthenticationHandler? auth_handler);

  // Create a NetLogExporter, which helps export NetLog to an existing file.
  // Note that the log is generally global, including all NetworkContexts
  // managed by the same NetworkService. The particular NetworkContext this is
  // called on will determine which NetworkContext gets its information and
  // configuration summary written out at the end of the log.
  CreateNetLogExporter(NetLogExporter& exporter);

  // Tries to preconnect to |url|. |num_streams| may be used to request more
  // than one connection be established in parallel.
  // |load_flags| is passed into the HttpRequestInfo used to make the request.
  // See |load_flags.h| for possible values.
  // |privacy_mode_enabled| is also passed into the HttpRequestInfo class: if
  // it is true, then the request must be sent over a connection that cannot be
  // tracked by the server (e.g. without channel id).
  PreconnectSockets(uint32 num_streams,
                    url.mojom.Url url,
                    int32 load_flags,
                    bool privacy_mode_enabled);

  // Creates a P2PSocketManager instance, used for WebRTC.
  CreateP2PSocketManager(P2PTrustedSocketManagerClient client,
                         P2PTrustedSocketManager& trusted_socket_manager,
                         P2PSocketManager& socket_manager);

  // Creates an MdnsResponder instance.
  CreateMdnsResponder(MdnsResponder& responder_request);

  // Resolves the given hostname (or IP address literal). See documentation at
  // HostResolver::ResolveHost.
  //
  // All outstanding requests are cancelled if the NetworkContext is destroyed.
  // Such requests will receive ERR_FAILED via |response_client|.
  //
  // TODO(crbug.com/821021): Consider deleting this if most/all usage goes
  // through CreateHostResolver, but most likely most usage except proxy
  // resolver will directly use this method.
  ResolveHost(HostPortPair host,
              ResolveHostParameters? optional_parameters,
              ResolveHostClient response_client);

  // Creates a HostResolver interface that can be passed to code/processes
  // without direct access to NetworkContext to make ResolveHost requests.
  //
  // If set, |config_overrides| will override configuration read from the system
  // DNS configuration when resolution is performed using the built-in resolver
  // (which can be forced using ResolveHostParameters::source = Source.DNS).
  //
  // If this NetworkContext is destroyed, all outstanding requests from child
  // HostResolvers will be cancelled. Such requests will receive ERR_FAILED via
  // |response_client|.
  //
  // TODO(crbug.com/821021): If necessary as usage and functionality is added to
  // the contained ResolveHost method, consider adding the ability for this to
  // be a restricted resolver with some functionality disabled (eg maybe MDNS).
  CreateHostResolver(DnsConfigOverrides? config_overrides,
                     HostResolver& host_resolver);

  // Checks the given certificate against the CertVerifier and CTVerifier. This
  // implementation is currently specific for use by Signed Exchange.
  VerifyCertForSignedExchange(X509Certificate certificate,
                              url.mojom.Url url,
                              string ocsp_response,
                              string sct_list) => (int32 error_code,
                                                   CertVerifyResult cv_result,
                                                   CTVerifyResult ct_result);

  // Adds explicitly-specified data as if it was processed from an
  // HSTS header. Used by tests and implementation of chrome://net-internals.
  AddHSTS(string host, mojo_base.mojom.Time expiry,
          bool include_subdomains) => ();

  // Returns true if it is known that |host| has requested to always be
  // accessed via HTTPS.
  IsHSTSActiveForHost(string host) => (bool result);

  // Retrieve values from the HSTS state from the associated contexts
  // transport security state.
  GetHSTSState(string domain) => (mojo_base.mojom.DictionaryValue state);

  // Sets allowed and blocked origins respectively for the URLLoaderFactory
  // consumers to access beyond the same-origin policy. The list is managed per
  // each |source_origin|, and each call will flash old set lists for the
  // |source_origin|. The passed |patterns| will be set instead. If an empty
  // array is given for |allow_patterns| and/or |block_patterns|, the
  // |source_origin|'s origin list for each is set to empty respectively.
  SetCorsOriginAccessListsForOrigin(
      url.mojom.Origin source_origin, array<CorsOriginPattern> allow_patterns,
      array<CorsOriginPattern> block_patterns) => ();

  // Deletes any dynamic data stored for |host| from the transport
  // security state. Returns true iff an entry was deleted.
  // See net::TransportSecurityState::DeleteDynamicDataForHost for more detail.
  DeleteDynamicDataForHost(string host) => (bool result);

  // Copies the contents of this NetworkContext's HttpAuthCache and returns a
  // key that can be used by LoadHttpAuthCache to restore the contents.
  // The data referenced by the returned key is not associated with this
  // NetworkContext, and can be loaded by any NetworkContext.
  // If there is no corresponding LoadHttpAuthCache call, the saved
  // HttpAuthCache data will leak.
  //
  // TODO(crbug.com/914082): Return a scoped handle that can automatically free
  // the cache when it goes out of scope.
  SaveHttpAuthCache() => (mojo_base.mojom.UnguessableToken cache_key);

  // Loads an HttpAuthCache previously saved by SaveHttpAuthCache, and
  // copies its contents into this NetworkContext's HttpAuthCache.
  LoadHttpAuthCache(mojo_base.mojom.UnguessableToken cache_key) => ();

  // Looks up credentials in the HttpAuthCache using the origin and path from
  // |url|. Only supports basic auth scheme.
  LookupBasicAuthCredentials(url.mojom.Url url)
      => (AuthCredentials? credentials);

  [Sync]
  // Enables the checking of static PKP records.
  EnableStaticKeyPinningForTesting() => ();

  [Sync]
  // Will force the transaction to fail with the given error code.
  SetFailingHttpTransactionForTesting(int32 rv) => ();

  [Sync]
  // Verifies the given certificate using the context's CertVerifier.
  VerifyCertificateForTesting(X509Certificate certificate,
                              string hostname,
                              string ocsp_response) => (int32 error_code);

  [Sync]
  // Adds a Domain Reliability Context.
  AddDomainReliabilityContextForTesting(
    url.mojom.Url origin, url.mojom.Url upload_url) => ();

  [Sync]
  // Forces all pending Domain Reliability uploads to run now, even if their
  // minimum delay has not yet passed.
  ForceDomainReliabilityUploadsForTesting() => ();
};
