Implemented OwnerSettingsService::Set() method.
[chromium-blink-merge.git] / chromecast / browser / url_request_context_factory.cc
blob77d77f332ff07c8eed2a79067ba1bbc6fc0be2bf
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/path_service.h"
11 #include "base/threading/worker_pool.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/cookies/cookie_store.h"
21 #include "net/dns/host_resolver.h"
22 #include "net/http/http_auth_handler_factory.h"
23 #include "net/http/http_cache.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/ocsp/nss_ocsp.h"
28 #include "net/proxy/proxy_service.h"
29 #include "net/socket/next_proto.h"
30 #include "net/ssl/channel_id_service.h"
31 #include "net/ssl/default_channel_id_store.h"
32 #include "net/ssl/ssl_config_service_defaults.h"
33 #include "net/url_request/data_protocol_handler.h"
34 #include "net/url_request/file_protocol_handler.h"
35 #include "net/url_request/url_request_context.h"
36 #include "net/url_request/url_request_context_getter.h"
37 #include "net/url_request/url_request_intercepting_job_factory.h"
38 #include "net/url_request/url_request_job_factory_impl.h"
40 namespace chromecast {
41 namespace shell {
43 namespace {
45 const char kCookieStoreFile[] = "Cookies";
47 } // namespace
49 // Private classes to expose URLRequestContextGetter that call back to the
50 // URLRequestContextFactory to create the URLRequestContext on demand.
52 // The URLRequestContextFactory::URLRequestContextGetter class is used for both
53 // the system and media URLRequestCotnexts.
54 class URLRequestContextFactory::URLRequestContextGetter
55 : public net::URLRequestContextGetter {
56 public:
57 URLRequestContextGetter(URLRequestContextFactory* factory, bool is_media)
58 : is_media_(is_media),
59 factory_(factory) {
62 virtual net::URLRequestContext* GetURLRequestContext() override {
63 if (!request_context_) {
64 if (is_media_) {
65 request_context_.reset(factory_->CreateMediaRequestContext());
66 } else {
67 request_context_.reset(factory_->CreateSystemRequestContext());
68 #if defined(USE_NSS)
69 // Set request context used by NSS for Crl requests.
70 net::SetURLRequestContextForNSSHttpIO(request_context_.get());
71 #endif // defined(USE_NSS)
74 return request_context_.get();
77 virtual scoped_refptr<base::SingleThreadTaskRunner>
78 GetNetworkTaskRunner() const override {
79 return content::BrowserThread::GetMessageLoopProxyForThread(
80 content::BrowserThread::IO);
83 private:
84 virtual ~URLRequestContextGetter() {}
86 const bool is_media_;
87 URLRequestContextFactory* const factory_;
88 scoped_ptr<net::URLRequestContext> request_context_;
90 DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);
93 // The URLRequestContextFactory::MainURLRequestContextGetter class is used for
94 // the main URLRequestContext.
95 class URLRequestContextFactory::MainURLRequestContextGetter
96 : public net::URLRequestContextGetter {
97 public:
98 MainURLRequestContextGetter(
99 URLRequestContextFactory* factory,
100 content::BrowserContext* browser_context,
101 content::ProtocolHandlerMap* protocol_handlers,
102 content::URLRequestInterceptorScopedVector request_interceptors)
103 : browser_context_(browser_context),
104 factory_(factory),
105 request_interceptors_(request_interceptors.Pass()) {
106 std::swap(protocol_handlers_, *protocol_handlers);
109 virtual net::URLRequestContext* GetURLRequestContext() override {
110 if (!request_context_) {
111 request_context_.reset(factory_->CreateMainRequestContext(
112 browser_context_, &protocol_handlers_, request_interceptors_.Pass()));
113 protocol_handlers_.clear();
115 return request_context_.get();
118 virtual scoped_refptr<base::SingleThreadTaskRunner>
119 GetNetworkTaskRunner() const override {
120 return content::BrowserThread::GetMessageLoopProxyForThread(
121 content::BrowserThread::IO);
124 private:
125 virtual ~MainURLRequestContextGetter() {}
127 content::BrowserContext* const browser_context_;
128 URLRequestContextFactory* const factory_;
129 content::ProtocolHandlerMap protocol_handlers_;
130 content::URLRequestInterceptorScopedVector request_interceptors_;
131 scoped_ptr<net::URLRequestContext> request_context_;
133 DISALLOW_COPY_AND_ASSIGN(MainURLRequestContextGetter);
136 URLRequestContextFactory::URLRequestContextFactory()
137 : app_network_delegate_(CastNetworkDelegate::Create()),
138 system_network_delegate_(CastNetworkDelegate::Create()),
139 system_dependencies_initialized_(false),
140 main_dependencies_initialized_(false),
141 media_dependencies_initialized_(false) {
144 URLRequestContextFactory::~URLRequestContextFactory() {
147 void URLRequestContextFactory::InitializeOnUIThread() {
148 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
149 // Cast http user agent settings must be initialized in UI thread
150 // because it registers itself to pref notification observer which is not
151 // thread safe.
152 http_user_agent_settings_.reset(new CastHttpUserAgentSettings());
154 // Proxy config service should be initialized in UI thread, since
155 // ProxyConfigServiceDelegate on Android expects UI thread.
156 proxy_config_service_.reset(net::ProxyService::CreateSystemProxyConfigService(
157 content::BrowserThread::GetMessageLoopProxyForThread(
158 content::BrowserThread::IO),
159 content::BrowserThread::GetMessageLoopProxyForThread(
160 content::BrowserThread::FILE)));
163 net::URLRequestContextGetter* URLRequestContextFactory::CreateMainGetter(
164 content::BrowserContext* browser_context,
165 content::ProtocolHandlerMap* protocol_handlers,
166 content::URLRequestInterceptorScopedVector request_interceptors) {
167 DCHECK(!main_getter_.get())
168 << "Main URLRequestContextGetter already initialized";
169 main_getter_ = new MainURLRequestContextGetter(this,
170 browser_context,
171 protocol_handlers,
172 request_interceptors.Pass());
173 return main_getter_.get();
176 net::URLRequestContextGetter* URLRequestContextFactory::GetMainGetter() {
177 CHECK(main_getter_.get());
178 return main_getter_.get();
181 net::URLRequestContextGetter* URLRequestContextFactory::GetSystemGetter() {
182 if (!system_getter_.get()) {
183 system_getter_ = new URLRequestContextGetter(this, false);
185 return system_getter_.get();
188 net::URLRequestContextGetter* URLRequestContextFactory::GetMediaGetter() {
189 if (!media_getter_.get()) {
190 media_getter_ = new URLRequestContextGetter(this, true);
192 return media_getter_.get();
195 void URLRequestContextFactory::InitializeSystemContextDependencies() {
196 if (system_dependencies_initialized_)
197 return;
199 host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL);
201 // TODO(lcwu): http://crbug.com/392352. For performance and security reasons,
202 // a persistent (on-disk) HttpServerProperties and ChannelIDService might be
203 // desirable in the future.
204 channel_id_service_.reset(
205 new net::ChannelIDService(new net::DefaultChannelIDStore(NULL),
206 base::WorkerPool::GetTaskRunner(true)));
208 cert_verifier_.reset(net::CertVerifier::CreateDefault());
210 ssl_config_service_ = new net::SSLConfigServiceDefaults;
212 transport_security_state_.reset(new net::TransportSecurityState());
213 http_auth_handler_factory_.reset(
214 net::HttpAuthHandlerFactory::CreateDefault(host_resolver_.get()));
216 http_server_properties_.reset(new net::HttpServerPropertiesImpl);
218 proxy_service_.reset(net::ProxyService::CreateUsingSystemProxyResolver(
219 proxy_config_service_.release(), 0, NULL));
220 system_dependencies_initialized_ = true;
223 void URLRequestContextFactory::InitializeMainContextDependencies(
224 net::HttpTransactionFactory* transaction_factory,
225 content::ProtocolHandlerMap* protocol_handlers,
226 content::URLRequestInterceptorScopedVector request_interceptors) {
227 if (main_dependencies_initialized_)
228 return;
230 main_transaction_factory_.reset(transaction_factory);
231 scoped_ptr<net::URLRequestJobFactoryImpl> job_factory(
232 new net::URLRequestJobFactoryImpl());
233 // Keep ProtocolHandlers added in sync with
234 // CastContentBrowserClient::IsHandledURL().
235 bool set_protocol = false;
236 for (content::ProtocolHandlerMap::iterator it = protocol_handlers->begin();
237 it != protocol_handlers->end();
238 ++it) {
239 set_protocol = job_factory->SetProtocolHandler(
240 it->first, it->second.release());
241 DCHECK(set_protocol);
243 set_protocol = job_factory->SetProtocolHandler(
244 url::kDataScheme,
245 new net::DataProtocolHandler);
246 DCHECK(set_protocol);
247 #if defined(OS_ANDROID)
248 set_protocol = job_factory->SetProtocolHandler(
249 url::kFileScheme,
250 new net::FileProtocolHandler(
251 content::BrowserThread::GetBlockingPool()->
252 GetTaskRunnerWithShutdownBehavior(
253 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
254 DCHECK(set_protocol);
255 #endif // defined(OS_ANDROID)
257 // Set up interceptors in the reverse order.
258 scoped_ptr<net::URLRequestJobFactory> top_job_factory = job_factory.Pass();
259 for (content::URLRequestInterceptorScopedVector::reverse_iterator i =
260 request_interceptors.rbegin();
261 i != request_interceptors.rend();
262 ++i) {
263 top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
264 top_job_factory.Pass(), make_scoped_ptr(*i)));
266 request_interceptors.weak_clear();
268 main_job_factory_.reset(top_job_factory.release());
270 main_dependencies_initialized_ = true;
273 void URLRequestContextFactory::InitializeMediaContextDependencies(
274 net::HttpTransactionFactory* transaction_factory) {
275 if (media_dependencies_initialized_)
276 return;
278 media_transaction_factory_.reset(transaction_factory);
279 media_dependencies_initialized_ = true;
282 void URLRequestContextFactory::PopulateNetworkSessionParams(
283 bool ignore_certificate_errors,
284 net::HttpNetworkSession::Params* params) {
285 params->host_resolver = host_resolver_.get();
286 params->cert_verifier = cert_verifier_.get();
287 params->channel_id_service = channel_id_service_.get();
288 params->ssl_config_service = ssl_config_service_.get();
289 params->transport_security_state = transport_security_state_.get();
290 params->http_auth_handler_factory = http_auth_handler_factory_.get();
291 params->http_server_properties = http_server_properties_->GetWeakPtr();
292 params->ignore_certificate_errors = ignore_certificate_errors;
293 params->proxy_service = proxy_service_.get();
295 // TODO(lcwu): http://crbug.com/329681. Remove this once spdy is enabled
296 // by default at the content level.
297 params->next_protos = net::NextProtosSpdy31();
298 params->use_alternate_protocols = true;
301 net::URLRequestContext* URLRequestContextFactory::CreateSystemRequestContext() {
302 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
303 InitializeSystemContextDependencies();
304 net::HttpNetworkSession::Params system_params;
305 PopulateNetworkSessionParams(false, &system_params);
306 system_transaction_factory_.reset(new net::HttpNetworkLayer(
307 new net::HttpNetworkSession(system_params)));
308 system_job_factory_.reset(new net::URLRequestJobFactoryImpl());
310 net::URLRequestContext* system_context = new net::URLRequestContext();
311 system_context->set_host_resolver(host_resolver_.get());
312 system_context->set_channel_id_service(channel_id_service_.get());
313 system_context->set_cert_verifier(cert_verifier_.get());
314 system_context->set_proxy_service(proxy_service_.get());
315 system_context->set_ssl_config_service(ssl_config_service_.get());
316 system_context->set_transport_security_state(
317 transport_security_state_.get());
318 system_context->set_http_auth_handler_factory(
319 http_auth_handler_factory_.get());
320 system_context->set_http_server_properties(
321 http_server_properties_->GetWeakPtr());
322 system_context->set_http_transaction_factory(
323 system_transaction_factory_.get());
324 system_context->set_http_user_agent_settings(
325 http_user_agent_settings_.get());
326 system_context->set_job_factory(system_job_factory_.get());
327 system_context->set_cookie_store(
328 content::CreateCookieStore(content::CookieStoreConfig()));
329 system_context->set_network_delegate(system_network_delegate_.get());
330 return system_context;
333 net::URLRequestContext* URLRequestContextFactory::CreateMediaRequestContext() {
334 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
335 DCHECK(main_getter_.get())
336 << "Getting MediaRequestContext before MainRequestContext";
337 net::URLRequestContext* main_context = main_getter_->GetURLRequestContext();
339 // Set non caching backend.
340 net::HttpNetworkSession* main_session =
341 main_transaction_factory_->GetSession();
342 InitializeMediaContextDependencies(
343 new net::HttpNetworkLayer(main_session));
345 net::URLRequestContext* media_context = new net::URLRequestContext();
346 media_context->CopyFrom(main_context);
347 media_context->set_http_transaction_factory(
348 media_transaction_factory_.get());
349 return media_context;
352 net::URLRequestContext* URLRequestContextFactory::CreateMainRequestContext(
353 content::BrowserContext* browser_context,
354 content::ProtocolHandlerMap* protocol_handlers,
355 content::URLRequestInterceptorScopedVector request_interceptors) {
356 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
357 InitializeSystemContextDependencies();
359 net::HttpCache::BackendFactory* main_backend =
360 net::HttpCache::DefaultBackend::InMemory(16 * 1024 * 1024);
362 bool ignore_certificate_errors = false;
363 CommandLine* cmd_line = CommandLine::ForCurrentProcess();
364 if (cmd_line->HasSwitch(switches::kIgnoreCertificateErrors)) {
365 ignore_certificate_errors = true;
367 net::HttpNetworkSession::Params network_session_params;
368 PopulateNetworkSessionParams(ignore_certificate_errors,
369 &network_session_params);
370 InitializeMainContextDependencies(
371 new net::HttpCache(network_session_params, main_backend),
372 protocol_handlers,
373 request_interceptors.Pass());
375 content::CookieStoreConfig cookie_config(
376 browser_context->GetPath().Append(kCookieStoreFile),
377 content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
378 NULL, NULL);
379 cookie_config.background_task_runner =
380 scoped_refptr<base::SequencedTaskRunner>();
381 scoped_refptr<net::CookieStore> cookie_store =
382 content::CreateCookieStore(cookie_config);
384 net::URLRequestContext* main_context = new net::URLRequestContext();
385 main_context->set_host_resolver(host_resolver_.get());
386 main_context->set_channel_id_service(channel_id_service_.get());
387 main_context->set_cert_verifier(cert_verifier_.get());
388 main_context->set_proxy_service(proxy_service_.get());
389 main_context->set_ssl_config_service(ssl_config_service_.get());
390 main_context->set_transport_security_state(transport_security_state_.get());
391 main_context->set_http_auth_handler_factory(
392 http_auth_handler_factory_.get());
393 main_context->set_http_server_properties(
394 http_server_properties_->GetWeakPtr());
395 main_context->set_cookie_store(cookie_store.get());
396 main_context->set_http_user_agent_settings(
397 http_user_agent_settings_.get());
399 main_context->set_http_transaction_factory(
400 main_transaction_factory_.get());
401 main_context->set_job_factory(main_job_factory_.get());
402 main_context->set_network_delegate(app_network_delegate_.get());
403 return main_context;
406 void URLRequestContextFactory::InitializeNetworkDelegates() {
407 app_network_delegate_->Initialize(false);
408 LOG(INFO) << "Initialized app network delegate.";
409 system_network_delegate_->Initialize(false);
410 LOG(INFO) << "Initialized system network delegate.";
413 } // namespace shell
414 } // namespace chromecast