Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / net / url_request / url_request_context_builder.cc
blob177bea7d0cce3aaa2595618c980e2fdf505e4924
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.
5 #include "net/url_request/url_request_context_builder.h"
7 #include <string>
9 #include "base/basictypes.h"
10 #include "base/compiler_specific.h"
11 #include "base/logging.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/strings/string_util.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "base/threading/thread.h"
16 #include "net/base/cache_type.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/network_delegate_impl.h"
19 #include "net/base/sdch_manager.h"
20 #include "net/cert/cert_verifier.h"
21 #include "net/cookies/cookie_monster.h"
22 #include "net/dns/host_resolver.h"
23 #include "net/ftp/ftp_network_layer.h"
24 #include "net/http/http_auth_handler_factory.h"
25 #include "net/http/http_cache.h"
26 #include "net/http/http_network_layer.h"
27 #include "net/http/http_server_properties_impl.h"
28 #include "net/http/http_server_properties_manager.h"
29 #include "net/http/transport_security_persister.h"
30 #include "net/http/transport_security_state.h"
31 #include "net/ssl/channel_id_service.h"
32 #include "net/ssl/default_channel_id_store.h"
33 #include "net/ssl/ssl_config_service_defaults.h"
34 #include "net/url_request/data_protocol_handler.h"
35 #include "net/url_request/static_http_user_agent_settings.h"
36 #include "net/url_request/url_request_backoff_manager.h"
37 #include "net/url_request/url_request_context.h"
38 #include "net/url_request/url_request_context_storage.h"
39 #include "net/url_request/url_request_intercepting_job_factory.h"
40 #include "net/url_request/url_request_interceptor.h"
41 #include "net/url_request/url_request_job_factory_impl.h"
42 #include "net/url_request/url_request_throttler_manager.h"
44 #if !defined(DISABLE_FILE_SUPPORT)
45 #include "net/url_request/file_protocol_handler.h"
46 #endif
48 #if !defined(DISABLE_FTP_SUPPORT)
49 #include "net/url_request/ftp_protocol_handler.h"
50 #endif
52 namespace net {
54 namespace {
56 class BasicNetworkDelegate : public NetworkDelegateImpl {
57 public:
58 BasicNetworkDelegate() {}
59 ~BasicNetworkDelegate() override {}
61 private:
62 int OnBeforeURLRequest(URLRequest* request,
63 const CompletionCallback& callback,
64 GURL* new_url) override {
65 return OK;
68 int OnBeforeSendHeaders(URLRequest* request,
69 const CompletionCallback& callback,
70 HttpRequestHeaders* headers) override {
71 return OK;
74 void OnSendHeaders(URLRequest* request,
75 const HttpRequestHeaders& headers) override {}
77 int OnHeadersReceived(
78 URLRequest* request,
79 const CompletionCallback& callback,
80 const HttpResponseHeaders* original_response_headers,
81 scoped_refptr<HttpResponseHeaders>* override_response_headers,
82 GURL* allowed_unsafe_redirect_url) override {
83 return OK;
86 void OnBeforeRedirect(URLRequest* request,
87 const GURL& new_location) override {}
89 void OnResponseStarted(URLRequest* request) override {}
91 void OnCompleted(URLRequest* request, bool started) override {}
93 void OnURLRequestDestroyed(URLRequest* request) override {}
95 void OnPACScriptError(int line_number, const base::string16& error) override {
98 NetworkDelegate::AuthRequiredResponse OnAuthRequired(
99 URLRequest* request,
100 const AuthChallengeInfo& auth_info,
101 const AuthCallback& callback,
102 AuthCredentials* credentials) override {
103 return NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
106 bool OnCanGetCookies(const URLRequest& request,
107 const CookieList& cookie_list) override {
108 return true;
111 bool OnCanSetCookie(const URLRequest& request,
112 const std::string& cookie_line,
113 CookieOptions* options) override {
114 return true;
117 bool OnCanAccessFile(const URLRequest& request,
118 const base::FilePath& path) const override {
119 return true;
122 DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate);
125 // Define a context class that can self-manage the ownership of its components
126 // via a UrlRequestContextStorage object.
127 class ContainerURLRequestContext : public URLRequestContext {
128 public:
129 explicit ContainerURLRequestContext(
130 const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner)
131 : file_task_runner_(file_task_runner), storage_(this) {}
132 ~ContainerURLRequestContext() override { AssertNoURLRequests(); }
134 URLRequestContextStorage* storage() {
135 return &storage_;
138 scoped_refptr<base::SingleThreadTaskRunner>& GetFileTaskRunner() {
139 // Create a new thread to run file tasks, if needed.
140 if (!file_task_runner_) {
141 DCHECK(!file_thread_);
142 file_thread_.reset(new base::Thread("Network File Thread"));
143 file_thread_->StartWithOptions(
144 base::Thread::Options(base::MessageLoop::TYPE_DEFAULT, 0));
145 file_task_runner_ = file_thread_->task_runner();
147 return file_task_runner_;
150 void set_transport_security_persister(
151 scoped_ptr<TransportSecurityPersister> transport_security_persister) {
152 transport_security_persister = transport_security_persister.Pass();
155 private:
156 // The thread should be torn down last.
157 scoped_ptr<base::Thread> file_thread_;
158 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;
160 URLRequestContextStorage storage_;
161 scoped_ptr<TransportSecurityPersister> transport_security_persister_;
163 DISALLOW_COPY_AND_ASSIGN(ContainerURLRequestContext);
166 } // namespace
168 URLRequestContextBuilder::HttpCacheParams::HttpCacheParams()
169 : type(IN_MEMORY),
170 max_size(0) {}
171 URLRequestContextBuilder::HttpCacheParams::~HttpCacheParams() {}
173 URLRequestContextBuilder::HttpNetworkSessionParams::HttpNetworkSessionParams()
174 : ignore_certificate_errors(false),
175 host_mapping_rules(NULL),
176 testing_fixed_http_port(0),
177 testing_fixed_https_port(0),
178 next_protos(NextProtosDefaults()),
179 use_alternative_services(true),
180 enable_quic(false),
181 enable_insecure_quic(false) {}
183 URLRequestContextBuilder::HttpNetworkSessionParams::~HttpNetworkSessionParams()
186 URLRequestContextBuilder::SchemeFactory::SchemeFactory(
187 const std::string& auth_scheme,
188 HttpAuthHandlerFactory* auth_handler_factory)
189 : scheme(auth_scheme), factory(auth_handler_factory) {
192 URLRequestContextBuilder::SchemeFactory::~SchemeFactory() {
195 URLRequestContextBuilder::URLRequestContextBuilder()
196 : data_enabled_(false),
197 #if !defined(DISABLE_FILE_SUPPORT)
198 file_enabled_(false),
199 #endif
200 #if !defined(DISABLE_FTP_SUPPORT)
201 ftp_enabled_(false),
202 #endif
203 http_cache_enabled_(true),
204 throttling_enabled_(false),
205 backoff_enabled_(false),
206 sdch_enabled_(false),
207 net_log_(nullptr) {
210 URLRequestContextBuilder::~URLRequestContextBuilder() {}
212 void URLRequestContextBuilder::SetHttpNetworkSessionComponents(
213 const URLRequestContext* context,
214 HttpNetworkSession::Params* params) {
215 params->host_resolver = context->host_resolver();
216 params->cert_verifier = context->cert_verifier();
217 params->transport_security_state = context->transport_security_state();
218 params->cert_transparency_verifier = context->cert_transparency_verifier();
219 params->proxy_service = context->proxy_service();
220 params->ssl_config_service = context->ssl_config_service();
221 params->http_auth_handler_factory = context->http_auth_handler_factory();
222 params->network_delegate = context->network_delegate();
223 params->http_server_properties = context->http_server_properties();
224 params->net_log = context->net_log();
225 params->channel_id_service = context->channel_id_service();
228 void URLRequestContextBuilder::EnableHttpCache(const HttpCacheParams& params) {
229 http_cache_enabled_ = true;
230 http_cache_params_ = params;
233 void URLRequestContextBuilder::DisableHttpCache() {
234 http_cache_enabled_ = false;
235 http_cache_params_ = HttpCacheParams();
238 void URLRequestContextBuilder::SetSpdyAndQuicEnabled(bool spdy_enabled,
239 bool quic_enabled) {
240 http_network_session_params_.next_protos =
241 NextProtosWithSpdyAndQuic(spdy_enabled, quic_enabled);
242 http_network_session_params_.enable_quic = quic_enabled;
245 void URLRequestContextBuilder::SetInterceptors(
246 ScopedVector<URLRequestInterceptor> url_request_interceptors) {
247 url_request_interceptors_ = url_request_interceptors.Pass();
250 void URLRequestContextBuilder::SetCookieAndChannelIdStores(
251 const scoped_refptr<CookieStore>& cookie_store,
252 scoped_ptr<ChannelIDService> channel_id_service) {
253 DCHECK(cookie_store);
254 cookie_store_ = cookie_store;
255 channel_id_service_ = channel_id_service.Pass();
258 void URLRequestContextBuilder::SetFileTaskRunner(
259 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
260 file_task_runner_ = task_runner;
263 void URLRequestContextBuilder::SetHttpServerProperties(
264 scoped_ptr<HttpServerProperties> http_server_properties) {
265 http_server_properties_ = http_server_properties.Pass();
268 scoped_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
269 scoped_ptr<ContainerURLRequestContext> context(
270 new ContainerURLRequestContext(file_task_runner_));
271 URLRequestContextStorage* storage = context->storage();
273 storage->set_http_user_agent_settings(
274 make_scoped_ptr(
275 new StaticHttpUserAgentSettings(accept_language_, user_agent_))
276 .Pass());
278 if (!network_delegate_)
279 network_delegate_.reset(new BasicNetworkDelegate);
280 storage->set_network_delegate(network_delegate_.Pass());
282 if (net_log_) {
283 // Unlike the other builder parameters, |net_log_| is not owned by the
284 // builder or resulting context.
285 context->set_net_log(net_log_);
286 } else {
287 storage->set_net_log(make_scoped_ptr(new NetLog));
290 if (!host_resolver_) {
291 host_resolver_ = HostResolver::CreateDefaultResolver(context->net_log());
293 storage->set_host_resolver(host_resolver_.Pass());
295 if (!proxy_service_) {
296 // TODO(willchan): Switch to using this code when
297 // ProxyService::CreateSystemProxyConfigService()'s signature doesn't suck.
298 #if defined(OS_LINUX) || defined(OS_ANDROID)
299 ProxyConfigService* proxy_config_service = proxy_config_service_.release();
300 #else
301 ProxyConfigService* proxy_config_service = NULL;
302 if (proxy_config_service_) {
303 proxy_config_service = proxy_config_service_.release();
304 } else {
305 proxy_config_service = ProxyService::CreateSystemProxyConfigService(
306 base::ThreadTaskRunnerHandle::Get().get(),
307 context->GetFileTaskRunner());
309 #endif // defined(OS_LINUX) || defined(OS_ANDROID)
310 proxy_service_ = ProxyService::CreateUsingSystemProxyResolver(
311 proxy_config_service,
312 0, // This results in using the default value.
313 context->net_log());
315 storage->set_proxy_service(proxy_service_.Pass());
317 storage->set_ssl_config_service(new SSLConfigServiceDefaults);
318 scoped_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_registry_factory(
319 HttpAuthHandlerRegistryFactory::CreateDefault(context->host_resolver()));
320 for (size_t i = 0; i < extra_http_auth_handlers_.size(); ++i) {
321 http_auth_handler_registry_factory->RegisterSchemeFactory(
322 extra_http_auth_handlers_[i].scheme,
323 extra_http_auth_handlers_[i].factory);
325 storage->set_http_auth_handler_factory(
326 http_auth_handler_registry_factory.Pass());
328 if (cookie_store_) {
329 storage->set_cookie_store(cookie_store_.get());
330 storage->set_channel_id_service(channel_id_service_.Pass());
331 } else {
332 storage->set_cookie_store(new CookieMonster(NULL, NULL));
333 // TODO(mmenke): This always creates a file thread, even when it ends up
334 // not being used. Consider lazily creating the thread.
335 storage->set_channel_id_service(make_scoped_ptr(new ChannelIDService(
336 new DefaultChannelIDStore(NULL), context->GetFileTaskRunner())));
339 if (sdch_enabled_) {
340 storage->set_sdch_manager(
341 scoped_ptr<net::SdchManager>(new SdchManager()).Pass());
344 storage->set_transport_security_state(
345 make_scoped_ptr(new TransportSecurityState()));
346 if (!transport_security_persister_path_.empty()) {
347 context->set_transport_security_persister(
348 make_scoped_ptr<TransportSecurityPersister>(
349 new TransportSecurityPersister(context->transport_security_state(),
350 transport_security_persister_path_,
351 context->GetFileTaskRunner(),
352 false)));
355 if (http_server_properties_) {
356 storage->set_http_server_properties(http_server_properties_.Pass());
357 } else {
358 storage->set_http_server_properties(
359 scoped_ptr<HttpServerProperties>(new HttpServerPropertiesImpl()));
362 storage->set_cert_verifier(CertVerifier::CreateDefault());
364 if (throttling_enabled_) {
365 storage->set_throttler_manager(
366 make_scoped_ptr(new URLRequestThrottlerManager()));
369 if (backoff_enabled_) {
370 storage->set_backoff_manager(
371 make_scoped_ptr(new URLRequestBackoffManager()));
374 HttpNetworkSession::Params network_session_params;
375 SetHttpNetworkSessionComponents(context.get(), &network_session_params);
377 network_session_params.ignore_certificate_errors =
378 http_network_session_params_.ignore_certificate_errors;
379 network_session_params.host_mapping_rules =
380 http_network_session_params_.host_mapping_rules;
381 network_session_params.testing_fixed_http_port =
382 http_network_session_params_.testing_fixed_http_port;
383 network_session_params.testing_fixed_https_port =
384 http_network_session_params_.testing_fixed_https_port;
385 network_session_params.use_alternative_services =
386 http_network_session_params_.use_alternative_services;
387 network_session_params.trusted_spdy_proxy =
388 http_network_session_params_.trusted_spdy_proxy;
389 network_session_params.next_protos = http_network_session_params_.next_protos;
390 network_session_params.enable_quic = http_network_session_params_.enable_quic;
391 network_session_params.enable_insecure_quic =
392 http_network_session_params_.enable_insecure_quic;
393 network_session_params.quic_connection_options =
394 http_network_session_params_.quic_connection_options;
396 scoped_ptr<HttpTransactionFactory> http_transaction_factory;
397 if (http_cache_enabled_) {
398 HttpCache::BackendFactory* http_cache_backend = NULL;
399 if (http_cache_params_.type == HttpCacheParams::DISK) {
400 http_cache_backend = new HttpCache::DefaultBackend(
401 DISK_CACHE, CACHE_BACKEND_DEFAULT, http_cache_params_.path,
402 http_cache_params_.max_size, context->GetFileTaskRunner());
403 } else {
404 http_cache_backend =
405 HttpCache::DefaultBackend::InMemory(http_cache_params_.max_size);
408 http_transaction_factory.reset(
409 new HttpCache(network_session_params, http_cache_backend));
410 } else {
411 scoped_refptr<HttpNetworkSession> network_session(
412 new HttpNetworkSession(network_session_params));
414 http_transaction_factory.reset(new HttpNetworkLayer(network_session.get()));
416 storage->set_http_transaction_factory(http_transaction_factory.Pass());
418 URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl;
419 if (data_enabled_)
420 job_factory->SetProtocolHandler("data",
421 make_scoped_ptr(new DataProtocolHandler));
423 #if !defined(DISABLE_FILE_SUPPORT)
424 if (file_enabled_) {
425 job_factory->SetProtocolHandler(
426 "file",
427 make_scoped_ptr(new FileProtocolHandler(context->GetFileTaskRunner())));
429 #endif // !defined(DISABLE_FILE_SUPPORT)
431 #if !defined(DISABLE_FTP_SUPPORT)
432 if (ftp_enabled_) {
433 ftp_transaction_factory_.reset(
434 new FtpNetworkLayer(context->host_resolver()));
435 job_factory->SetProtocolHandler(
436 "ftp", make_scoped_ptr(
437 new FtpProtocolHandler(ftp_transaction_factory_.get())));
439 #endif // !defined(DISABLE_FTP_SUPPORT)
441 scoped_ptr<net::URLRequestJobFactory> top_job_factory(job_factory);
442 if (!url_request_interceptors_.empty()) {
443 // Set up interceptors in the reverse order.
445 for (ScopedVector<net::URLRequestInterceptor>::reverse_iterator i =
446 url_request_interceptors_.rbegin();
447 i != url_request_interceptors_.rend(); ++i) {
448 top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
449 top_job_factory.Pass(), make_scoped_ptr(*i)));
451 url_request_interceptors_.weak_clear();
453 storage->set_job_factory(top_job_factory.Pass());
454 // TODO(willchan): Support sdch.
456 return context.Pass();
459 } // namespace net