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

#ifndef NET_URL_REQUEST_URL_REQUEST_H_
#define NET_URL_REQUEST_URL_REQUEST_H_

#include <stdint.h>

#include <memory>
#include <string>
#include <vector>

#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_piece.h"
#include "base/supports_user_data.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "base/types/pass_key.h"
#include "base/values.h"
#include "net/base/auth.h"
#include "net/base/completion_repeating_callback.h"
#include "net/base/idempotency.h"
#include "net/base/ip_endpoint.h"
#include "net/base/isolation_info.h"
#include "net/base/load_flags.h"
#include "net/base/load_states.h"
#include "net/base/load_timing_info.h"
#include "net/base/net_error_details.h"
#include "net/base/net_errors.h"
#include "net/base/net_export.h"
#include "net/base/network_delegate.h"
#include "net/base/proxy_chain.h"
#include "net/base/request_priority.h"
#include "net/base/upload_progress.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_partition_key.h"
#include "net/cookies/cookie_setting_override.h"
#include "net/cookies/site_for_cookies.h"
#include "net/dns/public/secure_dns_policy.h"
#include "net/filter/source_stream.h"
#include "net/http/http_raw_request_headers.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source.h"
#include "net/log/net_log_with_source.h"
#include "net/net_buildflags.h"
#include "net/socket/connection_attempts.h"
#include "net/socket/socket_tag.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/referrer_policy.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace net {

class CookieOptions;
class CookieInclusionStatus;
class IOBuffer;
struct LoadTimingInfo;
struct RedirectInfo;
class SSLCertRequestInfo;
class SSLInfo;
class SSLPrivateKey;
struct TransportInfo;
class UploadDataStream;
class URLRequestContext;
class URLRequestJob;
class X509Certificate;

//-----------------------------------------------------------------------------
// A class  representing the asynchronous load of a data stream from an URL.
//
// The lifetime of an instance of this class is completely controlled by the
// consumer, and the instance is not required to live on the heap or be
// allocated in any special way.  It is also valid to delete an URLRequest
// object during the handling of a callback to its delegate.  Of course, once
// the URLRequest is deleted, no further callbacks to its delegate will occur.
//
// NOTE: All usage of all instances of this class should be on the same thread.
//
class NET_EXPORT URLRequest : public base::SupportsUserData {
 public:
  // Max number of http redirects to follow. The Fetch spec says: "If
  // request's redirect count is twenty, return a network error."
  // https://fetch.spec.whatwg.org/#http-redirect-fetch
  static constexpr int kMaxRedirects = 20;

  // The delegate's methods are called from the message loop of the thread
  // on which the request's Start() method is called. See above for the
  // ordering of callbacks.
  //
  // The callbacks will be called in the following order:
  //   Start()
  //    - OnConnected* (zero or more calls, see method comment)
  //    - OnCertificateRequested* (zero or more calls, if the SSL server and/or
  //      SSL proxy requests a client certificate for authentication)
  //    - OnSSLCertificateError* (zero or one call, if the SSL server's
  //      certificate has an error)
  //    - OnReceivedRedirect* (zero or more calls, for the number of redirects)
  //    - OnAuthRequired* (zero or more calls, for the number of
  //      authentication failures)
  //    - OnResponseStarted
  //   Read() initiated by delegate
  //    - OnReadCompleted* (zero or more calls until all data is read)
  //
  // Read() must be called at least once. Read() returns bytes read when it
  // completes immediately, and a negative error value if an IO is pending or if
  // there is an error.
  class NET_EXPORT Delegate {
   public:
    // Called each time a connection is obtained, before any data is sent.
    //
    // |request| is never nullptr. Caller retains ownership.
    //
    // |info| describes the newly-obtained connection.
    //
    // This may be called several times if the request creates multiple HTTP
    // transactions, e.g. if the request is redirected. It may also be called
    // several times per transaction, e.g. if the connection is retried, after
    // each HTTP auth challenge, or for split HTTP range requests.
    //
    // If this returns an error, the transaction will stop. The transaction
    // will continue when the |callback| is run. If run with an error, the
    // transaction will fail.
    virtual int OnConnected(URLRequest* request,
                            const TransportInfo& info,
                            CompletionOnceCallback callback);

    // Called upon receiving a redirect.  The delegate may call the request's
    // Cancel method to prevent the redirect from being followed.  Since there
    // may be multiple chained redirects, there may also be more than one
    // redirect call.
    //
    // When this function is called, the request will still contain the
    // original URL, the destination of the redirect is provided in
    // |redirect_info.new_url|.  If the delegate does not cancel the request
    // and |*defer_redirect| is false, then the redirect will be followed, and
    // the request's URL will be changed to the new URL.  Otherwise if the
    // delegate does not cancel the request and |*defer_redirect| is true, then
    // the redirect will be followed once FollowDeferredRedirect is called
    // on the URLRequest.
    //
    // The caller must set |*defer_redirect| to false, so that delegates do not
    // need to set it if they are happy with the default behavior of not
    // deferring redirect.
    virtual void OnReceivedRedirect(URLRequest* request,
                                    const RedirectInfo& redirect_info,
                                    bool* defer_redirect);

    // Called when we receive an authentication failure.  The delegate should
    // call request->SetAuth() with the user's credentials once it obtains them,
    // or request->CancelAuth() to cancel the login and display the error page.
    // When it does so, the request will be reissued, restarting the sequence
    // of On* callbacks.
    //
    // NOTE: If auth_info.scheme is AUTH_SCHEME_NEGOTIATE on ChromeOS, this
    // method should not call SetAuth(). Instead, it should show ChromeOS
    // specific UI and cancel the request. (See b/260522530).
    virtual void OnAuthRequired(URLRequest* request,
                                const AuthChallengeInfo& auth_info);

