Chromium Code Reviews| Index: chromecast/shell/browser/url_request_context_factory.cc |
| diff --git a/chromecast/shell/browser/url_request_context_factory.cc b/chromecast/shell/browser/url_request_context_factory.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..5ed7870bfce2112bc55a54a51ebb3432692e63c9 |
| --- /dev/null |
| +++ b/chromecast/shell/browser/url_request_context_factory.cc |
| @@ -0,0 +1,355 @@ |
| +// Copyright 2014 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 "chromecast/shell/browser/url_request_context_factory.h" |
| + |
| +#include "base/command_line.h" |
| +#include "base/files/file_path.h" |
| +#include "base/macros.h" |
| +#include "base/path_service.h" |
| +#include "base/threading/worker_pool.h" |
| +#include "chromecast/shell/browser/cast_http_user_agent_settings.h" |
| +#include "content/public/browser/browser_context.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/cookie_store_factory.h" |
| +#include "content/public/common/content_switches.h" |
| +#include "content/public/common/url_constants.h" |
| +#include "net/cert/cert_verifier.h" |
| +#include "net/cookies/cookie_store.h" |
| +#include "net/dns/host_resolver.h" |
| +#include "net/http/http_auth_handler_factory.h" |
| +#include "net/http/http_cache.h" |
| +#include "net/http/http_network_layer.h" |
| +#include "net/http/http_server_properties_impl.h" |
| +#include "net/http/http_stream_factory.h" |
| +#include "net/ocsp/nss_ocsp.h" |
| +#include "net/proxy/proxy_service.h" |
| +#include "net/socket/next_proto.h" |
| +#include "net/ssl/default_server_bound_cert_store.h" |
| +#include "net/ssl/server_bound_cert_service.h" |
| +#include "net/ssl/ssl_config_service_defaults.h" |
| +#include "net/url_request/data_protocol_handler.h" |
| +#include "net/url_request/url_request_context.h" |
| +#include "net/url_request/url_request_context_getter.h" |
| +#include "net/url_request/url_request_job_factory_impl.h" |
| + |
| +namespace chromecast { |
| +namespace shell { |
| + |
| +namespace { |
| + |
| +const char kCookieStoreFile[] = "Cookies"; |
| + |
| +} // namespace |
| + |
| +// Private classes to expose URLRequestContextGetter that call back to the |
| +// URLRequestContextFactory to create the URLRequestContext on demand. |
| +// |
| +// The URLRequestContextFactory::URLRequestContextGetter class is used for both |
| +// the system and media URLRequestCotnexts. |
| +class URLRequestContextFactory::URLRequestContextGetter |
| + : public net::URLRequestContextGetter { |
| + public: |
| + URLRequestContextGetter(URLRequestContextFactory* factory, bool is_media) |
| + : is_media_(is_media), |
| + factory_(factory) { |
| + } |
| + |
| + virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE { |
| + if (!request_context_) { |
| + if (is_media_) { |
| + request_context_.reset(factory_->CreateMediaRequestContext()); |
| + } else { |
| + request_context_.reset(factory_->CreateSystemRequestContext()); |
| + // Set request context used by NSS for Crl requests. |
| + net::SetURLRequestContextForNSSHttpIO(request_context_.get()); |
| + } |
| + } |
| + return request_context_.get(); |
| + } |
| + |
| + virtual scoped_refptr<base::SingleThreadTaskRunner> |
| + GetNetworkTaskRunner() const OVERRIDE { |
| + return content::BrowserThread::GetMessageLoopProxyForThread( |
| + content::BrowserThread::IO); |
| + } |
| + |
| + private: |
| + virtual ~URLRequestContextGetter() {} |
| + |
| + const bool is_media_; |
| + URLRequestContextFactory* const factory_; |
| + scoped_ptr<net::URLRequestContext> request_context_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter); |
| +}; |
| + |
| +// The URLRequestContextFactory::MainURLRequestContextGetter class is used for |
| +// the main URLRequestContext. |
| +class URLRequestContextFactory::MainURLRequestContextGetter |
| + : public net::URLRequestContextGetter { |
| + public: |
| + MainURLRequestContextGetter(URLRequestContextFactory* factory, |
| + content::BrowserContext* browser_context, |
| + content::ProtocolHandlerMap* protocol_handlers) |
| + : browser_context_(browser_context), |
| + factory_(factory) { |
| + std::swap(protocol_handlers_, *protocol_handlers); |
| + } |
| + |
| + virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE { |
| + if (!request_context_) { |
| + request_context_.reset(factory_->CreateMainRequestContext( |
| + browser_context_, &protocol_handlers_)); |
| + protocol_handlers_.clear(); |
| + } |
| + return request_context_.get(); |
| + } |
| + |
| + virtual scoped_refptr<base::SingleThreadTaskRunner> |
| + GetNetworkTaskRunner() const OVERRIDE { |
| + return content::BrowserThread::GetMessageLoopProxyForThread( |
| + content::BrowserThread::IO); |
| + } |
| + |
| + private: |
| + virtual ~MainURLRequestContextGetter() {} |
| + |
| + content::BrowserContext* const browser_context_; |
| + URLRequestContextFactory* const factory_; |
| + content::ProtocolHandlerMap protocol_handlers_; |
| + scoped_ptr<net::URLRequestContext> request_context_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(MainURLRequestContextGetter); |
| +}; |
| + |
| +URLRequestContextFactory::URLRequestContextFactory() |
| + : system_dependencies_initialized_(false), |
| + main_dependencies_initialized_(false), |
| + media_dependencies_initialized_(false) { |
| +} |
| + |
| +URLRequestContextFactory::~URLRequestContextFactory() { |
| +} |
| + |
| +void URLRequestContextFactory::InitializeOnUIThread() { |
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| + // Cast http user agent settings must be initialized in UI thread |
| + // because it registers itself to pref notification observer which is not |
| + // thread safe. |
| + http_user_agent_settings_.reset(new CastHttpUserAgentSettings()); |
| +} |
| + |
| +net::URLRequestContextGetter* URLRequestContextFactory::CreateMainGetter( |
| + content::BrowserContext* browser_context, |
| + content::ProtocolHandlerMap* protocol_handlers) { |
| + DCHECK(!main_getter_) << "Main URLRequestContextGetter already initialized"; |
| + main_getter_ = new MainURLRequestContextGetter(this, |
| + browser_context, |
| + protocol_handlers); |
| + return main_getter_.get(); |
| +} |
| + |
| +net::URLRequestContextGetter* URLRequestContextFactory::GetMainGetter() { |
| + CHECK(main_getter_); |
| + return main_getter_.get(); |
| +} |
| + |
| +net::URLRequestContextGetter* URLRequestContextFactory::GetSystemGetter() { |
| + if (!system_getter_) { |
| + system_getter_ = new URLRequestContextGetter(this, false); |
| + } |
| + return system_getter_.get(); |
| +} |
| + |
| +net::URLRequestContextGetter* URLRequestContextFactory::GetMediaGetter() { |
| + if (!media_getter_) { |
| + media_getter_ = new URLRequestContextGetter(this, true); |
| + } |
| + return media_getter_.get(); |
| +} |
| + |
| +void URLRequestContextFactory::InitializeSystemContextDependencies() { |
| + if (!system_dependencies_initialized_) { |
|
mmenke
2014/07/08 15:43:59
Optional for this and and the next two functions:
lcwu1
2014/07/09 02:16:29
Done.
|
| + host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL); |
| + |
| + server_bound_cert_service_.reset(new net::ServerBoundCertService( |
| + new net::DefaultServerBoundCertStore(NULL), |
| + base::WorkerPool::GetTaskRunner(true))); |
| + |
| + cert_verifier_.reset(net::CertVerifier::CreateDefault()); |
| + |
| + ssl_config_service_ = new net::SSLConfigServiceDefaults; |
| + |
| + transport_security_state_.reset(new net::TransportSecurityState()); |
| + http_auth_handler_factory_.reset( |
| + net::HttpAuthHandlerFactory::CreateDefault(host_resolver_.get())); |
| + |
| + http_server_properties_.reset(new net::HttpServerPropertiesImpl); |
|
mmenke
2014/07/08 15:43:59
For performance reasons, may want an on-disk HttpS
lcwu1
2014/07/09 02:16:29
Added a TODO here.
|
| + |
| + proxy_service_.reset(net::ProxyService::CreateUsingSystemProxyResolver( |
| + net::ProxyService::CreateSystemProxyConfigService( |
| + content::BrowserThread::GetMessageLoopProxyForThread( |
| + content::BrowserThread::IO).get(), |
| + content::BrowserThread::UnsafeGetMessageLoopForThread( |
| + content::BrowserThread::FILE)), |
| + 0, |
| + NULL)); |
| + system_dependencies_initialized_ = true; |
| + } |
| +} |
| + |
| +void URLRequestContextFactory::InitializeMainContextDependencies( |
| + net::HttpTransactionFactory* transaction_factory, |
| + content::ProtocolHandlerMap* protocol_handlers) { |
| + if (!main_dependencies_initialized_) { |
| + main_transaction_factory_.reset(transaction_factory); |
| + main_job_factory_.reset(new net::URLRequestJobFactoryImpl()); |
| + // Keep ProtocolHandlers added in sync with |
| + // ShellContentBrowserClient::IsHandledURL(). |
| + bool set_protocol = false; |
| + for (content::ProtocolHandlerMap::iterator it = |
| + protocol_handlers->begin(); |
| + it != protocol_handlers->end(); |
| + ++it) { |
| + set_protocol = main_job_factory_->SetProtocolHandler( |
| + it->first, it->second.release()); |
| + DCHECK(set_protocol); |
| + } |
| + set_protocol = main_job_factory_->SetProtocolHandler( |
| + url::kDataScheme, |
| + new net::DataProtocolHandler); |
| + DCHECK(set_protocol); |
| + main_dependencies_initialized_ = true; |
| + } |
| +} |
| + |
| +void URLRequestContextFactory::InitializeMediaContextDependencies( |
| + net::HttpTransactionFactory* transaction_factory) { |
| + if (!media_dependencies_initialized_) { |
| + media_transaction_factory_.reset(transaction_factory); |
| + media_dependencies_initialized_ = true; |
| + } |
| +} |
| + |
| +void URLRequestContextFactory::PopulateNetworkSessionParams( |
| + bool ignore_certificate_errors, |
| + net::HttpNetworkSession::Params* params) { |
| + params->host_resolver = host_resolver_.get(); |
| + params->cert_verifier = cert_verifier_.get(); |
| + params->server_bound_cert_service = server_bound_cert_service_.get(); |
| + params->ssl_config_service = ssl_config_service_.get(); |
| + params->transport_security_state = transport_security_state_.get(); |
| + params->http_auth_handler_factory = http_auth_handler_factory_.get(); |
| + params->http_server_properties = http_server_properties_->GetWeakPtr(); |
| + params->ignore_certificate_errors = ignore_certificate_errors; |
| + params->proxy_service = proxy_service_.get(); |
| + |
| + // TODO(lcwu): http://crbug.com/329681. Remove this once spdy is enabled |
| + // by deafult at the content level. |
|
mmenke
2014/07/08 15:43:59
nit: deafult -> default
lcwu1
2014/07/09 02:16:29
Done.
|
| + params->next_protos = net::NextProtosSpdy31(); |
| + params->use_alternate_protocols = true; |
| +} |
| + |
| +net::URLRequestContext* URLRequestContextFactory::CreateSystemRequestContext() { |
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| + InitializeSystemContextDependencies(); |
| + net::HttpNetworkSession::Params system_params; |
| + PopulateNetworkSessionParams(false, &system_params); |
| + system_transaction_factory_.reset(new net::HttpNetworkLayer( |
| + new net::HttpNetworkSession(system_params))); |
| + |
| + net::URLRequestContext* system_context = new net::URLRequestContext(); |
| + system_context->set_host_resolver(host_resolver_.get()); |
| + system_context->set_server_bound_cert_service( |
| + server_bound_cert_service_.get()); |
| + system_context->set_cert_verifier(cert_verifier_.get()); |
| + system_context->set_proxy_service(proxy_service_.get()); |
| + system_context->set_ssl_config_service(ssl_config_service_.get()); |
| + system_context->set_transport_security_state( |
| + transport_security_state_.get()); |
| + system_context->set_http_auth_handler_factory( |
| + http_auth_handler_factory_.get()); |
| + system_context->set_http_server_properties( |
| + http_server_properties_->GetWeakPtr()); |
| + system_context->set_http_transaction_factory( |
| + system_transaction_factory_.get()); |
| + system_context->set_http_user_agent_settings( |
| + http_user_agent_settings_.get()); |
|
mmenke
2014/07/08 15:43:59
Should probably set up an in-memory cookie store f
lcwu1
2014/07/09 02:16:29
Done.
|
| + return system_context; |
| +} |
| + |
| +net::URLRequestContext* URLRequestContextFactory::CreateMediaRequestContext() { |
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| + DCHECK(main_getter_) |
| + << "Getting MediaRequestContext before MainRequestContext"; |
| + net::URLRequestContext* main_context = main_getter_->GetURLRequestContext(); |
| + |
| + // Set non caching backend. |
| + net::HttpNetworkSession* main_session = |
| + main_transaction_factory_->GetSession(); |
| + InitializeMediaContextDependencies( |
| + new net::HttpNetworkLayer(main_session)); |
| + |
| + net::URLRequestContext* media_context = new net::URLRequestContext(); |
| + media_context->CopyFrom(main_context); |
| + media_context->set_http_transaction_factory( |
| + media_transaction_factory_.get()); |
| + return media_context; |
| +} |
| + |
| +net::URLRequestContext* URLRequestContextFactory::CreateMainRequestContext( |
| + content::BrowserContext* browser_context, |
| + content::ProtocolHandlerMap* protocol_handlers) { |
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| + InitializeSystemContextDependencies(); |
| + |
| + net::HttpCache::BackendFactory* main_backend = |
| + net::HttpCache::DefaultBackend::InMemory(16 * 1024 * 1024); |
| + |
| + bool ignore_certificate_errors = false; |
| + CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
| + if (cmd_line->HasSwitch(switches::kIgnoreCertificateErrors)) { |
| + ignore_certificate_errors = true; |
| + } |
| + net::HttpNetworkSession::Params network_session_params; |
| + PopulateNetworkSessionParams(ignore_certificate_errors, |
| + &network_session_params); |
| + InitializeMainContextDependencies( |
| + new net::HttpCache(network_session_params, main_backend), |
| + protocol_handlers); |
| + |
| + content::CookieStoreConfig cookie_config( |
| + browser_context->GetPath().Append(kCookieStoreFile), |
| + content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES, |
| + NULL, NULL); |
| + cookie_config.background_task_runner = |
| + scoped_refptr<base::SequencedTaskRunner>(); |
| + scoped_refptr<net::CookieStore> cookie_store = |
| + content::CreateCookieStore(cookie_config); |
| + |
| + net::URLRequestContext* main_context = new net::URLRequestContext(); |
| + main_context->set_host_resolver(host_resolver_.get()); |
| + main_context->set_server_bound_cert_service( |
| + server_bound_cert_service_.get()); |
| + main_context->set_cert_verifier(cert_verifier_.get()); |
| + main_context->set_proxy_service(proxy_service_.get()); |
| + main_context->set_ssl_config_service(ssl_config_service_.get()); |
| + main_context->set_transport_security_state(transport_security_state_.get()); |
| + main_context->set_http_auth_handler_factory( |
| + http_auth_handler_factory_.get()); |
| + main_context->set_http_server_properties( |
| + http_server_properties_->GetWeakPtr()); |
| + main_context->set_cookie_store(cookie_store.get()); |
| + main_context->set_http_user_agent_settings( |
| + http_user_agent_settings_.get()); |
| + |
| + main_context->set_http_transaction_factory( |
| + main_transaction_factory_.get()); |
| + main_context->set_job_factory(main_job_factory_.get()); |
| + return main_context; |
| +} |
| + |
| +} // namespace shell |
| +} // namespace chromecast |