// Copyright 2019 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/time.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "services/network/public/mojom/alternate_protocol_usage.mojom";
import "services/network/public/mojom/auth.mojom";
import "services/network/public/mojom/cors.mojom";
import "services/network/public/mojom/device_bound_sessions.mojom";
import "services/network/public/mojom/encoded_body_length.mojom";
import "services/network/public/mojom/fetch_api.mojom";
import "services/network/public/mojom/http_request_headers.mojom";
import "services/network/public/mojom/http_response_headers.mojom";
import "services/network/public/mojom/ip_address_space.mojom";
import "services/network/public/mojom/ip_endpoint.mojom";
import "services/network/public/mojom/load_timing_info.mojom";
import "services/network/public/mojom/load_timing_internal_info.mojom";
import "services/network/public/mojom/network_param.mojom";
import "services/network/public/mojom/network_types.mojom";
import "services/network/public/mojom/parsed_headers.mojom";
import "services/network/public/mojom/parsed_request_cookie.mojom";
import "services/network/public/mojom/service_worker_router_info.mojom";
import "services/network/public/mojom/source_type.mojom";
import "services/network/public/mojom/ssl_info.mojom";
import "services/network/public/mojom/unencoded_digest.mojom";
import "services/proxy_resolver/public/mojom/proxy_resolver.mojom";
import "url/mojom/url.mojom";

// Describes the navigational delivery type of the response.
// `kNavigationalPrefetch` if the response is served by Prefetch; `kDefault`
// if the response if served from a normal network request, even if the response
// of the request is resurrected from the HTTP cache.
enum NavigationDeliveryType {
  kDefault,
  kNavigationalPrefetch,
};

struct URLResponseHead {
  // The time at which the request was made that resulted in this response.
  // For cached responses, this time could be "far" in the past.
  mojo_base.mojom.Time request_time;

  // The time at which the response headers were received.  For cached
  // responses, this time could be "far" in the past.
  mojo_base.mojom.Time response_time;

  // The response_time for when the response was first received. For cached
  // and revalidated responses, this is the time when the resource was first
  // received, and is not updated after revalidation.
  mojo_base.mojom.Time original_response_time;

  // The response headers or NULL if the URL type does not support headers.
  HttpResponseHeaders? headers;

  // The mime type of the response.  This may be a derived value.
  string mime_type;

  // The character encoding of the response or none if not applicable to the
  // response's mime type.  This may be a derived value.
  string charset;

  // Content length if available. -1 if not available
  int64 content_length = -1;

  // Length of the encoded data transferred over the network. In case there is
  // no data, contains -1.
  int64 encoded_data_length = -1;

  // Length of the response body data before decompression. It is null unless
  // the body has been read to the end.
  network.mojom.EncodedBodyLength? encoded_body_length;

  // True if the request accessed the network in the process of retrieving data.
  bool network_accessed = false;

  // Detailed timing information used by the WebTiming, HAR and Developer
  // Tools.  Includes socket ID and socket reuse information.
  LoadTimingInfo load_timing;

  // Load timing internal information that is exposed only to trustworthy
  // processes. Only provided if request has `trusted_params`.
  LoadTimingInternalInfo? load_timing_internal_info;

  // Set to true if the request had devtools_request_id set and OnRawRequest
  // and OnRawResponse are called on the corresponding DevToolsObserver. This
  // allows Chrome DevTools Protocol clients to know whether they should wait
  // for the signals from OnRawRequest and OnRawResponse for this request.
  bool emitted_extra_info = false;

  // True if the response was delivered using SPDY.
  bool was_fetched_via_spdy = false;

  // True if the response was delivered over a connection that negotiated ALPN.
  bool was_alpn_negotiated = false;

  // True if response could use alternate protocol. However, browser will
  // ignore the alternate protocol when spdy is not enabled on browser side.
  bool was_alternate_protocol_available = false;

  // Information about the type of connection used to fetch this response.
  ConnectionInfo connection_info;

  // ALPN protocol negotiated with the server.
  string alpn_negotiated_protocol;

  // The reason why Chrome uses a specific transport protocol
  // for HTTP semantics.
  AlternateProtocolUsage alternate_protocol_usage;

  // Remote address of the socket which fetched this resource.
  IPEndPoint remote_endpoint;

  // The IP address space of the request client/the request's policy container.
  // https://wicg.github.io/local-network-access/#policy-container-ip-address-space
  IPAddressSpace client_address_space = IPAddressSpace.kUnknown;