    // Called when we receive an SSL CertificateRequest message for client
    // authentication.  The delegate should call
    // request->ContinueWithCertificate() with the client certificate the user
    // selected and its private key, or request->ContinueWithCertificate(NULL,
    // NULL)
    // to continue the SSL handshake without a client certificate.
    virtual void OnCertificateRequested(URLRequest* request,
                                        SSLCertRequestInfo* cert_request_info);

    // Called when using SSL and the server responds with a certificate with
    // an error, for example, whose common name does not match the common name
    // we were expecting for that host.  The delegate should either do the
    // safe thing and Cancel() the request or decide to proceed by calling
    // ContinueDespiteLastError().  cert_error is a ERR_* error code
    // indicating what's wrong with the certificate.
    // If |fatal| is true then the host in question demands a higher level
    // of security (due e.g. to HTTP Strict Transport Security, user
    // preference, or built-in policy). In this case, errors must not be
    // bypassable by the user.
    virtual void OnSSLCertificateError(URLRequest* request,
                                       int net_error,
                                       const SSLInfo& ssl_info,
                                       bool fatal);

    // After calling Start(), the delegate will receive an OnResponseStarted
    // callback when the request has completed. |net_error| will be set to OK
    // or an actual net error.  On success, all redirects have been
    // followed and the final response is beginning to arrive.  At this point,
    // meta data about the response is available, including for example HTTP
    // response headers if this is a request for a HTTP resource.
    virtual void OnResponseStarted(URLRequest* request, int net_error);

    // Called when the a Read of the response body is completed after an
    // IO_PENDING status from a Read() call.
    // The data read is filled into the buffer which the caller passed
    // to Read() previously.
    //
    // If an error occurred, |bytes_read| will be set to the error.
    virtual void OnReadCompleted(URLRequest* request, int bytes_read) = 0;

   protected:
    virtual ~Delegate() = default;
  };

  // URLRequests are always created by calling URLRequestContext::CreateRequest.
  URLRequest(base::PassKey<URLRequestContext> pass_key,
             const GURL& url,
             RequestPriority priority,
             Delegate* delegate,
             const URLRequestContext* context,
             NetworkTrafficAnnotationTag traffic_annotation,
             bool is_for_websockets,
             absl::optional<net::NetLogSource> net_log_source);

  URLRequest(const URLRequest&) = delete;
  URLRequest& operator=(const URLRequest&) = delete;

  // If destroyed after Start() has been called but while IO is pending,
  // then the request will be effectively canceled and the delegate
  // will not have any more of its methods called.
  ~URLRequest() override;

  // Changes the default cookie policy from allowing all cookies to blocking all
  // cookies. Embedders that want to implement a more flexible policy should
  // change the default to blocking all cookies, and provide a NetworkDelegate
  // with the URLRequestContext that maintains the CookieStore.
  // The cookie policy default has to be set before the first URLRequest is
  // started. Once it was set to block all cookies, it cannot be changed back.
  static void SetDefaultCookiePolicyToBlock();

  // The original url is the url used to initialize the request, and it may
  // differ from the url if the request was redirected.
  const GURL& original_url() const { return url_chain_.front(); }
  // The chain of urls traversed by this request.  If the request had no
  // redirects, this vector will contain one element.
  const std::vector<GURL>& url_chain() const { return url_chain_; }
  const GURL& url() const { return url_chain_.back(); }

  // Explicitly set the URL chain for this request.  This can be used to
  // indicate a chain of redirects that happen at a layer above the network
  // service; e.g. navigation redirects.
  //
  // Note, the last entry in the new `url_chain` will be ignored.  Instead
  // the request will preserve its current URL.  This is done since the higher
  // layer providing the explicit `url_chain` may not be aware of modifications
  // to the request URL by throttles.
  //
  // This method should only be called on new requests that have a single
  // entry in their existing `url_chain_`.
  void SetURLChain(const std::vector<GURL>& url_chain);

  // The URL that should be consulted for the third-party cookie blocking
  // policy, as defined in Section 2.1.1 and 2.1.2 of
  // https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site.
  //
  // WARNING: This URL must only be used for the third-party cookie blocking
  //          policy. It MUST NEVER be used for any kind of SECURITY check.
  //
  //          For example, if a top-level navigation is redirected, the
  //          first-party for cookies will be the URL of the first URL in the
  //          redirect chain throughout the whole redirect. If it was used for
  //          a security check, an attacker might try to get around this check
  //          by starting from some page that redirects to the
  //          host-to-be-attacked.
  //
  const SiteForCookies& site_for_cookies() const { return site_for_cookies_; }
  // This method may only be called before Start().
  void set_site_for_cookies(const SiteForCookies& site_for_cookies);

  // Sets IsolationInfo for the request, which affects whether SameSite cookies
  // are sent, what NetworkAnonymizationKey is used for cached resources, and
  // how that behavior changes when following redirects. This may only be
  // changed before Start() is called.
  //
  // TODO(https://crbug.com/1060631): This isn't actually used yet for SameSite
  // cookies. Update consumers and fix that.
  void set_isolation_info(const IsolationInfo& isolation_info) {
    isolation_info_ = isolation_info;
    cookie_partition_key_ = CookiePartitionKey::FromNetworkIsolationKey(
        isolation_info.network_isolation_key());
  }

