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