Upstream version 7.35.143.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / browser / runtime_url_request_context_getter.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Copyright (c) 2013 Intel Corporation. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #include "xwalk/runtime/browser/runtime_url_request_context_getter.h"
7
8 #include <algorithm>
9 #include <vector>
10
11 #include "base/logging.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "base/threading/sequenced_worker_pool.h"
16 #include "base/threading/worker_pool.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/cookie_store_factory.h"
19 #include "content/public/common/content_switches.h"
20 #include "content/public/common/url_constants.h"
21 #include "net/cert/cert_verifier.h"
22 #include "net/cookies/cookie_monster.h"
23 #include "net/dns/host_resolver.h"
24 #include "net/dns/mapped_host_resolver.h"
25 #include "net/http/http_auth_handler_factory.h"
26 #include "net/http/http_cache.h"
27 #include "net/http/http_network_session.h"
28 #include "net/http/http_server_properties_impl.h"
29 #include "net/proxy/proxy_service.h"
30 #include "net/ssl/default_server_bound_cert_store.h"
31 #include "net/ssl/server_bound_cert_service.h"
32 #include "net/ssl/ssl_config_service_defaults.h"
33 #include "net/url_request/data_protocol_handler.h"
34 #include "net/url_request/file_protocol_handler.h"
35 #include "net/url_request/protocol_intercept_job_factory.h"
36 #include "net/url_request/static_http_user_agent_settings.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_job_factory_impl.h"
40 #include "xwalk/application/common/constants.h"
41 #include "xwalk/runtime/browser/runtime_network_delegate.h"
42
43 #if defined(OS_ANDROID)
44 #include "xwalk/runtime/browser/android/cookie_manager.h"
45 #include "xwalk/runtime/browser/android/net/android_protocol_handler.h"
46 #include "xwalk/runtime/browser/android/net/url_constants.h"
47 #include "xwalk/runtime/browser/android/net/xwalk_url_request_job_factory.h"
48 #include "xwalk/runtime/browser/android/xwalk_request_interceptor.h"
49 #endif
50
51 using content::BrowserThread;
52
53 namespace xwalk {
54
55 RuntimeURLRequestContextGetter::RuntimeURLRequestContextGetter(
56     bool ignore_certificate_errors,
57     const base::FilePath& base_path,
58     base::MessageLoop* io_loop,
59     base::MessageLoop* file_loop,
60     content::ProtocolHandlerMap* protocol_handlers,
61     content::ProtocolHandlerScopedVector protocol_interceptors)
62     : ignore_certificate_errors_(ignore_certificate_errors),
63       base_path_(base_path),
64       io_loop_(io_loop),
65       file_loop_(file_loop),
66       protocol_interceptors_(protocol_interceptors.Pass()) {
67   // Must first be created on the UI thread.
68   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
69
70   std::swap(protocol_handlers_, *protocol_handlers);
71
72   // We must create the proxy config service on the UI loop on Linux because it
73   // must synchronously run on the glib message loop. This will be passed to
74   // the URLRequestContextStorage on the IO thread in GetURLRequestContext().
75   proxy_config_service_.reset(
76       net::ProxyService::CreateSystemProxyConfigService(
77           io_loop_->message_loop_proxy(), file_loop_));
78 }
79
80 RuntimeURLRequestContextGetter::~RuntimeURLRequestContextGetter() {
81 }
82
83 net::URLRequestContext* RuntimeURLRequestContextGetter::GetURLRequestContext() {
84   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
85
86   if (!url_request_context_) {
87     url_request_context_.reset(new net::URLRequestContext());
88     network_delegate_.reset(new RuntimeNetworkDelegate);
89     url_request_context_->set_network_delegate(network_delegate_.get());
90     storage_.reset(
91         new net::URLRequestContextStorage(url_request_context_.get()));
92 #if defined(OS_ANDROID)
93     storage_->set_cookie_store(xwalk::GetCookieMonster());
94 #else
95     content::CookieStoreConfig cookie_config(base_path_.Append(
96         application::kCookieDatabaseFilename),
97         content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
98         NULL, NULL);
99     net::CookieStore* cookie_store = content::CreateCookieStore(cookie_config);
100
101     std::vector<const char*> cookieable_schemes(
102         net::CookieMonster::kDefaultCookieableSchemes,
103         net::CookieMonster::kDefaultCookieableSchemes +
104             net::CookieMonster::kDefaultCookieableSchemesCount - 1);
105     cookieable_schemes.push_back(application::kApplicationScheme);
106     cookieable_schemes.push_back(content::kChromeDevToolsScheme);
107
108     cookie_store->GetCookieMonster()->SetCookieableSchemes(
109         &cookieable_schemes[0], cookieable_schemes.size());
110     storage_->set_cookie_store(cookie_store);
111 #endif
112     storage_->set_server_bound_cert_service(new net::ServerBoundCertService(
113         new net::DefaultServerBoundCertStore(NULL),
114         base::WorkerPool::GetTaskRunner(true)));
115     storage_->set_http_user_agent_settings(
116         new net::StaticHttpUserAgentSettings("en-us,en", base::EmptyString()));
117
118     scoped_ptr<net::HostResolver> host_resolver(
119         net::HostResolver::CreateDefaultResolver(NULL));
120
121     storage_->set_cert_verifier(net::CertVerifier::CreateDefault());
122     storage_->set_transport_security_state(new net::TransportSecurityState);
123     storage_->set_proxy_service(
124         net::ProxyService::CreateUsingSystemProxyResolver(
125         proxy_config_service_.release(),
126         0,
127         NULL));
128     storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults);
129     storage_->set_http_auth_handler_factory(
130         net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
131     storage_->set_http_server_properties(scoped_ptr<net::HttpServerProperties>(
132         new net::HttpServerPropertiesImpl));
133
134     base::FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache"));
135     net::HttpCache::DefaultBackend* main_backend =
136         new net::HttpCache::DefaultBackend(
137             net::DISK_CACHE,
138             net::CACHE_BACKEND_DEFAULT,
139             cache_path,
140             0,
141             BrowserThread::GetMessageLoopProxyForThread(
142                 BrowserThread::CACHE));
143
144     net::HttpNetworkSession::Params network_session_params;
145     network_session_params.cert_verifier =
146         url_request_context_->cert_verifier();
147     network_session_params.transport_security_state =
148         url_request_context_->transport_security_state();
149     network_session_params.server_bound_cert_service =
150         url_request_context_->server_bound_cert_service();
151     network_session_params.proxy_service =
152         url_request_context_->proxy_service();
153     network_session_params.ssl_config_service =
154         url_request_context_->ssl_config_service();
155     network_session_params.http_auth_handler_factory =
156         url_request_context_->http_auth_handler_factory();
157     network_session_params.network_delegate =
158         network_delegate_.get();
159     network_session_params.http_server_properties =
160         url_request_context_->http_server_properties();
161     network_session_params.ignore_certificate_errors =
162         ignore_certificate_errors_;
163
164     // Give |storage_| ownership at the end in case it's |mapped_host_resolver|.
165     storage_->set_host_resolver(host_resolver.Pass());
166     network_session_params.host_resolver =
167         url_request_context_->host_resolver();
168
169     net::HttpCache* main_cache = new net::HttpCache(
170         network_session_params, main_backend);
171     storage_->set_http_transaction_factory(main_cache);
172
173 #if defined(OS_ANDROID)
174     scoped_ptr<XWalkURLRequestJobFactory> job_factory_impl(
175         new XWalkURLRequestJobFactory);
176 #else
177     scoped_ptr<net::URLRequestJobFactoryImpl> job_factory_impl(
178         new net::URLRequestJobFactoryImpl);
179 #endif
180
181     bool set_protocol;
182
183     // Step 1:
184     // Install all the default schemes for crosswalk.
185     for (content::ProtocolHandlerMap::iterator it =
186              protocol_handlers_.begin();
187          it != protocol_handlers_.end();
188          ++it) {
189       set_protocol = job_factory_impl->SetProtocolHandler(
190           it->first, it->second.release());
191       DCHECK(set_protocol);
192     }
193     protocol_handlers_.clear();
194
195     // Step 2:
196     // Add new basic schemes.
197     set_protocol = job_factory_impl->SetProtocolHandler(
198         content::kDataScheme,
199         new net::DataProtocolHandler);
200     DCHECK(set_protocol);
201     set_protocol = job_factory_impl->SetProtocolHandler(
202         content::kFileScheme,
203         new net::FileProtocolHandler(
204             content::BrowserThread::GetBlockingPool()->
205             GetTaskRunnerWithShutdownBehavior(
206                 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
207     DCHECK(set_protocol);
208
209     // Step 3:
210     // Add the scheme interceptors.
211     // Create a chain of URLRequestJobFactories. The handlers will be invoked
212     // in the order in which they appear in the protocol_handlers vector.
213     typedef std::vector<net::URLRequestJobFactory::ProtocolHandler*>
214         ProtocolHandlerVector;
215     ProtocolHandlerVector protocol_interceptors;
216
217 #if defined(OS_ANDROID)
218     protocol_interceptors.push_back(
219         CreateContentSchemeProtocolHandler().release());
220     protocol_interceptors.push_back(
221         CreateAssetFileProtocolHandler().release());
222     protocol_interceptors.push_back(
223         CreateAppSchemeProtocolHandler().release());
224     // The XWalkRequestInterceptor must come after the content and asset
225     // file job factories. This for WebViewClassic compatibility where it
226     // was not possible to intercept resource loads to resolvable content://
227     // and file:// URIs.
228     // This logical dependency is also the reason why the Content
229     // ProtocolHandler has to be added as a ProtocolInterceptJobFactory rather
230     // than via SetProtocolHandler.
231     protocol_interceptors.push_back(new XWalkRequestInterceptor());
232 #endif
233
234     // The chain of responsibility will execute the handlers in reverse to the
235     // order in which the elements of the chain are created.
236     scoped_ptr<net::URLRequestJobFactory> job_factory(
237         job_factory_impl.PassAs<net::URLRequestJobFactory>());
238     for (ProtocolHandlerVector::reverse_iterator
239              i = protocol_interceptors.rbegin();
240          i != protocol_interceptors.rend();
241          ++i) {
242       job_factory.reset(new net::ProtocolInterceptJobFactory(
243           job_factory.Pass(), make_scoped_ptr(*i)));
244     }
245
246     // Set up interceptors in the reverse order.
247     scoped_ptr<net::URLRequestJobFactory> top_job_factory =
248         job_factory.PassAs<net::URLRequestJobFactory>();
249     for (content::ProtocolHandlerScopedVector::reverse_iterator i =
250              protocol_interceptors_.rbegin();
251          i != protocol_interceptors_.rend();
252          ++i) {
253       top_job_factory.reset(new net::ProtocolInterceptJobFactory(
254           top_job_factory.Pass(), make_scoped_ptr(*i)));
255     }
256     protocol_interceptors_.weak_clear();
257
258     storage_->set_job_factory(top_job_factory.release());
259   }
260
261   return url_request_context_.get();
262 }
263
264 scoped_refptr<base::SingleThreadTaskRunner>
265     RuntimeURLRequestContextGetter::GetNetworkTaskRunner() const {
266   return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
267 }
268
269 net::HostResolver* RuntimeURLRequestContextGetter::host_resolver() {
270   return url_request_context_->host_resolver();
271 }
272
273 }  // namespace xwalk