diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-23 00:08:48 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-23 00:08:48 +0000 |
commit | c4744cdbbe22df6848e354dbfa9dbb1dc36e76d8 (patch) | |
tree | b6d92d6b17ae0e140485fb53b53ef0017a99a6c0 | |
parent | 95fb385e5e68a69a39c77d66d801bebdaf39c311 (diff) | |
download | chromium_src-c4744cdbbe22df6848e354dbfa9dbb1dc36e76d8.zip chromium_src-c4744cdbbe22df6848e354dbfa9dbb1dc36e76d8.tar.gz chromium_src-c4744cdbbe22df6848e354dbfa9dbb1dc36e76d8.tar.bz2 |
Revert 75668 for breaking ChromeOS build - Refactor HttpStreamFactory.
Rename StreamFactory and StreamRequest to HttpStreamFactory and HttpStreamRequest.
Rename HttpStreamFactory to HttpStreamFactoryImpl.
Create HttpStreamFactoryImpl::Request (inherits from HttpStreamRequest) and HttpStreamFactoryImpl::Job (most of the old HttpStreamRequest code, other than the interface, moved here).
Currently there is still a strong binding within HttpStreamFactoryImpl between requests and jobs. This will be removed in a future changelist.
Note that due to the preparation for late binding, information like HttpRequestInfo and SSLConfig and ProxyInfo are just copied. It's possible we can consider refcounting them to reduce copies, but I think it's not worth the effort / ugliness.
I also did some minor cleanups like moving SpdySettingsStorage into SpdySessionPool and some CloseIdleConnections() cleanup.
BUG=54371,42669
TEST=unit tests
Review URL: http://codereview.chromium.org/6543004
TBR=willchan@chromium.org
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75670 0039d316-1c4b-4281-b951-d872f2087c98
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; } |