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"
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.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"
39 #if !defined(DISABLE_FILE_SUPPORT)
40 #include "net/url_request/file_protocol_handler.h"
43 #if !defined(DISABLE_FTP_SUPPORT)
44 #include "net/url_request/ftp_protocol_handler.h"
51 class BasicNetworkDelegate
: public NetworkDelegate
{
53 BasicNetworkDelegate() {}
54 ~BasicNetworkDelegate() override
{}
57 int OnBeforeURLRequest(URLRequest
* request
,
58 const CompletionCallback
& callback
,
59 GURL
* new_url
) override
{
63 int OnBeforeSendHeaders(URLRequest
* request
,
64 const CompletionCallback
& callback
,
65 HttpRequestHeaders
* headers
) override
{
69 void OnSendHeaders(URLRequest
* request
,
70 const HttpRequestHeaders
& headers
) override
{}
72 int OnHeadersReceived(
74 const CompletionCallback
& callback
,
75 const HttpResponseHeaders
* original_response_headers
,
76 scoped_refptr
<HttpResponseHeaders
>* override_response_headers
,
77 GURL
* allowed_unsafe_redirect_url
) override
{
81 void OnBeforeRedirect(URLRequest
* request
,
82 const GURL
& new_location
) override
{}
84 void OnResponseStarted(URLRequest
* request
) override
{}
86 void OnRawBytesRead(const URLRequest
& request
, int bytes_read
) override
{}
88 void OnCompleted(URLRequest
* request
, bool started
) override
{}
90 void OnURLRequestDestroyed(URLRequest
* request
) override
{}
92 void OnPACScriptError(int line_number
, const base::string16
& error
) override
{
95 NetworkDelegate::AuthRequiredResponse
OnAuthRequired(
97 const AuthChallengeInfo
& auth_info
,
98 const AuthCallback
& callback
,
99 AuthCredentials
* credentials
) override
{
100 return NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION
;
103 bool OnCanGetCookies(const URLRequest
& request
,
104 const CookieList
& cookie_list
) override
{
108 bool OnCanSetCookie(const URLRequest
& request
,
109 const std::string
& cookie_line
,
110 CookieOptions
* options
) override
{
114 bool OnCanAccessFile(const net::URLRequest
& request
,
115 const base::FilePath
& path
) const override
{
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.
125 DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate
);
128 class BasicURLRequestContext
: public URLRequestContext
{
130 BasicURLRequestContext()
133 URLRequestContextStorage
* storage() {
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));
143 return cache_thread_
.get();
146 base::Thread
* GetFileThread() {
148 file_thread_
.reset(new base::Thread("Network File Thread"));
149 file_thread_
->StartWithOptions(
150 base::Thread::Options(base::MessageLoop::TYPE_DEFAULT
, 0));
152 return file_thread_
.get();
155 void set_transport_security_persister(
156 scoped_ptr
<TransportSecurityPersister
> transport_security_persister
) {
157 transport_security_persister
= transport_security_persister
.Pass();
161 ~BasicURLRequestContext() override
{ AssertNoURLRequests(); }
164 // Threads should be torn down last.
165 scoped_ptr
<base::Thread
> cache_thread_
;
166 scoped_ptr
<base::Thread
> file_thread_
;
168 URLRequestContextStorage storage_
;
169 scoped_ptr
<TransportSecurityPersister
> transport_security_persister_
;
171 DISALLOW_COPY_AND_ASSIGN(BasicURLRequestContext
);
176 URLRequestContextBuilder::HttpCacheParams::HttpCacheParams()
179 URLRequestContextBuilder::HttpCacheParams::~HttpCacheParams() {}
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),
191 URLRequestContextBuilder::HttpNetworkSessionParams::~HttpNetworkSessionParams()
194 URLRequestContextBuilder::SchemeFactory::SchemeFactory(
195 const std::string
& auth_scheme
,
196 net::HttpAuthHandlerFactory
* auth_handler_factory
)
197 : scheme(auth_scheme
), factory(auth_handler_factory
) {
200 URLRequestContextBuilder::SchemeFactory::~SchemeFactory() {
203 URLRequestContextBuilder::URLRequestContextBuilder()
204 : data_enabled_(false),
205 #if !defined(DISABLE_FILE_SUPPORT)
206 file_enabled_(false),
208 #if !defined(DISABLE_FTP_SUPPORT)
211 http_cache_enabled_(true),
212 throttling_enabled_(false),
213 channel_id_enabled_(true) {
216 URLRequestContextBuilder::~URLRequestContextBuilder() {}
218 void URLRequestContextBuilder::EnableHttpCache(const HttpCacheParams
& params
) {
219 http_cache_enabled_
= true;
220 http_cache_params_
= params
;
223 void URLRequestContextBuilder::DisableHttpCache() {
224 http_cache_enabled_
= false;
225 http_cache_params_
= HttpCacheParams();
228 void URLRequestContextBuilder::SetSpdyAndQuicEnabled(bool spdy_enabled
,
230 http_network_session_params_
.next_protos
=
231 NextProtosWithSpdyAndQuic(spdy_enabled
, quic_enabled
);
232 http_network_session_params_
.enable_quic
= quic_enabled
;
235 URLRequestContext
* URLRequestContextBuilder::Build() {
236 BasicURLRequestContext
* context
= new BasicURLRequestContext
;
237 URLRequestContextStorage
* storage
= context
->storage();
239 storage
->set_http_user_agent_settings(new StaticHttpUserAgentSettings(
240 accept_language_
, user_agent_
));
242 if (!network_delegate_
)
243 network_delegate_
.reset(new BasicNetworkDelegate
);
244 NetworkDelegate
* network_delegate
= network_delegate_
.release();
245 storage
->set_network_delegate(network_delegate
);
248 storage
->set_net_log(net_log_
.release());
250 storage
->set_net_log(new net::NetLog
);
253 if (!host_resolver_
) {
254 host_resolver_
= net::HostResolver::CreateDefaultResolver(
257 storage
->set_host_resolver(host_resolver_
.Pass());
259 if (!proxy_service_
) {
260 // TODO(willchan): Switch to using this code when
261 // ProxyService::CreateSystemProxyConfigService()'s signature doesn't suck.
262 #if defined(OS_LINUX) || defined(OS_ANDROID)
263 ProxyConfigService
* proxy_config_service
= proxy_config_service_
.release();
265 ProxyConfigService
* proxy_config_service
= NULL
;
266 if (proxy_config_service_
) {
267 proxy_config_service
= proxy_config_service_
.release();
269 proxy_config_service
=
270 ProxyService::CreateSystemProxyConfigService(
271 base::ThreadTaskRunnerHandle::Get().get(),
272 context
->GetFileThread()->task_runner());
274 #endif // defined(OS_LINUX) || defined(OS_ANDROID)
275 proxy_service_
.reset(
276 ProxyService::CreateUsingSystemProxyResolver(
277 proxy_config_service
,
278 0, // This results in using the default value.
279 context
->net_log()));
281 storage
->set_proxy_service(proxy_service_
.release());
283 storage
->set_ssl_config_service(new net::SSLConfigServiceDefaults
);
284 HttpAuthHandlerRegistryFactory
* http_auth_handler_registry_factory
=
285 net::HttpAuthHandlerRegistryFactory::CreateDefault(
286 context
->host_resolver());
287 for (size_t i
= 0; i
< extra_http_auth_handlers_
.size(); ++i
) {
288 http_auth_handler_registry_factory
->RegisterSchemeFactory(
289 extra_http_auth_handlers_
[i
].scheme
,
290 extra_http_auth_handlers_
[i
].factory
);
292 storage
->set_http_auth_handler_factory(http_auth_handler_registry_factory
);
293 storage
->set_cookie_store(new CookieMonster(NULL
, NULL
));
295 if (channel_id_enabled_
) {
296 // TODO(mmenke): This always creates a file thread, even when it ends up
297 // not being used. Consider lazily creating the thread.
298 storage
->set_channel_id_service(
299 new ChannelIDService(
300 new DefaultChannelIDStore(NULL
),
301 context
->GetFileThread()->message_loop_proxy()));
304 storage
->set_transport_security_state(new net::TransportSecurityState());
305 if (!transport_security_persister_path_
.empty()) {
306 context
->set_transport_security_persister(
307 make_scoped_ptr
<TransportSecurityPersister
>(
308 new TransportSecurityPersister(
309 context
->transport_security_state(),
310 transport_security_persister_path_
,
311 context
->GetFileThread()->message_loop_proxy(),
315 storage
->set_http_server_properties(
316 scoped_ptr
<net::HttpServerProperties
>(
317 new net::HttpServerPropertiesImpl()));
318 storage
->set_cert_verifier(CertVerifier::CreateDefault());
320 if (throttling_enabled_
)
321 storage
->set_throttler_manager(new URLRequestThrottlerManager());
323 net::HttpNetworkSession::Params network_session_params
;
324 network_session_params
.host_resolver
= context
->host_resolver();
325 network_session_params
.cert_verifier
= context
->cert_verifier();
326 network_session_params
.transport_security_state
=
327 context
->transport_security_state();
328 network_session_params
.proxy_service
= context
->proxy_service();
329 network_session_params
.ssl_config_service
=
330 context
->ssl_config_service();
331 network_session_params
.http_auth_handler_factory
=
332 context
->http_auth_handler_factory();
333 network_session_params
.network_delegate
= network_delegate
;
334 network_session_params
.http_server_properties
=
335 context
->http_server_properties();
336 network_session_params
.net_log
= context
->net_log();
338 network_session_params
.ignore_certificate_errors
=
339 http_network_session_params_
.ignore_certificate_errors
;
340 network_session_params
.host_mapping_rules
=
341 http_network_session_params_
.host_mapping_rules
;
342 network_session_params
.testing_fixed_http_port
=
343 http_network_session_params_
.testing_fixed_http_port
;
344 network_session_params
.testing_fixed_https_port
=
345 http_network_session_params_
.testing_fixed_https_port
;
346 network_session_params
.use_alternate_protocols
=
347 http_network_session_params_
.use_alternate_protocols
;
348 network_session_params
.trusted_spdy_proxy
=
349 http_network_session_params_
.trusted_spdy_proxy
;
350 network_session_params
.next_protos
= http_network_session_params_
.next_protos
;
351 network_session_params
.enable_quic
= http_network_session_params_
.enable_quic
;
352 network_session_params
.quic_connection_options
=
353 http_network_session_params_
.quic_connection_options
;
355 HttpTransactionFactory
* http_transaction_factory
= NULL
;
356 if (http_cache_enabled_
) {
357 network_session_params
.channel_id_service
=
358 context
->channel_id_service();
359 HttpCache::BackendFactory
* http_cache_backend
= NULL
;
360 if (http_cache_params_
.type
== HttpCacheParams::DISK
) {
361 http_cache_backend
= new HttpCache::DefaultBackend(
363 net::CACHE_BACKEND_DEFAULT
,
364 http_cache_params_
.path
,
365 http_cache_params_
.max_size
,
366 context
->GetCacheThread()->task_runner());
369 HttpCache::DefaultBackend::InMemory(http_cache_params_
.max_size
);
372 http_transaction_factory
= new HttpCache(
373 network_session_params
, http_cache_backend
);
375 scoped_refptr
<net::HttpNetworkSession
> network_session(
376 new net::HttpNetworkSession(network_session_params
));
378 http_transaction_factory
= new HttpNetworkLayer(network_session
.get());
380 storage
->set_http_transaction_factory(http_transaction_factory
);
382 URLRequestJobFactoryImpl
* job_factory
= new URLRequestJobFactoryImpl
;
384 job_factory
->SetProtocolHandler("data", new DataProtocolHandler
);
386 #if !defined(DISABLE_FILE_SUPPORT)
388 job_factory
->SetProtocolHandler(
390 new FileProtocolHandler(context
->GetFileThread()->message_loop_proxy()));
392 #endif // !defined(DISABLE_FILE_SUPPORT)
394 #if !defined(DISABLE_FTP_SUPPORT)
396 ftp_transaction_factory_
.reset(
397 new FtpNetworkLayer(context
->host_resolver()));
398 job_factory
->SetProtocolHandler("ftp",
399 new FtpProtocolHandler(ftp_transaction_factory_
.get()));
401 #endif // !defined(DISABLE_FTP_SUPPORT)
403 storage
->set_job_factory(job_factory
);
405 // TODO(willchan): Support sdch.