// Copyright (c) 2012 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.

#ifndef NET_HTTP_HTTP_STREAM_FACTORY_JOB_H_
#define NET_HTTP_HTTP_STREAM_FACTORY_JOB_H_

#include <memory>
#include <utility>

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "net/base/completion_repeating_callback.h"
#include "net/base/net_export.h"
#include "net/base/proxy_server.h"
#include "net/base/request_priority.h"
#include "net/http/bidirectional_stream_impl.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_controller.h"
#include "net/http/http_request_info.h"
#include "net/http/http_stream_factory.h"
#include "net/http/http_stream_request.h"
#include "net/log/net_log_with_source.h"
#include "net/proxy_resolution/proxy_resolution_service.h"
#if !defined(QUIC_DISABLED_FOR_STARBOARD)
#include "net/quic/quic_stream_factory.h"
#endif
#include "net/socket/client_socket_handle.h"
#include "net/socket/client_socket_pool_manager.h"
#include "net/socket/next_proto.h"
#include "net/socket/ssl_client_socket.h"
#include "net/spdy/spdy_session_key.h"
#include "net/ssl/ssl_config_service.h"

namespace net {

namespace test {

class HttpStreamFactoryJobPeer;

}  // namespace test

class ClientSocketHandle;
class HttpAuthController;
class HttpNetworkSession;
class HttpStream;
class SpdySessionPool;
class NetLog;
struct SSLConfig;

// An HttpStreamRequest exists for each stream which is in progress of being
// created for the HttpStreamFactory.
class HttpStreamFactory::Job {
 public:
  // For jobs issued simultaneously to an HTTP/2 supported server, a delay is
  // applied to avoid unnecessary socket connection establishments.
  // https://crbug.com/718576
  static const int kHTTP2ThrottleMs = 300;

  // Delegate to report Job's status to HttpStreamRequest and HttpStreamFactory.
  class NET_EXPORT_PRIVATE Delegate {
   public:
    virtual ~Delegate() {}

    // Invoked when |job| has an HttpStream ready.
    virtual void OnStreamReady(Job* job, const SSLConfig& used_ssl_config) = 0;

    // Invoked when |job| has a BidirectionalStream ready.
    virtual void OnBidirectionalStreamImplReady(
        Job* job,
        const SSLConfig& used_ssl_config,
        const ProxyInfo& used_proxy_info) = 0;

    // Invoked when |job| has a WebSocketHandshakeStream ready.
    virtual void OnWebSocketHandshakeStreamReady(
        Job* job,
        const SSLConfig& used_ssl_config,
        const ProxyInfo& used_proxy_info,
        std::unique_ptr<WebSocketHandshakeStreamBase> stream) = 0;

    // Invoked when |job| fails to create a stream.
    virtual void OnStreamFailed(Job* job,
                                int status,
                                const SSLConfig& used_ssl_config) = 0;

    // Invoked when |job| fails on the default network.
    virtual void OnFailedOnDefaultNetwork(Job* job) = 0;

    // Invoked when |job| has a certificate error for the HttpStreamRequest.
    virtual void OnCertificateError(Job* job,
                                    int status,
                                    const SSLConfig& used_ssl_config,
                                    const SSLInfo& ssl_info) = 0;

    // Invoked when |job| has a failure of the CONNECT request through an HTTPS
    // proxy.
    virtual void OnHttpsProxyTunnelResponse(
        Job* job,
        const HttpResponseInfo& response_info,
        const SSLConfig& used_ssl_config,
        const ProxyInfo& used_proxy_info,
        std::unique_ptr<HttpStream> stream) = 0;

    // Invoked when |job| raises failure for SSL Client Auth.
    virtual void OnNeedsClientAuth(Job* job,
                                   const SSLConfig& used_ssl_config,
                                   SSLCertRequestInfo* cert_info) = 0;

    // Invoked when |job| needs proxy authentication.
    virtual void OnNeedsProxyAuth(Job* job,
                                  const HttpResponseInfo& proxy_response,
                                  const SSLConfig& used_ssl_config,
                                  const ProxyInfo& used_proxy_info,
                                  HttpAuthController* auth_controller) = 0;

    // Returns true if the connection initialization to the proxy server
    // contained in |proxy_info| can be skipped.
    virtual bool OnInitConnection(const ProxyInfo& proxy_info) = 0;

    // Invoked to notify the HttpStreamRequest and HttpStreamFactory of the
    // readiness of new SPDY session.
    virtual void OnNewSpdySessionReady(
        Job* job,
        const base::WeakPtr<SpdySession>& spdy_session) = 0;

