// Copyright (c) 2010 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_REQUEST_H_ #define NET_HTTP_HTTP_STREAM_REQUEST_H_ #include "base/scoped_ptr.h" #include "base/task.h" #include "net/base/completion_callback.h" #include "net/base/host_mapping_rules.h" #include "net/base/ssl_config_service.h" #include "net/http/http_auth.h" #include "net/http/http_auth_controller.h" #include "net/http/http_alternate_protocols.h" #include "net/http/http_stream_factory.h" #include "net/http/stream_factory.h" #include "net/proxy/proxy_service.h" #include "net/socket/client_socket_handle.h" namespace net { class ClientSocketHandle; class HttpAuthController; class HttpNetworkSession; class HttpProxySocketParams; class HttpStreamFactory; class SOCKSSocketParams; class SSLSocketParams; class StreamRequestDelegate; class TCPSocketParams; struct HttpRequestInfo; // An HttpStreamRequest exists for each stream which is in progress of being // created for the StreamFactory. class HttpStreamRequest : public StreamRequest { public: HttpStreamRequest(HttpStreamFactory* factory, HttpNetworkSession* session); virtual ~HttpStreamRequest(); // Start initiates the process of creating a new HttpStream. // 3 parameters are passed in by reference. The caller asserts that the // lifecycle of these parameters will remain valid until the stream is // created, failed, or destroyed. In the first two cases, the delegate will // be called to notify completion of the request. void Start(const HttpRequestInfo* request_info, SSLConfig* ssl_config, ProxyInfo* proxy_info, Delegate* delegate, const BoundNetLog& net_log); // StreamRequest interface virtual int RestartWithCertificate(X509Certificate* client_cert); virtual int RestartTunnelWithProxyAuth(const string16& username, const string16& password); virtual LoadState GetLoadState() const; virtual bool was_alternate_protocol_available() const { return was_alternate_protocol_available_; } virtual bool was_npn_negotiated() const { return was_npn_negotiated_; } virtual bool using_spdy() const { return using_spdy_; } private: enum AlternateProtocolMode { kUnspecified, // Unspecified, check HttpAlternateProtocols kUsingAlternateProtocol, // Using an alternate protocol kDoNotUseAlternateProtocol, // Failed to connect once, do not try again. }; enum State { STATE_RESOLVE_PROXY, STATE_RESOLVE_PROXY_COMPLETE, 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 }; const HttpRequestInfo& request_info() const; ProxyInfo* proxy_info() const; SSLConfig* ssl_config() const; // Callbacks to the delegate. void OnStreamReadyCallback(); 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 OnIOComplete(int result); int RunLoop(int result); int DoLoop(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 DoResolveProxy(); int DoResolveProxyComplete(int result); int DoInitConnection(); int DoInitConnectionComplete(int result); int DoWaitingUserAction(int result); int DoCreateStream(); int DoCreateStreamComplete(int result); int DoRestartTunnelAuth(); int DoRestartTunnelAuthComplete(int result); // Set the motivation for this request onto the underlying socket. void SetSocketMotivation(); bool IsHttpsProxyAndHttpUrl(); // Returns a newly create SSLSocketParams, and sets several // fields of ssl_config_. scoped_refptr GenerateSslParams( scoped_refptr tcp_params, scoped_refptr http_proxy_params, scoped_refptr socks_params, ProxyServer::Scheme proxy_scheme, std::string hostname, bool want_spdy_over_npn); // AlternateProtocol API void MarkBrokenAlternateProtocolAndFallback(); // Retrieve SSLInfo from our SSL Socket. // This must only be called when we are using an SSLSocket. // After calling, the caller can use ssl_info_. void GetSSLInfo(); // 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); // Called to possibly recover from an SSL handshake error. Sets next_state_ // and returns OK if recovering from the error. Otherwise, the same error // code is returned. int HandleSSLHandshakeError(int error); // Record histograms of latency until Connect() completes. static void LogHttpConnectedMetrics(const ClientSocketHandle& handle); const HttpRequestInfo* request_info_; // Use request_info(). ProxyInfo* proxy_info_; // Use proxy_info(). SSLConfig* ssl_config_; // Use ssl_config(). scoped_refptr session_; CompletionCallbackImpl io_callback_; scoped_ptr connection_; scoped_refptr factory_; Delegate* delegate_; BoundNetLog net_log_; State next_state_; ProxyService::PacRequest* pac_request_; SSLInfo ssl_info_; // The hostname and port of the endpoint. This is not necessarily the one // specified by the URL, due to Alternate-Protocol or fixed testing ports. HostPortPair endpoint_; // True if handling a HTTPS request, or using SPDY with SSL bool using_ssl_; // True if this network transaction is using SPDY instead of HTTP. bool using_spdy_; // Force spdy for all connections. bool force_spdy_always_; // Force spdy only for SSL connections. bool force_spdy_over_ssl_; // The certificate error while using SPDY over SSL for insecure URLs. int spdy_certificate_error_; scoped_refptr auth_controllers_[HttpAuth::AUTH_NUM_TARGETS]; AlternateProtocolMode alternate_protocol_mode_; // Only valid if |alternate_protocol_mode_| == kUsingAlternateProtocol. HttpAlternateProtocols::Protocol alternate_protocol_; // 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_; scoped_ptr stream_; // True if finding the connection for this request found an alternate // protocol was available. bool was_alternate_protocol_available_; // True if we negotiated NPN. bool was_npn_negotiated_; ScopedRunnableMethodFactory method_factory_; DISALLOW_COPY_AND_ASSIGN(HttpStreamRequest); }; } // namespace net #endif // NET_HTTP_HTTP_STREAM_REQUEST_H_