  // The IP address space of the response, derived from the remote IP endpoint.
  // https://wicg.github.io/local-network-access/#response-ip-address-space
  IPAddressSpace response_address_space = IPAddressSpace.kUnknown;

  // True if the response was fetched from the cache and validated over the
  // network.
  bool is_validated = false;

  // True if the response came from cache.
  bool was_fetched_via_cache = false;

  // This field, along with `is_validated` and `was_fetched_via_cache`, are used
  // to determine the value of `PerformanceResourceTiming::deliveryType` Web
  // API. `kDefault` indicates the response is served from normal network
  // request; `kNavigationalPrefetch` indicates the response is served from a
  // prefetched URL.
  NavigationDeliveryType navigation_delivery_type = kDefault;

  // The proxy chain used for this request, if any.
  ProxyChain proxy_chain;

  // True if a service worker responded to the request. If the service worker
  // received a fetch event and did not call respondWith(), or was bypassed due
  // to absence of a fetch event handler, this is false.
  bool was_fetched_via_service_worker = false;

  // Source of a serviceworker response - CacheStorage, HttpCache, Network or
  // Unspecified (default).
  // The value can be Unspecified in some cases including:
  // 1. |was_fetched_via_service_worker| is false.
  // 2. The service worker responded with an error (response status code is 0).
  // 3. The service worker responded with a generated response, i.e.,
  // `respondWith(new Response(...))`.
  FetchResponseSource service_worker_response_source =
      FetchResponseSource.kUnspecified;

  // The URL list of the Response object the service worker passed to
  // respondWith() to create this response. For example, if the service worker
  // calls respondWith(fetch('http://example.com/a')) and http://example.com/a
  // redirects to http://example.net/b which redirects to http://example.org/c,
  // the URL list is the vector <"http://example.com/a", "http://example.net/b",
  // "http://example.org/c">. This is empty if the response was programmatically
  // generated as in respondWith(new Response()). It is also empty if a service
  // worker did not respond to the request or did not call respondWith().
  array<url.mojom.Url> url_list_via_service_worker;

  // The initial status of service worker on navigation request. This is the
  // status when `ServiceWorkerMainResourceLoader` is constructed. This is
  // similar to `evaluation_worker_status` in `service_worker_router_info`, but
  // it's set even if the ServiceWorker Static Routing API is not involved.
  ServiceWorkerStatus? initial_service_worker_status;

  // Information about ServiceWorker Static Routing API. If this field is set
  // with `matchedSourceType` field, a matching rule is found. If this field is
  // set without `matchedSource`, no matching rule is found. Otherwise, the API
  // is not used.
  ServiceWorkerRouterInfo? service_worker_router_info;

  // https://fetch.spec.whatwg.org/#concept-response-type
  FetchResponseType response_type = FetchResponseType.kDefault;

  // Pre-computed padding.  This should only be non-zero when |response_type|
  // is set to kOpaque.  Note, this is not set by network service, but will be
  // populated if the response was provided by a service worker FetchEvent
  // handler.
  int64 padding = 0;

  // The cache name of the CacheStorage from where the response is served via
  // the ServiceWorker. Empty if the response isn't from the CacheStorage.
  string cache_storage_cache_name;

  // Bitmask of status info of the SSL certificate. See cert_status_flags.h for
  // values.
  uint32 cert_status = 0;

  // Only provided if kURLLoadOptionSendSSLInfoWithResponse was specified to
  // the URLLoaderFactory::CreateLoaderAndStart option or
  // if ResourceRequest::devtools_request_id is set. When set via
  // |report_raw_headers|, the SSLInfo is not guaranteed to be fully populated
  // and may only contain certain fields of interest (namely, connection
  // parameters and certificate information).
  SSLInfo? ssl_info;

  // Only provided if `include_request_cookies_with_response` was true in the
  // request's `trusted_params` (and the loader is trusted). May include
  // cookies added by the loader.
  array<ParsedRequestCookie> request_cookies;

  // In case this is a CORS response fetched by a ServiceWorker, this is the
  // set of headers that should be exposed.
  array<string> cors_exposed_header_names;

  // True if service worker navigation preload was performed due to the request
  // for this response.
  bool did_service_worker_navigation_preload = false;

  // True if this resource is stale and needs async revalidation. Will only
  // possibly be set if the load_flags indicated SUPPORT_ASYNC_REVALIDATION.
  bool async_revalidation_requested = false;