    // Invoked when the |job| finishes pre-connecting sockets.
    virtual void OnPreconnectsComplete(Job* job) = 0;

    // Invoked to record connection attempts made by the socket layer to
    // HttpStreamRequest if |job| is associated with HttpStreamRequest.
    virtual void AddConnectionAttemptsToRequest(
        Job* job,
        const ConnectionAttempts& attempts) = 0;

    // Invoked when |job| finishes initiating a connection.
    virtual void OnConnectionInitialized(Job* job, int rv) = 0;

    // Return false if |job| can advance to the next state. Otherwise, |job|
    // will wait for Job::Resume() to be called before advancing.
    virtual bool ShouldWait(Job* job) = 0;

    // Called when |job| determines the appropriate |spdy_session_key| for the
    // HttpStreamRequest. Note that this does not mean that HTTP/2 is
    // necessarily supported for this SpdySessionKey, since we may need to wait
    // for ALPN negotiation to complete before knowing if HTTP/2 is available.
    virtual void SetSpdySessionKey(Job* job,
                                   const SpdySessionKey& spdy_session_key) = 0;

    // Remove session from the SpdySessionRequestMap.
    virtual void RemoveRequestFromSpdySessionRequestMapForJob(Job* job) = 0;

    virtual const NetLogWithSource* GetNetLog() const = 0;

    virtual WebSocketHandshakeStreamBase::CreateHelper*
    websocket_handshake_stream_create_helper() = 0;

    virtual void MaybeSetWaitTimeForMainJob(const base::TimeDelta& delay) = 0;
  };

  // Job is owned by |delegate|, hence |delegate| is valid for the lifetime of
  // the Job.
  //
  // |alternative_protocol| is the protocol required by Alternative Service, if
  // any:
  // * |alternative_protocol == kProtoUnknown| means that the Job can pool to an
  //   existing SpdySession, or bind to a idle TCP socket that might use either
  //   HTTP/1.1 or HTTP/2.
  // * |alternative_protocol == kProtoHTTP2| means that the Job can pool to an
  //   existing SpdySession, or bind to a idle TCP socket.  In the latter case,
  //   if the socket does not use HTTP/2, then the Job fails.
  // * |alternative_protocol == kProtoQUIC| means that the Job can pool to an
  //   existing QUIC connection or open a new one.
  // Note that this can be overwritten by specifying a QUIC proxy in
  // |proxy_info|, or by setting
  // HttpNetworkSession::Params::origins_to_force_quic_on.
  //
  // If |alternative_proxy_server| is a valid proxy server, then the Job will
  // use that instead of using ProxyResolutionService for proxy resolution.
  // Further, if |alternative_proxy_server| is a valid but bad proxy, then
  // fallback proxies are not used. It is illegal to call this constructor with
  // a valid |alternative_proxy_server| and an |alternate_protocol| different
  // from kProtoUnknown.
  Job(Delegate* delegate,
      JobType job_type,
      HttpNetworkSession* session,
      const HttpRequestInfo& request_info,
      RequestPriority priority,
      const ProxyInfo& proxy_info,
      const SSLConfig& server_ssl_config,
      const SSLConfig& proxy_ssl_config,
      HostPortPair destination,
      GURL origin_url,
      NextProto alternative_protocol,
      quic::QuicTransportVersion quic_version,
      const ProxyServer& alternative_proxy_server,
      bool is_websocket,
      bool enable_ip_based_pooling,
      NetLog* net_log);
  virtual ~Job();

  // Start initiates the process of creating a new HttpStream.
  // |delegate_| will be notified upon completion.
  void Start(HttpStreamRequest::StreamType stream_type);

  // Preconnect will attempt to request |num_streams| sockets from the
  // appropriate ClientSocketPool.
  int Preconnect(int num_streams);

  int RestartTunnelWithProxyAuth();
  LoadState GetLoadState() const;

  // Tells |this| that |delegate_| has determined it still needs to continue
  // connecting.
  virtual void Resume();

  // Called when |this| is orphaned by Delegate. This is valid for
  // ALTERNATIVE job only.
  void Orphan();

  void SetPriority(RequestPriority priority);

  RequestPriority priority() const { return priority_; }
  bool was_alpn_negotiated() const;
  NextProto negotiated_protocol() const;
  bool using_spdy() const;
  const NetLogWithSource& net_log() const { return net_log_; }
  HttpStreamRequest::StreamType stream_type() const { return stream_type_; }

  std::unique_ptr<HttpStream> ReleaseStream() { return std::move(stream_); }

