Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chromecast / shell / browser / url_request_context_factory.cc
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.
4
5 #include "chromecast/shell/browser/url_request_context_factory.h"
6
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/shell/browser/cast_http_user_agent_settings.h"
13 #include "content/public/browser/browser_context.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/cookie_store_factory.h"
16 #include "content/public/common/content_switches.h"
17 #include "content/public/common/url_constants.h"
18 #include "net/cert/cert_verifier.h"
19 #include "net/cookies/cookie_store.h"
20 #include "net/dns/host_resolver.h"
21 #include "net/http/http_auth_handler_factory.h"
22 #include "net/http/http_cache.h"
23 #include "net/http/http_network_layer.h"
24 #include "net/http/http_server_properties_impl.h"
25 #include "net/http/http_stream_factory.h"
26 #include "net/ocsp/nss_ocsp.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"
38
39 namespace chromecast {
40 namespace shell {
41
42 namespace {
43
44 const char kCookieStoreFile[] = "Cookies";
45
46 }  // namespace
47
48 // Private classes to expose URLRequestContextGetter that call back to the
49 // URLRequestContextFactory to create the URLRequestContext on demand.
50 //
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) {
59   }
60
61   virtual 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)
68         // Set request context used by NSS for Crl requests.
69         net::SetURLRequestContextForNSSHttpIO(request_context_.get());
70 #endif  // defined(USE_NSS)
71       }
72     }
73     return request_context_.get();
74   }
75
76   virtual scoped_refptr<base::SingleThreadTaskRunner>
77       GetNetworkTaskRunner() const OVERRIDE {
78     return content::BrowserThread::GetMessageLoopProxyForThread(
79         content::BrowserThread::IO);
80   }
81
82  private:
83   virtual ~URLRequestContextGetter() {}
84
85   const bool is_media_;
86   URLRequestContextFactory* const factory_;
87   scoped_ptr<net::URLRequestContext> request_context_;
88
89   DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);
90 };
91
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);
106   }
107
108   virtual 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();
113     }
114     return request_context_.get();
115   }
116
117   virtual scoped_refptr<base::SingleThreadTaskRunner>
118       GetNetworkTaskRunner() const OVERRIDE {
119     return content::BrowserThread::GetMessageLoopProxyForThread(
120         content::BrowserThread::IO);
121   }
122
123  private:
124   virtual ~MainURLRequestContextGetter() {}
125
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_;
131
132   DISALLOW_COPY_AND_ASSIGN(MainURLRequestContextGetter);
133 };
134
135 URLRequestContextFactory::URLRequestContextFactory()
136     : system_dependencies_initialized_(false),
137       main_dependencies_initialized_(false),
138       media_dependencies_initialized_(false) {
139 }
140
141 URLRequestContextFactory::~URLRequestContextFactory() {
142 }
143
144 void URLRequestContextFactory::InitializeOnUIThread() {
145   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
146   // Cast http user agent settings must be initialized in UI thread
147   // because it registers itself to pref notification observer which is not
148   // thread safe.
149   http_user_agent_settings_.reset(new CastHttpUserAgentSettings());
150
151   // Proxy config service should be initialized in UI thread, since
152   // ProxyConfigServiceDelegate on Android expects UI thread.
153   proxy_config_service_.reset(net::ProxyService::CreateSystemProxyConfigService(
154       content::BrowserThread::GetMessageLoopProxyForThread(
155           content::BrowserThread::IO),
156       content::BrowserThread::GetMessageLoopProxyForThread(
157           content::BrowserThread::FILE)));
158 }
159
160 net::URLRequestContextGetter* URLRequestContextFactory::CreateMainGetter(
161     content::BrowserContext* browser_context,
162     content::ProtocolHandlerMap* protocol_handlers,
163     content::URLRequestInterceptorScopedVector request_interceptors) {
164   DCHECK(!main_getter_.get())
165       << "Main URLRequestContextGetter already initialized";
166   main_getter_ = new MainURLRequestContextGetter(this,
167                                                  browser_context,
168                                                  protocol_handlers,
169                                                  request_interceptors.Pass());
170   return main_getter_.get();
171 }
172
173 net::URLRequestContextGetter* URLRequestContextFactory::GetMainGetter() {
174   CHECK(main_getter_.get());
175   return main_getter_.get();
176 }
177
178 net::URLRequestContextGetter* URLRequestContextFactory::GetSystemGetter() {
179   if (!system_getter_.get()) {
180     system_getter_ = new URLRequestContextGetter(this, false);
181   }
182   return system_getter_.get();
183 }
184
185 net::URLRequestContextGetter* URLRequestContextFactory::GetMediaGetter() {
186   if (!media_getter_.get()) {
187     media_getter_ = new URLRequestContextGetter(this, true);
188   }
189   return media_getter_.get();
190 }
191
192 void URLRequestContextFactory::InitializeSystemContextDependencies() {
193   if (system_dependencies_initialized_)
194     return;
195
196   host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL);
197
198   // TODO(lcwu): http://crbug.com/392352. For performance and security reasons,
199   // a persistent (on-disk) HttpServerProperties and ChannelIDService might be
200   // desirable in the future.
201   channel_id_service_.reset(
202       new net::ChannelIDService(new net::DefaultChannelIDStore(NULL),
203                                 base::WorkerPool::GetTaskRunner(true)));
204
205   cert_verifier_.reset(net::CertVerifier::CreateDefault());
206
207   ssl_config_service_ = new net::SSLConfigServiceDefaults;
208
209   transport_security_state_.reset(new net::TransportSecurityState());
210   http_auth_handler_factory_.reset(
211       net::HttpAuthHandlerFactory::CreateDefault(host_resolver_.get()));
212
213   http_server_properties_.reset(new net::HttpServerPropertiesImpl);
214
215   proxy_service_.reset(net::ProxyService::CreateUsingSystemProxyResolver(
216       proxy_config_service_.release(), 0, NULL));
217   system_dependencies_initialized_ = true;
218 }
219
220 void URLRequestContextFactory::InitializeMainContextDependencies(
221     net::HttpTransactionFactory* transaction_factory,
222     content::ProtocolHandlerMap* protocol_handlers,
223     content::URLRequestInterceptorScopedVector request_interceptors) {
224   if (main_dependencies_initialized_)
225     return;
226
227   main_transaction_factory_.reset(transaction_factory);
228   scoped_ptr<net::URLRequestJobFactoryImpl> job_factory(
229       new net::URLRequestJobFactoryImpl());
230   // Keep ProtocolHandlers added in sync with
231   // CastContentBrowserClient::IsHandledURL().
232   bool set_protocol = false;
233   for (content::ProtocolHandlerMap::iterator it = protocol_handlers->begin();
234        it != protocol_handlers->end();
235        ++it) {
236     set_protocol = job_factory->SetProtocolHandler(
237         it->first, it->second.release());
238     DCHECK(set_protocol);
239   }
240   set_protocol = job_factory->SetProtocolHandler(
241       url::kDataScheme,
242       new net::DataProtocolHandler);
243   DCHECK(set_protocol);
244 #if defined(OS_ANDROID)
245   set_protocol = job_factory->SetProtocolHandler(
246       url::kFileScheme,
247       new net::FileProtocolHandler(
248           content::BrowserThread::GetBlockingPool()->
249               GetTaskRunnerWithShutdownBehavior(
250                   base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
251   DCHECK(set_protocol);
252 #endif  // defined(OS_ANDROID)
253
254   // Set up interceptors in the reverse order.
255   scoped_ptr<net::URLRequestJobFactory> top_job_factory =
256       job_factory.PassAs<net::URLRequestJobFactory>();
257   for (content::URLRequestInterceptorScopedVector::reverse_iterator i =
258            request_interceptors.rbegin();
259        i != request_interceptors.rend();
260        ++i) {
261     top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
262         top_job_factory.Pass(), make_scoped_ptr(*i)));
263   }
264   request_interceptors.weak_clear();
265
266   main_job_factory_.reset(top_job_factory.release());
267
268   main_dependencies_initialized_ = true;
269 }
270
271 void URLRequestContextFactory::InitializeMediaContextDependencies(
272     net::HttpTransactionFactory* transaction_factory) {
273   if (media_dependencies_initialized_)
274     return;
275
276   media_transaction_factory_.reset(transaction_factory);
277   media_dependencies_initialized_ = true;
278 }
279
280 void URLRequestContextFactory::PopulateNetworkSessionParams(
281     bool ignore_certificate_errors,
282     net::HttpNetworkSession::Params* params) {
283   params->host_resolver = host_resolver_.get();
284   params->cert_verifier = cert_verifier_.get();
285   params->channel_id_service = channel_id_service_.get();
286   params->ssl_config_service = ssl_config_service_.get();
287   params->transport_security_state = transport_security_state_.get();
288   params->http_auth_handler_factory = http_auth_handler_factory_.get();
289   params->http_server_properties = http_server_properties_->GetWeakPtr();
290   params->ignore_certificate_errors = ignore_certificate_errors;
291   params->proxy_service = proxy_service_.get();
292
293   // TODO(lcwu): http://crbug.com/329681. Remove this once spdy is enabled
294   // by default at the content level.
295   params->next_protos = net::NextProtosSpdy31();
296   params->use_alternate_protocols = true;
297 }
298
299 net::URLRequestContext* URLRequestContextFactory::CreateSystemRequestContext() {
300   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
301   InitializeSystemContextDependencies();
302   net::HttpNetworkSession::Params system_params;
303   PopulateNetworkSessionParams(false, &system_params);
304   system_transaction_factory_.reset(new net::HttpNetworkLayer(
305       new net::HttpNetworkSession(system_params)));
306   system_job_factory_.reset(new net::URLRequestJobFactoryImpl());
307
308   net::URLRequestContext* system_context = new net::URLRequestContext();
309   system_context->set_host_resolver(host_resolver_.get());
310   system_context->set_channel_id_service(channel_id_service_.get());
311   system_context->set_cert_verifier(cert_verifier_.get());
312   system_context->set_proxy_service(proxy_service_.get());
313   system_context->set_ssl_config_service(ssl_config_service_.get());
314   system_context->set_transport_security_state(
315       transport_security_state_.get());
316   system_context->set_http_auth_handler_factory(
317       http_auth_handler_factory_.get());
318   system_context->set_http_server_properties(
319       http_server_properties_->GetWeakPtr());
320   system_context->set_http_transaction_factory(
321       system_transaction_factory_.get());
322   system_context->set_http_user_agent_settings(
323       http_user_agent_settings_.get());
324   system_context->set_job_factory(system_job_factory_.get());
325   system_context->set_cookie_store(
326       content::CreateCookieStore(content::CookieStoreConfig()));
327   return system_context;
328 }
329
330 net::URLRequestContext* URLRequestContextFactory::CreateMediaRequestContext() {
331   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
332   DCHECK(main_getter_.get())
333       << "Getting MediaRequestContext before MainRequestContext";
334   net::URLRequestContext* main_context = main_getter_->GetURLRequestContext();
335
336   // Set non caching backend.
337   net::HttpNetworkSession* main_session =
338       main_transaction_factory_->GetSession();
339   InitializeMediaContextDependencies(
340       new net::HttpNetworkLayer(main_session));
341
342   net::URLRequestContext* media_context = new net::URLRequestContext();
343   media_context->CopyFrom(main_context);
344   media_context->set_http_transaction_factory(
345       media_transaction_factory_.get());
346   return media_context;
347 }
348
349 net::URLRequestContext* URLRequestContextFactory::CreateMainRequestContext(
350     content::BrowserContext* browser_context,
351     content::ProtocolHandlerMap* protocol_handlers,
352     content::URLRequestInterceptorScopedVector request_interceptors) {
353   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
354   InitializeSystemContextDependencies();
355
356   net::HttpCache::BackendFactory* main_backend =
357       net::HttpCache::DefaultBackend::InMemory(16 * 1024 * 1024);
358
359   bool ignore_certificate_errors = false;
360   CommandLine* cmd_line = CommandLine::ForCurrentProcess();
361   if (cmd_line->HasSwitch(switches::kIgnoreCertificateErrors)) {
362     ignore_certificate_errors = true;
363   }
364   net::HttpNetworkSession::Params network_session_params;
365   PopulateNetworkSessionParams(ignore_certificate_errors,
366                                &network_session_params);
367   InitializeMainContextDependencies(
368       new net::HttpCache(network_session_params, main_backend),
369       protocol_handlers,
370       request_interceptors.Pass());
371
372   content::CookieStoreConfig cookie_config(
373       browser_context->GetPath().Append(kCookieStoreFile),
374       content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
375       NULL, NULL);
376   cookie_config.background_task_runner =
377       scoped_refptr<base::SequencedTaskRunner>();
378   scoped_refptr<net::CookieStore> cookie_store =
379       content::CreateCookieStore(cookie_config);
380
381   net::URLRequestContext* main_context = new net::URLRequestContext();
382   main_context->set_host_resolver(host_resolver_.get());
383   main_context->set_channel_id_service(channel_id_service_.get());
384   main_context->set_cert_verifier(cert_verifier_.get());
385   main_context->set_proxy_service(proxy_service_.get());
386   main_context->set_ssl_config_service(ssl_config_service_.get());
387   main_context->set_transport_security_state(transport_security_state_.get());
388   main_context->set_http_auth_handler_factory(
389       http_auth_handler_factory_.get());
390   main_context->set_http_server_properties(
391       http_server_properties_->GetWeakPtr());
392   main_context->set_cookie_store(cookie_store.get());
393   main_context->set_http_user_agent_settings(
394       http_user_agent_settings_.get());
395
396   main_context->set_http_transaction_factory(
397       main_transaction_factory_.get());
398   main_context->set_job_factory(main_job_factory_.get());
399   return main_context;
400 }
401
402 }  // namespace shell
403 }  // namespace chromecast