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 |