75092187beb7c611cb562d8f6a860678c18aa119
[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     const char* schemes[] = {application::kApplicationScheme,
101                              content::kChromeDevToolsScheme};
102     cookie_store->GetCookieMonster()->SetCookieableSchemes(schemes, 2);
103     storage_->set_cookie_store(cookie_store);
104 #endif
105     storage_->set_server_bound_cert_service(new net::ServerBoundCertService(
106         new net::DefaultServerBoundCertStore(NULL),
107         base::WorkerPool::GetTaskRunner(true)));
108     storage_->set_http_user_agent_settings(
109         new net::StaticHttpUserAgentSettings("en-us,en", base::EmptyString()));
110
111     scoped_ptr<net::HostResolver> host_resolver(
112         net::HostResolver::CreateDefaultResolver(NULL));
113
114     storage_->set_cert_verifier(net::CertVerifier::CreateDefault());
115     storage_->set_transport_security_state(new net::TransportSecurityState);
116     storage_->set_proxy_service(
117         net::ProxyService::CreateUsingSystemProxyResolver(
118         proxy_config_service_.release(),
119         0,
120         NULL));
121     storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults);
122     storage_->set_http_auth_handler_factory(
123         net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
124     storage_->set_http_server_properties(scoped_ptr<net::HttpServerProperties>(
125         new net::HttpServerPropertiesImpl));
126
127     base::FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache"));
128     net::HttpCache::DefaultBackend* main_backend =
129         new net::HttpCache::DefaultBackend(
130             net::DISK_CACHE,
131             net::CACHE_BACKEND_DEFAULT,
132             cache_path,
133             0,
134             BrowserThread::GetMessageLoopProxyForThread(
135                 BrowserThread::CACHE));
136
137     net::HttpNetworkSession::Params network_session_params;
138     network_session_params.cert_verifier =
139         url_request_context_->cert_verifier();
140     network_session_params.transport_security_state =
141         url_request_context_->transport_security_state();
142     network_session_params.server_bound_cert_service =
143         url_request_context_->server_bound_cert_service();
144     network_session_params.proxy_service =
145         url_request_context_->proxy_service();
146     network_session_params.ssl_config_service =
147         url_request_context_->ssl_config_service();
148     network_session_params.http_auth_handler_factory =
149         url_request_context_->http_auth_handler_factory();
150     network_session_params.network_delegate =
151         network_delegate_.get();
152     network_session_params.http_server_properties =
153         url_request_context_->http_server_properties();
154     network_session_params.ignore_certificate_errors =
155         ignore_certificate_errors_;
156
157     // Give |storage_| ownership at the end in case it's |mapped_host_resolver|.
158     storage_->set_host_resolver(host_resolver.Pass());
159     network_session_params.host_resolver =
160         url_request_context_->host_resolver();
161
162     net::HttpCache* main_cache = new net::HttpCache(
163         network_session_params, main_backend);
164     storage_->set_http_transaction_factory(main_cache);
165
166 #if defined(OS_ANDROID)
167     scoped_ptr<XWalkURLRequestJobFactory> job_factory_impl(
168         new XWalkURLRequestJobFactory);
169 #else
170     scoped_ptr<net::URLRequestJobFactoryImpl> job_factory_impl(
171         new net::URLRequestJobFactoryImpl);
172 #endif
173
174     bool set_protocol;
175
176     // Step 1:
177     // Install all the default schemes for crosswalk.
178     for (content::ProtocolHandlerMap::iterator it =
179              protocol_handlers_.begin();
180          it != protocol_handlers_.end();
181          ++it) {
182       set_protocol = job_factory_impl->SetProtocolHandler(
183           it->first, it->second.release());
184       DCHECK(set_protocol);
185     }
186     protocol_handlers_.clear();
187
188     // Step 2:
189     // Add new basic schemes.
190     set_protocol = job_factory_impl->SetProtocolHandler(
191         content::kDataScheme,
192         new net::DataProtocolHandler);
193     DCHECK(set_protocol);
194     set_protocol = job_factory_impl->SetProtocolHandler(
195         content::kFileScheme,
196         new net::FileProtocolHandler(
197             content::BrowserThread::GetBlockingPool()->
198             GetTaskRunnerWithShutdownBehavior(
199                 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
200     DCHECK(set_protocol);
201
202     // Step 3:
203     // Add the scheme interceptors.
204     // Create a chain of URLRequestJobFactories. The handlers will be invoked
205     // in the order in which they appear in the protocol_handlers vector.
206     typedef std::vector<net::URLRequestJobFactory::ProtocolHandler*>
207         ProtocolHandlerVector;
208     ProtocolHandlerVector protocol_interceptors;
209
210 #if defined(OS_ANDROID)
211     protocol_interceptors.push_back(
212         CreateContentSchemeProtocolHandler().release());
213     protocol_interceptors.push_back(
214         CreateAssetFileProtocolHandler().release());
215     protocol_interceptors.push_back(
216         CreateAppSchemeProtocolHandler().release());
217     // The XWalkRequestInterceptor must come after the content and asset
218     // file job factories. This for WebViewClassic compatibility where it
219     // was not possible to intercept resource loads to resolvable content://
220     // and file:// URIs.
221     // This logical dependency is also the reason why the Content
222     // ProtocolHandler has to be added as a ProtocolInterceptJobFactory rather
223     // than via SetProtocolHandler.
224     protocol_interceptors.push_back(new XWalkRequestInterceptor());
225 #endif
226
227     // The chain of responsibility will execute the handlers in reverse to the
228     // order in which the elements of the chain are created.
229     scoped_ptr<net::URLRequestJobFactory> job_factory(
230         job_factory_impl.PassAs<net::URLRequestJobFactory>());
231     for (ProtocolHandlerVector::reverse_iterator
232              i = protocol_interceptors.rbegin();
233          i != protocol_interceptors.rend();
234          ++i) {
235       job_factory.reset(new net::ProtocolInterceptJobFactory(
236           job_factory.Pass(), make_scoped_ptr(*i)));
237     }
238
239     // Set up interceptors in the reverse order.
240     scoped_ptr<net::URLRequestJobFactory> top_job_factory =
241         job_factory.PassAs<net::URLRequestJobFactory>();
242     for (content::ProtocolHandlerScopedVector::reverse_iterator i =
243              protocol_interceptors_.rbegin();
244          i != protocol_interceptors_.rend();
245          ++i) {
246       top_job_factory.reset(new net::ProtocolInterceptJobFactory(
247           top_job_factory.Pass(), make_scoped_ptr(*i)));
248     }
249     protocol_interceptors_.weak_clear();
250
251     storage_->set_job_factory(top_job_factory.release());
252   }
253
254   return url_request_context_.get();
255 }
256
257 scoped_refptr<base::SingleThreadTaskRunner>
258     RuntimeURLRequestContextGetter::GetNetworkTaskRunner() const {
259   return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
260 }
261
262 net::HostResolver* RuntimeURLRequestContextGetter::host_resolver() {
263   return url_request_context_->host_resolver();
264 }
265
266 }  // namespace xwalk