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/string_util.h"
13 #include "base/threading/thread.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "net/base/cert_verifier.h"
16 #include "net/base/host_resolver.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/network_delegate.h"
19 #include "net/base/ssl_config_service_defaults.h"
20 #include "net/base/transport_security_state.h"
21 #include "net/cookies/cookie_monster.h"
22 #include "net/ftp/ftp_network_layer.h"
23 #include "net/http/http_auth_handler_factory.h"
24 #include "net/http/http_cache.h"
25 #include "net/http/http_network_layer.h"
26 #include "net/http/http_network_session.h"
27 #include "net/http/http_server_properties_impl.h"
28 #include "net/proxy/proxy_service.h"
29 #include "net/url_request/static_http_user_agent_settings.h"
30 #include "net/url_request/url_request_context.h"
31 #include "net/url_request/url_request_context_storage.h"
37 class BasicNetworkDelegate
: public NetworkDelegate
{
39 BasicNetworkDelegate() {}
40 virtual ~BasicNetworkDelegate() {}
43 virtual int OnBeforeURLRequest(URLRequest
* request
,
44 const CompletionCallback
& callback
,
45 GURL
* new_url
) OVERRIDE
{
49 virtual int OnBeforeSendHeaders(URLRequest
* request
,
50 const CompletionCallback
& callback
,
51 HttpRequestHeaders
* headers
) OVERRIDE
{
55 virtual void OnSendHeaders(URLRequest
* request
,
56 const HttpRequestHeaders
& headers
) OVERRIDE
{}
58 virtual int OnHeadersReceived(
60 const CompletionCallback
& callback
,
61 const HttpResponseHeaders
* original_response_headers
,
62 scoped_refptr
<HttpResponseHeaders
>* override_response_headers
)
67 virtual void OnBeforeRedirect(URLRequest
* request
,
68 const GURL
& new_location
) OVERRIDE
{}
70 virtual void OnResponseStarted(URLRequest
* request
) OVERRIDE
{}
72 virtual void OnRawBytesRead(const URLRequest
& request
,
73 int bytes_read
) OVERRIDE
{}
75 virtual void OnCompleted(URLRequest
* request
, bool started
) OVERRIDE
{}
77 virtual void OnURLRequestDestroyed(URLRequest
* request
) OVERRIDE
{}
79 virtual void OnPACScriptError(int line_number
,
80 const string16
& error
) OVERRIDE
{}
82 virtual NetworkDelegate::AuthRequiredResponse
OnAuthRequired(
84 const AuthChallengeInfo
& auth_info
,
85 const AuthCallback
& callback
,
86 AuthCredentials
* credentials
) OVERRIDE
{
87 return NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION
;
90 virtual bool OnCanGetCookies(const URLRequest
& request
,
91 const CookieList
& cookie_list
) OVERRIDE
{
95 virtual bool OnCanSetCookie(const URLRequest
& request
,
96 const std::string
& cookie_line
,
97 CookieOptions
* options
) OVERRIDE
{
101 virtual bool OnCanAccessFile(const net::URLRequest
& request
,
102 const FilePath
& path
) const OVERRIDE
{
106 virtual bool OnCanThrottleRequest(const URLRequest
& request
) const OVERRIDE
{
110 virtual int OnBeforeSocketStreamConnect(
111 SocketStream
* stream
,
112 const CompletionCallback
& callback
) OVERRIDE
{
116 virtual void OnRequestWaitStateChange(const URLRequest
& request
,
117 RequestWaitState state
) OVERRIDE
{
120 DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate
);
123 class BasicURLRequestContext
: public URLRequestContext
{
125 BasicURLRequestContext()
126 : cache_thread_("Cache Thread"),
127 file_thread_("File Thread"),
128 ALLOW_THIS_IN_INITIALIZER_LIST(storage_(this)) {}
130 URLRequestContextStorage
* storage() {
134 void StartCacheThread() {
135 cache_thread_
.StartWithOptions(
136 base::Thread::Options(MessageLoop::TYPE_IO
, 0));
139 scoped_refptr
<base::MessageLoopProxy
> cache_message_loop_proxy() {
140 DCHECK(cache_thread_
.IsRunning());
141 return cache_thread_
.message_loop_proxy();
144 void StartFileThread() {
145 file_thread_
.StartWithOptions(
146 base::Thread::Options(MessageLoop::TYPE_DEFAULT
, 0));
149 MessageLoop
* file_message_loop() {
150 DCHECK(file_thread_
.IsRunning());
151 return file_thread_
.message_loop();
155 virtual ~BasicURLRequestContext() {}
158 base::Thread cache_thread_
;
159 base::Thread file_thread_
;
160 URLRequestContextStorage storage_
;
161 DISALLOW_COPY_AND_ASSIGN(BasicURLRequestContext
);
166 URLRequestContextBuilder::HttpCacheParams::HttpCacheParams()
169 URLRequestContextBuilder::HttpCacheParams::~HttpCacheParams() {}
171 URLRequestContextBuilder::HttpNetworkSessionParams::HttpNetworkSessionParams()
172 : ignore_certificate_errors(false),
173 host_mapping_rules(NULL
),
174 http_pipelining_enabled(false),
175 testing_fixed_http_port(0),
176 testing_fixed_https_port(0),
177 trusted_spdy_proxy() {}
179 URLRequestContextBuilder::HttpNetworkSessionParams::~HttpNetworkSessionParams()
182 URLRequestContextBuilder::URLRequestContextBuilder()
183 : ftp_enabled_(false),
184 http_cache_enabled_(true) {}
185 URLRequestContextBuilder::~URLRequestContextBuilder() {}
187 #if defined(OS_LINUX) || defined(OS_ANDROID)
188 void URLRequestContextBuilder::set_proxy_config_service(
189 ProxyConfigService
* proxy_config_service
) {
190 proxy_config_service_
.reset(proxy_config_service
);
192 #endif // defined(OS_LINUX) || defined(OS_ANDROID)
194 URLRequestContext
* URLRequestContextBuilder::Build() {
195 BasicURLRequestContext
* context
= new BasicURLRequestContext
;
196 URLRequestContextStorage
* storage
= context
->storage();
198 storage
->set_http_user_agent_settings(new StaticHttpUserAgentSettings(
199 accept_language_
, accept_charset_
, user_agent_
));
201 if (!network_delegate_
)
202 network_delegate_
.reset(new BasicNetworkDelegate
);
203 storage
->set_network_delegate(network_delegate_
.release());
205 storage
->set_host_resolver(net::HostResolver::CreateDefaultResolver(NULL
));
208 storage
->set_ftp_transaction_factory(
209 new FtpNetworkLayer(context
->host_resolver()));
212 context
->StartFileThread();
214 // TODO(willchan): Switch to using this code when
215 // ProxyService::CreateSystemProxyConfigService()'s signature doesn't suck.
216 #if defined(OS_LINUX) || defined(OS_ANDROID)
217 ProxyConfigService
* proxy_config_service
= proxy_config_service_
.release();
219 ProxyConfigService
* proxy_config_service
=
220 ProxyService::CreateSystemProxyConfigService(
221 base::ThreadTaskRunnerHandle::Get(),
222 context
->file_message_loop());
223 #endif // defined(OS_LINUX) || defined(OS_ANDROID)
224 storage
->set_proxy_service(
225 ProxyService::CreateUsingSystemProxyResolver(
226 proxy_config_service
,
227 4, // TODO(willchan): Find a better constant somewhere.
228 context
->net_log()));
229 storage
->set_ssl_config_service(new net::SSLConfigServiceDefaults
);
230 storage
->set_http_auth_handler_factory(
231 net::HttpAuthHandlerRegistryFactory::CreateDefault(
232 context
->host_resolver()));
233 storage
->set_cookie_store(new CookieMonster(NULL
, NULL
));
234 storage
->set_transport_security_state(new net::TransportSecurityState());
235 storage
->set_http_server_properties(new net::HttpServerPropertiesImpl
);
236 storage
->set_cert_verifier(CertVerifier::CreateDefault());
238 net::HttpNetworkSession::Params network_session_params
;
239 network_session_params
.host_resolver
= context
->host_resolver();
240 network_session_params
.cert_verifier
= context
->cert_verifier();
241 network_session_params
.transport_security_state
=
242 context
->transport_security_state();
243 network_session_params
.proxy_service
= context
->proxy_service();
244 network_session_params
.ssl_config_service
=
245 context
->ssl_config_service();
246 network_session_params
.http_auth_handler_factory
=
247 context
->http_auth_handler_factory();
248 network_session_params
.network_delegate
=
249 context
->network_delegate();
250 network_session_params
.http_server_properties
=
251 context
->http_server_properties();
252 network_session_params
.net_log
= context
->net_log();
253 network_session_params
.ignore_certificate_errors
=
254 http_network_session_params_
.ignore_certificate_errors
;
255 network_session_params
.host_mapping_rules
=
256 http_network_session_params_
.host_mapping_rules
;
257 network_session_params
.http_pipelining_enabled
=
258 http_network_session_params_
.http_pipelining_enabled
;
259 network_session_params
.testing_fixed_http_port
=
260 http_network_session_params_
.testing_fixed_http_port
;
261 network_session_params
.testing_fixed_https_port
=
262 http_network_session_params_
.testing_fixed_https_port
;
263 network_session_params
.trusted_spdy_proxy
=
264 http_network_session_params_
.trusted_spdy_proxy
;
266 HttpTransactionFactory
* http_transaction_factory
= NULL
;
267 if (http_cache_enabled_
) {
268 network_session_params
.server_bound_cert_service
=
269 context
->server_bound_cert_service();
270 HttpCache::BackendFactory
* http_cache_backend
= NULL
;
271 if (http_cache_params_
.type
== HttpCacheParams::DISK
) {
272 context
->StartCacheThread();
274 new HttpCache::DefaultBackend(DISK_CACHE
,
275 http_cache_params_
.path
,
276 http_cache_params_
.max_size
,
277 context
->cache_message_loop_proxy());
280 HttpCache::DefaultBackend::InMemory(http_cache_params_
.max_size
);
283 http_transaction_factory
= new HttpCache(
284 network_session_params
, http_cache_backend
);
286 scoped_refptr
<net::HttpNetworkSession
> network_session(
287 new net::HttpNetworkSession(network_session_params
));
289 http_transaction_factory
= new HttpNetworkLayer(network_session
);
291 storage
->set_http_transaction_factory(http_transaction_factory
);
293 // TODO(willchan): Support sdch.