1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Copyright 2014 Samsung Electronics. 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 "url_request_context_getter_efl.h"
8 #include "base/command_line.h"
9 #include "base/file_util.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/threading/worker_pool.h"
12 #include "base/threading/sequenced_worker_pool.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/cookie_store_factory.h"
15 #include "content/public/common/content_switches.h"
16 #include "content/public/common/url_constants.h"
17 #include "content/browser/net/sqlite_persistent_cookie_store.h"
18 #include "net/base/cache_type.h"
19 #include "net/cert/cert_verifier.h"
20 #include "net/dns/host_resolver.h"
21 #include "net/dns/mapped_host_resolver.h"
22 #include "net/http/http_auth_handler_factory.h"
23 #include "net/http/http_cache.h"
24 #include "net/http/http_server_properties_impl.h"
25 #include "net/proxy/proxy_service.h"
26 #include "net/ssl/default_server_bound_cert_store.h"
27 #include "net/ssl/server_bound_cert_service.h"
28 #include "net/ssl/ssl_config_service_defaults.h"
29 #include "net/url_request/data_protocol_handler.h"
30 #include "net/url_request/file_protocol_handler.h"
31 #include "net/url_request/static_http_user_agent_settings.h"
32 #include "net/url_request/url_request_context_storage.h"
33 #include "net/url_request/url_request_intercepting_job_factory.h"
34 #include "net/url_request/url_request_job_factory_impl.h"
35 #include "network_delegate_efl.h"
36 #include "eweb_context.h"
43 void InstallProtocolHandlers(net::URLRequestJobFactoryImpl* job_factory,
44 ProtocolHandlerMap* protocol_handlers) {
45 for (ProtocolHandlerMap::iterator it =
46 protocol_handlers->begin();
47 it != protocol_handlers->end();
49 bool set_protocol = job_factory->SetProtocolHandler(
50 it->first, it->second.release());
53 protocol_handlers->clear();
58 URLRequestContextGetterEfl::URLRequestContextGetterEfl(
59 EWebContext& web_context,
60 bool ignore_certificate_errors,
61 const base::FilePath& base_path,
62 base::MessageLoop* io_loop,
63 base::MessageLoop* file_loop,
64 ProtocolHandlerMap* protocol_handlers,
65 URLRequestInterceptorScopedVector request_interceptors,
67 : web_context_(web_context),
68 ignore_certificate_errors_(ignore_certificate_errors),
69 base_path_(base_path),
71 file_loop_(file_loop),
72 request_interceptors_(request_interceptors.Pass()),
74 // Must first be created on the UI thread.
75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
77 if (protocol_handlers)
78 std::swap(protocol_handlers_, *protocol_handlers);
80 proxy_config_service_.reset(
81 net::ProxyService::CreateSystemProxyConfigService(
82 io_loop_->message_loop_proxy().get(), file_loop_));
85 URLRequestContextGetterEfl::~URLRequestContextGetterEfl() {
88 net::URLRequestContext* URLRequestContextGetterEfl::GetURLRequestContext() {
89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
91 if (!url_request_context_) {
92 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
94 url_request_context_.reset(new net::URLRequestContext());
96 url_request_context_->set_net_log(net_log_);
98 network_delegate_.reset(new net::NetworkDelegateEfl(*(web_context_.cookieManager())));
100 url_request_context_->set_network_delegate(network_delegate_.get());
102 new net::URLRequestContextStorage(url_request_context_.get()));
103 storage_->set_cookie_store(
104 CreateCookieStore(CookieStoreConfig()));
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", std::string()));
111 scoped_ptr<net::HostResolver> host_resolver(
112 net::HostResolver::CreateDefaultResolver(
113 url_request_context_->net_log()));
115 storage_->set_cert_verifier(net::CertVerifier::CreateDefault());
116 storage_->set_transport_security_state(new net::TransportSecurityState);
118 // TODO(jam): use v8 if possible, look at chrome code.
119 storage_->set_proxy_service(
120 net::ProxyService::CreateUsingSystemProxyResolver(
121 proxy_config_service_.release(),
123 url_request_context_->net_log()));
125 storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults);
126 storage_->set_http_auth_handler_factory(
127 net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
128 storage_->set_http_server_properties(
129 scoped_ptr<net::HttpServerProperties>(
130 new net::HttpServerPropertiesImpl()));
132 base::FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache"));
133 net::HttpCache::DefaultBackend* main_backend =
134 new net::HttpCache::DefaultBackend(
136 net::CACHE_BACKEND_DEFAULT,
139 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)
142 net::HttpNetworkSession::Params network_session_params;
143 network_session_params.cert_verifier =
144 url_request_context_->cert_verifier();
145 network_session_params.transport_security_state =
146 url_request_context_->transport_security_state();
147 network_session_params.server_bound_cert_service =
148 url_request_context_->server_bound_cert_service();
149 network_session_params.proxy_service =
150 url_request_context_->proxy_service();
151 network_session_params.ssl_config_service =
152 url_request_context_->ssl_config_service();
153 network_session_params.http_auth_handler_factory =
154 url_request_context_->http_auth_handler_factory();
155 network_session_params.network_delegate =
156 network_delegate_.get();
157 network_session_params.http_server_properties =
158 url_request_context_->http_server_properties();
159 network_session_params.net_log =
160 url_request_context_->net_log();
161 network_session_params.ignore_certificate_errors =
162 ignore_certificate_errors_;
163 if (command_line.HasSwitch(switches::kTestingFixedHttpPort)) {
165 base::StringToInt(command_line.GetSwitchValueASCII(
166 switches::kTestingFixedHttpPort), &value);
167 network_session_params.testing_fixed_http_port = value;
169 if (command_line.HasSwitch(switches::kTestingFixedHttpsPort)) {
171 base::StringToInt(command_line.GetSwitchValueASCII(
172 switches::kTestingFixedHttpsPort), &value);
173 network_session_params.testing_fixed_https_port = value;
175 if (command_line.HasSwitch(switches::kHostResolverRules)) {
176 scoped_ptr<net::MappedHostResolver> mapped_host_resolver(
177 new net::MappedHostResolver(host_resolver.Pass()));
178 mapped_host_resolver->SetRulesFromString(
179 command_line.GetSwitchValueASCII(switches::kHostResolverRules));
180 host_resolver = mapped_host_resolver.Pass();
183 // Give |storage_| ownership at the end in case it's |mapped_host_resolver|.
184 storage_->set_host_resolver(host_resolver.Pass());
185 network_session_params.host_resolver =
186 url_request_context_->host_resolver();
188 net::HttpCache* main_cache = new net::HttpCache(
189 network_session_params, main_backend);
190 storage_->set_http_transaction_factory(main_cache);
192 scoped_ptr<net::URLRequestJobFactoryImpl> job_factory(
193 new net::URLRequestJobFactoryImpl());
194 // Keep ProtocolHandlers added in sync with
195 // ShellContentBrowserClient::IsHandledURL().
196 InstallProtocolHandlers(job_factory.get(), &protocol_handlers_);
197 bool set_protocol = job_factory->SetProtocolHandler(
198 url::kDataScheme, new net::DataProtocolHandler);
199 DCHECK(set_protocol);
200 set_protocol = job_factory->SetProtocolHandler(
202 new net::FileProtocolHandler(
203 BrowserThread::GetBlockingPool()->
204 GetTaskRunnerWithShutdownBehavior(
205 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
206 DCHECK(set_protocol);
208 // Set up interceptors in the reverse order.
209 scoped_ptr<net::URLRequestJobFactory> top_job_factory =
210 job_factory.PassAs<net::URLRequestJobFactory>();
211 for (URLRequestInterceptorScopedVector::reverse_iterator i =
212 request_interceptors_.rbegin();
213 i != request_interceptors_.rend();
215 top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
216 top_job_factory.Pass(), make_scoped_ptr(*i)));
218 request_interceptors_.weak_clear();
220 storage_->set_job_factory(top_job_factory.release());
223 return url_request_context_.get();
226 scoped_refptr<base::SingleThreadTaskRunner>
227 URLRequestContextGetterEfl::GetNetworkTaskRunner() const {
228 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
231 net::HostResolver* URLRequestContextGetterEfl::host_resolver() {
232 return url_request_context_->host_resolver();
235 void URLRequestContextGetterEfl::SetCookieStoragePath(
236 const base::FilePath& path,
237 bool persist_session_cookies,
240 if (url_request_context_->cookie_store() &&
241 (cookie_store_path_ == path)) {
242 // The path has not changed so don't do anything.
246 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
247 BrowserThread::PostTask(
248 BrowserThread::IO, FROM_HERE,
249 base::Bind(&URLRequestContextGetterEfl::SetCookieStoragePath,
250 this, path, persist_session_cookies, file_storage));
254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
256 CreateSQLitePersistentCookieStore(path, persist_session_cookies);
258 CreatePersistentCookieStore(path, persist_session_cookies);
262 void URLRequestContextGetterEfl::CreateSQLitePersistentCookieStore(
263 const base::FilePath& path,
264 bool persist_session_cookies)
266 using content::CookieStoreConfig;
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
268 scoped_refptr<SQLitePersistentCookieStore> persistent_store;
272 base::ThreadRestrictions::ScopedAllowIO allow_io;
273 if (base::DirectoryExists(path) ||
274 base::CreateDirectory(path)) {
275 const base::FilePath& cookie_path = path.AppendASCII("Cookies");
277 new SQLitePersistentCookieStore(
279 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
280 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
281 persist_session_cookies, NULL, NULL);
283 NOTREACHED() << "The cookie storage directory could not be created";
286 // Set the new cookie store that will be used for all new requests. The old
287 // cookie store, if any, will be automatically flushed and closed when no
288 // longer referenced.
289 scoped_refptr<net::CookieMonster> cookie_monster =
290 new net::CookieMonster(persistent_store.get(), NULL);
291 storage_->set_cookie_store(cookie_monster);
293 if (persistent_store.get() && persist_session_cookies)
294 cookie_monster->SetPersistSessionCookies(true);
296 cookie_store_path_ = path;
299 void URLRequestContextGetterEfl::CreatePersistentCookieStore(const base::FilePath& path,
300 bool persist_session_cookies)
302 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
303 cookie_store_path_ = path;
305 CookieStoreConfig config(
306 cookie_store_path_.Append(FILE_PATH_LITERAL("Cookies")),
307 CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
310 cookie_store_= CreateCookieStore(config);
311 cookie_store_->GetCookieMonster()->SetPersistSessionCookies(persist_session_cookies);
312 DCHECK(url_request_context_);
313 url_request_context_->set_cookie_store(cookie_store_.get());
316 }; // namespace content