| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 "net/url_request/url_request_context_builder.h" | |
| 6 | |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/basictypes.h" | |
| 10 #include "base/compiler_specific.h" | |
| 11 #include "base/logging.h" | |
| 12 #include "base/strings/string_util.h" | |
| 13 #include "base/thread_task_runner_handle.h" | |
| 14 #include "base/threading/thread.h" | |
| 15 #include "net/base/cache_type.h" | |
| 16 #include "net/base/net_errors.h" | |
| 17 #include "net/base/network_delegate_impl.h" | |
| 18 #include "net/cert/cert_verifier.h" | |
| 19 #include "net/cookies/cookie_monster.h" | |
| 20 #include "net/dns/host_resolver.h" | |
| 21 #include "net/ftp/ftp_network_layer.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_network_session.h" | |
| 26 #include "net/http/http_server_properties_impl.h" | |
| 27 #include "net/http/transport_security_persister.h" | |
| 28 #include "net/http/transport_security_state.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/static_http_user_agent_settings.h" | |
| 34 #include "net/url_request/url_request_context.h" | |
| 35 #include "net/url_request/url_request_context_storage.h" | |
| 36 #include "net/url_request/url_request_job_factory_impl.h" | |
| 37 #include "net/url_request/url_request_throttler_manager.h" | |
| 38 | |
| 39 #if !defined(DISABLE_FILE_SUPPORT) | |
| 40 #include "net/url_request/file_protocol_handler.h" | |
| 41 #endif | |
| 42 | |
| 43 #if !defined(DISABLE_FTP_SUPPORT) | |
| 44 #include "net/url_request/ftp_protocol_handler.h" | |
| 45 #endif | |
| 46 | |
| 47 namespace net { | |
| 48 | |
| 49 namespace { | |
| 50 | |
| 51 class BasicNetworkDelegate : public NetworkDelegateImpl { | |
| 52 public: | |
| 53 BasicNetworkDelegate() {} | |
| 54 ~BasicNetworkDelegate() override {} | |
| 55 | |
| 56 private: | |
| 57 int OnBeforeURLRequest(URLRequest* request, | |
| 58 const CompletionCallback& callback, | |
| 59 GURL* new_url) override { | |
| 60 return OK; | |
| 61 } | |
| 62 | |
| 63 int OnBeforeSendHeaders(URLRequest* request, | |
| 64 const CompletionCallback& callback, | |
| 65 HttpRequestHeaders* headers) override { | |
| 66 return OK; | |
| 67 } | |
| 68 | |
| 69 void OnSendHeaders(URLRequest* request, | |
| 70 const HttpRequestHeaders& headers) override {} | |
| 71 | |
| 72 int OnHeadersReceived( | |
| 73 URLRequest* request, | |
| 74 const CompletionCallback& callback, | |
| 75 const HttpResponseHeaders* original_response_headers, | |
| 76 scoped_refptr<HttpResponseHeaders>* override_response_headers, | |
| 77 GURL* allowed_unsafe_redirect_url) override { | |
| 78 return OK; | |
| 79 } | |
| 80 | |
| 81 void OnBeforeRedirect(URLRequest* request, | |
| 82 const GURL& new_location) override {} | |
| 83 | |
| 84 void OnResponseStarted(URLRequest* request) override {} | |
| 85 | |
| 86 void OnRawBytesRead(const URLRequest& request, int bytes_read) override {} | |
| 87 | |
| 88 void OnCompleted(URLRequest* request, bool started) override {} | |
| 89 | |
| 90 void OnURLRequestDestroyed(URLRequest* request) override {} | |
| 91 | |
| 92 void OnPACScriptError(int line_number, const base::string16& error) override { | |
| 93 } | |
| 94 | |
| 95 NetworkDelegate::AuthRequiredResponse OnAuthRequired( | |
| 96 URLRequest* request, | |
| 97 const AuthChallengeInfo& auth_info, | |
| 98 const AuthCallback& callback, | |
| 99 AuthCredentials* credentials) override { | |
| 100 return NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; | |
| 101 } | |
| 102 | |
| 103 bool OnCanGetCookies(const URLRequest& request, | |
| 104 const CookieList& cookie_list) override { | |
| 105 return true; | |
| 106 } | |
| 107 | |
| 108 bool OnCanSetCookie(const URLRequest& request, | |
| 109 const std::string& cookie_line, | |
| 110 CookieOptions* options) override { | |
| 111 return true; | |
| 112 } | |
| 113 | |
| 114 bool OnCanAccessFile(const net::URLRequest& request, | |
| 115 const base::FilePath& path) const override { | |
| 116 return true; | |
| 117 } | |
| 118 | |
| 119 bool OnCanThrottleRequest(const URLRequest& request) const override { | |
| 120 // Returning true will only enable throttling if there's also a | |
| 121 // URLRequestThrottlerManager, which there isn't, by default. | |
| 122 return true; | |
| 123 } | |
| 124 | |
| 125 DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate); | |
| 126 }; | |
| 127 | |
| 128 class BasicURLRequestContext : public URLRequestContext { | |
| 129 public: | |
| 130 BasicURLRequestContext() | |
| 131 : storage_(this) {} | |
| 132 | |
| 133 URLRequestContextStorage* storage() { | |
| 134 return &storage_; | |
| 135 } | |
| 136 | |
| 137 base::Thread* GetCacheThread() { | |
| 138 if (!cache_thread_) { | |
| 139 cache_thread_.reset(new base::Thread("Network Cache Thread")); | |
| 140 cache_thread_->StartWithOptions( | |
| 141 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); | |
| 142 } | |
| 143 return cache_thread_.get(); | |
| 144 } | |
| 145 | |
| 146 base::Thread* GetFileThread() { | |
| 147 if (!file_thread_) { | |
| 148 file_thread_.reset(new base::Thread("Network File Thread")); | |
| 149 file_thread_->StartWithOptions( | |
| 150 base::Thread::Options(base::MessageLoop::TYPE_DEFAULT, 0)); | |
| 151 } | |
| 152 return file_thread_.get(); | |
| 153 } | |
| 154 | |
| 155 void set_transport_security_persister( | |
| 156 scoped_ptr<TransportSecurityPersister> transport_security_persister) { | |
| 157 transport_security_persister = transport_security_persister.Pass(); | |
| 158 } | |
| 159 | |
| 160 protected: | |
| 161 ~BasicURLRequestContext() override { AssertNoURLRequests(); } | |
| 162 | |
| 163 private: | |
| 164 // Threads should be torn down last. | |
| 165 scoped_ptr<base::Thread> cache_thread_; | |
| 166 scoped_ptr<base::Thread> file_thread_; | |
| 167 | |
| 168 URLRequestContextStorage storage_; | |
| 169 scoped_ptr<TransportSecurityPersister> transport_security_persister_; | |
| 170 | |
| 171 DISALLOW_COPY_AND_ASSIGN(BasicURLRequestContext); | |
| 172 }; | |
| 173 | |
| 174 } // namespace | |
| 175 | |
| 176 URLRequestContextBuilder::HttpCacheParams::HttpCacheParams() | |
| 177 : type(IN_MEMORY), | |
| 178 max_size(0) {} | |
| 179 URLRequestContextBuilder::HttpCacheParams::~HttpCacheParams() {} | |
| 180 | |
| 181 URLRequestContextBuilder::HttpNetworkSessionParams::HttpNetworkSessionParams() | |
| 182 : ignore_certificate_errors(false), | |
| 183 host_mapping_rules(NULL), | |
| 184 testing_fixed_http_port(0), | |
| 185 testing_fixed_https_port(0), | |
| 186 next_protos(NextProtosDefaults()), | |
| 187 use_alternate_protocols(true), | |
| 188 enable_quic(false) { | |
| 189 } | |
| 190 | |
| 191 URLRequestContextBuilder::HttpNetworkSessionParams::~HttpNetworkSessionParams() | |
| 192 {} | |
| 193 | |
| 194 URLRequestContextBuilder::SchemeFactory::SchemeFactory( | |
| 195 const std::string& auth_scheme, | |
| 196 net::HttpAuthHandlerFactory* auth_handler_factory) | |
| 197 : scheme(auth_scheme), factory(auth_handler_factory) { | |
| 198 } | |
| 199 | |
| 200 URLRequestContextBuilder::SchemeFactory::~SchemeFactory() { | |
| 201 } | |
| 202 | |
| 203 URLRequestContextBuilder::URLRequestContextBuilder() | |
| 204 : data_enabled_(false), | |
| 205 #if !defined(DISABLE_FILE_SUPPORT) | |
| 206 file_enabled_(false), | |
| 207 #endif | |
| 208 #if !defined(DISABLE_FTP_SUPPORT) | |
| 209 ftp_enabled_(false), | |
| 210 #endif | |
| 211 http_cache_enabled_(true), | |
| 212 throttling_enabled_(false) { | |
| 213 } | |
| 214 | |
| 215 URLRequestContextBuilder::~URLRequestContextBuilder() {} | |
| 216 | |
| 217 void URLRequestContextBuilder::EnableHttpCache(const HttpCacheParams& params) { | |
| 218 http_cache_enabled_ = true; | |
| 219 http_cache_params_ = params; | |
| 220 } | |
| 221 | |
| 222 void URLRequestContextBuilder::DisableHttpCache() { | |
| 223 http_cache_enabled_ = false; | |
| 224 http_cache_params_ = HttpCacheParams(); | |
| 225 } | |
| 226 | |
| 227 void URLRequestContextBuilder::SetSpdyAndQuicEnabled(bool spdy_enabled, | |
| 228 bool quic_enabled) { | |
| 229 http_network_session_params_.next_protos = | |
| 230 NextProtosWithSpdyAndQuic(spdy_enabled, quic_enabled); | |
| 231 http_network_session_params_.enable_quic = quic_enabled; | |
| 232 } | |
| 233 | |
| 234 void URLRequestContextBuilder::SetCookieAndChannelIdStores( | |
| 235 const scoped_refptr<CookieStore>& cookie_store, | |
| 236 scoped_ptr<ChannelIDService> channel_id_service) { | |
| 237 DCHECK(cookie_store); | |
| 238 cookie_store_ = cookie_store; | |
| 239 channel_id_service_ = channel_id_service.Pass(); | |
| 240 } | |
| 241 | |
| 242 URLRequestContext* URLRequestContextBuilder::Build() { | |
| 243 BasicURLRequestContext* context = new BasicURLRequestContext; | |
| 244 URLRequestContextStorage* storage = context->storage(); | |
| 245 | |
| 246 storage->set_http_user_agent_settings(new StaticHttpUserAgentSettings( | |
| 247 accept_language_, user_agent_)); | |
| 248 | |
| 249 if (!network_delegate_) | |
| 250 network_delegate_.reset(new BasicNetworkDelegate); | |
| 251 NetworkDelegate* network_delegate = network_delegate_.release(); | |
| 252 storage->set_network_delegate(network_delegate); | |
| 253 | |
| 254 if (net_log_) { | |
| 255 storage->set_net_log(net_log_.release()); | |
| 256 } else { | |
| 257 storage->set_net_log(new net::NetLog); | |
| 258 } | |
| 259 | |
| 260 if (!host_resolver_) { | |
| 261 host_resolver_ = net::HostResolver::CreateDefaultResolver( | |
| 262 context->net_log()); | |
| 263 } | |
| 264 storage->set_host_resolver(host_resolver_.Pass()); | |
| 265 | |
| 266 if (!proxy_service_) { | |
| 267 // TODO(willchan): Switch to using this code when | |
| 268 // ProxyService::CreateSystemProxyConfigService()'s signature doesn't suck. | |
| 269 #if defined(OS_LINUX) || defined(OS_ANDROID) | |
| 270 ProxyConfigService* proxy_config_service = proxy_config_service_.release(); | |
| 271 #else | |
| 272 ProxyConfigService* proxy_config_service = NULL; | |
| 273 if (proxy_config_service_) { | |
| 274 proxy_config_service = proxy_config_service_.release(); | |
| 275 } else { | |
| 276 proxy_config_service = | |
| 277 ProxyService::CreateSystemProxyConfigService( | |
| 278 base::ThreadTaskRunnerHandle::Get().get(), | |
| 279 context->GetFileThread()->task_runner()); | |
| 280 } | |
| 281 #endif // defined(OS_LINUX) || defined(OS_ANDROID) | |
| 282 proxy_service_.reset( | |
| 283 ProxyService::CreateUsingSystemProxyResolver( | |
| 284 proxy_config_service, | |
| 285 0, // This results in using the default value. | |
| 286 context->net_log())); | |
| 287 } | |
| 288 storage->set_proxy_service(proxy_service_.release()); | |
| 289 | |
| 290 storage->set_ssl_config_service(new net::SSLConfigServiceDefaults); | |
| 291 HttpAuthHandlerRegistryFactory* http_auth_handler_registry_factory = | |
| 292 net::HttpAuthHandlerRegistryFactory::CreateDefault( | |
| 293 context->host_resolver()); | |
| 294 for (size_t i = 0; i < extra_http_auth_handlers_.size(); ++i) { | |
| 295 http_auth_handler_registry_factory->RegisterSchemeFactory( | |
| 296 extra_http_auth_handlers_[i].scheme, | |
| 297 extra_http_auth_handlers_[i].factory); | |
| 298 } | |
| 299 storage->set_http_auth_handler_factory(http_auth_handler_registry_factory); | |
| 300 | |
| 301 if (cookie_store_) { | |
| 302 storage->set_cookie_store(cookie_store_.get()); | |
| 303 storage->set_channel_id_service(channel_id_service_.Pass()); | |
| 304 } else { | |
| 305 storage->set_cookie_store(new CookieMonster(NULL, NULL)); | |
| 306 // TODO(mmenke): This always creates a file thread, even when it ends up | |
| 307 // not being used. Consider lazily creating the thread. | |
| 308 storage->set_channel_id_service(make_scoped_ptr( | |
| 309 new ChannelIDService(new DefaultChannelIDStore(NULL), | |
| 310 context->GetFileThread()->message_loop_proxy()))); | |
| 311 } | |
| 312 | |
| 313 storage->set_transport_security_state(new net::TransportSecurityState()); | |
| 314 if (!transport_security_persister_path_.empty()) { | |
| 315 context->set_transport_security_persister( | |
| 316 make_scoped_ptr<TransportSecurityPersister>( | |
| 317 new TransportSecurityPersister( | |
| 318 context->transport_security_state(), | |
| 319 transport_security_persister_path_, | |
| 320 context->GetFileThread()->message_loop_proxy(), | |
| 321 false))); | |
| 322 } | |
| 323 | |
| 324 storage->set_http_server_properties( | |
| 325 scoped_ptr<net::HttpServerProperties>( | |
| 326 new net::HttpServerPropertiesImpl())); | |
| 327 storage->set_cert_verifier(CertVerifier::CreateDefault()); | |
| 328 | |
| 329 if (throttling_enabled_) | |
| 330 storage->set_throttler_manager(new URLRequestThrottlerManager()); | |
| 331 | |
| 332 net::HttpNetworkSession::Params network_session_params; | |
| 333 network_session_params.host_resolver = context->host_resolver(); | |
| 334 network_session_params.cert_verifier = context->cert_verifier(); | |
| 335 network_session_params.transport_security_state = | |
| 336 context->transport_security_state(); | |
| 337 network_session_params.proxy_service = context->proxy_service(); | |
| 338 network_session_params.ssl_config_service = | |
| 339 context->ssl_config_service(); | |
| 340 network_session_params.http_auth_handler_factory = | |
| 341 context->http_auth_handler_factory(); | |
| 342 network_session_params.network_delegate = network_delegate; | |
| 343 network_session_params.http_server_properties = | |
| 344 context->http_server_properties(); | |
| 345 network_session_params.net_log = context->net_log(); | |
| 346 | |
| 347 network_session_params.ignore_certificate_errors = | |
| 348 http_network_session_params_.ignore_certificate_errors; | |
| 349 network_session_params.host_mapping_rules = | |
| 350 http_network_session_params_.host_mapping_rules; | |
| 351 network_session_params.testing_fixed_http_port = | |
| 352 http_network_session_params_.testing_fixed_http_port; | |
| 353 network_session_params.testing_fixed_https_port = | |
| 354 http_network_session_params_.testing_fixed_https_port; | |
| 355 network_session_params.use_alternate_protocols = | |
| 356 http_network_session_params_.use_alternate_protocols; | |
| 357 network_session_params.trusted_spdy_proxy = | |
| 358 http_network_session_params_.trusted_spdy_proxy; | |
| 359 network_session_params.next_protos = http_network_session_params_.next_protos; | |
| 360 network_session_params.enable_quic = http_network_session_params_.enable_quic; | |
| 361 network_session_params.quic_connection_options = | |
| 362 http_network_session_params_.quic_connection_options; | |
| 363 | |
| 364 HttpTransactionFactory* http_transaction_factory = NULL; | |
| 365 if (http_cache_enabled_) { | |
| 366 network_session_params.channel_id_service = | |
| 367 context->channel_id_service(); | |
| 368 HttpCache::BackendFactory* http_cache_backend = NULL; | |
| 369 if (http_cache_params_.type == HttpCacheParams::DISK) { | |
| 370 http_cache_backend = new HttpCache::DefaultBackend( | |
| 371 DISK_CACHE, | |
| 372 net::CACHE_BACKEND_DEFAULT, | |
| 373 http_cache_params_.path, | |
| 374 http_cache_params_.max_size, | |
| 375 context->GetCacheThread()->task_runner()); | |
| 376 } else { | |
| 377 http_cache_backend = | |
| 378 HttpCache::DefaultBackend::InMemory(http_cache_params_.max_size); | |
| 379 } | |
| 380 | |
| 381 http_transaction_factory = new HttpCache( | |
| 382 network_session_params, http_cache_backend); | |
| 383 } else { | |
| 384 scoped_refptr<net::HttpNetworkSession> network_session( | |
| 385 new net::HttpNetworkSession(network_session_params)); | |
| 386 | |
| 387 http_transaction_factory = new HttpNetworkLayer(network_session.get()); | |
| 388 } | |
| 389 storage->set_http_transaction_factory(http_transaction_factory); | |
| 390 | |
| 391 URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl; | |
| 392 if (data_enabled_) | |
| 393 job_factory->SetProtocolHandler("data", new DataProtocolHandler); | |
| 394 | |
| 395 #if !defined(DISABLE_FILE_SUPPORT) | |
| 396 if (file_enabled_) { | |
| 397 job_factory->SetProtocolHandler( | |
| 398 "file", | |
| 399 new FileProtocolHandler(context->GetFileThread()->message_loop_proxy())); | |
| 400 } | |
| 401 #endif // !defined(DISABLE_FILE_SUPPORT) | |
| 402 | |
| 403 #if !defined(DISABLE_FTP_SUPPORT) | |
| 404 if (ftp_enabled_) { | |
| 405 ftp_transaction_factory_.reset( | |
| 406 new FtpNetworkLayer(context->host_resolver())); | |
| 407 job_factory->SetProtocolHandler("ftp", | |
| 408 new FtpProtocolHandler(ftp_transaction_factory_.get())); | |
| 409 } | |
| 410 #endif // !defined(DISABLE_FTP_SUPPORT) | |
| 411 | |
| 412 storage->set_job_factory(job_factory); | |
| 413 | |
| 414 // TODO(willchan): Support sdch. | |
| 415 | |
| 416 return context; | |
| 417 } | |
| 418 | |
| 419 } // namespace net | |
| OLD | NEW |