Upstream version 9.38.198.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/channel_id_service.h"
31 #include "net/ssl/default_channel_id_store.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/static_http_user_agent_settings.h"
36 #include "net/url_request/url_request_context.h"
37 #include "net/url_request/url_request_context_storage.h"
38 #include "net/url_request/url_request_intercepting_job_factory.h"
39 #include "net/url_request/url_request_interceptor.h"
40 #include "net/url_request/url_request_job_factory_impl.h"
41 #include "xwalk/application/common/constants.h"
42 #include "xwalk/runtime/browser/runtime_network_delegate.h"
43
44 #if defined(OS_ANDROID)
45 #include "xwalk/runtime/browser/android/cookie_manager.h"
46 #include "xwalk/runtime/browser/android/net/android_protocol_handler.h"
47 #include "xwalk/runtime/browser/android/net/url_constants.h"
48 #include "xwalk/runtime/browser/android/net/xwalk_url_request_job_factory.h"
49 #include "xwalk/runtime/browser/android/xwalk_request_interceptor.h"
50 #endif
51
52 using content::BrowserThread;
53
54 namespace xwalk {
55
56 RuntimeURLRequestContextGetter::RuntimeURLRequestContextGetter(
57     bool ignore_certificate_errors,
58     const base::FilePath& base_path,
59     base::MessageLoop* io_loop,
60     base::MessageLoop* file_loop,
61     content::ProtocolHandlerMap* protocol_handlers,
62     content::URLRequestInterceptorScopedVector request_interceptors)
63     : ignore_certificate_errors_(ignore_certificate_errors),
64       base_path_(base_path),
65       io_loop_(io_loop),
66       file_loop_(file_loop),
67       request_interceptors_(request_interceptors.Pass()) {
68   // Must first be created on the UI thread.
69   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
70
71   std::swap(protocol_handlers_, *protocol_handlers);
72
73   // We must create the proxy config service on the UI loop on Linux because it
74   // must synchronously run on the glib message loop. This will be passed to
75   // the URLRequestContextStorage on the IO thread in GetURLRequestContext().
76   proxy_config_service_.reset(
77       net::ProxyService::CreateSystemProxyConfigService(
78           io_loop_->message_loop_proxy(), file_loop_));
79 }
80
81 RuntimeURLRequestContextGetter::~RuntimeURLRequestContextGetter() {
82 }
83
84 net::URLRequestContext* RuntimeURLRequestContextGetter::GetURLRequestContext() {
85   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
86
87   if (!url_request_context_) {
88     url_request_context_.reset(new net::URLRequestContext());
89     network_delegate_.reset(new RuntimeNetworkDelegate);
90     url_request_context_->set_network_delegate(network_delegate_.get());
91     storage_.reset(
92         new net::URLRequestContextStorage(url_request_context_.get()));
93 #if defined(OS_ANDROID)
94     storage_->set_cookie_store(xwalk::GetCookieMonster());
95 #else
96     content::CookieStoreConfig cookie_config(base_path_.Append(
97         application::kCookieDatabaseFilename),
98         content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
99         NULL, NULL);
100     net::CookieStore* cookie_store = content::CreateCookieStore(cookie_config);
101
102     std::vector<const char*> cookieable_schemes(
103         net::CookieMonster::kDefaultCookieableSchemes,
104         net::CookieMonster::kDefaultCookieableSchemes +
105             net::CookieMonster::kDefaultCookieableSchemesCount - 1);
106     cookieable_schemes.push_back(application::kApplicationScheme);
107     cookieable_schemes.push_back(content::kChromeDevToolsScheme);
108
109     cookie_store->GetCookieMonster()->SetCookieableSchemes(
110         &cookieable_schemes[0], cookieable_schemes.size());
111     storage_->set_cookie_store(cookie_store);
112 #endif
113     storage_->set_channel_id_service(new net::ChannelIDService(
114         new net::DefaultChannelIDStore(NULL),
115         base::WorkerPool::GetTaskRunner(true)));
116     storage_->set_http_user_agent_settings(
117         new net::StaticHttpUserAgentSettings("en-us,en", base::EmptyString()));
118
119     scoped_ptr<net::HostResolver> host_resolver(
120         net::HostResolver::CreateDefaultResolver(NULL));
121
122     storage_->set_cert_verifier(net::CertVerifier::CreateDefault());
123     storage_->set_transport_security_state(new net::TransportSecurityState);
124     storage_->set_proxy_service(
125         net::ProxyService::CreateUsingSystemProxyResolver(
126         proxy_config_service_.release(),
127         0,
128         NULL));
129     storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults);
130     storage_->set_http_auth_handler_factory(
131         net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
132     storage_->set_http_server_properties(scoped_ptr<net::HttpServerProperties>(
133         new net::HttpServerPropertiesImpl));
134
135     base::FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache"));
136     net::HttpCache::DefaultBackend* main_backend =
137         new net::HttpCache::DefaultBackend(
138             net::DISK_CACHE,
139             net::CACHE_BACKEND_DEFAULT,
140             cache_path,
141             0,
142             BrowserThread::GetMessageLoopProxyForThread(
143                 BrowserThread::CACHE));
144
145     net::HttpNetworkSession::Params network_session_params;
146     network_session_params.cert_verifier =
147         url_request_context_->cert_verifier();
148     network_session_params.transport_security_state =
149         url_request_context_->transport_security_state();
150     network_session_params.channel_id_service =
151         url_request_context_->channel_id_service();
152     network_session_params.proxy_service =
153         url_request_context_->proxy_service();
154     network_session_params.ssl_config_service =
155         url_request_context_->ssl_config_service();
156     network_session_params.http_auth_handler_factory =
157         url_request_context_->http_auth_handler_factory();
158     network_session_params.network_delegate =
159         network_delegate_.get();
160     network_session_params.http_server_properties =
161         url_request_context_->http_server_properties();
162     network_session_params.ignore_certificate_errors =
163         ignore_certificate_errors_;
164
165     // Give |storage_| ownership at the end in case it's |mapped_host_resolver|.
166     storage_->set_host_resolver(host_resolver.Pass());
167     network_session_params.host_resolver =
168         url_request_context_->host_resolver();
169
170     net::HttpCache* main_cache = new net::HttpCache(
171         network_session_params, main_backend);
172     storage_->set_http_transaction_factory(main_cache);
173
174 #if defined(OS_ANDROID)
175     scoped_ptr<XWalkURLRequestJobFactory> job_factory_impl(
176         new XWalkURLRequestJobFactory);
177 #else
178     scoped_ptr<net::URLRequestJobFactoryImpl> job_factory_impl(
179         new net::URLRequestJobFactoryImpl);
180 #endif
181
182     bool set_protocol;
183
184     // Step 1:
185     // Install all the default schemes for crosswalk.
186     for (content::ProtocolHandlerMap::iterator it =
187              protocol_handlers_.begin();
188          it != protocol_handlers_.end();
189          ++it) {
190       set_protocol = job_factory_impl->SetProtocolHandler(
191           it->first, it->second.release());
192       DCHECK(set_protocol);
193     }
194     protocol_handlers_.clear();
195
196     // Step 2:
197     // Add new basic schemes.
198     set_protocol = job_factory_impl->SetProtocolHandler(
199         url::kDataScheme,
200         new net::DataProtocolHandler);
201     DCHECK(set_protocol);
202     set_protocol = job_factory_impl->SetProtocolHandler(
203         url::kFileScheme,
204         new net::FileProtocolHandler(
205             content::BrowserThread::GetBlockingPool()->
206             GetTaskRunnerWithShutdownBehavior(
207                 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
208     DCHECK(set_protocol);
209
210     // Step 3:
211     // Add the scheme interceptors.
212   // in the order in which they appear in the |request_interceptors| vector.
213   typedef std::vector<net::URLRequestInterceptor*>
214       URLRequestInterceptorVector;
215   URLRequestInterceptorVector request_interceptors;
216
217 #if defined(OS_ANDROID)
218     request_interceptors.push_back(
219         CreateContentSchemeRequestInterceptor().release());
220     request_interceptors.push_back(
221         CreateAssetFileRequestInterceptor().release());
222     request_interceptors.push_back(
223         CreateAppSchemeRequestInterceptor().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     request_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 (URLRequestInterceptorVector::reverse_iterator
239              i = request_interceptors.rbegin();
240          i != request_interceptors.rend();
241          ++i) {
242       job_factory.reset(new net::URLRequestInterceptingJobFactory(
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::URLRequestInterceptorScopedVector::reverse_iterator i =
250              request_interceptors_.rbegin();
251          i != request_interceptors_.rend();
252          ++i) {
253       top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
254           top_job_factory.Pass(), make_scoped_ptr(*i)));
255     }
256     request_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