  // This will convert the passed NetworkAnonymizationKey to an IsolationInfo.
  // This IsolationInfo mmay be assigned an inaccurate frame origin because the
  // NetworkAnonymizationKey might not contain all the information to populate
  // it. Additionally the NetworkAnonymizationKey uses sites which will be
  // converted to origins when set on the IsolationInfo. If using this method it
  // is required to skip the cache and not use credentials. Before starting the
  // request, it must have the LoadFlag LOAD_DISABLE_CACHE set, and must be set
  // to not allow credentials, to ensure that the inaccurate frame origin has no
  // impact. The request will DCHECK otherwise.
  void set_isolation_info_from_network_anonymization_key(
      const NetworkAnonymizationKey& network_anonymization_key);

  const IsolationInfo& isolation_info() const { return isolation_info_; }

  const absl::optional<CookiePartitionKey>& cookie_partition_key() const {
    return cookie_partition_key_;
  }

  // Indicate whether SameSite cookies should be attached even though the
  // request is cross-site.
  bool force_ignore_site_for_cookies() const {
    return force_ignore_site_for_cookies_;
  }
  void set_force_ignore_site_for_cookies(bool attach) {
    force_ignore_site_for_cookies_ = attach;
  }

  // Indicates if the request should be treated as a main frame navigation for
  // SameSite cookie computations.  This flag overrides the IsolationInfo
  // request type associated with fetches from a service worker context.
  bool force_main_frame_for_same_site_cookies() const {
    return force_main_frame_for_same_site_cookies_;
  }
  void set_force_main_frame_for_same_site_cookies(bool value) {
    force_main_frame_for_same_site_cookies_ = value;
  }

  // Overrides pertaining to cookie settings for this particular request.
  CookieSettingOverrides& cookie_setting_overrides() {
    return cookie_setting_overrides_;
  }
  const CookieSettingOverrides& cookie_setting_overrides() const {
    return cookie_setting_overrides_;
  }

  // The first-party URL policy to apply when updating the first party URL
  // during redirects. The first-party URL policy may only be changed before
  // Start() is called.
  RedirectInfo::FirstPartyURLPolicy first_party_url_policy() const {
    return first_party_url_policy_;
  }
  void set_first_party_url_policy(
      RedirectInfo::FirstPartyURLPolicy first_party_url_policy);

  // The origin of the context which initiated the request. This is distinct
  // from the "first party for cookies" discussed above in a number of ways:
  //
  // 1. The request's initiator does not change during a redirect. If a form
  //    submission from `https://example.com/` redirects through a number of
  //    sites before landing on `https://not-example.com/`, the initiator for
  //    each of those requests will be `https://example.com/`.
  //
  // 2. The request's initiator is the origin of the frame or worker which made
  //    the request, even for top-level navigations. That is, if
  //    `https://example.com/`'s form submission is made in the top-level frame,
  //    the first party for cookies would be the target URL's origin. The
  //    initiator remains `https://example.com/`.
  //
  // This value is used to perform the cross-origin check specified in Section
  // 4.3 of https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site.
  //
  // Note: the initiator can be null for browser-initiated top level
  // navigations. This is different from a unique Origin (e.g. in sandboxed
  // iframes).
  const absl::optional<url::Origin>& initiator() const { return initiator_; }
  // This method may only be called before Start().
  void set_initiator(const absl::optional<url::Origin>& initiator);

  // The request method.  "GET" is the default value. The request method may
  // only be changed before Start() is called. Request methods are
  // case-sensitive, so standard HTTP methods like GET or POST should be
  // specified in uppercase.
  const std::string& method() const { return method_; }
  void set_method(base::StringPiece method);

#if BUILDFLAG(ENABLE_REPORTING)
  // Reporting upload nesting depth of this request.
  //
  // If the request is not a Reporting upload, the depth is 0.
  //
  // If the request is a Reporting upload, the depth is the max of the depth
  // of the requests reported within it plus 1. (Non-NEL reports are
  // considered to have depth 0.)
  int reporting_upload_depth() const { return reporting_upload_depth_; }
  void set_reporting_upload_depth(int reporting_upload_depth);
#endif

  // The referrer URL for the request
  const std::string& referrer() const { return referrer_; }
  // Sets the referrer URL for the request. Can only be changed before Start()
  // is called. |referrer| is sanitized to remove URL fragment, user name and
  // password. If a referrer policy is set via set_referrer_policy(), then
  // |referrer| should obey the policy; if it doesn't, it will be cleared when
  // the request is started. The referrer URL may be suppressed or changed
  // during the course of the request, for example because of a referrer policy
  // set with set_referrer_policy().
  void SetReferrer(base::StringPiece referrer);

  // The referrer policy to apply when updating the referrer during redirects.
  // The referrer policy may only be changed before Start() is called. Any
  // referrer set via SetReferrer() is expected to obey the policy set via
  // set_referrer_policy(); otherwise the referrer will be cleared when the
  // request is started.
  ReferrerPolicy referrer_policy() const { return referrer_policy_; }
  void set_referrer_policy(ReferrerPolicy referrer_policy);

  // Sets whether credentials are allowed.
  // If credentials are allowed, the request will send and save HTTP
  // cookies, as well as authentication to the origin server. If not,
  // they will not be sent, however proxy-level authentication will
  // still occur. Setting this will force the LOAD_DO_NOT_SAVE_COOKIES field to
  // be set in |load_flags_|. See https://crbug.com/799935.
  void set_allow_credentials(bool allow_credentials);
  bool allow_credentials() const { return allow_credentials_; }

  // Sets the upload data.
  void set_upload(std::unique_ptr<UploadDataStream> upload);

