Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chromecast / browser / url_request_context_factory.cc
blobc3b0f8853f6f5d36298b9b05c25f1344abf89d0c
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromecast/browser/url_request_context_factory.h"
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/macros.h"
10 #include "base/threading/worker_pool.h"
11 #include "chromecast/base/chromecast_switches.h"
12 #include "chromecast/browser/cast_http_user_agent_settings.h"
13 #include "chromecast/browser/cast_network_delegate.h"
14 #include "content/public/browser/browser_context.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/cookie_store_factory.h"
17 #include "content/public/common/content_switches.h"
18 #include "content/public/common/url_constants.h"
19 #include "net/cert/cert_verifier.h"
20 #include "net/cert_net/nss_ocsp.h"
21 #include "net/cookies/cookie_store.h"
22 #include "net/dns/host_resolver.h"
23 #include "net/http/http_auth_handler_factory.h"
24 #include "net/http/http_network_layer.h"
25 #include "net/http/http_server_properties_impl.h"
26 #include "net/http/http_stream_factory.h"
27 #include "net/proxy/proxy_service.h"
28 #include "net/socket/next_proto.h"
29 #include "net/ssl/channel_id_service.h"
30 #include "net/ssl/default_channel_id_store.h"
31 #include "net/ssl/ssl_config_service_defaults.h"
32 #include "net/url_request/data_protocol_handler.h"
33 #include "net/url_request/file_protocol_handler.h"
34 #include "net/url_request/url_request_context.h"
35 #include "net/url_request/url_request_context_getter.h"
36 #include "net/url_request/url_request_intercepting_job_factory.h"
37 #include "net/url_request/url_request_job_factory_impl.h"
39 namespace chromecast {
40 namespace shell {
42 namespace {
44 const char kCookieStoreFile[] = "Cookies";
46 } // namespace
48 // Private classes to expose URLRequestContextGetter that call back to the
49 // URLRequestContextFactory to create the URLRequestContext on demand.
51 // The URLRequestContextFactory::URLRequestContextGetter class is used for both
52 // the system and media URLRequestCotnexts.
53 class URLRequestContextFactory::URLRequestContextGetter
54 : public net::URLRequestContextGetter {
55 public:
56 URLRequestContextGetter(URLRequestContextFactory* factory, bool is_media)
57 : is_media_(is_media),
58 factory_(factory) {
61 net::URLRequestContext* GetURLRequestContext() override {
62 if (!request_context_) {
63 if (is_media_) {
64 request_context_.reset(factory_->CreateMediaRequestContext());
65 } else {
66 request_context_.reset(factory_->CreateSystemRequestContext());
67 #if defined(USE_NSS_CERTS)
68 // Set request context used by NSS for Crl requests.
69 net::SetURLRequestContextForNSSHttpIO(request_context_.get());
70 #endif // defined(USE_NSS_CERTS)
73 return request_context_.get();
76 scoped_refptr<base::SingleThreadTaskRunner>
77 GetNetworkTaskRunner() const override {
78 return content::BrowserThread::GetMessageLoopProxyForThread(
79 content::BrowserThread::IO);
82 private:
83 ~URLRequestContextGetter() override {}
85 const bool is_media_;
86 URLRequestContextFactory* const factory_;
87 scoped_ptr<net::URLRequestContext> request_context_;
89 DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);
92 // The URLRequestContextFactory::MainURLRequestContextGetter class is used for
93 // the main URLRequestContext.
94 class URLRequestContextFactory::MainURLRequestContextGetter
95 : public net::URLRequestContextGetter {
96 public:
97 MainURLRequestContextGetter(
98 URLRequestContextFactory* factory,
99 content::BrowserContext* browser_context,
100 content::ProtocolHandlerMap* protocol_handlers,
101 content::URLRequestInterceptorScopedVector request_interceptors)
102 : browser_context_(browser_context),
103 factory_(factory),
104 request_interceptors_(request_interceptors.Pass()) {
105 std::swap(protocol_handlers_, *protocol_handlers);
108 net::URLRequestContext* GetURLRequestContext() override {
109 if (!request_context_) {
110 request_context_.reset(factory_->CreateMainRequestContext(
111 browser_context_, &protocol_handlers_, request_interceptors_.Pass()));
112 protocol_handlers_.clear();
114 return request_context_.get();
117 scoped_refptr<base::SingleThreadTaskRunner>
118 GetNetworkTaskRunner() const override {
119 return content::BrowserThread::GetMessageLoopProxyForThread(
120 content::BrowserThread::IO);
123 private:
124 ~MainURLRequestContextGetter() override {}
126 content::BrowserContext* const browser_context_;
127 URLRequestContextFactory* const factory_;
128 content::ProtocolHandlerMap protocol_handlers_;
129 content::URLRequestInterceptorScopedVector request_interceptors_;
130 scoped_ptr<net::URLRequestContext> request_context_;
132 DISALLOW_COPY_AND_ASSIGN(MainURLRequestContextGetter);
135 URLRequestContextFactory::URLRequestContextFactory()
136 : app_network_delegate_(CastNetworkDelegate::Create()),
137 system_network_delegate_(CastNetworkDelegate::Create()),
138 system_dependencies_initialized_(false),
139 main_dependencies_initialized_(false),
140 media_dependencies_initialized_(false) {
143 URLRequestContextFactory::~URLRequestContextFactory() {
146 void URLRequestContextFactory::InitializeOnUIThread(net::NetLog* net_log) {
147 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
148 // Cast http user agent settings must be initialized in UI thread
149 // because it registers itself to pref notification observer which is not
150 // thread safe.
151 http_user_agent_settings_.reset(new CastHttpUserAgentSettings());
153 // Proxy config service should be initialized in UI thread, since
154 // ProxyConfigServiceDelegate on Android expects UI thread.
155 proxy_config_service_.reset(net::ProxyService::CreateSystemProxyConfigService(
156 content::BrowserThread::GetMessageLoopProxyForThread(
157 content::BrowserThread::IO),
158 content::BrowserThread::GetMessageLoopProxyForThread(
159 content::BrowserThread::FILE)));
161 net_log_ = net_log;
164 net::URLRequestContextGetter* URLRequestContextFactory::CreateMainGetter(
165 content::BrowserContext* browser_context,
166 content::ProtocolHandlerMap* protocol_handlers,
167 content::URLRequestInterceptorScopedVector request_interceptors) {
168 DCHECK(!main_getter_.get())
169 << "Main URLRequestContextGetter already initialized";
170 main_getter_ = new MainURLRequestContextGetter(this,
171 browser_context,
172 protocol_handlers,
173 request_interceptors.Pass());
174 return main_getter_.get();
177 net::URLRequestContextGetter* URLRequestContextFactory::GetMainGetter() {
178 CHECK(main_getter_.get());
179 return main_getter_.get();
182 net::URLRequestContextGetter* URLRequestContextFactory::GetSystemGetter() {
183 if (!system_getter_.get()) {
184 system_getter_ = new URLRequestContextGetter(this, false);
186 return system_getter_.get();
189 net::URLRequestContextGetter* URLRequestContextFactory::GetMediaGetter() {
190 if (!media_getter_.get()) {
191 media_getter_ = new URLRequestContextGetter(this, true);
193 return media_getter_.get();
196 void URLRequestContextFactory::InitializeSystemContextDependencies() {
197 if (system_dependencies_initialized_)
198 return;
200 host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL);
202 // TODO(lcwu): http://crbug.com/392352. For performance and security reasons,
203 // a persistent (on-disk) HttpServerProperties and ChannelIDService might be
204 // desirable in the future.
205 channel_id_service_.reset(
206 new net::ChannelIDService(new net::DefaultChannelIDStore(NULL),
207 base::WorkerPool::GetTaskRunner(true)));
209 cert_verifier_.reset(net::CertVerifier::CreateDefault());
211 ssl_config_service_ = new net::SSLConfigServiceDefaults;
213 transport_security_state_.reset(new net::TransportSecurityState());
214 http_auth_handler_factory_.reset(
215 net::HttpAuthHandlerFactory::CreateDefault(host_resolver_.get()));
217 http_server_properties_.reset(new net::HttpServerPropertiesImpl);
219 proxy_service_.reset(net::ProxyService::CreateUsingSystemProxyResolver(
220 proxy_config_service_.release(), 0, NULL));
221 system_dependencies_initialized_ = true;
224 void URLRequestContextFactory::InitializeMainContextDependencies(
225 net::HttpTransactionFactory* transaction_factory,
226 content::ProtocolHandlerMap* protocol_handlers,
227 content::URLRequestInterceptorScopedVector request_interceptors) {
228 if (main_dependencies_initialized_)
229 return;
231 main_transaction_factory_.reset(transaction_factory);
232 scoped_ptr<net::URLRequestJobFactoryImpl> job_factory(
233 new net::URLRequestJobFactoryImpl());
234 // Keep ProtocolHandlers added in sync with
235 // CastContentBrowserClient::IsHandledURL().
236 bool set_protocol = false;
237 for (content::ProtocolHandlerMap::iterator it = protocol_handlers->begin();
238 it != protocol_handlers->end();
239 ++it) {
240 set_protocol = job_factory->SetProtocolHandler(
241 it->first, make_scoped_ptr(it->second.release()));
242 DCHECK(set_protocol);
244 set_protocol = job_factory->SetProtocolHandler(
245 url::kDataScheme, make_scoped_ptr(new net::DataProtocolHandler));
246 DCHECK(set_protocol);
248 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
249 switches::kEnableLocalFileAccesses)) {
250 set_protocol = job_factory->SetProtocolHandler(
251 url::kFileScheme,
252 make_scoped_ptr(new net::FileProtocolHandler(
253 content::BrowserThread::GetBlockingPool()
254 ->GetTaskRunnerWithShutdownBehavior(
255 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN))));
256 DCHECK(set_protocol);
259 // Set up interceptors in the reverse order.
260 scoped_ptr<net::URLRequestJobFactory> top_job_factory = job_factory.Pass();
261 for (content::URLRequestInterceptorScopedVector::reverse_iterator i =
262 request_interceptors.rbegin();
263 i != request_interceptors.rend();
264 ++i) {
265 top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
266 top_job_factory.Pass(), make_scoped_ptr(*i)));
268 request_interceptors.weak_clear();
270 main_job_factory_.reset(top_job_factory.release());
272 main_dependencies_initialized_ = true;
275 void URLRequestContextFactory::InitializeMediaContextDependencies(
276 net::HttpTransactionFactory* transaction_factory) {
277 if (media_dependencies_initialized_)
278 return;
280 media_transaction_factory_.reset(transaction_factory);
281 media_dependencies_initialized_ = true;
284 void URLRequestContextFactory::PopulateNetworkSessionParams(
285 bool ignore_certificate_errors,
286 net::HttpNetworkSession::Params* params) {
287 params->host_resolver = host_resolver_.get();
288 params->cert_verifier = cert_verifier_.get();
289 params->channel_id_service = channel_id_service_.get();
290 params->ssl_config_service = ssl_config_service_.get();
291 params->transport_security_state = transport_security_state_.get();
292 params->http_auth_handler_factory = http_auth_handler_factory_.get();
293 params->http_server_properties = http_server_properties_->GetWeakPtr();
294 params->ignore_certificate_errors = ignore_certificate_errors;
295 params->proxy_service = proxy_service_.get();
297 // TODO(lcwu): http://crbug.com/329681. Remove this once spdy is enabled
298 // by default at the content level.
299 params->next_protos = net::NextProtosSpdy31();
300 params->use_alternative_services = true;
303 net::URLRequestContext* URLRequestContextFactory::CreateSystemRequestContext() {
304 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
305 InitializeSystemContextDependencies();
306 net::HttpNetworkSession::Params system_params;
307 PopulateNetworkSessionParams(false, &system_params);
308 system_transaction_factory_.reset(new net::HttpNetworkLayer(
309 new net::HttpNetworkSession(system_params)));
310 system_job_factory_.reset(new net::URLRequestJobFactoryImpl());
312 net::URLRequestContext* system_context = new net::URLRequestContext();
313 system_context->set_host_resolver(host_resolver_.get());
314 system_context->set_channel_id_service(channel_id_service_.get());
315 system_context->set_cert_verifier(cert_verifier_.get());
316 system_context->set_proxy_service(proxy_service_.get());
317 system_context->set_ssl_config_service(ssl_config_service_.get());
318 system_context->set_transport_security_state(
319 transport_security_state_.get());
320 system_context->set_http_auth_handler_factory(
321 http_auth_handler_factory_.get());
322 system_context->set_http_server_properties(
323 http_server_properties_->GetWeakPtr());
324 system_context->set_http_transaction_factory(
325 system_transaction_factory_.get());
326 system_context->set_http_user_agent_settings(
327 http_user_agent_settings_.get());
328 system_context->set_job_factory(system_job_factory_.get());
329 system_context->set_cookie_store(
330 content::CreateCookieStore(content::CookieStoreConfig()));
331 system_context->set_network_delegate(system_network_delegate_.get());
332 system_context->set_net_log(net_log_);
333 return system_context;
336 net::URLRequestContext* URLRequestContextFactory::CreateMediaRequestContext() {
337 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
338 DCHECK(main_getter_.get())
339 << "Getting MediaRequestContext before MainRequestContext";
340 net::URLRequestContext* main_context = main_getter_->GetURLRequestContext();
342 // Set non caching backend.
343 net::HttpNetworkSession* main_session =
344 main_transaction_factory_->GetSession();
345 InitializeMediaContextDependencies(
346 new net::HttpNetworkLayer(main_session));
348 net::URLRequestContext* media_context = new net::URLRequestContext();
349 media_context->CopyFrom(main_context);
350 media_context->set_http_transaction_factory(
351 media_transaction_factory_.get());
352 media_context->set_net_log(net_log_);
353 return media_context;
356 net::URLRequestContext* URLRequestContextFactory::CreateMainRequestContext(
357 content::BrowserContext* browser_context,
358 content::ProtocolHandlerMap* protocol_handlers,
359 content::URLRequestInterceptorScopedVector request_interceptors) {
360 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
361 InitializeSystemContextDependencies();
363 bool ignore_certificate_errors = false;
364 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
365 if (cmd_line->HasSwitch(switches::kIgnoreCertificateErrors)) {
366 ignore_certificate_errors = true;
368 net::HttpNetworkSession::Params network_session_params;
369 PopulateNetworkSessionParams(ignore_certificate_errors,
370 &network_session_params);
371 InitializeMainContextDependencies(
372 new net::HttpNetworkLayer(
373 new net::HttpNetworkSession(network_session_params)),
374 protocol_handlers,
375 request_interceptors.Pass());
377 content::CookieStoreConfig cookie_config(
378 browser_context->GetPath().Append(kCookieStoreFile),
379 content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
380 NULL, NULL);
381 cookie_config.background_task_runner =
382 scoped_refptr<base::SequencedTaskRunner>();
383 scoped_refptr<net::CookieStore> cookie_store =
384 content::CreateCookieStore(cookie_config);
386 net::URLRequestContext* main_context = new net::URLRequestContext();
387 main_context->set_host_resolver(host_resolver_.get());
388 main_context->set_channel_id_service(channel_id_service_.get());
389 main_context->set_cert_verifier(cert_verifier_.get());
390 main_context->set_proxy_service(proxy_service_.get());
391 main_context->set_ssl_config_service(ssl_config_service_.get());
392 main_context->set_transport_security_state(transport_security_state_.get());
393 main_context->set_http_auth_handler_factory(
394 http_auth_handler_factory_.get());
395 main_context->set_http_server_properties(
396 http_server_properties_->GetWeakPtr());
397 main_context->set_cookie_store(cookie_store.get());
398 main_context->set_http_user_agent_settings(
399 http_user_agent_settings_.get());
401 main_context->set_http_transaction_factory(
402 main_transaction_factory_.get());
403 main_context->set_job_factory(main_job_factory_.get());
404 main_context->set_network_delegate(app_network_delegate_.get());
405 main_context->set_net_log(net_log_);
406 return main_context;
409 void URLRequestContextFactory::InitializeNetworkDelegates() {
410 app_network_delegate_->Initialize(false);
411 LOG(INFO) << "Initialized app network delegate.";
412 system_network_delegate_->Initialize(false);
413 LOG(INFO) << "Initialized system network delegate.";
416 } // namespace shell
417 } // namespace chromecast