  std::unique_ptr<BidirectionalStreamImpl> ReleaseBidirectionalStream() {
    return std::move(bidirectional_stream_impl_);
  }

  // Returns the estimated memory usage in bytes.
  size_t EstimateMemoryUsage() const;

  bool is_waiting() const { return next_state_ == STATE_WAIT_COMPLETE; }
  const SSLConfig& server_ssl_config() const;
  const SSLConfig& proxy_ssl_config() const;
  const ProxyInfo& proxy_info() const;

  JobType job_type() const { return job_type_; }

  const ProxyServer alternative_proxy_server() const {
    return alternative_proxy_server_;
  }

  bool using_existing_quic_session() const {
    return using_existing_quic_session_;
  }

#if !defined(QUIC_DISABLED_FOR_STARBOARD)
  bool using_quic() const { return using_quic_; }
#else
  bool using_quic() const { return false; }
#endif

  bool should_reconsider_proxy() const { return should_reconsider_proxy_; }

  NetErrorDetails* net_error_details() { return &net_error_details_; }

 private:
  friend class test::HttpStreamFactoryJobPeer;

  enum State {
    STATE_START,
    // The main and alternative jobs are started in parallel.  The main job
    // can wait if it's paused. The alternative job never waits.
    //
    // An HTTP/2 alternative job notifies the JobController in DoInitConnection
    // unless it can pool to an existing SpdySession.  JobController, in turn,
    // resumes the main job.
    //
    // A QUIC alternative job notifies the JobController in DoInitConnection
    // regardless of whether it pools to an existing QUIC session, but the main
    // job is only resumed after some delay.
    //
    // If the main job is resumed, then it races the alternative job.
    STATE_WAIT,
    STATE_WAIT_COMPLETE,

    STATE_EVALUATE_THROTTLE,
    STATE_INIT_CONNECTION,
    STATE_INIT_CONNECTION_COMPLETE,
    STATE_WAITING_USER_ACTION,
    STATE_RESTART_TUNNEL_AUTH,
    STATE_RESTART_TUNNEL_AUTH_COMPLETE,
    STATE_CREATE_STREAM,
    STATE_CREATE_STREAM_COMPLETE,
    STATE_DRAIN_BODY_FOR_AUTH_RESTART,
    STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE,
    STATE_DONE,
    STATE_NONE,
    // Used for UMA.
    STATE_MAX,
  };

  void OnStreamReadyCallback();
  void OnBidirectionalStreamImplReadyCallback();
  void OnWebSocketHandshakeStreamReadyCallback();
  // This callback function is called when a new SPDY session is created.
  void OnNewSpdySessionReadyCallback();
  void OnStreamFailedCallback(int result);
  void OnCertificateErrorCallback(int result, const SSLInfo& ssl_info);
  void OnNeedsProxyAuthCallback(const HttpResponseInfo& response_info,
                                HttpAuthController* auth_controller);
  void OnNeedsClientAuthCallback(SSLCertRequestInfo* cert_info);
  void OnHttpsProxyTunnelResponseCallback(const HttpResponseInfo& response_info,
                                          std::unique_ptr<HttpStream> stream);
  void OnPreconnectsComplete();

  void OnIOComplete(int result);
  // RunLoop() finishes asynchronously and invokes one of the On* methods (see
  // above) when done.
  void RunLoop(int result);
  int DoLoop(int result);
  int StartInternal();
  int DoInitConnectionImpl();

  // If this is a QUIC alt job, then this function is called when host
  // resolution completes. It's called with the next result after host
  // resolution, not the result of host resolution itself.
  void OnQuicHostResolution(int result);

  // Invoked when the underlying connection fails on the default network.
  void OnFailedOnDefaultNetwork(int result);

  // Each of these methods corresponds to a State value.  Those with an input
  // argument receive the result from the previous state.  If a method returns
  // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
  // next state method as the result arg.
  int DoStart();
  int DoWait();
  int DoWaitComplete(int result);
  int DoEvaluateThrottle();
  int DoInitConnection();
  int DoInitConnectionComplete(int result);
  int DoWaitingUserAction(int result);
  int DoCreateStream();
  int DoCreateStreamComplete(int result);
  int DoRestartTunnelAuth();
  int DoRestartTunnelAuthComplete(int result);

  void ResumeInitConnection();
#if !defined(COBALT_DISABLE_SPDY)
  // Creates a SpdyHttpStream or a BidirectionalStreamImpl from the given values
  // and sets to |stream_| or |bidirectional_stream_impl_| respectively. Does
  // nothing if |stream_factory_| is for WebSocket.
  int SetSpdyHttpStreamOrBidirectionalStreamImpl(
      base::WeakPtr<SpdySession> session);
#endif

