| 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 "chromecast/shell/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" | |
| 39 | |
| 40 namespace chromecast { | |
| 41 namespace shell { | |
| 42 | |
| 43 namespace { | |
| 44 | |
| 45 const char kCookieStoreFile[] = "Cookies"; | |
| 46 | |
| 47 } // namespace | |
| 48 | |
| 49 // Private classes to expose URLRequestContextGetter that call back to the | |
| 50 // URLRequestContextFactory to create the URLRequestContext on demand. | |
| 51 // | |
| 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) { | |
| 60 } | |
| 61 | |
| 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) | |
| 72 } | |
| 73 } | |
| 74 return request_context_.get(); | |
| 75 } | |
| 76 | |
| 77 virtual scoped_refptr<base::SingleThreadTaskRunner> | |
| 78 GetNetworkTaskRunner() const override { | |
| 79 return content::BrowserThread::GetMessageLoopProxyForThread( | |
| 80 content::BrowserThread::IO); | |
| 81 } | |
| 82 | |
| 83 private: | |
| 84 virtual ~URLRequestContextGetter() {} | |
| 85 | |
| 86 const bool is_media_; | |
| 87 URLRequestContextFactory* const factory_; | |
| 88 scoped_ptr<net::URLRequestContext> request_context_; | |
| 89 | |
| 90 DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter); | |
| 91 }; | |
| 92 | |
| 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); | |
| 107 } | |
| 108 | |
| 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(); | |
| 114 } | |
| 115 return request_context_.get(); | |
| 116 } | |
| 117 | |
| 118 virtual scoped_refptr<base::SingleThreadTaskRunner> | |
| 119 GetNetworkTaskRunner() const override { | |
| 120 return content::BrowserThread::GetMessageLoopProxyForThread( | |
| 121 content::BrowserThread::IO); | |
| 122 } | |
| 123 | |
| 124 private: | |
| 125 virtual ~MainURLRequestContextGetter() {} | |
| 126 | |
| 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_; | |
| 132 | |
| 133 DISALLOW_COPY_AND_ASSIGN(MainURLRequestContextGetter); | |
| 134 }; | |
| 135 | |
| 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) { | |
| 142 } | |
| 143 | |
| 144 URLRequestContextFactory::~URLRequestContextFactory() { | |
| 145 } | |
| 146 | |
| 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()); | |
| 153 | |
| 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))); | |
| 161 } | |
| 162 | |
| 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(); | |
| 174 } | |
| 175 | |
| 176 net::URLRequestContextGetter* URLRequestContextFactory::GetMainGetter() { | |
| 177 CHECK(main_getter_.get()); | |
| 178 return main_getter_.get(); | |
| 179 } | |
| 180 | |
| 181 net::URLRequestContextGetter* URLRequestContextFactory::GetSystemGetter() { | |
| 182 if (!system_getter_.get()) { | |
| 183 system_getter_ = new URLRequestContextGetter(this, false); | |
| 184 } | |
| 185 return system_getter_.get(); | |
| 186 } | |
| 187 | |
| 188 net::URLRequestContextGetter* URLRequestContextFactory::GetMediaGetter() { | |
| 189 if (!media_getter_.get()) { | |
| 190 media_getter_ = new URLRequestContextGetter(this, true); | |
| 191 } | |
| 192 return media_getter_.get(); | |
| 193 } | |
| 194 | |
| 195 void URLRequestContextFactory::InitializeSystemContextDependencies() { | |
| 196 if (system_dependencies_initialized_) | |
| 197 return; | |
| 198 | |
| 199 host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL); | |
| 200 | |
| 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))); | |
| 207 | |
| 208 cert_verifier_.reset(net::CertVerifier::CreateDefault()); | |
| 209 | |
| 210 ssl_config_service_ = new net::SSLConfigServiceDefaults; | |
| 211 | |
| 212 transport_security_state_.reset(new net::TransportSecurityState()); | |
| 213 http_auth_handler_factory_.reset( | |
| 214 net::HttpAuthHandlerFactory::CreateDefault(host_resolver_.get())); | |
| 215 | |
| 216 http_server_properties_.reset(new net::HttpServerPropertiesImpl); | |
| 217 | |
| 218 proxy_service_.reset(net::ProxyService::CreateUsingSystemProxyResolver( | |
| 219 proxy_config_service_.release(), 0, NULL)); | |
| 220 system_dependencies_initialized_ = true; | |
| 221 } | |
| 222 | |
| 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; | |
| 229 | |
| 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); | |
| 242 } | |
| 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) | |
| 256 | |
| 257 // Set up interceptors in the reverse order. | |
| 258 scoped_ptr<net::URLRequestJobFactory> top_job_factory = | |
| 259 job_factory.PassAs<net::URLRequestJobFactory>(); | |
| 260 for (content::URLRequestInterceptorScopedVector::reverse_iterator i = | |
| 261 request_interceptors.rbegin(); | |
| 262 i != request_interceptors.rend(); | |
| 263 ++i) { | |
| 264 top_job_factory.reset(new net::URLRequestInterceptingJobFactory( | |
| 265 top_job_factory.Pass(), make_scoped_ptr(*i))); | |
| 266 } | |
| 267 request_interceptors.weak_clear(); | |
| 268 | |
| 269 main_job_factory_.reset(top_job_factory.release()); | |
| 270 | |
| 271 main_dependencies_initialized_ = true; | |
| 272 } | |
| 273 | |
| 274 void URLRequestContextFactory::InitializeMediaContextDependencies( | |
| 275 net::HttpTransactionFactory* transaction_factory) { | |
| 276 if (media_dependencies_initialized_) | |
| 277 return; | |
| 278 | |
| 279 media_transaction_factory_.reset(transaction_factory); | |
| 280 media_dependencies_initialized_ = true; | |
| 281 } | |
| 282 | |
| 283 void URLRequestContextFactory::PopulateNetworkSessionParams( | |
| 284 bool ignore_certificate_errors, | |
| 285 net::HttpNetworkSession::Params* params) { | |
| 286 params->host_resolver = host_resolver_.get(); | |
| 287 params->cert_verifier = cert_verifier_.get(); | |
| 288 params->channel_id_service = channel_id_service_.get(); | |
| 289 params->ssl_config_service = ssl_config_service_.get(); | |
| 290 params->transport_security_state = transport_security_state_.get(); | |
| 291 params->http_auth_handler_factory = http_auth_handler_factory_.get(); | |
| 292 params->http_server_properties = http_server_properties_->GetWeakPtr(); | |
| 293 params->ignore_certificate_errors = ignore_certificate_errors; | |
| 294 params->proxy_service = proxy_service_.get(); | |
| 295 | |
| 296 // TODO(lcwu): http://crbug.com/329681. Remove this once spdy is enabled | |
| 297 // by default at the content level. | |
| 298 params->next_protos = net::NextProtosSpdy31(); | |
| 299 params->use_alternate_protocols = true; | |
| 300 } | |
| 301 | |
| 302 net::URLRequestContext* URLRequestContextFactory::CreateSystemRequestContext() { | |
| 303 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
| 304 InitializeSystemContextDependencies(); | |
| 305 net::HttpNetworkSession::Params system_params; | |
| 306 PopulateNetworkSessionParams(false, &system_params); | |
| 307 system_transaction_factory_.reset(new net::HttpNetworkLayer( | |
| 308 new net::HttpNetworkSession(system_params))); | |
| 309 system_job_factory_.reset(new net::URLRequestJobFactoryImpl()); | |
| 310 | |
| 311 net::URLRequestContext* system_context = new net::URLRequestContext(); | |
| 312 system_context->set_host_resolver(host_resolver_.get()); | |
| 313 system_context->set_channel_id_service(channel_id_service_.get()); | |
| 314 system_context->set_cert_verifier(cert_verifier_.get()); | |
| 315 system_context->set_proxy_service(proxy_service_.get()); | |
| 316 system_context->set_ssl_config_service(ssl_config_service_.get()); | |
| 317 system_context->set_transport_security_state( | |
| 318 transport_security_state_.get()); | |
| 319 system_context->set_http_auth_handler_factory( | |
| 320 http_auth_handler_factory_.get()); | |
| 321 system_context->set_http_server_properties( | |
| 322 http_server_properties_->GetWeakPtr()); | |
| 323 system_context->set_http_transaction_factory( | |
| 324 system_transaction_factory_.get()); | |
| 325 system_context->set_http_user_agent_settings( | |
| 326 http_user_agent_settings_.get()); | |
| 327 system_context->set_job_factory(system_job_factory_.get()); | |
| 328 system_context->set_cookie_store( | |
| 329 content::CreateCookieStore(content::CookieStoreConfig())); | |
| 330 system_context->set_network_delegate(system_network_delegate_.get()); | |
| 331 return system_context; | |
| 332 } | |
| 333 | |
| 334 net::URLRequestContext* URLRequestContextFactory::CreateMediaRequestContext() { | |
| 335 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
| 336 DCHECK(main_getter_.get()) | |
| 337 << "Getting MediaRequestContext before MainRequestContext"; | |
| 338 net::URLRequestContext* main_context = main_getter_->GetURLRequestContext(); | |
| 339 | |
| 340 // Set non caching backend. | |
| 341 net::HttpNetworkSession* main_session = | |
| 342 main_transaction_factory_->GetSession(); | |
| 343 InitializeMediaContextDependencies( | |
| 344 new net::HttpNetworkLayer(main_session)); | |
| 345 | |
| 346 net::URLRequestContext* media_context = new net::URLRequestContext(); | |
| 347 media_context->CopyFrom(main_context); | |
| 348 media_context->set_http_transaction_factory( | |
| 349 media_transaction_factory_.get()); | |
| 350 return media_context; | |
| 351 } | |
| 352 | |
| 353 net::URLRequestContext* URLRequestContextFactory::CreateMainRequestContext( | |
| 354 content::BrowserContext* browser_context, | |
| 355 content::ProtocolHandlerMap* protocol_handlers, | |
| 356 content::URLRequestInterceptorScopedVector request_interceptors) { | |
| 357 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
| 358 InitializeSystemContextDependencies(); | |
| 359 | |
| 360 net::HttpCache::BackendFactory* main_backend = | |
| 361 net::HttpCache::DefaultBackend::InMemory(16 * 1024 * 1024); | |
| 362 | |
| 363 bool ignore_certificate_errors = false; | |
| 364 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | |
| 365 if (cmd_line->HasSwitch(switches::kIgnoreCertificateErrors)) { | |
| 366 ignore_certificate_errors = true; | |
| 367 } | |
| 368 net::HttpNetworkSession::Params network_session_params; | |
| 369 PopulateNetworkSessionParams(ignore_certificate_errors, | |
| 370 &network_session_params); | |
| 371 InitializeMainContextDependencies( | |
| 372 new net::HttpCache(network_session_params, main_backend), | |
| 373 protocol_handlers, | |
| 374 request_interceptors.Pass()); | |
| 375 | |
| 376 content::CookieStoreConfig cookie_config( | |
| 377 browser_context->GetPath().Append(kCookieStoreFile), | |
| 378 content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES, | |
| 379 NULL, NULL); | |
| 380 cookie_config.background_task_runner = | |
| 381 scoped_refptr<base::SequencedTaskRunner>(); | |
| 382 scoped_refptr<net::CookieStore> cookie_store = | |
| 383 content::CreateCookieStore(cookie_config); | |
| 384 | |
| 385 net::URLRequestContext* main_context = new net::URLRequestContext(); | |
| 386 main_context->set_host_resolver(host_resolver_.get()); | |
| 387 main_context->set_channel_id_service(channel_id_service_.get()); | |
| 388 main_context->set_cert_verifier(cert_verifier_.get()); | |
| 389 main_context->set_proxy_service(proxy_service_.get()); | |
| 390 main_context->set_ssl_config_service(ssl_config_service_.get()); | |
| 391 main_context->set_transport_security_state(transport_security_state_.get()); | |
| 392 main_context->set_http_auth_handler_factory( | |
| 393 http_auth_handler_factory_.get()); | |
| 394 main_context->set_http_server_properties( | |
| 395 http_server_properties_->GetWeakPtr()); | |
| 396 main_context->set_cookie_store(cookie_store.get()); | |
| 397 main_context->set_http_user_agent_settings( | |
| 398 http_user_agent_settings_.get()); | |
| 399 | |
| 400 main_context->set_http_transaction_factory( | |
| 401 main_transaction_factory_.get()); | |
| 402 main_context->set_job_factory(main_job_factory_.get()); | |
| 403 main_context->set_network_delegate(app_network_delegate_.get()); | |
| 404 return main_context; | |
| 405 } | |
| 406 | |
| 407 void URLRequestContextFactory::InitializeNetworkDelegates() { | |
| 408 app_network_delegate_->Initialize(false); | |
| 409 LOG(INFO) << "Initialized app network delegate."; | |
| 410 system_network_delegate_->Initialize(false); | |
| 411 LOG(INFO) << "Initialized system network delegate."; | |
| 412 } | |
| 413 | |
| 414 } // namespace shell | |
| 415 } // namespace chromecast | |
| OLD | NEW |