  // Gets the upload data.
  const UploadDataStream* get_upload_for_testing() const;

  // Returns true if the request has a non-empty message body to upload.
  bool has_upload() const;

  // Set or remove a extra request header.  These methods may only be called
  // before Start() is called, or between receiving a redirect and trying to
  // follow it.
  void SetExtraRequestHeaderByName(base::StringPiece name,
                                   base::StringPiece value,
                                   bool overwrite);
  void RemoveRequestHeaderByName(base::StringPiece name);

  // Sets all extra request headers.  Any extra request headers set by other
  // methods are overwritten by this method.  This method may only be called
  // before Start() is called.  It is an error to call it later.
  void SetExtraRequestHeaders(const HttpRequestHeaders& headers);

  const HttpRequestHeaders& extra_request_headers() const {
    return extra_request_headers_;
  }

  // Gets the total amount of data received from network after SSL decoding and
  // proxy handling. Pertains only to the last URLRequestJob issued by this
  // URLRequest, i.e. reset on redirects, but not reset when multiple roundtrips
  // are used for range requests or auth.
  int64_t GetTotalReceivedBytes() const;

  // Gets the total amount of data sent over the network before SSL encoding and
  // proxy handling. Pertains only to the last URLRequestJob issued by this
  // URLRequest, i.e. reset on redirects, but not reset when multiple roundtrips
  // are used for range requests or auth.
  int64_t GetTotalSentBytes() const;

  // The size of the response body before removing any content encodings.
  // Does not include redirects or sub-requests issued at lower levels (range
  // requests or auth). Only includes bytes which have been read so far,
  // including bytes from the cache.
  int64_t GetRawBodyBytes() const;

  // Returns the current load state for the request. The returned value's
  // |param| field is an optional parameter describing details related to the
  // load state. Not all load states have a parameter.
  LoadStateWithParam GetLoadState() const;

  // Returns a partial representation of the request's state as a value, for
  // debugging.
  base::Value::Dict GetStateAsValue() const;

  // Logs information about the what external object currently blocking the
  // request.  LogUnblocked must be called before resuming the request.  This
  // can be called multiple times in a row either with or without calling
  // LogUnblocked between calls.  |blocked_by| must not be empty.
  void LogBlockedBy(base::StringPiece blocked_by);

  // Just like LogBlockedBy, but also makes GetLoadState return source as the
  // |param| in the value returned by GetLoadState.  Calling LogUnblocked or
  // LogBlockedBy will clear the load param.  |blocked_by| must not be empty.
  void LogAndReportBlockedBy(base::StringPiece blocked_by);

  // Logs that the request is no longer blocked by the last caller to
  // LogBlockedBy.
  void LogUnblocked();

  // Returns the current upload progress in bytes. When the upload data is
  // chunked, size is set to zero, but position will not be.
  UploadProgress GetUploadProgress() const;

  // Get response header(s) by name.  This method may only be called
  // once the delegate's OnResponseStarted method has been called.  Headers
  // that appear more than once in the response are coalesced, with values
  // separated by commas (per RFC 2616). This will not work with cookies since
  // comma can be used in cookie values.
  void GetResponseHeaderByName(base::StringPiece name,
                               std::string* value) const;

  // The time when |this| was constructed.
  base::TimeTicks creation_time() const { return creation_time_; }

  // The time at which the returned response was requested.  For cached
  // responses, this is the last time the cache entry was validated.
  const base::Time& request_time() const { return response_info_.request_time; }

  // The time at which the returned response was generated.  For cached
  // responses, this is the last time the cache entry was validated.
  const base::Time& response_time() const {
    return response_info_.response_time;
  }

  // Indicate if this response was fetched from disk cache.
  bool was_cached() const { return response_info_.was_cached; }

  // Returns true if the URLRequest was delivered over SPDY.
  bool was_fetched_via_spdy() const {
    return response_info_.was_fetched_via_spdy;
  }

  // Returns the host and port that the content was fetched from.  See
  // http_response_info.h for caveats relating to cached content.
  IPEndPoint GetResponseRemoteEndpoint() const;

  // Get all response headers, as a HttpResponseHeaders object.  See comments
  // in HttpResponseHeaders class as to the format of the data.
  HttpResponseHeaders* response_headers() const;

  // Get the SSL connection info.
  const SSLInfo& ssl_info() const { return response_info_.ssl_info; }

  const absl::optional<AuthChallengeInfo>& auth_challenge_info() const;

  // Gets timing information related to the request.  Events that have not yet
  // occurred are left uninitialized.  After a second request starts, due to
  // a redirect or authentication, values will be reset.
  //
  // LoadTimingInfo only contains ConnectTiming information and socket IDs for
  // non-cached HTTP responses.
  void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;

  // Gets the networkd error details of the most recent origin that the network
  // stack makes the request to.
  void PopulateNetErrorDetails(NetErrorDetails* details) const;

  // Gets the remote endpoint of the most recent socket that the network stack
  // used to make this request.
  //
  // Note that GetResponseRemoteEndpoint returns the |socket_address| field from
  // HttpResponseInfo, which is only populated once the response headers are
  // received, and can return cached values for cache revalidation requests.
  // GetTransactionRemoteEndpoint will only return addresses from the current
  // request.
  //
  // Returns true and fills in |endpoint| if the endpoint is available; returns
  // false and leaves |endpoint| unchanged if it is unavailable.
  bool GetTransactionRemoteEndpoint(IPEndPoint* endpoint) const;

