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