  // Returns to STATE_INIT_CONNECTION and resets some state.
  void ReturnToStateInitConnection(bool close_connection);

  // Sets several fields of |ssl_config| based on the proxy info and other
  // factors.
  void InitSSLConfig(SSLConfig* ssl_config, bool is_proxy) const;

  // Retrieve SSLInfo from our SSL Socket.
  // This must only be called when we are using an SSLSocket.
  void GetSSLInfo(SSLInfo* ssl_info);

  // Called in Job constructor: should Job be forced to use QUIC.
  static bool ShouldForceQuic(HttpNetworkSession* session,
                              const HostPortPair& destination,
                              const GURL& origin_url,
                              const ProxyInfo& proxy_info);

#if !defined(COBALT_DISABLE_SPDY)
  // Called in Job constructor. Use |spdy_session_key_| after construction.
  static SpdySessionKey GetSpdySessionKey(bool spdy_session_direct,
                                          const ProxyServer& proxy_server,
                                          const GURL& origin_url,
                                          PrivacyMode privacy_mode,
                                          const SocketTag& socket_tag);
#endif

  // Returns true if the current request can use an existing spdy session.
  bool CanUseExistingSpdySession() const;

  // Called when we encounter a network error that could be resolved by trying
  // a new proxy configuration.  If there is another proxy configuration to try
  // then this method sets next_state_ appropriately and returns either OK or
  // ERR_IO_PENDING depending on whether or not the new proxy configuration is
  // available synchronously or asynchronously.  Otherwise, the given error
  // code is simply returned.
  int ReconsiderProxyAfterError(int error);

  // Called to handle a certificate error.  Stores the certificate in the
  // allowed_bad_certs list, and checks if the error can be ignored.  Returns
  // OK if it can be ignored, or the error code otherwise.
  int HandleCertificateError(int error);

  // Called to handle a client certificate request.
  int HandleCertificateRequest(int error);

  ClientSocketPoolManager::SocketGroupType GetSocketGroup() const;

  void MaybeCopyConnectionAttemptsFromSocketOrHandle();

  // Record histograms of latency until Connect() completes.
  static void LogHttpConnectedMetrics(const ClientSocketHandle& handle);

#if !defined(COBALT_DISABLE_SPDY)
  // Invoked by the transport socket pool after host resolution is complete
  // to allow the connection to be aborted, if a matching SPDY session can
  // be found.  Will return ERR_SPDY_SESSION_ALREADY_EXISTS if such a
  // session is found, and OK otherwise.
  static int OnHostResolution(SpdySessionPool* spdy_session_pool,
                              const SpdySessionKey& spdy_session_key,
                              bool enable_ip_based_pooling,
                              bool is_websocket,
                              const AddressList& addresses,
                              const NetLogWithSource& net_log);
#endif

  const HttpRequestInfo request_info_;
  RequestPriority priority_;
  const ProxyInfo proxy_info_;
  SSLConfig server_ssl_config_;
  SSLConfig proxy_ssl_config_;
  const NetLogWithSource net_log_;

  const CompletionRepeatingCallback io_callback_;
  std::unique_ptr<ClientSocketHandle> connection_;
  HttpNetworkSession* const session_;

  State next_state_;

  // The server we are trying to reach, could be that of the origin or of the
  // alternative service (after applying host mapping rules).
  const HostPortPair destination_;

  // The origin url we're trying to reach. This url may be different from the
  // original request when host mapping rules are set-up.
  const GURL origin_url_;

  // Alternative proxy server that should be used by |this| to fetch the
  // request.
  const ProxyServer alternative_proxy_server_;

  // True if request is for Websocket.
  const bool is_websocket_;

  // True if WebSocket request is allowed to use a WebSocket-capable existing
  // HTTP/2 connection.  In this case FindAvailableSession() must be called with
  // |enable_websocket = true|.
  const bool try_websocket_over_http2_;

  // Enable pooling to a SpdySession with matching IP and certificate
  // even if the SpdySessionKey is different.
  const bool enable_ip_based_pooling_;

  // Unowned. |this| job is owned by |delegate_|.
  Delegate* const delegate_;

  const JobType job_type_;

  // True if handling a HTTPS request.
  const bool using_ssl_;

  // True if Job uses QUIC.
  const bool using_quic_;

  // quic::QuicTransportVersion that should be used to connect to the QUIC
  // server if Job uses QUIC.
  quic::QuicTransportVersion quic_version_;