  // Get the mime type.  This method may only be called once the delegate's
  // OnResponseStarted method has been called.
  void GetMimeType(std::string* mime_type) const;

  // Get the charset (character encoding).  This method may only be called once
  // the delegate's OnResponseStarted method has been called.
  void GetCharset(std::string* charset) const;

  // Returns the HTTP response code (e.g., 200, 404, and so on).  This method
  // may only be called once the delegate's OnResponseStarted method has been
  // called.  For non-HTTP requests, this method returns -1.
  int GetResponseCode() const;

  // Get the HTTP response info in its entirety.
  const HttpResponseInfo& response_info() const { return response_info_; }

  // Access the LOAD_* flags modifying this request (see load_flags.h).
  int load_flags() const { return load_flags_; }

  bool is_created_from_network_anonymization_key() const {
    return is_created_from_network_anonymization_key_;
  }

  // Returns the Secure DNS Policy for the request.
  SecureDnsPolicy secure_dns_policy() const { return secure_dns_policy_; }

  void set_maybe_sent_cookies(CookieAccessResultList cookies);
  void set_maybe_stored_cookies(CookieAndLineAccessResultList cookies);

  // These lists contain a list of cookies that are associated with the given
  // request, both those that were sent and accepted, and those that were
  // removed or flagged from the request before use. The status indicates
  // whether they were actually used (INCLUDE), or the reason they were removed
  // or flagged. They are cleared on redirects and other request restarts that
  // cause sent cookies to be recomputed / new cookies to potentially be
  // received (such as calling SetAuth() to send HTTP auth credentials, but not
  // calling ContinueWithCertification() to respond to client cert challenges),
  // and only contain the cookies relevant to the most recent roundtrip.

  // Populated while the http request is being built.
  const CookieAccessResultList& maybe_sent_cookies() const {
    return maybe_sent_cookies_;
  }
  // Populated after the response headers are received.
  const CookieAndLineAccessResultList& maybe_stored_cookies() const {
    return maybe_stored_cookies_;
  }

  // The new flags may change the IGNORE_LIMITS flag only when called
  // before Start() is called, it must only set the flag, and if set,
  // the priority of this request must already be MAXIMUM_PRIORITY.
  void SetLoadFlags(int flags);

  // Controls the Secure DNS behavior to use when creating the socket for this
  // request.
  void SetSecureDnsPolicy(SecureDnsPolicy secure_dns_policy);

  // Returns true if the request is "pending" (i.e., if Start() has been called,
  // and the response has not yet been called).
  bool is_pending() const { return is_pending_; }

  // Returns true if the request is in the process of redirecting to a new
  // URL but has not yet initiated the new request.
  bool is_redirecting() const { return is_redirecting_; }

  // This method is called to start the request.  The delegate will receive
  // a OnResponseStarted callback when the request is started.  The request
  // must have a delegate set before this method is called.
  void Start();

  // This method may be called at any time after Start() has been called to
  // cancel the request.  This method may be called many times, and it has
  // no effect once the response has completed.  It is guaranteed that no
  // methods of the delegate will be called after the request has been
  // cancelled, except that this may call the delegate's OnReadCompleted()
  // during the call to Cancel itself. Returns |ERR_ABORTED| or other net error
  // if there was one.
  int Cancel();

  // Cancels the request and sets the error to |error|, unless the request
  // already failed with another error code (see net_error_list.h). Returns
  // final network error code.
  int CancelWithError(int error);

  // Cancels the request and sets the error to |error| (see net_error_list.h
  // for values) and attaches |ssl_info| as the SSLInfo for that request.  This
  // is useful to attach a certificate and certificate error to a canceled
  // request.
  void CancelWithSSLError(int error, const SSLInfo& ssl_info);

  // Read initiates an asynchronous read from the response, and must only be
  // called after the OnResponseStarted callback is received with a net::OK. If
  // data is available, length and the data will be returned immediately. If the
  // request has failed, an error code will be returned. If data is not yet
  // available, Read returns net::ERR_IO_PENDING, and the Delegate's
  // OnReadComplete method will be called asynchronously with the result of the
  // read, unless the URLRequest is canceled.
  //
  // The |buf| parameter is a buffer to receive the data. If the operation
  // completes asynchronously, the implementation will reference the buffer
  // until OnReadComplete is called. The buffer must be at least |max_bytes| in
  // length.
  //
  // The |max_bytes| parameter is the maximum number of bytes to read.
  int Read(IOBuffer* buf, int max_bytes);

  // This method may be called to follow a redirect that was deferred in
  // response to an OnReceivedRedirect call. If non-null,
  // |modified_headers| are changes applied to the request headers after
  // updating them for the redirect.
  void FollowDeferredRedirect(
      const absl::optional<std::vector<std::string>>& removed_headers,
      const absl::optional<net::HttpRequestHeaders>& modified_headers);

  // One of the following two methods should be called in response to an
  // OnAuthRequired() callback (and only then).
  // SetAuth will reissue the request with the given credentials.
  // CancelAuth will give up and display the error page.
  void SetAuth(const AuthCredentials& credentials);
  void CancelAuth();

  // This method can be called after the user selects a client certificate to
  // instruct this URLRequest to continue with the request with the
  // certificate.  Pass NULL if the user doesn't have a client certificate.
  void ContinueWithCertificate(scoped_refptr<X509Certificate> client_cert,
                               scoped_refptr<SSLPrivateKey> client_private_key);

  // This method can be called after some error notifications to instruct this
  // URLRequest to ignore the current error and continue with the request.  To
  // cancel the request instead, call Cancel().
  void ContinueDespiteLastError();

