diff options
36 files changed, 805 insertions, 1096 deletions
diff --git a/chrome/browser/net/preconnect.cc b/chrome/browser/net/preconnect.cc index 8152f62..c35bc0e 100644 --- a/chrome/browser/net/preconnect.cc +++ b/chrome/browser/net/preconnect.cc @@ -6,37 +6,44 @@ #include "base/logging.h" #include "base/metrics/histogram.h" -#include "chrome/browser/browser_thread.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/browser_thread.h" #include "chrome/common/net/url_request_context_getter.h" -#include "net/base/net_log.h" -#include "net/base/ssl_config_service.h" #include "net/http/http_network_session.h" -#include "net/http/http_request_info.h" -#include "net/http/http_stream_factory.h" #include "net/http/http_transaction_factory.h" #include "net/url_request/url_request_context.h" namespace chrome_browser_net { -void PreconnectOnUIThread( - const GURL& url, - UrlInfo::ResolutionMotivation motivation, - int count) { +// static +void Preconnect::PreconnectOnUIThread(const GURL& url, + UrlInfo::ResolutionMotivation motivation, int count) { // Prewarm connection to Search URL. BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - NewRunnableFunction(PreconnectOnIOThread, url, motivation, + NewRunnableFunction(Preconnect::PreconnectOnIOThread, url, motivation, count)); return; } +// static +void Preconnect::PreconnectOnIOThread(const GURL& url, + UrlInfo::ResolutionMotivation motivation, int count) { + Preconnect* preconnect = new Preconnect(motivation); + // TODO(jar): Should I use PostTask for LearnedSubresources to delay the + // preconnection a tad? + preconnect->Connect(url, count); +} + +Preconnect::Preconnect(UrlInfo::ResolutionMotivation motivation) + : motivation_(motivation), + ALLOW_THIS_IN_INITIALIZER_LIST( + io_callback_(this, &Preconnect::OnPreconnectComplete)) {} -void PreconnectOnIOThread( - const GURL& url, - UrlInfo::ResolutionMotivation motivation, - int count) { +Preconnect::~Preconnect() {} + +void Preconnect::Connect(const GURL& url, int count) { URLRequestContextGetter* getter = Profile::GetDefaultRequestContext(); if (!getter) return; @@ -46,16 +53,16 @@ void PreconnectOnIOThread( } // We are now commited to doing the async preconnection call. - UMA_HISTOGRAM_ENUMERATION("Net.PreconnectMotivation", motivation, + UMA_HISTOGRAM_ENUMERATION("Net.PreconnectMotivation", motivation_, UrlInfo::MAX_MOTIVATED); net::URLRequestContext* context = getter->GetURLRequestContext(); net::HttpTransactionFactory* factory = context->http_transaction_factory(); net::HttpNetworkSession* session = factory->GetSession(); - net::HttpRequestInfo request_info; - request_info.url = url; - request_info.method = "GET"; + request_info_.reset(new net::HttpRequestInfo()); + request_info_->url = url; + request_info_->method = "GET"; // It almost doesn't matter whether we use net::LOWEST or net::HIGHEST // priority here, as we won't make a request, and will surrender the created // socket to the pool as soon as we can. However, we would like to mark the @@ -67,19 +74,19 @@ void PreconnectOnIOThread( // as speculative, and better detect stats (if it gets used). // TODO(jar): histogram to see how often we accidentally use a previously- // unused socket, when a previously used socket was available. - request_info.priority = net::HIGHEST; + request_info_->priority = net::HIGHEST; // Translate the motivation from UrlRequest motivations to HttpRequest // motivations. - switch (motivation) { + switch (motivation_) { case UrlInfo::OMNIBOX_MOTIVATED: - request_info.motivation = net::HttpRequestInfo::OMNIBOX_MOTIVATED; + request_info_->motivation = net::HttpRequestInfo::OMNIBOX_MOTIVATED; break; case UrlInfo::LEARNED_REFERAL_MOTIVATED: - request_info.motivation = net::HttpRequestInfo::PRECONNECT_MOTIVATED; + request_info_->motivation = net::HttpRequestInfo::PRECONNECT_MOTIVATED; break; case UrlInfo::EARLY_LOAD_MOTIVATED: - request_info.motivation = net::HttpRequestInfo::EARLY_LOAD_MOTIVATED; + request_info_->motivation = net::HttpRequestInfo::EARLY_LOAD_MOTIVATED; break; default: // Other motivations should never happen here. @@ -88,17 +95,26 @@ void PreconnectOnIOThread( } // Setup the SSL Configuration. - net::SSLConfig ssl_config; - session->ssl_config_service()->GetSSLConfig(&ssl_config); + ssl_config_.reset(new net::SSLConfig()); + session->ssl_config_service()->GetSSLConfig(ssl_config_.get()); if (session->http_stream_factory()->next_protos()) - ssl_config.next_protos = *session->http_stream_factory()->next_protos(); + ssl_config_->next_protos = *session->http_stream_factory()->next_protos(); // All preconnects should perform EV certificate verification. - ssl_config.verify_ev_cert = true; + ssl_config_->verify_ev_cert = true; + + proxy_info_.reset(new net::ProxyInfo()); + net::StreamFactory* stream_factory = session->http_stream_factory(); + int rv = stream_factory->PreconnectStreams(count, request_info_.get(), + ssl_config_.get(), + proxy_info_.get(), session, + net_log_, &io_callback_); + if (rv != net::ERR_IO_PENDING) + delete this; +} - net::HttpStreamFactory* http_stream_factory = session->http_stream_factory(); - http_stream_factory->PreconnectStreams( - count, request_info, ssl_config, net::BoundNetLog()); +void Preconnect::OnPreconnectComplete(int error_code) { + delete this; } } // namespace chrome_browser_net diff --git a/chrome/browser/net/preconnect.h b/chrome/browser/net/preconnect.h index 0175122..a950167 100644 --- a/chrome/browser/net/preconnect.h +++ b/chrome/browser/net/preconnect.h @@ -9,25 +9,72 @@ #define CHROME_BROWSER_NET_PRECONNECT_H_ #pragma once +#include "base/scoped_ptr.h" #include "chrome/browser/net/url_info.h" +#include "net/base/completion_callback.h" +#include "net/base/net_log.h" +#include "net/http/http_request_info.h" +#include "net/http/stream_factory.h" -class GURL; +namespace net { + +class ProxyInfo; +struct SSLConfig; + +} // namespace net namespace chrome_browser_net { -// Try to preconnect. Typically motivated by OMNIBOX to reach search service. -// |count| may be used to request more than one connection be established in -// parallel. -void PreconnectOnUIThread(const GURL& url, - UrlInfo::ResolutionMotivation motivation, - int count); - -// Try to preconnect. Typically used by predictor when a subresource probably -// needs a connection. |count| may be used to request more than one connection -// be established in parallel. -void PreconnectOnIOThread(const GURL& url, - UrlInfo::ResolutionMotivation motivation, - int count); +class Preconnect { + public: + // Try to preconnect. Typically motivated by OMNIBOX to reach search service. + // |count| may be used to request more than one connection be established in + // parallel. + static void PreconnectOnUIThread(const GURL& url, + UrlInfo::ResolutionMotivation motivation, + int count); + + // Try to preconnect. Typically used by predictor when a subresource probably + // needs a connection. |count| may be used to request more than one connection + // be established in parallel. + static void PreconnectOnIOThread(const GURL& url, + UrlInfo::ResolutionMotivation motivation, + int count); + + private: + explicit Preconnect(UrlInfo::ResolutionMotivation motivation); + virtual ~Preconnect(); + + void OnPreconnectComplete(int error_code); + + // Request actual connection, via interface that tags request as needed for + // preconnect only (so that they can be merged with connections needed for + // navigations). + void Connect(const GURL& url, int count); + + // Generally either LEARNED_REFERAL_MOTIVATED, OMNIBOX_MOTIVATED or + // EARLY_LOAD_MOTIVATED to indicate why we were trying to do a preconnection. + const UrlInfo::ResolutionMotivation motivation_; + + // HttpRequestInfo used for connecting. + scoped_ptr<net::HttpRequestInfo> request_info_; + + // SSLConfig used for connecting. + scoped_ptr<net::SSLConfig> ssl_config_; + + // ProxyInfo used for connecting. + scoped_ptr<net::ProxyInfo> proxy_info_; + + // A net log to use for this preconnect. + net::BoundNetLog net_log_; + + // Our preconnect. + scoped_ptr<net::StreamRequest> stream_request_; + + net::CompletionCallbackImpl<Preconnect> io_callback_; + + DISALLOW_COPY_AND_ASSIGN(Preconnect); +}; } // namespace chrome_browser_net diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc index 06aca37..327d709 100644 --- a/chrome/browser/net/predictor.cc +++ b/chrome/browser/net/predictor.cc @@ -183,8 +183,8 @@ void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) { return; // We've done a preconnect recently. last_omnibox_preconnect_ = now; const int kConnectionsNeeded = 1; - PreconnectOnUIThread(CanonicalizeUrl(url), motivation, - kConnectionsNeeded); + Preconnect::PreconnectOnUIThread(CanonicalizeUrl(url), motivation, + kConnectionsNeeded); return; // Skip pre-resolution, since we'll open a connection. } } else { @@ -217,8 +217,8 @@ void Predictor::PreconnectUrlAndSubresources(const GURL& url) { std::string host = url.HostNoBrackets(); UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); const int kConnectionsNeeded = 1; - PreconnectOnUIThread(CanonicalizeUrl(url), motivation, - kConnectionsNeeded); + Preconnect::PreconnectOnUIThread(CanonicalizeUrl(url), motivation, + kConnectionsNeeded); PredictFrameSubresources(url.GetWithEmptyPath()); } } @@ -259,7 +259,7 @@ void Predictor::PrepareFrameSubresources(const GURL& url) { int count = static_cast<int>(std::ceil(connection_expectation)); if (url.host() == future_url->first.host()) ++count; - PreconnectOnIOThread(future_url->first, motivation, count); + Preconnect::PreconnectOnIOThread(future_url->first, motivation, count); } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) { evalution = PRERESOLUTION; future_url->second.preresolution_increment(); diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 4308e7a..388bddb 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -1357,7 +1357,7 @@ void RenderMessageFilter::OnCloseCurrentConnections() { if (!CheckBenchmarkingEnabled()) return; request_context_->GetURLRequestContext()-> - http_transaction_factory()->GetCache()->CloseAllConnections(); + http_transaction_factory()->GetCache()->CloseCurrentConnections(); } void RenderMessageFilter::OnSetCacheMode(bool enabled) { diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc index a821a30..7c35f69 100644 --- a/net/http/http_cache.cc +++ b/net/http/http_cache.cc @@ -451,12 +451,15 @@ void HttpCache::WriteMetadata(const GURL& url, writer->Write(url, expected_response_time, buf, buf_len); } -void HttpCache::CloseAllConnections() { +void HttpCache::CloseCurrentConnections() { net::HttpNetworkLayer* network = static_cast<net::HttpNetworkLayer*>(network_layer_.get()); HttpNetworkSession* session = network->GetSession(); - if (session) - session->CloseAllConnections(); + if (session) { + session->FlushSocketPools(); + if (session->spdy_session_pool()) + session->spdy_session_pool()->CloseCurrentSessions(); + } } int HttpCache::CreateTransaction(scoped_ptr<HttpTransaction>* trans) { diff --git a/net/http/http_cache.h b/net/http/http_cache.h index ba7a18e..cdbddfe 100644 --- a/net/http/http_cache.h +++ b/net/http/http_cache.h @@ -176,7 +176,7 @@ class HttpCache : public HttpTransactionFactory, // Close currently active sockets so that fresh page loads will not use any // recycled connections. For sockets currently in use, they may not close // immediately, but they will not be reusable. This is for debugging. - void CloseAllConnections(); + void CloseCurrentConnections(); // HttpTransactionFactory implementation: virtual int CreateTransaction(scoped_ptr<HttpTransaction>* trans); diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc index 0fb1050..e979ad0 100644 --- a/net/http/http_network_layer.cc +++ b/net/http/http_network_layer.cc @@ -156,7 +156,7 @@ void HttpNetworkLayer::Suspend(bool suspend) { suspended_ = suspend; if (suspend && session_) - session_->CloseIdleConnections(); + session_->tcp_socket_pool()->CloseIdleSockets(); } } // namespace net diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index e67390c..b50b6e9 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc @@ -6,16 +6,13 @@ #include <utility> -#include "base/compiler_specific.h" #include "base/logging.h" #include "base/stl_util-inl.h" #include "base/string_util.h" #include "base/values.h" #include "net/http/http_auth_handler_factory.h" #include "net/http/http_response_body_drainer.h" -#include "net/http/http_stream_factory_impl.h" #include "net/http/url_security_manager.h" -#include "net/proxy/proxy_service.h" #include "net/socket/client_socket_factory.h" #include "net/spdy/spdy_session_pool.h" @@ -23,10 +20,7 @@ namespace net { // TODO(mbelshe): Move the socket factories into HttpStreamFactory. HttpNetworkSession::HttpNetworkSession(const Params& params) - : net_log_(params.net_log), - network_delegate_(params.network_delegate), - cert_verifier_(params.cert_verifier), - http_auth_handler_factory_(params.http_auth_handler_factory), + : cert_verifier_(NULL), proxy_service_(params.proxy_service), ssl_config_service_(params.ssl_config_service), socket_pool_manager_(params.net_log, @@ -41,8 +35,9 @@ HttpNetworkSession::HttpNetworkSession(const Params& params) params.proxy_service, params.ssl_config_service), spdy_session_pool_(params.ssl_config_service), - ALLOW_THIS_IN_INITIALIZER_LIST(http_stream_factory_( - new HttpStreamFactoryImpl(this))) { + http_auth_handler_factory_(params.http_auth_handler_factory), + network_delegate_(params.network_delegate), + net_log_(params.net_log) { DCHECK(params.proxy_service); DCHECK(params.ssl_config_service); } diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index 5c8f705..36cb652 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h @@ -71,7 +71,7 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession>, explicit HttpNetworkSession(const Params& params); - HttpAuthCache* http_auth_cache() { return &http_auth_cache_; } + HttpAuthCache* auth_cache() { return &auth_cache_; } SSLClientAuthCache* ssl_client_auth_cache() { return &ssl_client_auth_cache_; } @@ -87,6 +87,14 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession>, return &alternate_protocols_; } + // Access to the SpdySettingsStorage + const SpdySettingsStorage& spdy_settings() const { + return spdy_settings_; + } + SpdySettingsStorage* mutable_spdy_settings() { + return &spdy_settings_; + } + TCPClientSocketPool* tcp_socket_pool() { return socket_pool_manager_.tcp_socket_pool(); } @@ -122,7 +130,7 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession>, } HttpStreamFactory* http_stream_factory() { - return http_stream_factory_.get(); + return &http_stream_factory_; } NetLog* net_log() { @@ -139,37 +147,30 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession>, // responsible for deleting the returned value. Value* SpdySessionPoolInfoToValue() const; - void CloseAllConnections() { + void FlushSocketPools() { socket_pool_manager_.FlushSocketPools(); - spdy_session_pool_.CloseCurrentSessions(); - } - - void CloseIdleConnections() { - socket_pool_manager_.CloseIdleSockets(); } - private: friend class base::RefCounted<HttpNetworkSession>; friend class HttpNetworkSessionPeer; ~HttpNetworkSession(); - NetLog* const net_log_; - HttpNetworkDelegate* const network_delegate_; - CertVerifier* const cert_verifier_; - HttpAuthHandlerFactory* const http_auth_handler_factory_; - + HttpAuthCache auth_cache_; + SSLClientAuthCache ssl_client_auth_cache_; + HttpAlternateProtocols alternate_protocols_; + CertVerifier* cert_verifier_; // Not const since it's modified by HttpNetworkSessionPeer for testing. scoped_refptr<ProxyService> proxy_service_; const scoped_refptr<SSLConfigService> ssl_config_service_; - - HttpAuthCache http_auth_cache_; - SSLClientAuthCache ssl_client_auth_cache_; - HttpAlternateProtocols alternate_protocols_; ClientSocketPoolManager socket_pool_manager_; SpdySessionPool spdy_session_pool_; - scoped_ptr<HttpStreamFactory> http_stream_factory_; + HttpStreamFactory http_stream_factory_; + HttpAuthHandlerFactory* const http_auth_handler_factory_; + HttpNetworkDelegate* const network_delegate_; + NetLog* const net_log_; + SpdySettingsStorage spdy_settings_; std::set<HttpResponseBodyDrainer*> response_drainers_; }; diff --git a/net/http/http_network_session_peer.cc b/net/http/http_network_session_peer.cc index 2ed3e76..7bb342c 100644 --- a/net/http/http_network_session_peer.cc +++ b/net/http/http_network_session_peer.cc @@ -6,7 +6,6 @@ #include "net/http/http_network_session.h" #include "net/http/http_proxy_client_socket_pool.h" -#include "net/proxy/proxy_service.h" #include "net/socket/socks_client_socket_pool.h" #include "net/socket/ssl_client_socket_pool.h" #include "net/socket/tcp_client_socket_pool.h" @@ -67,9 +66,4 @@ void HttpNetworkSessionPeer::SetProxyService(ProxyService* proxy_service) { session_->proxy_service_ = proxy_service; } -void HttpNetworkSessionPeer::SetHttpStreamFactory( - HttpStreamFactory* http_stream_factory) { - session_->http_stream_factory_.reset(http_stream_factory); -} - } // namespace net diff --git a/net/http/http_network_session_peer.h b/net/http/http_network_session_peer.h index 06101ca..398488b 100644 --- a/net/http/http_network_session_peer.h +++ b/net/http/http_network_session_peer.h @@ -13,7 +13,6 @@ namespace net { class HostPortPair; class HttpNetworkSession; class HttpProxyClientSocketPool; -class HttpStreamFactory; class ProxyService; class SOCKSClientSocketPool; class SSLClientSocketPool; @@ -43,8 +42,6 @@ class HttpNetworkSessionPeer { void SetProxyService(ProxyService* proxy_service); - void SetHttpStreamFactory(HttpStreamFactory* http_stream_factory); - private: const scoped_refptr<HttpNetworkSession> session_; diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 98b9cd7..128497f 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -42,7 +42,7 @@ #include "net/http/http_response_body_drainer.h" #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" -#include "net/http/http_stream_factory.h" +#include "net/http/http_stream_request.h" #include "net/http/http_util.h" #include "net/http/url_security_manager.h" #include "net/socket/client_socket_factory.h" @@ -359,15 +359,11 @@ uint64 HttpNetworkTransaction::GetUploadProgress() const { return stream_->GetUploadProgress(); } -void HttpNetworkTransaction::OnStreamReady(const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - HttpStream* stream) { +void HttpNetworkTransaction::OnStreamReady(HttpStream* stream) { DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); DCHECK(stream_request_.get()); stream_.reset(stream); - ssl_config_ = used_ssl_config; - proxy_info_ = used_proxy_info; response_.was_alternate_protocol_available = stream_request_->was_alternate_protocol_available(); response_.was_npn_negotiated = stream_request_->was_npn_negotiated(); @@ -377,28 +373,23 @@ void HttpNetworkTransaction::OnStreamReady(const SSLConfig& used_ssl_config, OnIOComplete(OK); } -void HttpNetworkTransaction::OnStreamFailed(int result, - const SSLConfig& used_ssl_config) { +void HttpNetworkTransaction::OnStreamFailed(int result) { DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); DCHECK_NE(OK, result); DCHECK(stream_request_.get()); DCHECK(!stream_.get()); - ssl_config_ = used_ssl_config; OnIOComplete(result); } -void HttpNetworkTransaction::OnCertificateError( - int result, - const SSLConfig& used_ssl_config, - const SSLInfo& ssl_info) { +void HttpNetworkTransaction::OnCertificateError(int result, + const SSLInfo& ssl_info) { DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); DCHECK_NE(OK, result); DCHECK(stream_request_.get()); DCHECK(!stream_.get()); response_.ssl_info = ssl_info; - ssl_config_ = used_ssl_config; // TODO(mbelshe): For now, we're going to pass the error through, and that // will close the stream_request in all cases. This means that we're always @@ -411,8 +402,6 @@ void HttpNetworkTransaction::OnCertificateError( void HttpNetworkTransaction::OnNeedsProxyAuth( const HttpResponseInfo& proxy_response, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, HttpAuthController* auth_controller) { DCHECK(stream_request_.get()); DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); @@ -421,8 +410,6 @@ void HttpNetworkTransaction::OnNeedsProxyAuth( response_.headers = proxy_response.headers; response_.auth_challenge = proxy_response.auth_challenge; headers_valid_ = true; - ssl_config_ = used_ssl_config; - proxy_info_ = used_proxy_info; auth_controllers_[HttpAuth::AUTH_PROXY] = auth_controller; pending_auth_target_ = HttpAuth::AUTH_PROXY; @@ -431,26 +418,20 @@ void HttpNetworkTransaction::OnNeedsProxyAuth( } void HttpNetworkTransaction::OnNeedsClientAuth( - const SSLConfig& used_ssl_config, SSLCertRequestInfo* cert_info) { DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); - ssl_config_ = used_ssl_config; response_.cert_request_info = cert_info; OnIOComplete(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); } void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( const HttpResponseInfo& response_info, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, HttpStream* stream) { DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); headers_valid_ = true; response_ = response_info; - ssl_config_ = used_ssl_config; - proxy_info_ = used_proxy_info; stream_.reset(stream); stream_request_.reset(); // we're done with the stream request OnIOComplete(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); @@ -568,8 +549,10 @@ int HttpNetworkTransaction::DoCreateStream() { stream_request_.reset( session_->http_stream_factory()->RequestStream( - *request_, - ssl_config_, + request_, + &ssl_config_, + &proxy_info_, + session_, this, net_log_)); DCHECK(stream_request_.get()); @@ -626,7 +609,7 @@ int HttpNetworkTransaction::DoGenerateProxyAuthToken() { auth_controllers_[target] = new HttpAuthController(target, AuthURL(target), - session_->http_auth_cache(), + session_->auth_cache(), session_->http_auth_handler_factory()); return auth_controllers_[target]->MaybeGenerateAuthToken(request_, &io_callback_, @@ -647,7 +630,7 @@ int HttpNetworkTransaction::DoGenerateServerAuthToken() { auth_controllers_[target] = new HttpAuthController(target, AuthURL(target), - session_->http_auth_cache(), + session_->auth_cache(), session_->http_auth_handler_factory()); if (!ShouldApplyServerAuth()) return OK; diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index 3cec010..66b6b29 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h @@ -19,8 +19,8 @@ #include "net/http/http_auth.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_info.h" -#include "net/http/http_stream_factory.h" #include "net/http/http_transaction.h" +#include "net/http/stream_factory.h" #include "net/proxy/proxy_service.h" namespace net { @@ -33,7 +33,7 @@ class IOBuffer; struct HttpRequestInfo; class HttpNetworkTransaction : public HttpTransaction, - public HttpStreamRequest::Delegate { + public StreamRequest::Delegate { public: explicit HttpNetworkTransaction(HttpNetworkSession* session); @@ -57,25 +57,15 @@ class HttpNetworkTransaction : public HttpTransaction, virtual LoadState GetLoadState() const; virtual uint64 GetUploadProgress() const; - // HttpStreamRequest::Delegate methods: - virtual void OnStreamReady(const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - HttpStream* stream); - virtual void OnStreamFailed(int status, - const SSLConfig& used_ssl_config); - virtual void OnCertificateError(int status, - const SSLConfig& used_ssl_config, - const SSLInfo& ssl_info); + // StreamRequest::Delegate methods: + virtual void OnStreamReady(HttpStream* stream); + virtual void OnStreamFailed(int status); + virtual void OnCertificateError(int status, const SSLInfo& ssl_info); virtual void OnNeedsProxyAuth( const HttpResponseInfo& response_info, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, HttpAuthController* auth_controller); - virtual void OnNeedsClientAuth(const SSLConfig& used_ssl_config, - SSLCertRequestInfo* cert_info); + virtual void OnNeedsClientAuth(SSLCertRequestInfo* cert_info); virtual void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, HttpStream* stream); private: @@ -225,10 +215,9 @@ class HttpNetworkTransaction : public HttpTransaction, const HttpRequestInfo* request_; HttpResponseInfo response_; - // |proxy_info_| is the ProxyInfo used by the HttpStreamRequest. ProxyInfo proxy_info_; - scoped_ptr<HttpStreamRequest> stream_request_; + scoped_ptr<StreamRequest> stream_request_; scoped_ptr<HttpStream> stream_; // True if we've validated the headers that the stream parser has returned. diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index ecd6132..e54edf5 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -1581,7 +1581,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { EXPECT_TRUE(response->auth_challenge.get() == NULL); trans.reset(); - session->CloseAllConnections(); + session->FlushSocketPools(); } // Test the request-challenge-retry sequence for basic auth, over a keep-alive @@ -1695,7 +1695,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) { // Flush the idle socket before the NetLog and HttpNetworkTransaction go // out of scope. - session->CloseAllConnections(); + session->FlushSocketPools(); } // Test that we don't read the response body when we fail to establish a tunnel, @@ -1753,7 +1753,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) { EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); // Flush the idle socket before the HttpNetworkTransaction goes out of scope. - session->CloseAllConnections(); + session->FlushSocketPools(); } // Test when a server (non-proxy) returns a 407 (proxy-authenticate). @@ -6923,7 +6923,8 @@ TEST_F(HttpNetworkTransactionTest, HostPortPair host_port_pair("www.google.com", 443); HostPortProxyPair pair(host_port_pair, ProxyServer::Direct()); scoped_refptr<SpdySession> spdy_session = - session->spdy_session_pool()->Get(pair, BoundNetLog()); + session->spdy_session_pool()->Get(pair, session->mutable_spdy_settings(), + BoundNetLog()); scoped_refptr<TCPSocketParams> tcp_params( new TCPSocketParams("www.google.com", 443, MEDIUM, GURL(), false)); @@ -8166,7 +8167,8 @@ TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) { HostPortPair host_port_pair("www.google.com", 443); HostPortProxyPair pair(host_port_pair, ProxyServer::Direct()); scoped_refptr<SpdySession> spdy_session = - session->spdy_session_pool()->Get(pair, BoundNetLog()); + session->spdy_session_pool()->Get(pair, session->mutable_spdy_settings(), + BoundNetLog()); scoped_refptr<TCPSocketParams> tcp_params( new TCPSocketParams("www.google.com", 443, MEDIUM, GURL(), false)); TestCompletionCallback callback; diff --git a/net/http/http_proxy_client_socket_pool.cc b/net/http/http_proxy_client_socket_pool.cc index 13d6286..3129133 100644 --- a/net/http/http_proxy_client_socket_pool.cc +++ b/net/http/http_proxy_client_socket_pool.cc @@ -36,10 +36,12 @@ HttpProxySocketParams::HttpProxySocketParams( HttpAuthCache* http_auth_cache, HttpAuthHandlerFactory* http_auth_handler_factory, SpdySessionPool* spdy_session_pool, + SpdySettingsStorage* spdy_settings, bool tunnel) : tcp_params_(tcp_params), ssl_params_(ssl_params), spdy_session_pool_(spdy_session_pool), + spdy_settings_(spdy_settings), request_url_(request_url), user_agent_(user_agent), endpoint_(endpoint), @@ -289,11 +291,11 @@ int HttpProxyConnectJob::DoSpdyProxyCreateStream() { transport_socket_handle_->socket()->Disconnect(); transport_socket_handle_->Reset(); } - spdy_session = spdy_pool->Get(pair, net_log()); + spdy_session = spdy_pool->Get(pair, params_->spdy_settings(), net_log()); } else { // Create a session direct to the proxy itself int rv = spdy_pool->GetSpdySessionFromSocket( - pair, transport_socket_handle_.release(), + pair, params_->spdy_settings(), transport_socket_handle_.release(), net_log(), OK, &spdy_session, /*using_ssl_*/ true); if (rv < 0) return rv; diff --git a/net/http/http_proxy_client_socket_pool.h b/net/http/http_proxy_client_socket_pool.h index 4ae07cf..4757b27 100644 --- a/net/http/http_proxy_client_socket_pool.h +++ b/net/http/http_proxy_client_socket_pool.h @@ -28,6 +28,7 @@ class HttpAuthHandlerFactory; class SSLClientSocketPool; class SSLSocketParams; class SpdySessionPool; +class SpdySettingsStorage; class SpdyStream; class TCPClientSocketPool; class TCPSocketParams; @@ -46,6 +47,7 @@ class HttpProxySocketParams : public base::RefCounted<HttpProxySocketParams> { HttpAuthCache* http_auth_cache, HttpAuthHandlerFactory* http_auth_handler_factory, SpdySessionPool* spdy_session_pool, + SpdySettingsStorage* spdy_settings, bool tunnel); const scoped_refptr<TCPSocketParams>& tcp_params() const { @@ -64,6 +66,9 @@ class HttpProxySocketParams : public base::RefCounted<HttpProxySocketParams> { SpdySessionPool* spdy_session_pool() { return spdy_session_pool_; } + SpdySettingsStorage* spdy_settings() { + return spdy_settings_; + } const HostResolver::RequestInfo& destination() const; bool tunnel() const { return tunnel_; } @@ -74,6 +79,7 @@ class HttpProxySocketParams : public base::RefCounted<HttpProxySocketParams> { const scoped_refptr<TCPSocketParams> tcp_params_; const scoped_refptr<SSLSocketParams> ssl_params_; SpdySessionPool* spdy_session_pool_; + SpdySettingsStorage* spdy_settings_; const GURL request_url_; const std::string user_agent_; const HostPortPair endpoint_; diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc index 5830b3a7..359a058 100644 --- a/net/http/http_proxy_client_socket_pool_unittest.cc +++ b/net/http/http_proxy_client_socket_pool_unittest.cc @@ -94,13 +94,13 @@ class HttpProxyClientSocketPoolTest : public TestWithHttpParam { void AddAuthToCache() { const string16 kFoo(ASCIIToUTF16("foo")); const string16 kBar(ASCIIToUTF16("bar")); - session_->http_auth_cache()->Add(GURL("http://proxy/"), - "MyRealm1", - HttpAuth::AUTH_SCHEME_BASIC, - "Basic realm=MyRealm1", - kFoo, - kBar, - "/"); + session_->auth_cache()->Add(GURL("http://proxy/"), + "MyRealm1", + HttpAuth::AUTH_SCHEME_BASIC, + "Basic realm=MyRealm1", + kFoo, + kBar, + "/"); } scoped_refptr<TCPSocketParams> GetTcpParams() { @@ -125,9 +125,10 @@ class HttpProxyClientSocketPoolTest : public TestWithHttpParam { GURL(tunnel ? "https://www.google.com/" : "http://www.google.com"), "", HostPortPair("www.google.com", tunnel ? 443 : 80), - session_->http_auth_cache(), + session_->auth_cache(), session_->http_auth_handler_factory(), session_->spdy_session_pool(), + session_->mutable_spdy_settings(), tunnel)); } diff --git a/net/http/http_stream_factory.cc b/net/http/http_stream_factory.cc index 9189e99..4673d58 100644 --- a/net/http/http_stream_factory.cc +++ b/net/http/http_stream_factory.cc @@ -1,16 +1,17 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. #include "net/http/http_stream_factory.h" -#include "base/logging.h" +#include "base/stl_util-inl.h" #include "base/string_number_conversions.h" #include "base/string_split.h" -#include "googleurl/src/gurl.h" -#include "net/base/host_mapping_rules.h" -#include "net/base/host_port_pair.h" -#include "net/http/http_alternate_protocols.h" +#include "base/string_util.h" +#include "net/base/net_log.h" +#include "net/base/net_util.h" +#include "net/http/http_network_session.h" +#include "net/http/http_stream_request.h" namespace net { @@ -31,7 +32,62 @@ std::list<HostPortPair>* HttpStreamFactory::forced_spdy_exclusions_ = NULL; // static bool HttpStreamFactory::ignore_certificate_errors_ = false; -HttpStreamFactory::~HttpStreamFactory() {} +HttpStreamFactory::HttpStreamFactory() { +} + +HttpStreamFactory::~HttpStreamFactory() { + RequestCallbackMap request_callback_map; + request_callback_map.swap(request_callback_map_); + for (RequestCallbackMap::iterator it = request_callback_map.begin(); + it != request_callback_map.end(); ++it) { + delete it->first; + // We don't invoke the callback in the destructor. + } +} + +// static +void HttpStreamFactory::SetHostMappingRules(const std::string& rules) { + HostMappingRules* host_mapping_rules = new HostMappingRules(); + host_mapping_rules->SetRulesFromString(rules); + delete host_mapping_rules_; + host_mapping_rules_ = host_mapping_rules; +} + +StreamRequest* HttpStreamFactory::RequestStream( + const HttpRequestInfo* request_info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + HttpNetworkSession* session, + StreamRequest::Delegate* delegate, + const BoundNetLog& net_log) { + HttpStreamRequest* stream = new HttpStreamRequest(this, session); + stream->Start(request_info, ssl_config, proxy_info, delegate, net_log); + return stream; +} + +int HttpStreamFactory::PreconnectStreams( + int num_streams, + const HttpRequestInfo* request_info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + HttpNetworkSession* session, + const BoundNetLog& net_log, + CompletionCallback* callback) { + HttpStreamRequest* stream = new HttpStreamRequest(this, session); + int rv = stream->Preconnect(num_streams, request_info, ssl_config, + proxy_info, this, net_log); + DCHECK_EQ(ERR_IO_PENDING, rv); + request_callback_map_[stream] = callback; + return rv; +} + +void HttpStreamFactory::AddTLSIntolerantServer(const GURL& url) { + tls_intolerant_servers_.insert(GetHostAndPort(url)); +} + +bool HttpStreamFactory::IsTLSIntolerantServer(const GURL& url) { + return ContainsKey(tls_intolerant_servers_, GetHostAndPort(url)); +} void HttpStreamFactory::ProcessAlternateProtocol( HttpAlternateProtocols* alternate_protocols, @@ -72,7 +128,8 @@ void HttpStreamFactory::ProcessAlternateProtocol( } HostPortPair host_port(http_host_port_pair); - host_mapping_rules().RewriteHost(&host_port); + if (host_mapping_rules_) + host_mapping_rules_->RewriteHost(&host_port); if (alternate_protocols->HasAlternateProtocolFor(host_port)) { const HttpAlternateProtocols::PortProtocolPair existing_alternate = @@ -87,7 +144,7 @@ void HttpStreamFactory::ProcessAlternateProtocol( GURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url, HostPortPair* endpoint) { - if (host_mapping_rules().RewriteHost(endpoint)) { + if (host_mapping_rules_ && host_mapping_rules_->RewriteHost(endpoint)) { url_canon::Replacements<char> replacements; const std::string port_str = base::IntToString(endpoint->port()); replacements.SetPort(port_str.c_str(), @@ -99,29 +156,15 @@ GURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url, return url; } -// static -void HttpStreamFactory::add_forced_spdy_exclusion(const std::string& value) { - HostPortPair pair = HostPortPair::FromURL(GURL(value)); - if (!forced_spdy_exclusions_) - forced_spdy_exclusions_ = new std::list<HostPortPair>(); - forced_spdy_exclusions_->push_back(pair); -} - -// static -void HttpStreamFactory::SetHostMappingRules(const std::string& rules) { - HostMappingRules* host_mapping_rules = new HostMappingRules; - host_mapping_rules->SetRulesFromString(rules); - delete host_mapping_rules_; - host_mapping_rules_ = host_mapping_rules; -} - -HttpStreamFactory::HttpStreamFactory() {} - -// static -const HostMappingRules& HttpStreamFactory::host_mapping_rules() { - if (!host_mapping_rules_) - host_mapping_rules_ = new HostMappingRules; - return *host_mapping_rules_; +void HttpStreamFactory::OnPreconnectsComplete( + HttpStreamRequest* request, int result) { + RequestCallbackMap::iterator it = request_callback_map_.find(request); + DCHECK(it != request_callback_map_.end()); + CompletionCallback* callback = it->second; + request_callback_map_.erase(it); + delete request; + callback->Run(result); } } // namespace net + diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h index 3d3bada..97bd79c 100644 --- a/net/http/http_stream_factory.h +++ b/net/http/http_stream_factory.h @@ -6,176 +6,35 @@ #define NET_HTTP_HTTP_STREAM_FACTORY_H_ #include <list> +#include <map> +#include <set> #include <string> -#include "base/string16.h" -#include "base/ref_counted.h" +#include "base/scoped_ptr.h" #include "net/base/completion_callback.h" -#include "net/base/load_states.h" - -class GURL; +#include "net/base/host_mapping_rules.h" +#include "net/base/host_port_pair.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_stream_request.h" +#include "net/http/stream_factory.h" +#include "net/proxy/proxy_service.h" +#include "net/socket/client_socket_handle.h" namespace net { -class BoundNetLog; -class HostMappingRules; -class HostPortPair; -class HttpAlternateProtocols; -class HttpAuthController; class HttpNetworkSession; -class HttpResponseInfo; -class HttpStream; -class ProxyInfo; -class SSLCertRequestInfo; -class SSLInfo; -class X509Certificate; struct HttpRequestInfo; -struct SSLConfig; - -// The HttpStreamRequest is the client's handle to the worker object which -// handles the creation of an HttpStream. While the HttpStream is being -// created, this object is the creator's handle for interacting with the -// HttpStream creation process. The request is cancelled by deleting it, after -// which no callbacks will be invoked. -class HttpStreamRequest { - public: - // The HttpStreamRequest::Delegate is a set of callback methods for a - // HttpStreamRequestJob. Generally, only one of these methods will be - // called as a result of a stream request. - class Delegate { - public: - virtual ~Delegate() {} - - // This is the success case. - // |stream| is now owned by the delegate. - // |used_ssl_config| indicates the actual SSL configuration used for this - // stream, since the HttpStreamRequest may have modified the configuration - // during stream processing. - // |used_proxy_info| indicates the actual ProxyInfo used for this stream, - // since the HttpStreamRequest performs the proxy resolution. - virtual void OnStreamReady( - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - HttpStream* stream) = 0; - - // This is the failure to create a stream case. - // |used_ssl_config| indicates the actual SSL configuration used for this - // stream, since the HttpStreamRequest may have modified the configuration - // during stream processing. - virtual void OnStreamFailed(int status, - const SSLConfig& used_ssl_config) = 0; - - // Called when we have a certificate error for the request. - // |used_ssl_config| indicates the actual SSL configuration used for this - // stream, since the HttpStreamRequest may have modified the configuration - // during stream processing. - virtual void OnCertificateError(int status, - const SSLConfig& used_ssl_config, - const SSLInfo& ssl_info) = 0; - - // This is the failure case where we need proxy authentication during - // proxy tunnel establishment. For the tunnel case, we were unable to - // create the HttpStream, so the caller provides the auth and then resumes - // the HttpStreamRequest. - // - // For the non-tunnel case, the caller will discover the authentication - // failure when reading response headers. At that point, he will handle the - // authentication failure and restart the HttpStreamRequest entirely. - // - // Ownership of |auth_controller| and |proxy_response| are owned - // by the HttpStreamRequest. |proxy_response| is not guaranteed to be usable - // after the lifetime of this callback. The delegate may take a reference - // to |auth_controller| if it is needed beyond the lifetime of this - // callback. - // - // |used_ssl_config| indicates the actual SSL configuration used for this - // stream, since the HttpStreamRequest may have modified the configuration - // during stream processing. - virtual void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - HttpAuthController* auth_controller) = 0; - - // This is the failure for SSL Client Auth - // Ownership of |cert_info| is retained by the HttpStreamRequest. The - // delegate may take a reference if it needs the cert_info beyond the - // lifetime of this callback. - virtual void OnNeedsClientAuth(const SSLConfig& used_ssl_config, - SSLCertRequestInfo* cert_info) = 0; - - // This is the failure of the CONNECT request through an HTTPS proxy. - // Headers can be read from |response_info|, while the body can be read - // from |stream|. - // - // |used_ssl_config| indicates the actual SSL configuration used for this - // stream, since the HttpStreamRequest may have modified the configuration - // during stream processing. - // - // |used_proxy_info| indicates the actual ProxyInfo used for this stream, - // since the HttpStreamRequest performs the proxy resolution. - // - // Ownership of |stream| is transferred to the delegate. - virtual void OnHttpsProxyTunnelResponse( - const HttpResponseInfo& response_info, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - HttpStream* stream) = 0; - }; - - virtual ~HttpStreamRequest() {} - - // When a HttpStream creation process is stalled due to necessity - // of Proxy authentication credentials, the delegate OnNeedsProxyAuth - // will have been called. It now becomes the delegate's responsibility - // to collect the necessary credentials, and then call this method to - // resume the HttpStream creation process. - virtual int RestartTunnelWithProxyAuth(const string16& username, - const string16& password) = 0; - - // Returns the LoadState for the request. - virtual LoadState GetLoadState() const = 0; - - // Returns true if an AlternateProtocol for this request was available. - virtual bool was_alternate_protocol_available() const = 0; - - // Returns true if TLS/NPN was negotiated for this stream. - virtual bool was_npn_negotiated() const = 0; - - // Returns true if this stream is being fetched over SPDY. - virtual bool using_spdy() const = 0; -}; +class HttpStreamRequest; -// The HttpStreamFactory defines an interface for creating usable HttpStreams. -class HttpStreamFactory { +class HttpStreamFactory : public StreamFactory, + public HttpStreamRequest::PreconnectDelegate { public: + HttpStreamFactory(); virtual ~HttpStreamFactory(); - void ProcessAlternateProtocol( - HttpAlternateProtocols* alternate_protocols, - const std::string& alternate_protocol_str, - const HostPortPair& http_host_port_pair); - - // Virtual interface methods. - - // Request a stream. - // Will callback to the HttpStreamRequestDelegate upon completion. - virtual HttpStreamRequest* RequestStream( - const HttpRequestInfo& info, - const SSLConfig& ssl_config, - HttpStreamRequest::Delegate* delegate, - const BoundNetLog& net_log) = 0; - - // Requests that enough connections for |num_streams| be opened. - virtual void PreconnectStreams(int num_streams, - const HttpRequestInfo& info, - const SSLConfig& ssl_config, - const BoundNetLog& net_log) = 0; - - virtual void AddTLSIntolerantServer(const GURL& url) = 0; - virtual bool IsTLSIntolerantServer(const GURL& url) const = 0; - // Static settings - static GURL ApplyHostMappingRules(const GURL& url, HostPortPair* endpoint); // Turns spdy on or off. static void set_spdy_enabled(bool value) { @@ -206,7 +65,12 @@ class HttpStreamFactory { static bool force_spdy_always() { return force_spdy_always_; } // Add a URL to exclude from forced SPDY. - static void add_forced_spdy_exclusion(const std::string& value); + static void add_forced_spdy_exclusion(const std::string& value) { + HostPortPair pair = HostPortPair::FromURL(GURL(value)); + if (!forced_spdy_exclusions_) + forced_spdy_exclusions_ = new std::list<HostPortPair>(); + forced_spdy_exclusions_->push_back(pair); + } static std::list<HostPortPair>* forced_spdy_exclusions() { return forced_spdy_exclusions_; } @@ -218,7 +82,7 @@ class HttpStreamFactory { } static const std::string* next_protos() { return next_protos_; } - // Sets the HttpStreamFactoryImpl into a mode where it can ignore certificate + // Sets the HttpStreamFactory into a mode where it can ignore certificate // errors. This is for testing. static void set_ignore_certificate_errors(bool value) { ignore_certificate_errors_ = value; @@ -229,11 +93,35 @@ class HttpStreamFactory { static void SetHostMappingRules(const std::string& rules); - protected: - HttpStreamFactory(); + // StreamFactory Interface + virtual StreamRequest* RequestStream(const HttpRequestInfo* info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + HttpNetworkSession* session, + StreamRequest::Delegate* delegate, + const BoundNetLog& net_log); + virtual int PreconnectStreams(int num_streams, + const HttpRequestInfo* info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + HttpNetworkSession* session, + const BoundNetLog& net_log, + CompletionCallback* callback); + virtual void AddTLSIntolerantServer(const GURL& url); + virtual bool IsTLSIntolerantServer(const GURL& url); + virtual void ProcessAlternateProtocol( + HttpAlternateProtocols* alternate_protocols, + const std::string& alternate_protocol_str, + const HostPortPair& http_host_port_pair); + virtual GURL ApplyHostMappingRules(const GURL& url, HostPortPair* endpoint); + + // HttpStreamRequest::PreconnectDelegate API + virtual void OnPreconnectsComplete(HttpStreamRequest* request, int result); private: - static const HostMappingRules& host_mapping_rules(); + typedef std::map<HttpStreamRequest*, CompletionCallback*> RequestCallbackMap; + RequestCallbackMap request_callback_map_; + std::set<std::string> tls_intolerant_servers_; static const HostMappingRules* host_mapping_rules_; static const std::string* next_protos_; @@ -250,3 +138,4 @@ class HttpStreamFactory { } // namespace net #endif // NET_HTTP_HTTP_STREAM_FACTORY_H_ + diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc deleted file mode 100644 index 02dd29d..0000000 --- a/net/http/http_stream_factory_impl.cc +++ /dev/null @@ -1,299 +0,0 @@ -// 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. - -#include "net/http/http_stream_factory_impl.h" - -#include "base/stl_util-inl.h" -#include "net/base/net_log.h" -#include "net/base/net_util.h" -#include "net/http/http_network_session.h" -#include "net/http/http_stream_factory_impl_job.h" - -namespace net { - -class HttpStreamFactoryImpl::Request : public HttpStreamRequest { - public: - Request(HttpStreamFactoryImpl* factory, - HttpStreamRequest::Delegate* delegate); - virtual ~Request(); - - Job* job() const { return job_; } - - // Binds |job| to this request. - void BindJob(HttpStreamFactoryImpl::Job* job); - - // Marks completion of the request. Must be called before OnStreamReady(). - void Complete(bool was_alternate_protocol_available, - bool was_npn_negotiated, - bool using_spdy); - - // HttpStreamRequest::Delegate methods which we implement. Note we don't - // actually subclass HttpStreamRequest::Delegate. - - void OnStreamReady( - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - HttpStream* stream); - void OnStreamFailed(int status, const SSLConfig& used_ssl_config); - void OnCertificateError(int status, - const SSLConfig& used_ssl_config, - const SSLInfo& ssl_info); - void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - HttpAuthController* auth_controller); - void OnNeedsClientAuth(const SSLConfig& used_ssl_config, - SSLCertRequestInfo* cert_info); - void OnHttpsProxyTunnelResponse( - const HttpResponseInfo& response_info, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - HttpStream* stream); - - // HttpStreamRequest methods. - - virtual int RestartTunnelWithProxyAuth(const string16& username, - const string16& password); - virtual LoadState GetLoadState() const; - virtual bool was_alternate_protocol_available() const; - virtual bool was_npn_negotiated() const; - virtual bool using_spdy() const; - - private: - HttpStreamFactoryImpl* const factory_; - HttpStreamRequest::Delegate* const delegate_; - - // The |job_| that this request is tied to. - // TODO(willchan): Revisit this when we decouple requests and jobs further. - HttpStreamFactoryImpl::Job* job_; - - bool completed_; - bool was_alternate_protocol_available_; - bool was_npn_negotiated_; - bool using_spdy_; - DISALLOW_COPY_AND_ASSIGN(Request); -}; - -HttpStreamFactoryImpl::Request::Request(HttpStreamFactoryImpl* factory, - HttpStreamRequest::Delegate* delegate) - : factory_(factory), - delegate_(delegate), - job_(NULL), - completed_(false), - was_alternate_protocol_available_(false), - was_npn_negotiated_(false), - using_spdy_(false) { - DCHECK(factory_); - DCHECK(delegate_); -} - -HttpStreamFactoryImpl::Request::~Request() { - factory_->request_map_.erase(job_); - - // TODO(willchan): Remove this when we decouple requests and jobs. - delete job_; -} - -void HttpStreamFactoryImpl::Request::BindJob(HttpStreamFactoryImpl::Job* job) { - DCHECK(job); - DCHECK(!job_); - job_ = job; -} - -void HttpStreamFactoryImpl::Request::Complete( - bool was_alternate_protocol_available, - bool was_npn_negotiated, - bool using_spdy) { - DCHECK(!completed_); - completed_ = true; - was_alternate_protocol_available_ = was_alternate_protocol_available; - was_npn_negotiated_ = was_npn_negotiated; - using_spdy_ = using_spdy; -} - -void HttpStreamFactoryImpl::Request::OnStreamReady( - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - HttpStream* stream) { - DCHECK(stream); - DCHECK(completed_); - delegate_->OnStreamReady(used_ssl_config, used_proxy_info, stream); -} - -void HttpStreamFactoryImpl::Request::OnStreamFailed( - int status, - const SSLConfig& used_ssl_config) { - DCHECK_NE(OK, status); - delegate_->OnStreamFailed(status, used_ssl_config); -} - -void HttpStreamFactoryImpl::Request::OnCertificateError( - int status, - const SSLConfig& used_ssl_config, - const SSLInfo& ssl_info) { - DCHECK_NE(OK, status); - delegate_->OnCertificateError(status, used_ssl_config, ssl_info); -} - -void HttpStreamFactoryImpl::Request::OnNeedsProxyAuth( - const HttpResponseInfo& proxy_response, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - HttpAuthController* auth_controller) { - delegate_->OnNeedsProxyAuth( - proxy_response, used_ssl_config, used_proxy_info, auth_controller); -} - -void HttpStreamFactoryImpl::Request::OnNeedsClientAuth( - const SSLConfig& used_ssl_config, - SSLCertRequestInfo* cert_info) { - delegate_->OnNeedsClientAuth(used_ssl_config, cert_info); -} - -void HttpStreamFactoryImpl::Request::OnHttpsProxyTunnelResponse( - const HttpResponseInfo& response_info, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - HttpStream* stream) { - delegate_->OnHttpsProxyTunnelResponse( - response_info, used_ssl_config, used_proxy_info, stream); -} - -int HttpStreamFactoryImpl::Request::RestartTunnelWithProxyAuth( - const string16& username, - const string16& password) { - return job_->RestartTunnelWithProxyAuth(username, password); -} - -LoadState HttpStreamFactoryImpl::Request::GetLoadState() const { - return factory_->GetLoadState(*this); -} - -bool HttpStreamFactoryImpl::Request::was_alternate_protocol_available() const { - DCHECK(completed_); - return was_alternate_protocol_available_; -} - -bool HttpStreamFactoryImpl::Request::was_npn_negotiated() const { - DCHECK(completed_); - return was_npn_negotiated_; -} - -bool HttpStreamFactoryImpl::Request::using_spdy() const { - DCHECK(completed_); - return using_spdy_; -} - -HttpStreamFactoryImpl::HttpStreamFactoryImpl(HttpNetworkSession* session) - : session_(session) {} - -HttpStreamFactoryImpl::~HttpStreamFactoryImpl() { - DCHECK(request_map_.empty()); - - std::set<const Job*> tmp_job_set; - tmp_job_set.swap(preconnect_job_set_); - STLDeleteContainerPointers(tmp_job_set.begin(), tmp_job_set.end()); - DCHECK(preconnect_job_set_.empty()); -} - -HttpStreamRequest* HttpStreamFactoryImpl::RequestStream( - const HttpRequestInfo& request_info, - const SSLConfig& ssl_config, - HttpStreamRequest::Delegate* delegate, - const BoundNetLog& net_log) { - Job* job = new Job(this, session_); - Request* request = new Request(this, delegate); - request_map_[job] = request; - request->BindJob(job); - job->Start(request_info, ssl_config, net_log); - return request; -} - -void HttpStreamFactoryImpl::PreconnectStreams( - int num_streams, - const HttpRequestInfo& request_info, - const SSLConfig& ssl_config, - const BoundNetLog& net_log) { - Job* job = new Job(this, session_); - preconnect_job_set_.insert(job); - job->Preconnect(num_streams, request_info, ssl_config, net_log); -} - -void HttpStreamFactoryImpl::AddTLSIntolerantServer(const GURL& url) { - tls_intolerant_servers_.insert(GetHostAndPort(url)); -} - -bool HttpStreamFactoryImpl::IsTLSIntolerantServer(const GURL& url) const { - return ContainsKey(tls_intolerant_servers_, GetHostAndPort(url)); -} - -LoadState HttpStreamFactoryImpl::GetLoadState(const Request& request) const { - // TODO(willchan): Will break when we do late binding. - return request.job()->GetLoadState(); -} - -void HttpStreamFactoryImpl::OnStreamReady(const Job* job, - const SSLConfig& ssl_config, - const ProxyInfo& proxy_info, - HttpStream* stream) { - DCHECK(ContainsKey(request_map_, job)); - Request* request = request_map_[job]; - request->Complete(job->was_alternate_protocol_available(), - job->was_npn_negotiated(), - job->using_spdy()); - request->OnStreamReady(ssl_config, proxy_info, stream); -} - -void HttpStreamFactoryImpl::OnStreamFailed(const Job* job, - int result, - const SSLConfig& ssl_config) { - DCHECK(ContainsKey(request_map_, job)); - request_map_[job]->OnStreamFailed(result, ssl_config); -} - -void HttpStreamFactoryImpl::OnCertificateError(const Job* job, - int result, - const SSLConfig& ssl_config, - const SSLInfo& ssl_info) { - DCHECK(ContainsKey(request_map_, job)); - request_map_[job]->OnCertificateError(result, ssl_config, ssl_info); -} - -void HttpStreamFactoryImpl::OnNeedsProxyAuth( - const Job* job, - const HttpResponseInfo& response, - const SSLConfig& ssl_config, - const ProxyInfo& proxy_info, - HttpAuthController* auth_controller) { - DCHECK(ContainsKey(request_map_, job)); - request_map_[job]->OnNeedsProxyAuth( - response, ssl_config, proxy_info, auth_controller); -} - -void HttpStreamFactoryImpl::OnNeedsClientAuth( - const Job* job, - const SSLConfig& ssl_config, - SSLCertRequestInfo* cert_info) { - DCHECK(ContainsKey(request_map_, job)); - request_map_[job]->OnNeedsClientAuth(ssl_config, cert_info); -} - -void HttpStreamFactoryImpl::OnHttpsProxyTunnelResponse( - const Job* job, - const HttpResponseInfo& response_info, - const SSLConfig& ssl_config, - const ProxyInfo& proxy_info, - HttpStream* stream) { - DCHECK(ContainsKey(request_map_, job)); - request_map_[job]->OnHttpsProxyTunnelResponse( - response_info, ssl_config, proxy_info, stream); -} - -void HttpStreamFactoryImpl::OnPreconnectsComplete(const Job* job) { - preconnect_job_set_.erase(job); - delete job; - OnPreconnectsCompleteInternal(); -} - -} // namespace net diff --git a/net/http/http_stream_factory_impl.h b/net/http/http_stream_factory_impl.h deleted file mode 100644 index d86a8fa..0000000 --- a/net/http/http_stream_factory_impl.h +++ /dev/null @@ -1,94 +0,0 @@ -// 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_FACTORY_IMPL_H_ -#define NET_HTTP_HTTP_STREAM_FACTORY_IMPL_H_ - -#include <map> -#include <set> -#include <string> - -#include "net/http/http_stream_factory.h" - -namespace net { - -class HttpNetworkSession; - -class HttpStreamFactoryImpl : public HttpStreamFactory { - public: - explicit HttpStreamFactoryImpl(HttpNetworkSession* session); - virtual ~HttpStreamFactoryImpl(); - - // HttpStreamFactory Interface - virtual HttpStreamRequest* RequestStream( - const HttpRequestInfo& info, - const SSLConfig& ssl_config, - HttpStreamRequest::Delegate* delegate, - const BoundNetLog& net_log); - - virtual void PreconnectStreams(int num_streams, - const HttpRequestInfo& info, - const SSLConfig& ssl_config, - const BoundNetLog& net_log); - virtual void AddTLSIntolerantServer(const GURL& url); - virtual bool IsTLSIntolerantServer(const GURL& url) const; - - private: - class Request; - class Job; - - LoadState GetLoadState(const Request& request) const; - - void OnStreamReady(const Job* job, - const SSLConfig& ssl_config, - const ProxyInfo& proxy_info, - HttpStream* stream); - void OnStreamFailed(const Job* job, int result, const SSLConfig& ssl_config); - void OnCertificateError(const Job* job, - int result, - const SSLConfig& ssl_config, - const SSLInfo& ssl_info); - void OnNeedsProxyAuth(const Job* job, - const HttpResponseInfo& response_info, - const SSLConfig& ssl_config, - const ProxyInfo& proxy_info, - HttpAuthController* auth_controller); - void OnNeedsClientAuth(const Job* job, - const SSLConfig& ssl_config, - SSLCertRequestInfo* cert_info); - void OnHttpsProxyTunnelResponse(const Job* job, - const HttpResponseInfo& response_info, - const SSLConfig& ssl_config, - const ProxyInfo& proxy_info, - HttpStream* stream); - - void OnPreconnectsComplete(const Job* job); - - // Called when the Preconnect completes. Used for testing. - virtual void OnPreconnectsCompleteInternal() {} - - HttpNetworkSession* const session_; - - std::set<std::string> tls_intolerant_servers_; - - // All Requests are handed out to clients. By the time HttpStreamFactoryImpl - // is destroyed, all Requests should be deleted (which should remove them from - // |request_map_|. - // TODO(willchan): Change to a different key when we enable late binding. This - // is the key part that keeps things tightly bound. - // Note that currently the Request assumes ownership of the Job. We will break - // this with late binding, and the factory will own the Job. - std::map<const Job*, Request*> request_map_; - - // These jobs correspond to preconnect requests and have no associated Request - // object. They're owned by HttpStreamFactoryImpl. Leftover jobs will be - // deleted when the factory is destroyed. - std::set<const Job*> preconnect_job_set_; - - DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImpl); -}; - -} // namespace net - -#endif // NET_HTTP_HTTP_STREAM_FACTORY_IMPL_H_ diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_unittest.cc index f316251..617d885 100644 --- a/net/http/http_stream_factory_impl_unittest.cc +++ b/net/http/http_stream_factory_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/http/http_stream_factory_impl.h" +#include "net/http/http_stream_factory.h" #include <string> @@ -16,8 +16,6 @@ #include "net/http/http_network_session.h" #include "net/http/http_network_session_peer.h" #include "net/http/http_request_info.h" -#include "net/proxy/proxy_info.h" -#include "net/proxy/proxy_service.h" #include "net/socket/socket_test_util.h" #include "net/spdy/spdy_session.h" #include "net/spdy/spdy_session_pool.h" @@ -27,34 +25,6 @@ namespace net { namespace { -class MockHttpStreamFactoryImpl : public HttpStreamFactoryImpl { - public: - MockHttpStreamFactoryImpl(HttpNetworkSession* session) - : HttpStreamFactoryImpl(session), - preconnect_done_(false), - waiting_for_preconnect_(false) {} - - - void WaitForPreconnects() { - while (!preconnect_done_) { - waiting_for_preconnect_ = true; - MessageLoop::current()->Run(); - waiting_for_preconnect_ = false; - } - } - - private: - // HttpStreamFactoryImpl methods. - virtual void OnPreconnectsCompleteInternal() { - preconnect_done_ = true; - if (waiting_for_preconnect_) - MessageLoop::current()->Quit(); - } - - bool preconnect_done_; - bool waiting_for_preconnect_; -}; - struct SessionDependencies { // Custom proxy service dependency. explicit SessionDependencies(ProxyService* proxy_service) @@ -100,12 +70,8 @@ TestCase kTests[] = { { 2, true}, }; -void PreconnectHelper(const TestCase& test, - HttpNetworkSession* session) { - HttpNetworkSessionPeer peer(session); - MockHttpStreamFactoryImpl* mock_factory = - new MockHttpStreamFactoryImpl(session); - peer.SetHttpStreamFactory(mock_factory); +int PreconnectHelper(const TestCase& test, + HttpNetworkSession* session) { SSLConfig ssl_config; session->ssl_config_service()->GetSSLConfig(&ssl_config); @@ -118,9 +84,12 @@ void PreconnectHelper(const TestCase& test, ProxyInfo proxy_info; TestCompletionCallback callback; - session->http_stream_factory()->PreconnectStreams( - test.num_streams, request, ssl_config, BoundNetLog()); - mock_factory->WaitForPreconnects(); + int rv = session->http_stream_factory()->PreconnectStreams( + test.num_streams, &request, &ssl_config, &proxy_info, session, + BoundNetLog(), &callback); + if (rv != ERR_IO_PENDING) + return ERR_UNEXPECTED; + return callback.WaitForResult(); }; template<typename ParentPool> @@ -226,7 +195,7 @@ TEST(HttpStreamFactoryTest, PreconnectDirect) { session_deps.host_resolver.get(), session_deps.cert_verifier.get()); peer.SetSSLSocketPool(ssl_conn_pool); - PreconnectHelper(kTests[i], session); + EXPECT_EQ(OK, PreconnectHelper(kTests[i], session)); if (kTests[i].ssl) EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); else @@ -250,7 +219,7 @@ TEST(HttpStreamFactoryTest, PreconnectHttpProxy) { session_deps.host_resolver.get(), session_deps.cert_verifier.get()); peer.SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); - PreconnectHelper(kTests[i], session); + EXPECT_EQ(OK, PreconnectHelper(kTests[i], session)); if (kTests[i].ssl) EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); else @@ -275,7 +244,7 @@ TEST(HttpStreamFactoryTest, PreconnectSocksProxy) { session_deps.host_resolver.get(), session_deps.cert_verifier.get()); peer.SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); - PreconnectHelper(kTests[i], session); + EXPECT_EQ(OK, PreconnectHelper(kTests[i], session)); if (kTests[i].ssl) EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); else @@ -293,7 +262,8 @@ TEST(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) { HostPortPair host_port_pair("www.google.com", 443); HostPortProxyPair pair(host_port_pair, ProxyServer::Direct()); scoped_refptr<SpdySession> spdy_session = - session->spdy_session_pool()->Get(pair, BoundNetLog()); + session->spdy_session_pool()->Get( + pair, session->mutable_spdy_settings(), BoundNetLog()); CapturePreconnectsTCPSocketPool* tcp_conn_pool = new CapturePreconnectsTCPSocketPool( @@ -305,7 +275,7 @@ TEST(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) { session_deps.host_resolver.get(), session_deps.cert_verifier.get()); peer.SetSSLSocketPool(ssl_conn_pool); - PreconnectHelper(kTests[i], session); + EXPECT_EQ(OK, PreconnectHelper(kTests[i], session)); // We shouldn't be preconnecting if we have an existing session, which is // the case for https://www.google.com. if (kTests[i].ssl) diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_request.cc index 3f1968c..4814e55 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_request.cc @@ -2,9 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/http/http_stream_factory_impl_job.h" +#include "net/http/http_stream_request.h" -#include "base/logging.h" #include "base/stl_util-inl.h" #include "base/string_number_conversions.h" #include "base/string_util.h" @@ -45,12 +44,18 @@ GURL UpgradeUrlToHttps(const GURL& original_url) { } // namespace -HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory, - HttpNetworkSession* session) - : ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_(this, &Job::OnIOComplete)), - connection_(new ClientSocketHandle), +HttpStreamRequest::HttpStreamRequest( + StreamFactory* factory, + HttpNetworkSession* session) + : request_info_(NULL), + proxy_info_(NULL), + ssl_config_(NULL), session_(session), - stream_factory_(stream_factory), + ALLOW_THIS_IN_INITIALIZER_LIST( + io_callback_(this, &HttpStreamRequest::OnIOComplete)), + connection_(new ClientSocketHandle), + factory_(factory), + delegate_(NULL), next_state_(STATE_NONE), pac_request_(NULL), using_ssl_(false), @@ -62,6 +67,7 @@ HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory, establishing_tunnel_(false), was_alternate_protocol_available_(false), was_npn_negotiated_(false), + preconnect_delegate_(NULL), num_streams_(0), ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { if (HttpStreamFactory::use_alternate_protocols()) @@ -70,7 +76,7 @@ HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory, alternate_protocol_mode_ = kDoNotUseAlternateProtocol; } -HttpStreamFactoryImpl::Job::~Job() { +HttpStreamRequest::~HttpStreamRequest() { // When we're in a partially constructed state, waiting for the user to // provide certificate handling information or authentication, we can't reuse // this stream at all. @@ -87,30 +93,49 @@ HttpStreamFactoryImpl::Job::~Job() { stream_->Close(true /* not reusable */); } -void HttpStreamFactoryImpl::Job::Start(const HttpRequestInfo& request_info, - const SSLConfig& ssl_config, - const BoundNetLog& net_log) { - StartInternal(request_info, ssl_config, net_log); +void HttpStreamRequest::Start(const HttpRequestInfo* request_info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + Delegate* delegate, + const BoundNetLog& net_log) { + DCHECK(preconnect_delegate_ == NULL && delegate_ == NULL); + DCHECK(delegate); + delegate_ = delegate; + StartInternal(request_info, ssl_config, proxy_info, net_log); } -int HttpStreamFactoryImpl::Job::Preconnect(int num_streams, - const HttpRequestInfo& request_info, - const SSLConfig& ssl_config, - const BoundNetLog& net_log) { - DCHECK_GT(num_streams, 0); +int HttpStreamRequest::Preconnect(int num_streams, + const HttpRequestInfo* request_info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + PreconnectDelegate* delegate, + const BoundNetLog& net_log) { + DCHECK(preconnect_delegate_ == NULL && delegate_ == NULL); + DCHECK(delegate); num_streams_ = num_streams; - return StartInternal(request_info, ssl_config, net_log); + preconnect_delegate_ = delegate; + return StartInternal(request_info, ssl_config, proxy_info, net_log); +} + +int HttpStreamRequest::RestartWithCertificate(X509Certificate* client_cert) { + ssl_config()->client_cert = client_cert; + ssl_config()->send_client_cert = true; + next_state_ = STATE_INIT_CONNECTION; + // Reset the other member variables. + // Note: this is necessary only with SSL renegotiation. + stream_.reset(); + return RunLoop(OK); } -int HttpStreamFactoryImpl::Job::RestartTunnelWithProxyAuth( - const string16& username, const string16& password) { +int HttpStreamRequest::RestartTunnelWithProxyAuth(const string16& username, + const string16& password) { DCHECK(establishing_tunnel_); next_state_ = STATE_RESTART_TUNNEL_AUTH; stream_.reset(); return RunLoop(OK); } -LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { +LoadState HttpStreamRequest::GetLoadState() const { switch (next_state_) { case STATE_RESOLVE_PROXY_COMPLETE: return LOAD_STATE_RESOLVING_PROXY_FOR_URL; @@ -123,19 +148,19 @@ LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { } } -bool HttpStreamFactoryImpl::Job::was_alternate_protocol_available() const { +bool HttpStreamRequest::was_alternate_protocol_available() const { return was_alternate_protocol_available_; } -bool HttpStreamFactoryImpl::Job::was_npn_negotiated() const { +bool HttpStreamRequest::was_npn_negotiated() const { return was_npn_negotiated_; } -bool HttpStreamFactoryImpl::Job::using_spdy() const { +bool HttpStreamRequest::using_spdy() const { return using_spdy_; } -void HttpStreamFactoryImpl::Job::GetSSLInfo() { +void HttpStreamRequest::GetSSLInfo() { DCHECK(using_ssl_); DCHECK(!establishing_tunnel_); DCHECK(connection_.get() && connection_->socket()); @@ -144,59 +169,70 @@ void HttpStreamFactoryImpl::Job::GetSSLInfo() { ssl_socket->GetSSLInfo(&ssl_info_); } -void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() { +const HttpRequestInfo& HttpStreamRequest::request_info() const { + return *request_info_; +} + +ProxyInfo* HttpStreamRequest::proxy_info() const { + return proxy_info_; +} + +SSLConfig* HttpStreamRequest::ssl_config() const { + return ssl_config_; +} + +void HttpStreamRequest::OnStreamReadyCallback() { DCHECK(stream_.get()); - stream_factory_->OnStreamReady( - this, ssl_config_, proxy_info_, stream_.release()); + delegate_->OnStreamReady(stream_.release()); } -void HttpStreamFactoryImpl::Job::OnStreamFailedCallback(int result) { - stream_factory_->OnStreamFailed(this, result, ssl_config_); +void HttpStreamRequest::OnStreamFailedCallback(int result) { + delegate_->OnStreamFailed(result); } -void HttpStreamFactoryImpl::Job::OnCertificateErrorCallback( - int result, const SSLInfo& ssl_info) { - stream_factory_->OnCertificateError(this, result, ssl_config_, ssl_info); +void HttpStreamRequest::OnCertificateErrorCallback(int result, + const SSLInfo& ssl_info) { + delegate_->OnCertificateError(result, ssl_info); } -void HttpStreamFactoryImpl::Job::OnNeedsProxyAuthCallback( +void HttpStreamRequest::OnNeedsProxyAuthCallback( const HttpResponseInfo& response, HttpAuthController* auth_controller) { - stream_factory_->OnNeedsProxyAuth( - this, response, ssl_config_, proxy_info_, auth_controller); + delegate_->OnNeedsProxyAuth(response, auth_controller); } -void HttpStreamFactoryImpl::Job::OnNeedsClientAuthCallback( +void HttpStreamRequest::OnNeedsClientAuthCallback( SSLCertRequestInfo* cert_info) { - stream_factory_->OnNeedsClientAuth(this, ssl_config_, cert_info); + delegate_->OnNeedsClientAuth(cert_info); } -void HttpStreamFactoryImpl::Job::OnHttpsProxyTunnelResponseCallback( +void HttpStreamRequest::OnHttpsProxyTunnelResponseCallback( const HttpResponseInfo& response_info, HttpStream* stream) { - stream_factory_->OnHttpsProxyTunnelResponse( - this, response_info, ssl_config_, proxy_info_, stream); + delegate_->OnHttpsProxyTunnelResponse(response_info, stream); } -void HttpStreamFactoryImpl::Job::OnPreconnectsComplete() { - stream_factory_->OnPreconnectsComplete(this); +void HttpStreamRequest::OnPreconnectsComplete(int result) { + preconnect_delegate_->OnPreconnectsComplete(this, result); } -void HttpStreamFactoryImpl::Job::OnIOComplete(int result) { +void HttpStreamRequest::OnIOComplete(int result) { RunLoop(result); } -int HttpStreamFactoryImpl::Job::RunLoop(int result) { +int HttpStreamRequest::RunLoop(int result) { result = DoLoop(result); + DCHECK(delegate_ || preconnect_delegate_); + if (result == ERR_IO_PENDING) return result; - if (IsPreconnecting()) { + if (preconnect_delegate_) { MessageLoop::current()->PostTask( FROM_HERE, method_factory_.NewRunnableMethod( - &HttpStreamFactoryImpl::Job::OnPreconnectsComplete)); + &HttpStreamRequest::OnPreconnectsComplete, result)); return ERR_IO_PENDING; } @@ -208,7 +244,7 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) { MessageLoop::current()->PostTask( FROM_HERE, method_factory_.NewRunnableMethod( - &HttpStreamFactoryImpl::Job::OnCertificateErrorCallback, + &HttpStreamRequest::OnCertificateErrorCallback, result, ssl_info_)); return ERR_IO_PENDING; } @@ -229,7 +265,7 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) { MessageLoop::current()->PostTask( FROM_HERE, method_factory_.NewRunnableMethod( - &HttpStreamFactoryImpl::Job::OnNeedsProxyAuthCallback, + &HttpStreamRequest::OnNeedsProxyAuthCallback, *tunnel_auth_response, http_proxy_socket->auth_controller())); } @@ -239,7 +275,7 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) { MessageLoop::current()->PostTask( FROM_HERE, method_factory_.NewRunnableMethod( - &HttpStreamFactoryImpl::Job::OnNeedsClientAuthCallback, + &HttpStreamRequest::OnNeedsClientAuthCallback, connection_->ssl_error_response_info().cert_request_info)); return ERR_IO_PENDING; @@ -254,7 +290,7 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) { MessageLoop::current()->PostTask( FROM_HERE, method_factory_.NewRunnableMethod( - &HttpStreamFactoryImpl::Job::OnHttpsProxyTunnelResponseCallback, + &HttpStreamRequest::OnHttpsProxyTunnelResponseCallback, *proxy_socket->GetConnectResponseInfo(), proxy_socket->CreateConnectResponseStream())); return ERR_IO_PENDING; @@ -265,21 +301,21 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) { MessageLoop::current()->PostTask( FROM_HERE, method_factory_.NewRunnableMethod( - &HttpStreamFactoryImpl::Job::OnStreamReadyCallback)); + &HttpStreamRequest::OnStreamReadyCallback)); return ERR_IO_PENDING; default: MessageLoop::current()->PostTask( FROM_HERE, method_factory_.NewRunnableMethod( - &HttpStreamFactoryImpl::Job::OnStreamFailedCallback, + &HttpStreamRequest::OnStreamFailedCallback, result)); return ERR_IO_PENDING; } return result; } -int HttpStreamFactoryImpl::Job::DoLoop(int result) { +int HttpStreamRequest::DoLoop(int result) { DCHECK_NE(next_state_, STATE_NONE); int rv = result; do { @@ -326,13 +362,14 @@ int HttpStreamFactoryImpl::Job::DoLoop(int result) { return rv; } -int HttpStreamFactoryImpl::Job::StartInternal( - const HttpRequestInfo& request_info, - const SSLConfig& ssl_config, - const BoundNetLog& net_log) { +int HttpStreamRequest::StartInternal(const HttpRequestInfo* request_info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + const BoundNetLog& net_log) { CHECK_EQ(STATE_NONE, next_state_); request_info_ = request_info; ssl_config_ = ssl_config; + proxy_info_ = proxy_info; net_log_ = net_log; next_state_ = STATE_RESOLVE_PROXY; int rv = RunLoop(OK); @@ -340,24 +377,23 @@ int HttpStreamFactoryImpl::Job::StartInternal( return rv; } -int HttpStreamFactoryImpl::Job::DoResolveProxy() { +int HttpStreamRequest::DoResolveProxy() { DCHECK(!pac_request_); next_state_ = STATE_RESOLVE_PROXY_COMPLETE; // |endpoint_| indicates the final destination endpoint. - endpoint_ = HostPortPair(request_info_.url.HostNoBrackets(), - request_info_.url.EffectiveIntPort()); + endpoint_ = HostPortPair(request_info().url.HostNoBrackets(), + request_info().url.EffectiveIntPort()); // Extra URL we might be attempting to resolve to. - GURL alternate_endpoint_url = request_info_.url; + GURL alternate_endpoint_url = request_info().url; // Tracks whether we are using |request_.url| or |alternate_endpoint_url|. - const GURL *curr_endpoint_url = &request_info_.url; + const GURL *curr_endpoint_url = &request_info().url; alternate_endpoint_url = - HttpStreamFactory::ApplyHostMappingRules( - alternate_endpoint_url, &endpoint_); + factory_->ApplyHostMappingRules(alternate_endpoint_url, &endpoint_); const HttpAlternateProtocols& alternate_protocols = session_->alternate_protocols(); @@ -380,17 +416,17 @@ int HttpStreamFactoryImpl::Job::DoResolveProxy() { } } - if (request_info_.load_flags & LOAD_BYPASS_PROXY) { - proxy_info_.UseDirect(); + if (request_info().load_flags & LOAD_BYPASS_PROXY) { + proxy_info()->UseDirect(); return OK; } return session_->proxy_service()->ResolveProxy( - *curr_endpoint_url, &proxy_info_, &io_callback_, &pac_request_, + *curr_endpoint_url, proxy_info(), &io_callback_, &pac_request_, net_log_); } -int HttpStreamFactoryImpl::Job::DoResolveProxyComplete(int result) { +int HttpStreamRequest::DoResolveProxyComplete(int result) { pac_request_ = NULL; if (result != OK) @@ -400,12 +436,12 @@ int HttpStreamFactoryImpl::Job::DoResolveProxyComplete(int result) { // AlternateProtocol. // Remove unsupported proxies from the list. - proxy_info_.RemoveProxiesWithoutScheme( + proxy_info()->RemoveProxiesWithoutScheme( ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP | ProxyServer::SCHEME_HTTPS | ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5); - if (proxy_info_.is_empty()) { + if (proxy_info()->is_empty()) { // No proxies/direct to choose from. This happens when we don't support any // of the proxies in the returned list. return ERR_NO_SUPPORTED_PROXIES; @@ -415,7 +451,7 @@ int HttpStreamFactoryImpl::Job::DoResolveProxyComplete(int result) { return OK; } -static bool HasSpdyExclusion(const HostPortPair& endpoint) { +bool HasSpdyExclusion(const HostPortPair& endpoint) { std::list<HostPortPair>* exclusions = HttpStreamFactory::forced_spdy_exclusions(); if (!exclusions) @@ -428,25 +464,25 @@ static bool HasSpdyExclusion(const HostPortPair& endpoint) { return false; } -bool HttpStreamFactoryImpl::Job::ShouldForceSpdySSL() { +bool HttpStreamRequest::ShouldForceSpdySSL() { bool rv = force_spdy_always_ && force_spdy_over_ssl_; return rv && !HasSpdyExclusion(endpoint_); } -bool HttpStreamFactoryImpl::Job::ShouldForceSpdyWithoutSSL() { +bool HttpStreamRequest::ShouldForceSpdyWithoutSSL() { bool rv = force_spdy_always_ && !force_spdy_over_ssl_; return rv && !HasSpdyExclusion(endpoint_); } -int HttpStreamFactoryImpl::Job::DoInitConnection() { +int HttpStreamRequest::DoInitConnection() { DCHECK(!connection_->is_initialized()); - DCHECK(proxy_info_.proxy_server().is_valid()); + DCHECK(proxy_info()->proxy_server().is_valid()); next_state_ = STATE_INIT_CONNECTION_COMPLETE; bool want_spdy_over_npn = alternate_protocol_mode_ == kUsingAlternateProtocol && alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_2; - using_ssl_ = request_info_.url.SchemeIs("https") || + using_ssl_ = request_info().url.SchemeIs("https") || ShouldForceSpdySSL() || want_spdy_over_npn; using_spdy_ = false; @@ -455,11 +491,11 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { if (HttpStreamFactory::spdy_enabled() && !HasSpdyExclusion(endpoint_)) { // Check first if we have a spdy session for this group. If so, then go // straight to using that. - HostPortProxyPair pair(endpoint_, proxy_info_.proxy_server()); + HostPortProxyPair pair(endpoint_, proxy_info()->proxy_server()); if (session_->spdy_session_pool()->HasSession(pair)) { // If we're preconnecting, but we already have a SpdySession, we don't // actually need to preconnect any sockets, so we're done. - if (IsPreconnecting()) + if (preconnect_delegate_) return OK; using_spdy_ = true; next_state_ = STATE_CREATE_STREAM; @@ -468,7 +504,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { // Check next if we have a spdy session for this proxy. If so, then go // straight to using that. if (IsHttpsProxyAndHttpUrl()) { - HostPortProxyPair proxy(proxy_info_.proxy_server().host_port_pair(), + HostPortProxyPair proxy(proxy_info()->proxy_server().host_port_pair(), ProxyServer::Direct()); if (session_->spdy_session_pool()->HasSession(proxy)) { using_spdy_ = true; @@ -488,9 +524,9 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { // If the user is refreshing the page, bypass the host cache. bool disable_resolver_cache = - request_info_.load_flags & LOAD_BYPASS_CACHE || - request_info_.load_flags & LOAD_VALIDATE_CACHE || - request_info_.load_flags & LOAD_DISABLE_CACHE; + request_info().load_flags & LOAD_BYPASS_CACHE || + request_info().load_flags & LOAD_VALIDATE_CACHE || + request_info().load_flags & LOAD_DISABLE_CACHE; // Build up the connection parameters. scoped_refptr<TCPSocketParams> tcp_params; @@ -498,19 +534,19 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { scoped_refptr<SOCKSSocketParams> socks_params; scoped_ptr<HostPortPair> proxy_host_port; - if (proxy_info_.is_direct()) { - tcp_params = new TCPSocketParams(endpoint_, request_info_.priority, - request_info_.referrer, + if (proxy_info()->is_direct()) { + tcp_params = new TCPSocketParams(endpoint_, request_info().priority, + request_info().referrer, disable_resolver_cache); } else { - ProxyServer proxy_server = proxy_info_.proxy_server(); + ProxyServer proxy_server = proxy_info()->proxy_server(); proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair())); scoped_refptr<TCPSocketParams> proxy_tcp_params( - new TCPSocketParams(*proxy_host_port, request_info_.priority, - request_info_.referrer, disable_resolver_cache)); + new TCPSocketParams(*proxy_host_port, request_info().priority, + request_info().referrer, disable_resolver_cache)); - if (proxy_info_.is_http() || proxy_info_.is_https()) { - GURL authentication_url = request_info_.url; + if (proxy_info()->is_http() || proxy_info()->is_https()) { + GURL authentication_url = request_info().url; if (using_ssl_ && !authentication_url.SchemeIs("https")) { // If a proxy tunnel connection needs to be established due to // an Alternate-Protocol, the URL needs to be changed to indicate @@ -525,10 +561,10 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { } establishing_tunnel_ = using_ssl_; std::string user_agent; - request_info_.extra_headers.GetHeader(HttpRequestHeaders::kUserAgent, + request_info().extra_headers.GetHeader(HttpRequestHeaders::kUserAgent, &user_agent); scoped_refptr<SSLSocketParams> ssl_params; - if (proxy_info_.is_https()) { + if (proxy_info()->is_https()) { // Set ssl_params, and unset proxy_tcp_params ssl_params = GenerateSSLParams(proxy_tcp_params, NULL, NULL, ProxyServer::SCHEME_DIRECT, @@ -543,12 +579,13 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { authentication_url, user_agent, endpoint_, - session_->http_auth_cache(), + session_->auth_cache(), session_->http_auth_handler_factory(), session_->spdy_session_pool(), + session_->mutable_spdy_settings(), using_ssl_); } else { - DCHECK(proxy_info_.is_socks()); + DCHECK(proxy_info()->is_socks()); char socks_version; if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5) socks_version = '5'; @@ -560,8 +597,8 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { socks_params = new SOCKSSocketParams(proxy_tcp_params, socks_version == '5', endpoint_, - request_info_.priority, - request_info_.referrer); + request_info().priority, + request_info().referrer); } } @@ -569,71 +606,71 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { if (using_ssl_) { scoped_refptr<SSLSocketParams> ssl_params = GenerateSSLParams(tcp_params, http_proxy_params, socks_params, - proxy_info_.proxy_server().scheme(), - HostPortPair::FromURL(request_info_.url), + proxy_info()->proxy_server().scheme(), + HostPortPair::FromURL(request_info().url), want_spdy_over_npn); SSLClientSocketPool* ssl_pool = NULL; - if (proxy_info_.is_direct()) + if (proxy_info()->is_direct()) ssl_pool = session_->ssl_socket_pool(); else ssl_pool = session_->GetSocketPoolForSSLWithProxy(*proxy_host_port); - if (IsPreconnecting()) { + if (preconnect_delegate_) { RequestSocketsForPool(ssl_pool, connection_group, ssl_params, num_streams_, net_log_); return OK; } return connection_->Init(connection_group, ssl_params, - request_info_.priority, &io_callback_, ssl_pool, + request_info().priority, &io_callback_, ssl_pool, net_log_); } // Finally, get the connection started. - if (proxy_info_.is_http() || proxy_info_.is_https()) { + if (proxy_info()->is_http() || proxy_info()->is_https()) { HttpProxyClientSocketPool* pool = session_->GetSocketPoolForHTTPProxy(*proxy_host_port); - if (IsPreconnecting()) { + if (preconnect_delegate_) { RequestSocketsForPool(pool, connection_group, http_proxy_params, num_streams_, net_log_); return OK; } return connection_->Init(connection_group, http_proxy_params, - request_info_.priority, &io_callback_, + request_info().priority, &io_callback_, pool, net_log_); } - if (proxy_info_.is_socks()) { + if (proxy_info()->is_socks()) { SOCKSClientSocketPool* pool = session_->GetSocketPoolForSOCKSProxy(*proxy_host_port); - if (IsPreconnecting()) { + if (preconnect_delegate_) { RequestSocketsForPool(pool, connection_group, socks_params, num_streams_, net_log_); return OK; } return connection_->Init(connection_group, socks_params, - request_info_.priority, &io_callback_, pool, + request_info().priority, &io_callback_, pool, net_log_); } - DCHECK(proxy_info_.is_direct()); + DCHECK(proxy_info()->is_direct()); TCPClientSocketPool* pool = session_->tcp_socket_pool(); - if (IsPreconnecting()) { + if (preconnect_delegate_) { RequestSocketsForPool(pool, connection_group, tcp_params, num_streams_, net_log_); return OK; } return connection_->Init(connection_group, tcp_params, - request_info_.priority, &io_callback_, + request_info().priority, &io_callback_, pool, net_log_); } -int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { - if (IsPreconnecting()) { +int HttpStreamRequest::DoInitConnectionComplete(int result) { + if (preconnect_delegate_) { DCHECK_EQ(OK, result); return OK; } @@ -659,7 +696,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { } if (ShouldForceSpdySSL()) SwitchToSpdyMode(); - } else if (proxy_info_.is_https() && connection_->socket() && + } else if (proxy_info()->is_https() && connection_->socket() && result == OK) { HttpProxyClientSocket* proxy_socket = static_cast<HttpProxyClientSocket*>(connection_->socket()); @@ -712,7 +749,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { if (using_ssl_) { DCHECK(ssl_started); if (IsCertificateError(result)) { - if (using_spdy_ && request_info_.url.SchemeIs("http")) { + if (using_spdy_ && request_info().url.SchemeIs("http")) { // We ignore certificate errors for http over spdy. spdy_certificate_error_ = result; result = OK; @@ -734,7 +771,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { return OK; } -int HttpStreamFactoryImpl::Job::DoWaitingUserAction(int result) { +int HttpStreamRequest::DoWaitingUserAction(int result) { // This state indicates that the stream request is in a partially // completed state, and we've called back to the delegate for more // information. @@ -743,7 +780,7 @@ int HttpStreamFactoryImpl::Job::DoWaitingUserAction(int result) { return ERR_IO_PENDING; } -int HttpStreamFactoryImpl::Job::DoCreateStream() { +int HttpStreamRequest::DoCreateStream() { next_state_ = STATE_CREATE_STREAM_COMPLETE; // We only set the socket motivation if we're the first to use @@ -752,11 +789,11 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { if (connection_->socket() && !connection_->is_reused()) SetSocketMotivation(); - const ProxyServer& proxy_server = proxy_info_.proxy_server(); + const ProxyServer& proxy_server = proxy_info()->proxy_server(); if (!using_spdy_) { - bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && - request_info_.url.SchemeIs("http"); + bool using_proxy = (proxy_info()->is_http() || proxy_info()->is_https()) && + request_info().url.SchemeIs("http"); stream_.reset(new HttpBasicStream(connection_.release(), NULL, using_proxy)); return OK; @@ -772,14 +809,16 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { if (spdy_pool->HasSession(pair)) { // We have a SPDY session to the origin server. This might be a direct // connection, or it might be a SPDY session through an HTTP or HTTPS proxy. - spdy_session = spdy_pool->Get(pair, net_log_); + spdy_session = + spdy_pool->Get(pair, session_->mutable_spdy_settings(), net_log_); } else if (IsHttpsProxyAndHttpUrl()) { // If we don't have a direct SPDY session, and we're using an HTTPS // proxy, then we might have a SPDY session to the proxy pair = HostPortProxyPair(proxy_server.host_port_pair(), ProxyServer::Direct()); if (spdy_pool->HasSession(pair)) { - spdy_session = spdy_pool->Get(pair, net_log_); + spdy_session = + spdy_pool->Get(pair, session_->mutable_spdy_settings(), net_log_); } direct = false; } @@ -795,8 +834,8 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { // contain an SSLClientSocket. CHECK(connection_->socket()); int error = spdy_pool->GetSpdySessionFromSocket( - pair, connection_.release(), net_log_, spdy_certificate_error_, - &spdy_session, using_ssl_); + pair, session_->mutable_spdy_settings(), connection_.release(), + net_log_, spdy_certificate_error_, &spdy_session, using_ssl_); if (error != OK) return error; } @@ -804,12 +843,12 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { if (spdy_session->IsClosed()) return ERR_CONNECTION_CLOSED; - bool use_relative_url = direct || request_info_.url.SchemeIs("https"); + bool use_relative_url = direct || request_info().url.SchemeIs("https"); stream_.reset(new SpdyHttpStream(spdy_session, use_relative_url)); return OK; } -int HttpStreamFactoryImpl::Job::DoCreateStreamComplete(int result) { +int HttpStreamRequest::DoCreateStreamComplete(int result) { if (result < 0) return result; @@ -817,14 +856,14 @@ int HttpStreamFactoryImpl::Job::DoCreateStreamComplete(int result) { return OK; } -int HttpStreamFactoryImpl::Job::DoRestartTunnelAuth() { +int HttpStreamRequest::DoRestartTunnelAuth() { next_state_ = STATE_RESTART_TUNNEL_AUTH_COMPLETE; HttpProxyClientSocket* http_proxy_socket = static_cast<HttpProxyClientSocket*>(connection_->socket()); return http_proxy_socket->RestartWithAuth(&io_callback_); } -int HttpStreamFactoryImpl::Job::DoRestartTunnelAuthComplete(int result) { +int HttpStreamRequest::DoRestartTunnelAuthComplete(int result) { if (result == ERR_PROXY_AUTH_REQUESTED) return result; @@ -844,21 +883,21 @@ int HttpStreamFactoryImpl::Job::DoRestartTunnelAuthComplete(int result) { return ReconsiderProxyAfterError(result); } -void HttpStreamFactoryImpl::Job::SetSocketMotivation() { - if (request_info_.motivation == HttpRequestInfo::PRECONNECT_MOTIVATED) +void HttpStreamRequest::SetSocketMotivation() { + if (request_info_->motivation == HttpRequestInfo::PRECONNECT_MOTIVATED) connection_->socket()->SetSubresourceSpeculation(); - else if (request_info_.motivation == HttpRequestInfo::OMNIBOX_MOTIVATED) + else if (request_info_->motivation == HttpRequestInfo::OMNIBOX_MOTIVATED) connection_->socket()->SetOmniboxSpeculation(); // TODO(mbelshe): Add other motivations (like EARLY_LOAD_MOTIVATED). } -bool HttpStreamFactoryImpl::Job::IsHttpsProxyAndHttpUrl() { - return proxy_info_.is_https() && request_info_.url.SchemeIs("http"); +bool HttpStreamRequest::IsHttpsProxyAndHttpUrl() { + return proxy_info()->is_https() && request_info().url.SchemeIs("http"); } // Returns a newly create SSLSocketParams, and sets several // fields of ssl_config_. -scoped_refptr<SSLSocketParams> HttpStreamFactoryImpl::Job::GenerateSSLParams( +scoped_refptr<SSLSocketParams> HttpStreamRequest::GenerateSSLParams( scoped_refptr<TCPSocketParams> tcp_params, scoped_refptr<HttpProxySocketParams> http_proxy_params, scoped_refptr<SOCKSSocketParams> socks_params, @@ -866,14 +905,14 @@ scoped_refptr<SSLSocketParams> HttpStreamFactoryImpl::Job::GenerateSSLParams( const HostPortPair& host_and_port, bool want_spdy_over_npn) { - if (stream_factory_->IsTLSIntolerantServer(request_info_.url)) { + if (factory_->IsTLSIntolerantServer(request_info().url)) { LOG(WARNING) << "Falling back to SSLv3 because host is TLS intolerant: " - << GetHostAndPort(request_info_.url); - ssl_config_.ssl3_fallback = true; - ssl_config_.tls1_enabled = false; + << GetHostAndPort(request_info().url); + ssl_config()->ssl3_fallback = true; + ssl_config()->tls1_enabled = false; } - if (proxy_info_.is_https() && ssl_config_.send_client_cert) { + if (proxy_info()->is_https() && ssl_config()->send_client_cert) { // When connecting through an HTTPS proxy, disable TLS False Start so // that client authentication errors can be distinguished between those // originating from the proxy server (ERR_PROXY_CONNECTION_FAILED) and @@ -882,27 +921,27 @@ scoped_refptr<SSLSocketParams> HttpStreamFactoryImpl::Job::GenerateSSLParams( // TODO(rch): This assumes that the HTTPS proxy will only request a // client certificate during the initial handshake. // http://crbug.com/59292 - ssl_config_.false_start_enabled = false; + ssl_config()->false_start_enabled = false; } UMA_HISTOGRAM_ENUMERATION("Net.ConnectionUsedSSLv3Fallback", - static_cast<int>(ssl_config_.ssl3_fallback), 2); + static_cast<int>(ssl_config()->ssl3_fallback), 2); - int load_flags = request_info_.load_flags; + int load_flags = request_info().load_flags; if (HttpStreamFactory::ignore_certificate_errors()) load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; - if (request_info_.load_flags & LOAD_VERIFY_EV_CERT) - ssl_config_.verify_ev_cert = true; + if (request_info().load_flags & LOAD_VERIFY_EV_CERT) + ssl_config()->verify_ev_cert = true; - if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_HTTP || - proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_HTTPS) { - ssl_config_.mitm_proxies_allowed = true; + if (proxy_info()->proxy_server().scheme() == ProxyServer::SCHEME_HTTP || + proxy_info()->proxy_server().scheme() == ProxyServer::SCHEME_HTTPS) { + ssl_config()->mitm_proxies_allowed = true; } scoped_refptr<SSLSocketParams> ssl_params( new SSLSocketParams(tcp_params, socks_params, http_proxy_params, proxy_scheme, host_and_port, - ssl_config_, load_flags, + *ssl_config(), load_flags, ShouldForceSpdySSL(), want_spdy_over_npn)); @@ -910,7 +949,7 @@ scoped_refptr<SSLSocketParams> HttpStreamFactoryImpl::Job::GenerateSSLParams( } -void HttpStreamFactoryImpl::Job::MarkBrokenAlternateProtocolAndFallback() { +void HttpStreamRequest::MarkBrokenAlternateProtocolAndFallback() { // We have to: // * Reset the endpoint to be the unmodified URL specified destination. // * Mark the endpoint as broken so we don't try again. @@ -918,8 +957,8 @@ void HttpStreamFactoryImpl::Job::MarkBrokenAlternateProtocolAndFallback() { // ignore future Alternate-Protocol headers from the HostPortPair. // * Reset the connection and go back to STATE_INIT_CONNECTION. - endpoint_ = HostPortPair(request_info_.url.HostNoBrackets(), - request_info_.url.EffectiveIntPort()); + endpoint_ = HostPortPair(request_info().url.HostNoBrackets(), + request_info().url.EffectiveIntPort()); session_->mutable_alternate_protocols()->MarkBrokenAlternateProtocolFor( endpoint_); @@ -931,7 +970,7 @@ void HttpStreamFactoryImpl::Job::MarkBrokenAlternateProtocolAndFallback() { next_state_ = STATE_INIT_CONNECTION; } -int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) { +int HttpStreamRequest::ReconsiderProxyAfterError(int error) { DCHECK(!pac_request_); // A failure to resolve the hostname or any error related to establishing a @@ -969,17 +1008,17 @@ int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) { return error; } - if (request_info_.load_flags & LOAD_BYPASS_PROXY) { + if (request_info().load_flags & LOAD_BYPASS_PROXY) { return error; } - if (proxy_info_.is_https() && ssl_config_.send_client_cert) { + if (proxy_info()->is_https() && ssl_config()->send_client_cert) { session_->ssl_client_auth_cache()->Remove( - proxy_info_.proxy_server().host_port_pair().ToString()); + proxy_info()->proxy_server().host_port_pair().ToString()); } int rv = session_->proxy_service()->ReconsiderProxyAfterError( - request_info_.url, &proxy_info_, &io_callback_, &pac_request_, + request_info().url, proxy_info(), &io_callback_, &pac_request_, net_log_); if (rv == OK || rv == ERR_IO_PENDING) { // If the error was during connection setup, there is no socket to @@ -999,7 +1038,7 @@ int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) { return rv; } -int HttpStreamFactoryImpl::Job::HandleCertificateError(int error) { +int HttpStreamRequest::HandleCertificateError(int error) { DCHECK(using_ssl_); DCHECK(IsCertificateError(error)); @@ -1014,9 +1053,9 @@ int HttpStreamFactoryImpl::Job::HandleCertificateError(int error) { SSLConfig::CertAndStatus bad_cert; bad_cert.cert = ssl_info_.cert; bad_cert.cert_status = ssl_info_.cert_status; - ssl_config_.allowed_bad_certs.push_back(bad_cert); + ssl_config()->allowed_bad_certs.push_back(bad_cert); - int load_flags = request_info_.load_flags; + int load_flags = request_info().load_flags; if (HttpStreamFactory::ignore_certificate_errors()) load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; if (ssl_socket->IgnoreCertError(error, load_flags)) @@ -1024,13 +1063,13 @@ int HttpStreamFactoryImpl::Job::HandleCertificateError(int error) { return error; } -void HttpStreamFactoryImpl::Job::SwitchToSpdyMode() { +void HttpStreamRequest::SwitchToSpdyMode() { if (HttpStreamFactory::spdy_enabled()) using_spdy_ = true; } // static -void HttpStreamFactoryImpl::Job::LogHttpConnectedMetrics( +void HttpStreamRequest::LogHttpConnectedMetrics( const ClientSocketHandle& handle) { UMA_HISTOGRAM_ENUMERATION("Net.HttpSocketType", handle.reuse_type(), ClientSocketHandle::NUM_TYPES); @@ -1063,9 +1102,4 @@ void HttpStreamFactoryImpl::Job::LogHttpConnectedMetrics( } } -bool HttpStreamFactoryImpl::Job::IsPreconnecting() const { - DCHECK_GE(num_streams_, 0); - return num_streams_ > 0; -} - } // namespace net diff --git a/net/http/http_stream_factory_impl_job.h b/net/http/http_stream_request.h index 38f8081..fca2332 100644 --- a/net/http/http_stream_factory_impl_job.h +++ b/net/http/http_stream_request.h @@ -1,20 +1,19 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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_FACTORY_IMPL_JOB_H_ -#define NET_HTTP_HTTP_STREAM_FACTORY_IMPL_JOB_H_ +#ifndef NET_HTTP_HTTP_STREAM_REQUEST_H_ +#define NET_HTTP_HTTP_STREAM_REQUEST_H_ -#include "base/ref_counted.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_alternate_protocols.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_impl.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" @@ -24,39 +23,55 @@ class ClientSocketHandle; class HttpAuthController; class HttpNetworkSession; class HttpProxySocketParams; -class HttpStream; class SOCKSSocketParams; class SSLSocketParams; +class StreamRequestDelegate; class TCPSocketParams; +struct HttpRequestInfo; -// An HttpStreamRequestImpl exists for each stream which is in progress of being +// An HttpStreamRequest exists for each stream which is in progress of being // created for the StreamFactory. -class HttpStreamFactoryImpl::Job { +class HttpStreamRequest : public StreamRequest { public: - Job(HttpStreamFactoryImpl* stream_factory, HttpNetworkSession* session); - ~Job(); + 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, - const SSLConfig& ssl_config, + 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, - const SSLConfig& ssl_config, + const HttpRequestInfo* request_info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + PreconnectDelegate* delegate, const BoundNetLog& net_log); - int RestartTunnelWithProxyAuth(const string16& username, - const string16& password); - LoadState GetLoadState() const; + // StreamRequest interface + virtual int RestartWithCertificate(X509Certificate* client_cert); + virtual int RestartTunnelWithProxyAuth(const string16& username, + const string16& password); + virtual LoadState GetLoadState() const; - bool was_alternate_protocol_available() const; - bool was_npn_negotiated() const; - bool using_spdy() const; + virtual bool was_alternate_protocol_available() const; + virtual bool was_npn_negotiated() const; + virtual bool using_spdy() const; private: enum AlternateProtocolMode { @@ -81,6 +96,11 @@ class HttpStreamFactoryImpl::Job { 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); @@ -89,13 +109,14 @@ class HttpStreamFactoryImpl::Job { void OnNeedsClientAuthCallback(SSLCertRequestInfo* cert_info); void OnHttpsProxyTunnelResponseCallback(const HttpResponseInfo& response_info, HttpStream* stream); - void OnPreconnectsComplete(); + void OnPreconnectsComplete(int result); void OnIOComplete(int result); int RunLoop(int result); int DoLoop(int result); - int StartInternal(const HttpRequestInfo& request_info, - const SSLConfig& ssl_config, + 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 @@ -163,17 +184,15 @@ class HttpStreamFactoryImpl::Job { // Record histograms of latency until Connect() completes. static void LogHttpConnectedMetrics(const ClientSocketHandle& handle); - // Indicates whether or not this job is performing a preconnect. - bool IsPreconnecting() const; + const HttpRequestInfo* request_info_; // Use request_info(). + ProxyInfo* proxy_info_; // Use proxy_info(). + SSLConfig* ssl_config_; // Use ssl_config(). - HttpRequestInfo request_info_; - ProxyInfo proxy_info_; - SSLConfig ssl_config_; - - CompletionCallbackImpl<Job> io_callback_; + scoped_refptr<HttpNetworkSession> session_; + CompletionCallbackImpl<HttpStreamRequest> io_callback_; scoped_ptr<ClientSocketHandle> connection_; - HttpNetworkSession* const session_; - HttpStreamFactoryImpl* const stream_factory_; + StreamFactory* const factory_; + Delegate* delegate_; BoundNetLog net_log_; State next_state_; ProxyService::PacRequest* pac_request_; @@ -198,7 +217,7 @@ class HttpStreamFactoryImpl::Job { int spdy_certificate_error_; scoped_refptr<HttpAuthController> - auth_controllers_[HttpAuth::AUTH_NUM_TARGETS]; + auth_controllers_[HttpAuth::AUTH_NUM_TARGETS]; AlternateProtocolMode alternate_protocol_mode_; @@ -218,15 +237,16 @@ class HttpStreamFactoryImpl::Job { // True if we negotiated NPN. bool was_npn_negotiated_; - // 0 if we're not preconnecting. Otherwise, the number of streams to - // preconnect. + PreconnectDelegate* preconnect_delegate_; + + // Only used if |preconnect_delegate_| is non-NULL. int num_streams_; - ScopedRunnableMethodFactory<Job> method_factory_; + ScopedRunnableMethodFactory<HttpStreamRequest> method_factory_; - DISALLOW_COPY_AND_ASSIGN(Job); + DISALLOW_COPY_AND_ASSIGN(HttpStreamRequest); }; } // namespace net -#endif // NET_HTTP_HTTP_STREAM_FACTORY_IMPL_JOB_H_ +#endif // NET_HTTP_HTTP_STREAM_REQUEST_H_ diff --git a/net/http/stream_factory.h b/net/http/stream_factory.h new file mode 100644 index 0000000..1a7aa77 --- /dev/null +++ b/net/http/stream_factory.h @@ -0,0 +1,156 @@ +// 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_STREAM_FACTORY_H_ +#define NET_HTTP_STREAM_FACTORY_H_ + +#include <string> + +#include "base/ref_counted.h" +#include "net/base/completion_callback.h" +#include "net/base/load_states.h" + +namespace net { + +class BoundNetLog; +class HostPortPair; +class HttpAlternateProtocols; +class HttpAuthController; +class HttpNetworkSession; +class HttpResponseInfo; +class HttpStream; +class ProxyInfo; +class SSLCertRequestInfo; +class SSLInfo; +class X509Certificate; +struct HttpRequestInfo; +struct SSLConfig; + +// The StreamRequest is the client's handle to the worker object which handles +// the creation of an HttpStream. While the HttpStream is being created, this +// object is the creator's handle for interacting with the HttpStream creation +// process. The request is cancelled by deleting it, after which no callbacks +// will be invoked. +class StreamRequest { + public: + // The StreamRequestDelegate is a set of callback methods for a + // StreamRequestJob. Generally, only one of these methods will be + // called as a result of a stream request. + class Delegate { + public: + virtual ~Delegate() {} + + // This is the success case. + // |stream| is now owned by the delegate. + virtual void OnStreamReady(HttpStream* stream) = 0; + + // This is the failure to create a stream case. + virtual void OnStreamFailed(int status) = 0; + + // Called when we have a certificate error for the request. + virtual void OnCertificateError(int status, const SSLInfo& ssl_info) = 0; + + // This is the failure case where we need proxy authentication during + // proxy tunnel establishment. For the tunnel case, we were unable to + // create the HttpStream, so the caller provides the auth and then resumes + // the StreamRequest. For the non-tunnel case, the caller will handle + // the authentication failure and restart the StreamRequest entirely. + // Ownership of |auth_controller| and |proxy_response| are owned + // by the StreamRequest. |proxy_response| is not guaranteed to be usable + // after the lifetime of this callback. The delegate may take a reference + // to |auth_controller| if it is needed beyond the lifetime of this + // callback. + virtual void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response, + HttpAuthController* auth_controller) = 0; + + // This is the failure for SSL Client Auth + // Ownership of |cert_info| is retained by the StreamRequest. The delegate + // may take a reference if it needs the cert_info beyond the lifetime of + // this callback. + virtual void OnNeedsClientAuth(SSLCertRequestInfo* cert_info) = 0; + + // This is the failure of the CONNECT request through an HTTPS proxy. + // Headers can be read from |response_info|, while the body can be read + // from |stream|. + // Ownership of |stream| is transferred to the delegate. + virtual void OnHttpsProxyTunnelResponse( + const HttpResponseInfo& response_info, HttpStream* stream) = 0; + }; + + virtual ~StreamRequest() {} + + // When a HttpStream creation process requires a SSL Certificate, + // the delegate OnNeedsClientAuth handler will have been called. + // It now becomes the delegate's responsibility to collect the certificate + // (probably from the user), and then call this method to resume + // the HttpStream creation process. + // Ownership of |client_cert| remains with the StreamRequest. The + // delegate can take a reference if needed beyond the lifetime of this + // call. + virtual int RestartWithCertificate(X509Certificate* client_cert) = 0; + + // When a HttpStream creation process is stalled due to necessity + // of Proxy authentication credentials, the delegate OnNeedsProxyAuth + // will have been called. It now becomes the delegate's responsibility + // to collect the necessary credentials, and then call this method to + // resume the HttpStream creation process. + virtual int RestartTunnelWithProxyAuth(const string16& username, + const string16& password) = 0; + + // Returns the LoadState for the request. + virtual LoadState GetLoadState() const = 0; + + // Returns true if an AlternateProtocol for this request was available. + virtual bool was_alternate_protocol_available() const = 0; + + // Returns true if TLS/NPN was negotiated for this stream. + virtual bool was_npn_negotiated() const = 0; + + // Returns true if this stream is being fetched over SPDY. + virtual bool using_spdy() const = 0; +}; + +// The StreamFactory defines an interface for creating usable HttpStreams. +class StreamFactory { + public: + virtual ~StreamFactory() {} + + // Request a stream. + // Will callback to the StreamRequestDelegate upon completion. + // |info|, |ssl_config|, and |proxy_info| must be kept alive until + // |delegate| is called. + virtual StreamRequest* RequestStream(const HttpRequestInfo* info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + HttpNetworkSession* session, + StreamRequest::Delegate* delegate, + const BoundNetLog& net_log) = 0; + + // Requests that enough connections for |num_streams| be opened. If + // ERR_IO_PENDING is returned, |info|, |ssl_config|, and |proxy_info| must + // be kept alive until |callback| is invoked. That callback will be given the + // final error code. + virtual int PreconnectStreams(int num_streams, + const HttpRequestInfo* info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + HttpNetworkSession* session, + const BoundNetLog& net_log, + CompletionCallback* callback) = 0; + + virtual void AddTLSIntolerantServer(const GURL& url) = 0; + virtual bool IsTLSIntolerantServer(const GURL& url) = 0; + + virtual void ProcessAlternateProtocol( + HttpAlternateProtocols* alternate_protocols, + const std::string& alternate_protocol_str, + const HostPortPair& http_host_port_pair) = 0; + + virtual GURL ApplyHostMappingRules(const GURL& url, + HostPortPair* endpoint) = 0; +}; + +} // namespace net + +#endif // NET_HTTP_STREAM_FACTORY_H_ diff --git a/net/net.gyp b/net/net.gyp index 3cfd242..5266f74a 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -505,12 +505,10 @@ 'http/http_stream.h', 'http/http_stream_factory.cc', 'http/http_stream_factory.h', - 'http/http_stream_factory_impl.cc', - 'http/http_stream_factory_impl.h', - 'http/http_stream_factory_impl_job.cc', - 'http/http_stream_factory_impl_job.h', 'http/http_stream_parser.cc', 'http/http_stream_parser.h', + 'http/http_stream_request.cc', + 'http/http_stream_request.h', 'http/http_transaction.h', 'http/http_transaction_factory.h', 'http/url_security_manager.h', @@ -534,6 +532,7 @@ 'http/partial_data.cc', 'http/partial_data.h', 'http/proxy_client_socket.h', + 'http/stream_factory.h', 'ocsp/nss_ocsp.cc', 'ocsp/nss_ocsp.h', 'proxy/init_proxy_resolver.cc', @@ -944,7 +943,7 @@ 'http/http_request_headers_unittest.cc', 'http/http_response_body_drainer_unittest.cc', 'http/http_response_headers_unittest.cc', - 'http/http_stream_factory_impl_unittest.cc', + 'http/http_stream_factory_unittest.cc', 'http/http_transaction_unittest.cc', 'http/http_transaction_unittest.h', 'http/http_util_unittest.cc', diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc index 999b4e6..8516fbc 100644 --- a/net/socket/client_socket_pool_manager.cc +++ b/net/socket/client_socket_pool_manager.cc @@ -152,55 +152,6 @@ void ClientSocketPoolManager::FlushSocketPools() { tcp_socket_pool_->Flush(); } -void ClientSocketPoolManager::CloseIdleSockets() { - // Close sockets in the highest level pools first, since higher level pools' - // sockets may release stuff to the lower level pools. - for (SSLSocketPoolMap::const_iterator it = - ssl_socket_pools_for_proxies_.begin(); - it != ssl_socket_pools_for_proxies_.end(); - ++it) - it->second->CloseIdleSockets(); - - for (HTTPProxySocketPoolMap::const_iterator it = - http_proxy_socket_pools_.begin(); - it != http_proxy_socket_pools_.end(); - ++it) - it->second->CloseIdleSockets(); - - for (SSLSocketPoolMap::const_iterator it = - ssl_socket_pools_for_https_proxies_.begin(); - it != ssl_socket_pools_for_https_proxies_.end(); - ++it) - it->second->CloseIdleSockets(); - - for (TCPSocketPoolMap::const_iterator it = - tcp_socket_pools_for_https_proxies_.begin(); - it != tcp_socket_pools_for_https_proxies_.end(); - ++it) - it->second->CloseIdleSockets(); - - for (TCPSocketPoolMap::const_iterator it = - tcp_socket_pools_for_http_proxies_.begin(); - it != tcp_socket_pools_for_http_proxies_.end(); - ++it) - it->second->CloseIdleSockets(); - - for (SOCKSSocketPoolMap::const_iterator it = - socks_socket_pools_.begin(); - it != socks_socket_pools_.end(); - ++it) - it->second->CloseIdleSockets(); - - for (TCPSocketPoolMap::const_iterator it = - tcp_socket_pools_for_socks_proxies_.begin(); - it != tcp_socket_pools_for_socks_proxies_.end(); - ++it) - it->second->CloseIdleSockets(); - - ssl_socket_pool_->CloseIdleSockets(); - tcp_socket_pool_->CloseIdleSockets(); -} - SOCKSClientSocketPool* ClientSocketPoolManager::GetSocketPoolForSOCKSProxy( const HostPortPair& socks_proxy) { SOCKSSocketPoolMap::const_iterator it = socks_socket_pools_.find(socks_proxy); diff --git a/net/socket/client_socket_pool_manager.h b/net/socket/client_socket_pool_manager.h index 7d610a9..d6d09e91 100644 --- a/net/socket/client_socket_pool_manager.h +++ b/net/socket/client_socket_pool_manager.h @@ -71,7 +71,6 @@ class ClientSocketPoolManager : public base::NonThreadSafe { ~ClientSocketPoolManager(); void FlushSocketPools(); - void CloseIdleSockets(); TCPClientSocketPool* tcp_socket_pool() { return tcp_socket_pool_.get(); } diff --git a/net/socket/ssl_client_socket_pool_unittest.cc b/net/socket/ssl_client_socket_pool_unittest.cc index 091a94ae..e211591 100644 --- a/net/socket/ssl_client_socket_pool_unittest.cc +++ b/net/socket/ssl_client_socket_pool_unittest.cc @@ -19,7 +19,6 @@ #include "net/http/http_network_session.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" -#include "net/proxy/proxy_service.h" #include "net/socket/client_socket_handle.h" #include "net/socket/client_socket_pool_histograms.h" #include "net/socket/socket_test_util.h" @@ -63,9 +62,10 @@ class SSLClientSocketPoolTest : public testing::Test { http_proxy_socket_params_(new HttpProxySocketParams( proxy_tcp_socket_params_, NULL, GURL("http://host"), "", HostPortPair("host", 80), - session_->http_auth_cache(), + session_->auth_cache(), session_->http_auth_handler_factory(), session_->spdy_session_pool(), + session_->mutable_spdy_settings(), true)), http_proxy_histograms_("MockHttpProxy"), http_proxy_socket_pool_( @@ -117,13 +117,13 @@ class SSLClientSocketPoolTest : public testing::Test { void AddAuthToCache() { const string16 kFoo(ASCIIToUTF16("foo")); const string16 kBar(ASCIIToUTF16("bar")); - session_->http_auth_cache()->Add(GURL("http://proxy:443/"), - "MyRealm1", - HttpAuth::AUTH_SCHEME_BASIC, - "Basic realm=MyRealm1", - kFoo, - kBar, - "/"); + session_->auth_cache()->Add(GURL("http://proxy:443/"), + "MyRealm1", + HttpAuth::AUTH_SCHEME_BASIC, + "Basic realm=MyRealm1", + kFoo, + kBar, + "/"); } HttpNetworkSession* CreateNetworkSession() { diff --git a/net/spdy/spdy_http_stream_unittest.cc b/net/spdy/spdy_http_stream_unittest.cc index 1688871..df979ec 100644 --- a/net/spdy/spdy_http_stream_unittest.cc +++ b/net/spdy/spdy_http_stream_unittest.cc @@ -29,7 +29,8 @@ class SpdyHttpStreamTest : public testing::Test { data_ = new OrderedSocketData(reads, reads_count, writes, writes_count); session_deps_.socket_factory->AddSocketDataProvider(data_.get()); http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); - session_ = http_session_->spdy_session_pool()->Get(pair, BoundNetLog()); + session_ = http_session_->spdy_session_pool()-> + Get(pair, http_session_->mutable_spdy_settings(), BoundNetLog()); tcp_params_ = new TCPSocketParams(host_port_pair.host(), host_port_pair.port(), MEDIUM, GURL(), false); diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 019cc4c..402f2f7 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -393,7 +393,8 @@ class SpdyNetworkTransactionTest const scoped_refptr<HttpNetworkSession>& session = helper.session(); SpdySessionPool* pool(session->spdy_session_pool()); EXPECT_TRUE(pool->HasSession(pair)); - scoped_refptr<SpdySession> spdy_session(pool->Get(pair, log)); + scoped_refptr<SpdySession> spdy_session( + pool->Get(pair, session->mutable_spdy_settings(), log)); ASSERT_TRUE(spdy_session.get() != NULL); EXPECT_EQ(0u, spdy_session->num_active_streams()); EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams()); @@ -4015,8 +4016,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) { // Verify that no settings exist initially. HostPortPair host_port_pair("www.google.com", helper.port()); - SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); - EXPECT_TRUE(spdy_session_pool->spdy_settings().Get(host_port_pair).empty()); + EXPECT_TRUE(helper.session()->spdy_settings().Get(host_port_pair).empty()); // Construct the request. scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); @@ -4078,7 +4078,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) { { // Verify we had two persisted settings. spdy::SpdySettings saved_settings = - spdy_session_pool->spdy_settings().Get(host_port_pair); + helper.session()->spdy_settings().Get(host_port_pair); ASSERT_EQ(2u, saved_settings.size()); // Verify the first persisted setting. @@ -4124,8 +4124,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { // Verify that no settings exist initially. HostPortPair host_port_pair("www.google.com", helper.port()); - SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); - EXPECT_TRUE(spdy_session_pool->spdy_settings().Get(host_port_pair).empty()); + EXPECT_TRUE(helper.session()->spdy_settings().Get(host_port_pair).empty()); unsigned int kSampleId1 = 0x1; unsigned int kSampleValue1 = 0x0a0a0a0a; @@ -4144,14 +4143,14 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { setting.set_id(kSampleId2); settings.push_back(std::make_pair(setting, kSampleValue2)); - spdy_session_pool->mutable_spdy_settings()->Set(host_port_pair, settings); + helper.session()->mutable_spdy_settings()->Set(host_port_pair, settings); } - EXPECT_EQ(2u, spdy_session_pool->spdy_settings().Get(host_port_pair).size()); + EXPECT_EQ(2u, helper.session()->spdy_settings().Get(host_port_pair).size()); // Construct the SETTINGS frame. const spdy::SpdySettings& settings = - spdy_session_pool->spdy_settings().Get(host_port_pair); + helper.session()->spdy_settings().Get(host_port_pair); scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); // Construct the request. @@ -4191,7 +4190,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { { // Verify we had two persisted settings. spdy::SpdySettings saved_settings = - spdy_session_pool->spdy_settings().Get(host_port_pair); + helper.session()->spdy_settings().Get(host_port_pair); ASSERT_EQ(2u, saved_settings.size()); // Verify the first persisted setting. diff --git a/net/spdy/spdy_proxy_client_socket_unittest.cc b/net/spdy/spdy_proxy_client_socket_unittest.cc index 9023ca9..e4483bd 100644 --- a/net/spdy/spdy_proxy_client_socket_unittest.cc +++ b/net/spdy/spdy_proxy_client_socket_unittest.cc @@ -85,13 +85,13 @@ class SpdyProxyClientSocketTest : public PlatformTest { void AddAuthToCache() { const string16 kFoo(ASCIIToUTF16("foo")); const string16 kBar(ASCIIToUTF16("bar")); - session_->http_auth_cache()->Add(GURL(kProxyUrl), - "MyRealm1", - HttpAuth::AUTH_SCHEME_BASIC, - "Basic realm=MyRealm1", - kFoo, - kBar, - "/"); + session_->auth_cache()->Add(GURL(kProxyUrl), + "MyRealm1", + HttpAuth::AUTH_SCHEME_BASIC, + "Basic realm=MyRealm1", + kFoo, + kBar, + "/"); } void Run(int steps) { @@ -175,6 +175,7 @@ void SpdyProxyClientSocketTest::Initialize(MockRead* reads, // Creates a new spdy session spdy_session_ = session_->spdy_session_pool()->Get(endpoint_host_port_proxy_pair_, + session_->mutable_spdy_settings(), BoundNetLog()); // Perform the TCP connect @@ -195,7 +196,7 @@ void SpdyProxyClientSocketTest::Initialize(MockRead* reads, sock_.reset( new SpdyProxyClientSocket(spdy_stream_, user_agent_, endpoint_host_port_pair_, url_, - proxy_host_port_, session_->http_auth_cache(), + proxy_host_port_, session_->auth_cache(), session_->http_auth_handler_factory())); } diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc index b32495e..f4ec575 100644 --- a/net/spdy/spdy_session_pool.cc +++ b/net/spdy/spdy_session_pool.cc @@ -34,6 +34,7 @@ SpdySessionPool::~SpdySessionPool() { scoped_refptr<SpdySession> SpdySessionPool::Get( const HostPortProxyPair& host_port_proxy_pair, + SpdySettingsStorage* spdy_settings, const BoundNetLog& net_log) { scoped_refptr<SpdySession> spdy_session; SpdySessionList* list = GetSessionList(host_port_proxy_pair); @@ -52,7 +53,7 @@ scoped_refptr<SpdySession> SpdySessionPool::Get( DCHECK(list); if (!spdy_session) { - spdy_session = new SpdySession(host_port_proxy_pair, this, &spdy_settings_, + spdy_session = new SpdySession(host_port_proxy_pair, this, spdy_settings, net_log.net_log()); net_log.AddEvent( NetLog::TYPE_SPDY_SESSION_POOL_CREATED_NEW_SESSION, @@ -68,13 +69,14 @@ scoped_refptr<SpdySession> SpdySessionPool::Get( net::Error SpdySessionPool::GetSpdySessionFromSocket( const HostPortProxyPair& host_port_proxy_pair, + SpdySettingsStorage* spdy_settings, ClientSocketHandle* connection, const BoundNetLog& net_log, int certificate_error_code, scoped_refptr<SpdySession>* spdy_session, bool is_secure) { // Create the SPDY session and add it to the pool. - *spdy_session = new SpdySession(host_port_proxy_pair, this, &spdy_settings_, + *spdy_session = new SpdySession(host_port_proxy_pair, this, spdy_settings, net_log.net_log()); SpdySessionList* list = GetSessionList(host_port_proxy_pair); if (!list) diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h index 10da747..7f30b20 100644 --- a/net/spdy/spdy_session_pool.h +++ b/net/spdy/spdy_session_pool.h @@ -20,7 +20,6 @@ #include "net/base/ssl_config_service.h" #include "net/proxy/proxy_config.h" #include "net/proxy/proxy_server.h" -#include "net/spdy/spdy_settings_storage.h" namespace net { // Sessions are uniquely identified by their HostPortPair and the proxy server @@ -31,6 +30,7 @@ class BoundNetLog; class ClientSocketHandle; class HttpNetworkSession; class SpdySession; +class SpdySettingsStorage; // This is a very simple pool for open SpdySessions. // TODO(mbelshe): Make this production ready. @@ -45,6 +45,7 @@ class SpdySessionPool // use. scoped_refptr<SpdySession> Get( const HostPortProxyPair& host_port_proxy_pair, + SpdySettingsStorage* spdy_settings, const BoundNetLog& net_log); // Set the maximum concurrent sessions per domain. @@ -65,6 +66,7 @@ class SpdySessionPool // Returns an error on failure, and |spdy_session| will be NULL. net::Error GetSpdySessionFromSocket( const HostPortProxyPair& host_port_proxy_pair, + SpdySettingsStorage* spdy_settings, ClientSocketHandle* connection, const BoundNetLog& net_log, int certificate_error_code, @@ -90,9 +92,6 @@ class SpdySessionPool // responsible for deleting the returned value. Value* SpdySessionPoolInfoToValue() const; - SpdySettingsStorage* mutable_spdy_settings() { return &spdy_settings_; } - const SpdySettingsStorage& spdy_settings() const { return spdy_settings_; } - // NetworkChangeNotifier::Observer methods: // We flush all idle sessions and release references to the active ones so @@ -125,8 +124,6 @@ class SpdySessionPool const HostPortProxyPair& host_port_proxy_pair) const; void RemoveSessionList(const HostPortProxyPair& host_port_proxy_pair); - SpdySettingsStorage spdy_settings_; - // This is our weak session pool - one session per domain. SpdySessionsMap sessions_; diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc index 0f3b601..44848e3 100644 --- a/net/spdy/spdy_session_unittest.cc +++ b/net/spdy/spdy_session_unittest.cc @@ -88,7 +88,8 @@ TEST_F(SpdySessionTest, GoAway) { SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool()); EXPECT_FALSE(spdy_session_pool->HasSession(pair)); scoped_refptr<SpdySession> session = - spdy_session_pool->Get(pair, BoundNetLog()); + spdy_session_pool->Get(pair, http_session->mutable_spdy_settings(), + BoundNetLog()); EXPECT_TRUE(spdy_session_pool->HasSession(pair)); scoped_refptr<TCPSocketParams> tcp_params( @@ -106,7 +107,8 @@ TEST_F(SpdySessionTest, GoAway) { EXPECT_FALSE(spdy_session_pool->HasSession(pair)); scoped_refptr<SpdySession> session2 = - spdy_session_pool->Get(pair, BoundNetLog()); + spdy_session_pool->Get(pair, http_session->mutable_spdy_settings(), + BoundNetLog()); // Delete the first session. session = NULL; @@ -185,17 +187,18 @@ TEST_F(SpdySessionTest, OnSettings) { HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct()); // Initialize the SpdySettingsStorage with 1 max concurrent streams. - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool()); spdy::SpdySettings old_settings; id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); old_settings.push_back(spdy::SpdySetting(id, 1)); - spdy_session_pool->mutable_spdy_settings()->Set( + http_session->mutable_spdy_settings()->Set( test_host_port_pair, old_settings); // Create a session. + SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool()); EXPECT_FALSE(spdy_session_pool->HasSession(pair)); scoped_refptr<SpdySession> session = - spdy_session_pool->Get(pair, BoundNetLog()); + spdy_session_pool->Get(pair, http_session->mutable_spdy_settings(), + BoundNetLog()); ASSERT_TRUE(spdy_session_pool->HasSession(pair)); scoped_refptr<TCPSocketParams> tcp_params( @@ -264,19 +267,19 @@ TEST_F(SpdySessionTest, CancelPendingCreateStream) { HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct()); // Initialize the SpdySettingsStorage with 1 max concurrent streams. - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool()); spdy::SpdySettings settings; spdy::SettingsFlagsAndId id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); settings.push_back(spdy::SpdySetting(id, 1)); - spdy_session_pool->mutable_spdy_settings()->Set( - test_host_port_pair, settings); + http_session->mutable_spdy_settings()->Set(test_host_port_pair, settings); // Create a session. + SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool()); EXPECT_FALSE(spdy_session_pool->HasSession(pair)); scoped_refptr<SpdySession> session = - spdy_session_pool->Get(pair, BoundNetLog()); + spdy_session_pool->Get(pair, http_session->mutable_spdy_settings(), + BoundNetLog()); ASSERT_TRUE(spdy_session_pool->HasSession(pair)); scoped_refptr<TCPSocketParams> tcp_params( @@ -366,12 +369,12 @@ TEST_F(SpdySessionTest, SendSettingsOnNewSession) { id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); settings.clear(); settings.push_back(spdy::SpdySetting(id, kBogusSettingValue)); + http_session->mutable_spdy_settings()->Set(test_host_port_pair, settings); SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool()); - spdy_session_pool->mutable_spdy_settings()->Set( - test_host_port_pair, settings); EXPECT_FALSE(spdy_session_pool->HasSession(pair)); scoped_refptr<SpdySession> session = - spdy_session_pool->Get(pair, BoundNetLog()); + spdy_session_pool->Get(pair, http_session->mutable_spdy_settings(), + BoundNetLog()); EXPECT_TRUE(spdy_session_pool->HasSession(pair)); scoped_refptr<TCPSocketParams> tcp_params( diff --git a/net/spdy/spdy_stream_unittest.cc b/net/spdy/spdy_stream_unittest.cc index 532c79f..9c7b934 100644 --- a/net/spdy/spdy_stream_unittest.cc +++ b/net/spdy/spdy_stream_unittest.cc @@ -117,7 +117,9 @@ class SpdyStreamTest : public testing::Test { HostPortPair host_port_pair("www.google.com", 80); HostPortProxyPair pair(host_port_pair, ProxyServer::Direct()); scoped_refptr<SpdySession> session( - session_->spdy_session_pool()->Get(pair, BoundNetLog())); + session_->spdy_session_pool()->Get(pair, + session_->mutable_spdy_settings(), + BoundNetLog())); return session; } |