OLD | NEW |
---|---|
(Empty) | |
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/default_server_bound_cert_store.h" | |
30 #include "net/ssl/server_bound_cert_service.h" | |
31 #include "net/ssl/ssl_config_service_defaults.h" | |
32 #include "net/url_request/data_protocol_handler.h" | |
33 #include "net/url_request/url_request_context.h" | |
34 #include "net/url_request/url_request_context_getter.h" | |
35 #include "net/url_request/url_request_job_factory_impl.h" | |
36 | |
37 namespace chromecast { | |
38 namespace shell { | |
39 | |
40 namespace { | |
41 | |
42 const char kCookieStoreFile[] = "Cookies"; | |
43 | |
44 } // namespace | |
45 | |
46 // Private classes to expose URLRequestContextGetter that call back to the | |
47 // URLRequestContextFactory to create the URLRequestContext on demand. | |
48 // | |
49 // The URLRequestContextFactory::URLRequestContextGetter class is used for both | |
50 // the system and media URLRequestCotnexts. | |
51 class URLRequestContextFactory::URLRequestContextGetter | |
52 : public net::URLRequestContextGetter { | |
53 public: | |
54 URLRequestContextGetter(URLRequestContextFactory* factory, bool is_media) | |
55 : is_media_(is_media), | |
56 factory_(factory) { | |
57 } | |
58 | |
59 virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE { | |
60 if (!request_context_) { | |
61 if (is_media_) { | |
62 request_context_.reset(factory_->CreateMediaRequestContext()); | |
63 } else { | |
64 request_context_.reset(factory_->CreateSystemRequestContext()); | |
65 // Set request context used by NSS for Crl requests. | |
66 net::SetURLRequestContextForNSSHttpIO(request_context_.get()); | |
67 } | |
68 } | |
69 return request_context_.get(); | |
70 } | |
71 | |
72 virtual scoped_refptr<base::SingleThreadTaskRunner> | |
73 GetNetworkTaskRunner() const OVERRIDE { | |
74 return content::BrowserThread::GetMessageLoopProxyForThread( | |
75 content::BrowserThread::IO); | |
76 } | |
77 | |
78 private: | |
79 virtual ~URLRequestContextGetter() {} | |
80 | |
81 const bool is_media_; | |
82 URLRequestContextFactory* const factory_; | |
83 scoped_ptr<net::URLRequestContext> request_context_; | |
84 | |
85 DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter); | |
86 }; | |
87 | |
88 // The URLRequestContextFactory::MainURLRequestContextGetter class is used for | |
89 // the main URLRequestContext. | |
90 class URLRequestContextFactory::MainURLRequestContextGetter | |
91 : public net::URLRequestContextGetter { | |
92 public: | |
93 MainURLRequestContextGetter(URLRequestContextFactory* factory, | |
94 content::BrowserContext* browser_context, | |
95 content::ProtocolHandlerMap* protocol_handlers) | |
96 : browser_context_(browser_context), | |
97 factory_(factory) { | |
98 std::swap(protocol_handlers_, *protocol_handlers); | |
99 } | |
100 | |
101 virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE { | |
102 if (!request_context_) { | |
103 request_context_.reset(factory_->CreateMainRequestContext( | |
104 browser_context_, &protocol_handlers_)); | |
105 protocol_handlers_.clear(); | |
106 } | |
107 return request_context_.get(); | |
108 } | |
109 | |
110 virtual scoped_refptr<base::SingleThreadTaskRunner> | |
111 GetNetworkTaskRunner() const OVERRIDE { | |
112 return content::BrowserThread::GetMessageLoopProxyForThread( | |
113 content::BrowserThread::IO); | |
114 } | |
115 | |
116 private: | |
117 virtual ~MainURLRequestContextGetter() {} | |
118 | |
119 content::BrowserContext* const browser_context_; | |
120 URLRequestContextFactory* const factory_; | |
121 content::ProtocolHandlerMap protocol_handlers_; | |
122 scoped_ptr<net::URLRequestContext> request_context_; | |
123 | |
124 DISALLOW_COPY_AND_ASSIGN(MainURLRequestContextGetter); | |
125 }; | |
126 | |
127 URLRequestContextFactory::URLRequestContextFactory() | |
128 : system_dependencies_initialized_(false), | |
129 main_dependencies_initialized_(false), | |
130 media_dependencies_initialized_(false) { | |
131 } | |
132 | |
133 URLRequestContextFactory::~URLRequestContextFactory() { | |
134 } | |
135 | |
136 void URLRequestContextFactory::InitializeOnUIThread() { | |
137 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
138 // Cast http user agent settings must be initialized in UI thread | |
139 // because it registers itself to pref notification observer which is not | |
140 // thread safe. | |
141 http_user_agent_settings_.reset(new CastHttpUserAgentSettings()); | |
142 } | |
143 | |
144 net::URLRequestContextGetter* URLRequestContextFactory::CreateMainGetter( | |
145 content::BrowserContext* browser_context, | |
146 content::ProtocolHandlerMap* protocol_handlers) { | |
147 DCHECK(!main_getter_) << "Main URLRequestContextGetter already initialized"; | |
148 main_getter_ = new MainURLRequestContextGetter(this, | |
149 browser_context, | |
150 protocol_handlers); | |
151 return main_getter_.get(); | |
152 } | |
153 | |
154 net::URLRequestContextGetter* URLRequestContextFactory::GetMainGetter() { | |
155 CHECK(main_getter_); | |
156 return main_getter_.get(); | |
157 } | |
158 | |
159 net::URLRequestContextGetter* URLRequestContextFactory::GetSystemGetter() { | |
160 if (!system_getter_) { | |
161 system_getter_ = new URLRequestContextGetter(this, false); | |
162 } | |
163 return system_getter_.get(); | |
164 } | |
165 | |
166 net::URLRequestContextGetter* URLRequestContextFactory::GetMediaGetter() { | |
167 if (!media_getter_) { | |
168 media_getter_ = new URLRequestContextGetter(this, true); | |
169 } | |
170 return media_getter_.get(); | |
171 } | |
172 | |
173 void URLRequestContextFactory::InitializeSystemContextDependencies() { | |
174 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.
| |
175 host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL); | |
176 | |
177 server_bound_cert_service_.reset(new net::ServerBoundCertService( | |
178 new net::DefaultServerBoundCertStore(NULL), | |
179 base::WorkerPool::GetTaskRunner(true))); | |
180 | |
181 cert_verifier_.reset(net::CertVerifier::CreateDefault()); | |
182 | |
183 ssl_config_service_ = new net::SSLConfigServiceDefaults; | |
184 | |
185 transport_security_state_.reset(new net::TransportSecurityState()); | |
186 http_auth_handler_factory_.reset( | |
187 net::HttpAuthHandlerFactory::CreateDefault(host_resolver_.get())); | |
188 | |
189 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.
| |
190 | |
191 proxy_service_.reset(net::ProxyService::CreateUsingSystemProxyResolver( | |
192 net::ProxyService::CreateSystemProxyConfigService( | |
193 content::BrowserThread::GetMessageLoopProxyForThread( | |
194 content::BrowserThread::IO).get(), | |
195 content::BrowserThread::UnsafeGetMessageLoopForThread( | |
196 content::BrowserThread::FILE)), | |
197 0, | |
198 NULL)); | |
199 system_dependencies_initialized_ = true; | |
200 } | |
201 } | |
202 | |
203 void URLRequestContextFactory::InitializeMainContextDependencies( | |
204 net::HttpTransactionFactory* transaction_factory, | |
205 content::ProtocolHandlerMap* protocol_handlers) { | |
206 if (!main_dependencies_initialized_) { | |
207 main_transaction_factory_.reset(transaction_factory); | |
208 main_job_factory_.reset(new net::URLRequestJobFactoryImpl()); | |
209 // Keep ProtocolHandlers added in sync with | |
210 // ShellContentBrowserClient::IsHandledURL(). | |
211 bool set_protocol = false; | |
212 for (content::ProtocolHandlerMap::iterator it = | |
213 protocol_handlers->begin(); | |
214 it != protocol_handlers->end(); | |
215 ++it) { | |
216 set_protocol = main_job_factory_->SetProtocolHandler( | |
217 it->first, it->second.release()); | |
218 DCHECK(set_protocol); | |
219 } | |
220 set_protocol = main_job_factory_->SetProtocolHandler( | |
221 url::kDataScheme, | |
222 new net::DataProtocolHandler); | |
223 DCHECK(set_protocol); | |
224 main_dependencies_initialized_ = true; | |
225 } | |
226 } | |
227 | |
228 void URLRequestContextFactory::InitializeMediaContextDependencies( | |
229 net::HttpTransactionFactory* transaction_factory) { | |
230 if (!media_dependencies_initialized_) { | |
231 media_transaction_factory_.reset(transaction_factory); | |
232 media_dependencies_initialized_ = true; | |
233 } | |
234 } | |
235 | |
236 void URLRequestContextFactory::PopulateNetworkSessionParams( | |
237 bool ignore_certificate_errors, | |
238 net::HttpNetworkSession::Params* params) { | |
239 params->host_resolver = host_resolver_.get(); | |
240 params->cert_verifier = cert_verifier_.get(); | |
241 params->server_bound_cert_service = server_bound_cert_service_.get(); | |
242 params->ssl_config_service = ssl_config_service_.get(); | |
243 params->transport_security_state = transport_security_state_.get(); | |
244 params->http_auth_handler_factory = http_auth_handler_factory_.get(); | |
245 params->http_server_properties = http_server_properties_->GetWeakPtr(); | |
246 params->ignore_certificate_errors = ignore_certificate_errors; | |
247 params->proxy_service = proxy_service_.get(); | |
248 | |
249 // TODO(lcwu): http://crbug.com/329681. Remove this once spdy is enabled | |
250 // by deafult at the content level. | |
mmenke
2014/07/08 15:43:59
nit: deafult -> default
lcwu1
2014/07/09 02:16:29
Done.
| |
251 params->next_protos = net::NextProtosSpdy31(); | |
252 params->use_alternate_protocols = true; | |
253 } | |
254 | |
255 net::URLRequestContext* URLRequestContextFactory::CreateSystemRequestContext() { | |
256 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
257 InitializeSystemContextDependencies(); | |
258 net::HttpNetworkSession::Params system_params; | |
259 PopulateNetworkSessionParams(false, &system_params); | |
260 system_transaction_factory_.reset(new net::HttpNetworkLayer( | |
261 new net::HttpNetworkSession(system_params))); | |
262 | |
263 net::URLRequestContext* system_context = new net::URLRequestContext(); | |
264 system_context->set_host_resolver(host_resolver_.get()); | |
265 system_context->set_server_bound_cert_service( | |
266 server_bound_cert_service_.get()); | |
267 system_context->set_cert_verifier(cert_verifier_.get()); | |
268 system_context->set_proxy_service(proxy_service_.get()); | |
269 system_context->set_ssl_config_service(ssl_config_service_.get()); | |
270 system_context->set_transport_security_state( | |
271 transport_security_state_.get()); | |
272 system_context->set_http_auth_handler_factory( | |
273 http_auth_handler_factory_.get()); | |
274 system_context->set_http_server_properties( | |
275 http_server_properties_->GetWeakPtr()); | |
276 system_context->set_http_transaction_factory( | |
277 system_transaction_factory_.get()); | |
278 system_context->set_http_user_agent_settings( | |
279 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.
| |
280 return system_context; | |
281 } | |
282 | |
283 net::URLRequestContext* URLRequestContextFactory::CreateMediaRequestContext() { | |
284 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
285 DCHECK(main_getter_) | |
286 << "Getting MediaRequestContext before MainRequestContext"; | |
287 net::URLRequestContext* main_context = main_getter_->GetURLRequestContext(); | |
288 | |
289 // Set non caching backend. | |
290 net::HttpNetworkSession* main_session = | |
291 main_transaction_factory_->GetSession(); | |
292 InitializeMediaContextDependencies( | |
293 new net::HttpNetworkLayer(main_session)); | |
294 | |
295 net::URLRequestContext* media_context = new net::URLRequestContext(); | |
296 media_context->CopyFrom(main_context); | |
297 media_context->set_http_transaction_factory( | |
298 media_transaction_factory_.get()); | |
299 return media_context; | |
300 } | |
301 | |
302 net::URLRequestContext* URLRequestContextFactory::CreateMainRequestContext( | |
303 content::BrowserContext* browser_context, | |
304 content::ProtocolHandlerMap* protocol_handlers) { | |
305 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
306 InitializeSystemContextDependencies(); | |
307 | |
308 net::HttpCache::BackendFactory* main_backend = | |
309 net::HttpCache::DefaultBackend::InMemory(16 * 1024 * 1024); | |
310 | |
311 bool ignore_certificate_errors = false; | |
312 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | |
313 if (cmd_line->HasSwitch(switches::kIgnoreCertificateErrors)) { | |
314 ignore_certificate_errors = true; | |
315 } | |
316 net::HttpNetworkSession::Params network_session_params; | |
317 PopulateNetworkSessionParams(ignore_certificate_errors, | |
318 &network_session_params); | |
319 InitializeMainContextDependencies( | |
320 new net::HttpCache(network_session_params, main_backend), | |
321 protocol_handlers); | |
322 | |
323 content::CookieStoreConfig cookie_config( | |
324 browser_context->GetPath().Append(kCookieStoreFile), | |
325 content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES, | |
326 NULL, NULL); | |
327 cookie_config.background_task_runner = | |
328 scoped_refptr<base::SequencedTaskRunner>(); | |
329 scoped_refptr<net::CookieStore> cookie_store = | |
330 content::CreateCookieStore(cookie_config); | |
331 | |
332 net::URLRequestContext* main_context = new net::URLRequestContext(); | |
333 main_context->set_host_resolver(host_resolver_.get()); | |
334 main_context->set_server_bound_cert_service( | |
335 server_bound_cert_service_.get()); | |
336 main_context->set_cert_verifier(cert_verifier_.get()); | |
337 main_context->set_proxy_service(proxy_service_.get()); | |
338 main_context->set_ssl_config_service(ssl_config_service_.get()); | |
339 main_context->set_transport_security_state(transport_security_state_.get()); | |
340 main_context->set_http_auth_handler_factory( | |
341 http_auth_handler_factory_.get()); | |
342 main_context->set_http_server_properties( | |
343 http_server_properties_->GetWeakPtr()); | |
344 main_context->set_cookie_store(cookie_store.get()); | |
345 main_context->set_http_user_agent_settings( | |
346 http_user_agent_settings_.get()); | |
347 | |
348 main_context->set_http_transaction_factory( | |
349 main_transaction_factory_.get()); | |
350 main_context->set_job_factory(main_job_factory_.get()); | |
351 return main_context; | |
352 } | |
353 | |
354 } // namespace shell | |
355 } // namespace chromecast | |
OLD | NEW |