  // True if Alternative Service protocol field requires that HTTP/2 is used.
  // In this case, Job fails if it cannot pool to an existing SpdySession and
  // the server does not negotiate HTTP/2 on a new socket.
  const bool expect_spdy_;

  // True if Job actually uses HTTP/2.
  bool using_spdy_;

  // True if this job might succeed with a different proxy config.
  bool should_reconsider_proxy_;

#if !defined(QUIC_DISABLED_FOR_STARBOARD)
  QuicStreamRequest quic_request_;
#endif

  // Only valid for a QUIC job. Set when a QUIC connection is started. If true,
  // then OnQuicHostResolution() is expected to be called in the future.
  bool expect_on_quic_host_resolution_;

  // True if this job used an existing QUIC session.
  bool using_existing_quic_session_;

  // True when the tunnel is in the process of being established - we can't
  // read from the socket until the tunnel is done.
  bool establishing_tunnel_;

  std::unique_ptr<HttpStream> stream_;
  std::unique_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
  std::unique_ptr<BidirectionalStreamImpl> bidirectional_stream_impl_;

  // True if we negotiated ALPN.
  bool was_alpn_negotiated_;

  // Protocol negotiated with the server.
  NextProto negotiated_protocol_;

  // 0 if we're not preconnecting. Otherwise, the number of streams to
  // preconnect.
  int num_streams_;

#if !defined(COBALT_DISABLE_SPDY)
  // Initialized when we create a new SpdySession.
  base::WeakPtr<SpdySession> new_spdy_session_;

  // Initialized when we have an existing SpdySession.
  base::WeakPtr<SpdySession> existing_spdy_session_;

  // Once Job claims a pushed stream on a SpdySession, |pushed_stream_id_| is
  // the ID of the claimed stream, and |existing_spdy_session_| points to that
  // SpdySession.  Otherwise |pushed_stream_id_| is set to kNoPushedStreamFound
  // (but |existing_spdy_session_| can still be non-null).
  spdy::SpdyStreamId pushed_stream_id_;

  // True if not connecting to an Https proxy for an Http url.
  const bool spdy_session_direct_;

  const SpdySessionKey spdy_session_key_;
#endif

  // Type of stream that is requested.
  HttpStreamRequest::StreamType stream_type_;

  // Whether Job has continued to DoInitConnection().
  bool init_connection_already_resumed_;

  NetErrorDetails net_error_details_;

  base::WeakPtrFactory<Job> ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(Job);
};

// Factory for creating Jobs.
class HttpStreamFactory::JobFactory {
 public:
  JobFactory();

  virtual ~JobFactory();

  virtual std::unique_ptr<HttpStreamFactory::Job> CreateMainJob(
      HttpStreamFactory::Job::Delegate* delegate,
      HttpStreamFactory::JobType job_type,
      HttpNetworkSession* session,
      const HttpRequestInfo& request_info,
      RequestPriority priority,
      const ProxyInfo& proxy_info,
      const SSLConfig& server_ssl_config,
      const SSLConfig& proxy_ssl_config,
      HostPortPair destination,
      GURL origin_url,
      bool is_websocket,
      bool enable_ip_based_pooling,
      NetLog* net_log);

  virtual std::unique_ptr<HttpStreamFactory::Job> CreateAltSvcJob(
      HttpStreamFactory::Job::Delegate* delegate,
      HttpStreamFactory::JobType job_type,
      HttpNetworkSession* session,
      const HttpRequestInfo& request_info,
      RequestPriority priority,
      const ProxyInfo& proxy_info,
      const SSLConfig& server_ssl_config,
      const SSLConfig& proxy_ssl_config,
      HostPortPair destination,
      GURL origin_url,
      NextProto alternative_protocol,
      quic::QuicTransportVersion quic_version,
      bool is_websocket,
      bool enable_ip_based_pooling,
      NetLog* net_log);

  virtual std::unique_ptr<HttpStreamFactory::Job> CreateAltProxyJob(
      HttpStreamFactory::Job::Delegate* delegate,
      HttpStreamFactory::JobType job_type,
      HttpNetworkSession* session,
      const HttpRequestInfo& request_info,
      RequestPriority priority,
      const ProxyInfo& proxy_info,
      const SSLConfig& server_ssl_config,
      const SSLConfig& proxy_ssl_config,
      HostPortPair destination,
      GURL origin_url,
      const ProxyServer& alternative_proxy_server,
      bool is_websocket,
      bool enable_ip_based_pooling,
      NetLog* net_log);
};

}  // namespace net

#endif  // NET_HTTP_HTTP_STREAM_FACTORY_JOB_H_