  // True if mime sniffing has been done. In that case, we don't need to do
  // mime sniffing anymore.
  bool did_mime_sniff = false;

  // True if the response is an inner response of a signed exchange.
  bool is_signed_exchange_inner_response = false;

  // True if the response is an inner response of a WebBundle.
  bool is_web_bundle_inner_response = false;

  // True if this resource is served from the prefetch cache.
  bool was_in_prefetch_cache = false;

  // True if this resource is served from the prefetch cache, and its success
  // may have been influenced by cross-site state. Such responses may require
  // special handling to make it harder to detect that this has happened.
  bool is_prefetch_with_cross_site_contamination = false;

  // True if the request included a cookie.
  bool was_cookie_in_request = false;

  // True if the response was intercepted by a plugin.
  bool intercepted_by_plugin = false;

  // https://fetch.spec.whatwg.org/#concept-response-range-requested-flag
  bool has_range_requested = false;

  // https://fetch.spec.whatwg.org/#concept-response-timing-allow-passed
  bool timing_allow_passed = false;

  // If the request received an authentication challenge, the challenge info is
  // recorded here.
  AuthChallengeInfo? auth_challenge_info;

  // TimeTicks::Now() when the browser received the request from the renderer.
  mojo_base.mojom.TimeTicks request_start;

  // TimeTicks::Now() when the browser sent the response to the renderer.
  mojo_base.mojom.TimeTicks response_start;

  // A set of security related parsed headers. This is for clients that should
  // not do the parsing themselves, because they aren't sandboxed (e.g. the
  // browser process). This is the output of network::PopulateParsedHeaders().
  //
  // This can be null. It means the URLLoader didn't parsed the headers. Either
  // it wasn't implemented or not allowed from its process.
  ParsedHeaders? parsed_headers;

  // Set by the browser process on cross-origin prefetch responses. This token
  // is propagated to the renderer and set on recursive prefetch requests
  // (see corresponding documentation in url_loader.mojom).
  mojo_base.mojom.UnguessableToken? recursive_prefetch_token;

  // Aliases, if any, for the destination URL, as read from DNS CNAME records.
  // Includes all known aliases, e.g. from A, AAAA, or HTTPS, not just from the
  // address used for the connection, in no particular order.
  array<string> dns_aliases;

  // True when there is an "authorization" header on the request and it is
  // covered by the wildcard in the preflight response.
  // TODO(crbug.com/40168475): Remove this once the investigation is done.
  bool has_authorization_covered_by_wildcard_on_preflight = false;

  // [spec] https://fetch.spec.whatwg.org/#response-request-includes-credentials
  // The request's |includeCredentials| value from the "HTTP-network fetch"
  // algorithm.
  // See: https://fetch.spec.whatwg.org/#concept-http-network-fetch
  bool request_include_credentials = true;

  // If this response contains JavaScript, then downstream components may cache
  // the parsed bytecode, but must use a source hash comparison rather than the
  // response time when determining whether the current version of the script
  // matches the cached bytecode.
  bool should_use_source_hash_for_js_code_cache = false;

  // True if the request included an available compression dictionary.
  bool did_send_available_dictionary = false;

  // True if the response used a shared dictionary for decoding its body.
  bool did_use_shared_dictionary = false;

  // True if this request used the pervasive/unpartitioned cache-key scope.
  bool is_shared_resource = false;

  // True if the client should load the response content after setting the
  // environment's `has storage access` bit.
  bool load_with_storage_access = false;

  // List of content decoding algorithms to attempt. The client needs to decode
  // the response body using these algorithms, in the reverse order.
  // This is only non-empty if `client_side_content_decoding_enabled` was set to
  // true on the request.
  array<SourceType> client_side_content_decoding_types;

  // Whether the request is in the scope of a device bound session.
  DeviceBoundSessionUsage device_bound_session_usage =
      DeviceBoundSessionUsage.kUnknown;

  // True if the synthetic response is used. This indicates the response headers
  // are returned with the locally storead headers. See crbug.com/352578800.
  bool from_synthetic_response = false;

  // The parsed value of the Unencoded-Digest header, if present.
  UnencodedDigests? unencoded_digests;

  // True if HTTP authentication was used to fetch this response. This will not
  // be set for proxy auth.
  bool did_use_server_http_auth = false;

  // True if Sec-Private-Verification-Token was removed because cookies were
  // included.
  bool pvt_token_removed_due_to_cookies = false;
};