  // Aborts the request (without invoking any completion callbacks) and closes
  // the current connection, rather than returning it to the socket pool. Only
  // affects HTTP/1.1 connections and tunnels.
  //
  // Intended to be used in cases where socket reuse can potentially leak data
  // across sites.
  //
  // May only be called after Delegate::OnResponseStarted() has been invoked
  // with net::OK, but before the body has been completely read. After the last
  // body has been read, the socket may have already been handed off to another
  // consumer.
  //
  // Due to transactions potentially being shared by multiple URLRequests in
  // some cases, it is possible the socket may not be immediately closed, but
  // will instead be closed when all URLRequests sharing the socket have been
  // destroyed.
  void AbortAndCloseConnection();

  // Used to specify the context (cookie store, cache) for this request.
  const URLRequestContext* context() const;

  // Returns context()->network_delegate().
  NetworkDelegate* network_delegate() const;

  const NetLogWithSource& net_log() const { return net_log_; }

  // Returns the expected content size if available
  int64_t GetExpectedContentSize() const;

  // Returns the priority level for this request.
  RequestPriority priority() const { return priority_; }

  // Returns the incremental loading priority flag for this request.
  bool priority_incremental() const { return priority_incremental_; }

  // Sets the priority level for this request and any related
  // jobs. Must not change the priority to anything other than
  // MAXIMUM_PRIORITY if the IGNORE_LIMITS load flag is set.
  void SetPriority(RequestPriority priority);

  // Sets the incremental priority flag for this request.
  void SetPriorityIncremental(bool priority_incremental);

  void set_received_response_content_length(int64_t received_content_length) {
    received_response_content_length_ = received_content_length;
  }

  // The number of bytes in the raw response body (before any decompression,
  // etc.). This is only available after the final Read completes.
  int64_t received_response_content_length() const {
    return received_response_content_length_;
  }

  // Available when the request headers are sent, which is before the more
  // general response_info() is available.
  const ProxyChain& proxy_chain() const { return proxy_chain_; }

  // Gets the connection attempts made in the process of servicing this
  // URLRequest. Only guaranteed to be valid if called after the request fails
  // or after the response headers are received.
  ConnectionAttempts GetConnectionAttempts() const;

  const NetworkTrafficAnnotationTag& traffic_annotation() const {
    return traffic_annotation_;
  }

  const absl::optional<base::flat_set<net::SourceStream::SourceType>>&
  accepted_stream_types() const {
    return accepted_stream_types_;
  }

  void set_accepted_stream_types(
      const absl::optional<base::flat_set<net::SourceStream::SourceType>>&
          types) {
    if (types) {
      DCHECK(!types->contains(net::SourceStream::SourceType::TYPE_NONE));
      DCHECK(!types->contains(net::SourceStream::SourceType::TYPE_UNKNOWN));
    }
    accepted_stream_types_ = types;
  }

  // Sets a callback that will be invoked each time the request is about to
  // be actually sent and will receive actual request headers that are about
  // to hit the wire, including SPDY/QUIC internal headers.
  //
  // Can only be set once before the request is started.
  void SetRequestHeadersCallback(RequestHeadersCallback callback);

  // Sets a callback that will be invoked each time the response is received
  // from the remote party with the actual response headers received. Note this
  // is different from response_headers() getter in that in case of revalidation
  // request, the latter will return cached headers, while the callback will be
  // called with a response from the server.
  void SetResponseHeadersCallback(ResponseHeadersCallback callback);

  // Sets a callback that will be invoked each time a 103 Early Hints response
  // is received from the remote party.
  void SetEarlyResponseHeadersCallback(ResponseHeadersCallback callback);

  // Set a callback that will be invoked when a matching shared dictionary is
  // available to determine whether it is allowed to use the dictionary.
  void SetIsSharedDictionaryReadAllowedCallback(
      base::RepeatingCallback<bool()> callback);

  // Sets socket tag to be applied to all sockets used to execute this request.
  // Must be set before Start() is called.  Only currently supported for HTTP
  // and HTTPS requests on Android; UID tagging requires
  // MODIFY_NETWORK_ACCOUNTING permission.
  // NOTE(pauljensen): Setting a tag disallows sharing of sockets with requests
  // with other tags, which may adversely effect performance by prohibiting
  // connection sharing. In other words use of multiplexed sockets (e.g. HTTP/2
  // and QUIC) will only be allowed if all requests have the same socket tag.
  void set_socket_tag(const SocketTag& socket_tag);
  const SocketTag& socket_tag() const { return socket_tag_; }

  // |upgrade_if_insecure| should be set to true if this request (including
  // redirects) should be upgraded to HTTPS due to an Upgrade-Insecure-Requests
  // requirement.
  void set_upgrade_if_insecure(bool upgrade_if_insecure) {
    upgrade_if_insecure_ = upgrade_if_insecure;
  }
  bool upgrade_if_insecure() const { return upgrade_if_insecure_; }

  // By default, client certs will be sent (provided via
  // Delegate::OnCertificateRequested) when cookies are disabled
  // (LOAD_DO_NOT_SEND_COOKIES / LOAD_DO_NOT_SAVE_COOKIES). As described at
  // https://crbug.com/775438, this is not the desired behavior. When
  // |send_client_certs| is set to false, this will suppress the
  // Delegate::OnCertificateRequested callback when cookies/credentials are also
  // suppressed. This method has no effect if credentials are enabled (cookies
  // saved and sent).
  // TODO(https://crbug.com/775438): Remove this when the underlying
  // issue is fixed.
  void set_send_client_certs(bool send_client_certs) {
    send_client_certs_ = send_client_certs;
  }
  bool send_client_certs() const { return send_client_certs_; }

