blob: c07dc1c67ddf03da5c2fe4596888be232746eefe [file] [log] [blame]
// 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/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 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:
class PreconnectDelegate {
public:
virtual ~PreconnectDelegate() {}
virtual void OnPreconnectsComplete(HttpStreamRequest* request,
int result) = 0;
};
HttpStreamRequest(StreamFactory* 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);
int Preconnect(int num_streams,
const HttpRequestInfo* request_info,
SSLConfig* ssl_config,
ProxyInfo* proxy_info,
PreconnectDelegate* 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 OnPreconnectsComplete(int result);
void OnIOComplete(int result);
int RunLoop(int result);
int DoLoop(int result);
int StartInternal(const HttpRequestInfo* request_info,
SSLConfig* ssl_config,
ProxyInfo* proxy_info,
const BoundNetLog& net_log);
// 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<SSLSocketParams> GenerateSSLParams(
scoped_refptr<TCPSocketParams> tcp_params,
scoped_refptr<HttpProxySocketParams> http_proxy_params,
scoped_refptr<SOCKSSocketParams> socks_params,
ProxyServer::Scheme proxy_scheme,
const HostPortPair& host_and_port,
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);
// Moves this stream request into SPDY mode.
void SwitchToSpdyMode();
// 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<HttpNetworkSession> session_;
CompletionCallbackImpl<HttpStreamRequest> io_callback_;
scoped_ptr<ClientSocketHandle> connection_;
StreamFactory* const 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<HttpAuthController>
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<HttpStream> 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_;
PreconnectDelegate* preconnect_delegate_;
// Only used if |preconnect_delegate_| is non-NULL.
int num_streams_;
ScopedRunnableMethodFactory<HttpStreamRequest> method_factory_;
DISALLOW_COPY_AND_ASSIGN(HttpStreamRequest);
};
} // namespace net
#endif // NET_HTTP_HTTP_STREAM_REQUEST_H_