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.
6 #include "xwalk/runtime/browser/runtime_url_request_context_getter.h"
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"
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"
51 using content::BrowserThread;
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),
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));
70 std::swap(protocol_handlers_, *protocol_handlers);
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_));
80 RuntimeURLRequestContextGetter::~RuntimeURLRequestContextGetter() {
83 net::URLRequestContext* RuntimeURLRequestContextGetter::GetURLRequestContext() {
84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
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());
91 new net::URLRequestContextStorage(url_request_context_.get()));
92 #if defined(OS_ANDROID)
93 storage_->set_cookie_store(xwalk::GetCookieMonster());
95 content::CookieStoreConfig cookie_config(base_path_.Append(
96 application::kCookieDatabaseFilename),
97 content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
99 net::CookieStore* cookie_store = content::CreateCookieStore(cookie_config);
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);
108 cookie_store->GetCookieMonster()->SetCookieableSchemes(
109 &cookieable_schemes[0], cookieable_schemes.size());
110 storage_->set_cookie_store(cookie_store);
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()));
118 scoped_ptr<net::HostResolver> host_resolver(
119 net::HostResolver::CreateDefaultResolver(NULL));
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(),
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));
134 base::FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache"));
135 net::HttpCache::DefaultBackend* main_backend =
136 new net::HttpCache::DefaultBackend(
138 net::CACHE_BACKEND_DEFAULT,
141 BrowserThread::GetMessageLoopProxyForThread(
142 BrowserThread::CACHE));
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_;
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();
169 net::HttpCache* main_cache = new net::HttpCache(
170 network_session_params, main_backend);
171 storage_->set_http_transaction_factory(main_cache);
173 #if defined(OS_ANDROID)
174 scoped_ptr<XWalkURLRequestJobFactory> job_factory_impl(
175 new XWalkURLRequestJobFactory);
177 scoped_ptr<net::URLRequestJobFactoryImpl> job_factory_impl(
178 new net::URLRequestJobFactoryImpl);
184 // Install all the default schemes for crosswalk.
185 for (content::ProtocolHandlerMap::iterator it =
186 protocol_handlers_.begin();
187 it != protocol_handlers_.end();
189 set_protocol = job_factory_impl->SetProtocolHandler(
190 it->first, it->second.release());
191 DCHECK(set_protocol);
193 protocol_handlers_.clear();
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);
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;
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://
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());
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();
242 job_factory.reset(new net::ProtocolInterceptJobFactory(
243 job_factory.Pass(), make_scoped_ptr(*i)));
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();
253 top_job_factory.reset(new net::ProtocolInterceptJobFactory(
254 top_job_factory.Pass(), make_scoped_ptr(*i)));
256 protocol_interceptors_.weak_clear();
258 storage_->set_job_factory(top_job_factory.release());
261 return url_request_context_.get();
264 scoped_refptr<base::SingleThreadTaskRunner>
265 RuntimeURLRequestContextGetter::GetNetworkTaskRunner() const {
266 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
269 net::HostResolver* RuntimeURLRequestContextGetter::host_resolver() {
270 return url_request_context_->host_resolver();