  bool is_for_websockets() const { return is_for_websockets_; }

  void SetIdempotency(Idempotency idempotency) { idempotency_ = idempotency; }
  Idempotency GetIdempotency() const { return idempotency_; }

  void set_has_storage_access(bool has_storage_access) {
    DCHECK(!is_pending_);
    DCHECK(!has_notified_completion_);
    has_storage_access_ = has_storage_access;
  }
  bool has_storage_access() const { return has_storage_access_; }

  static bool DefaultCanUseCookies();

  base::WeakPtr<URLRequest> GetWeakPtr();

 protected:
  // Allow the URLRequestJob class to control the is_pending() flag.
  void set_is_pending(bool value) { is_pending_ = value; }

  // Setter / getter for the status of the request. Status is represented as a
  // net::Error code. See |status_|.
  int status() const { return status_; }
  void set_status(int status);

  // Returns true if the request failed or was cancelled.
  bool failed() const;

  // Returns the error status of the request.

  // Allow the URLRequestJob to redirect this request. If non-null,
  // |removed_headers| and |modified_headers| are changes
  // applied to the request headers after updating them for the redirect.
  void Redirect(
      const RedirectInfo& redirect_info,
      const absl::optional<std::vector<std::string>>& removed_headers,
      const absl::optional<net::HttpRequestHeaders>& modified_headers);

  // Called by URLRequestJob to allow interception when a redirect occurs.
  void NotifyReceivedRedirect(const RedirectInfo& redirect_info,
                              bool* defer_redirect);

 private:
  friend class URLRequestJob;

  // For testing purposes.
  // TODO(maksims): Remove this.
  friend class TestNetworkDelegate;

  // Resumes or blocks a request paused by the NetworkDelegate::OnBeforeRequest
  // handler. If |blocked| is true, the request is blocked and an error page is
  // returned indicating so. This should only be called after Start is called
  // and OnBeforeRequest returns true (signalling that the request should be
  // paused).
  void BeforeRequestComplete(int error);

  void StartJob(std::unique_ptr<URLRequestJob> job);

  // Restarting involves replacing the current job with a new one such as what
  // happens when following a HTTP redirect.
  void RestartWithJob(std::unique_ptr<URLRequestJob> job);
  void PrepareToRestart();

  // Cancels the request and set the error and ssl info for this request to the
  // passed values. Returns the error that was set.
  int DoCancel(int error, const SSLInfo& ssl_info);

  // Called by the URLRequestJob when the headers are received, before any other
  // method, to allow caching of load timing information.
  void OnHeadersComplete();

  // Notifies the network delegate that the request has been completed.
  // This does not imply a successful completion. Also a canceled request is
  // considered completed.
  void NotifyRequestCompleted();

  // Called by URLRequestJob to allow interception when the final response
  // occurs.
  void NotifyResponseStarted(int net_error);

  // These functions delegate to |delegate_|.  See URLRequest::Delegate for the
  // meaning of these functions.
  int NotifyConnected(const TransportInfo& info,
                      CompletionOnceCallback callback);
  void NotifyAuthRequired(std::unique_ptr<AuthChallengeInfo> auth_info);
  void NotifyCertificateRequested(SSLCertRequestInfo* cert_request_info);
  void NotifySSLCertificateError(int net_error,
                                 const SSLInfo& ssl_info,
                                 bool fatal);
  void NotifyReadCompleted(int bytes_read);

  // This function delegates to the NetworkDelegate if it is not nullptr.
  // Otherwise, cookies can be used unless SetDefaultCookiePolicyToBlock() has
  // been called.
  bool CanSetCookie(const net::CanonicalCookie& cookie,
                    CookieOptions* options,
                    CookieInclusionStatus* inclusion_status) const;

  // Called just before calling a delegate that may block a request. |type|
  // should be the delegate's event type,
  // e.g. NetLogEventType::NETWORK_DELEGATE_AUTH_REQUIRED.
  void OnCallToDelegate(NetLogEventType type);
  // Called when the delegate lets a request continue.  Also called on
  // cancellation. `error` is an optional error code associated with
  // completion. It's only for logging purposes, and will not directly cancel
  // the request if it's a value other than OK.
  void OnCallToDelegateComplete(int error = OK);

  // Records the referrer policy of the given request, bucketed by
  // whether the request is same-origin or not. To save computation,
  // takes this fact as a boolean parameter rather than dynamically
  // checking.
  void RecordReferrerGranularityMetrics(bool request_is_same_origin) const;

  // Creates a partial IsolationInfo with the information accessible from the
  // NetworkAnonymiationKey.
  net::IsolationInfo CreateIsolationInfoFromNetworkAnonymizationKey(
      const NetworkAnonymizationKey& network_anonymization_key);

  // Contextual information used for this request. Cannot be NULL. This contains
  // most of the dependencies which are shared between requests (disk cache,
  // cookie store, socket pool, etc.)
  raw_ptr<const URLRequestContext> context_;

  // Tracks the time spent in various load states throughout this request.
  NetLogWithSource net_log_;

  std::unique_ptr<URLRequestJob> job_;
  std::unique_ptr<UploadDataStream> upload_data_stream_;

  std::vector<GURL> url_chain_;
  SiteForCookies site_for_cookies_;

  IsolationInfo isolation_info_;
  // TODO(dylancutler): Have URLRequestHttpJob use this partition key instead of
  // keeping its own copy.
  absl::optional<CookiePartitionKey> cookie_partition_key_ = absl::nullopt;

  bool force_ignore_site_for_cookies_ = false;
  bool force_main_frame_for_same_site_cookies_ = false;
  CookieSettingOverrides cookie_setting_overrides_;

  absl::optional<url::Origin> initiator_;
  GURL delegate_redirect_url_;
  std::string method_;  // "GET", "POST", etc. Case-sensitive.
  std::string referrer_;
  ReferrerPolicy referrer_policy_ =
      ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE;
  RedirectInfo::FirstPartyURLPolicy first_party_url_policy_ =
      RedirectInfo::FirstPartyURLPolicy::NEVER_CHANGE_URL;
  HttpRequestHeaders extra_request_headers_;
  // Flags indicating the request type for the load. Expected values are LOAD_*
  // enums above.
  int load_flags_ = LOAD_NORMAL;
  // Whether the request is allowed to send credentials in general. Set by
  // caller.
  bool allow_credentials_ = true;
  // Whether the request is eligible for using storage access permission grant
  // if one exists. Only set by caller when constructed and will not change
  // during redirects.
  bool has_storage_access_ = false;
  SecureDnsPolicy secure_dns_policy_ = SecureDnsPolicy::kAllow;

  CookieAccessResultList maybe_sent_cookies_;
  CookieAndLineAccessResultList maybe_stored_cookies_;

#if BUILDFLAG(ENABLE_REPORTING)
  int reporting_upload_depth_ = 0;
#endif

  // Never access methods of the |delegate_| directly. Always use the
  // Notify... methods for this.
  raw_ptr<Delegate, DanglingUntriaged> delegate_;

  const bool is_for_websockets_;

  // Current error status of the job, as a net::Error code. When the job is
  // busy, it is ERR_IO_PENDING. When the job is idle (either completed, or
  // awaiting a call from the URLRequestDelegate before continuing the request),
  // it is OK. If the request has been cancelled without a specific error, it is
  // ERR_ABORTED. And on failure, it's the corresponding error code for that
  // error.
  //
  // |status_| may bounce between ERR_IO_PENDING and OK as a request proceeds,
  // but once an error is encountered or the request is canceled, it will take
  // the appropriate error code and never change again. If multiple failures
  // have been encountered, this will be the first error encountered.
  int status_ = OK;

  bool is_created_from_network_anonymization_key_ = false;

  // The HTTP response info, lazily initialized.
  HttpResponseInfo response_info_;

  // Tells us whether the job is outstanding. This is true from the time
  // Start() is called to the time we dispatch RequestComplete and indicates
  // whether the job is active.
  bool is_pending_ = false;

  // Indicates if the request is in the process of redirecting to a new
  // location.  It is true from the time the headers complete until a
  // new request begins.
  bool is_redirecting_ = false;

  // Number of times we're willing to redirect.  Used to guard against
  // infinite redirects.
  int redirect_limit_;

  // Cached value for use after we've orphaned the job handling the
  // first transaction in a request involving redirects.
  UploadProgress final_upload_progress_;

  // The priority level for this request.  Objects like
  // ClientSocketPool use this to determine which URLRequest to
  // allocate sockets to first.
  RequestPriority priority_;

  // The incremental flag for this request that indicates if it should be
  // loaded concurrently with other resources of the same priority for
  // protocols that support HTTP extensible priorities (RFC 9218).
  // Currently only used in HTTP/3.
  bool priority_incremental_ = kDefaultPriorityIncremental;

  // If |calling_delegate_| is true, the event type of the delegate being
  // called.
  NetLogEventType delegate_event_type_ = NetLogEventType::FAILED;

  // True if this request is currently calling a delegate, or is blocked waiting
  // for the URL request or network delegate to resume it.
  bool calling_delegate_ = false;

  // An optional parameter that provides additional information about what
  // |this| is currently being blocked by.
  std::string blocked_by_;
  bool use_blocked_by_as_load_param_ = false;

  // Safe-guard to ensure that we do not send multiple "I am completed"
  // messages to network delegate.
  // TODO(battre): Remove this. http://crbug.com/89049
  bool has_notified_completion_ = false;

  int64_t received_response_content_length_ = 0;

  base::TimeTicks creation_time_;

  // Timing information for the most recent request.  Its start times are
  // populated during Start(), and the rest are populated in OnResponseReceived.
  LoadTimingInfo load_timing_info_;

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

  // If not null, the network service will not advertise any stream types
  // (via Accept-Encoding) that are not listed. Also, it will not attempt
  // decoding any non-listed stream types.
  absl::optional<base::flat_set<net::SourceStream::SourceType>>
      accepted_stream_types_;

  const NetworkTrafficAnnotationTag traffic_annotation_;

  SocketTag socket_tag_;

  // See Set{Request|Response,EarlyResponse}HeadersCallback() above for details.
  RequestHeadersCallback request_headers_callback_;
  ResponseHeadersCallback early_response_headers_callback_;
  ResponseHeadersCallback response_headers_callback_;

  // See SetIsSharedDictionaryReadAllowedCallback() above for details.
  base::RepeatingCallback<bool()> is_shared_dictionary_read_allowed_callback_;

  bool upgrade_if_insecure_ = false;

  bool send_client_certs_ = true;

  // Idempotency of the request.
  Idempotency idempotency_ = DEFAULT_IDEMPOTENCY;

  THREAD_CHECKER(thread_checker_);

  base::WeakPtrFactory<URLRequest> weak_factory_{this};
};

}  // namespace net

#endif  // NET_URL_REQUEST_URL_REQUEST_H_
