1
// vim:expandtab:shiftwidth=2:tabstop=2:
2
// Copyright (C) 2013 Canonical Ltd.
4
// This library is free software; you can redistribute it and/or
5
// modify it under the terms of the GNU Lesser General Public
6
// License as published by the Free Software Foundation; either
7
// version 2.1 of the License, or (at your option) any later version.
9
// This library is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
// Lesser General Public License for more details.
14
// You should have received a copy of the GNU Lesser General Public
15
// License along with this library; if not, write to the Free Software
16
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
#include "oxide_url_request_context.h"
22
#include "base/files/file_path.h"
23
#include "base/logging.h"
24
#include "base/threading/worker_pool.h"
25
#include "content/public/browser/browser_thread.h"
26
#include "content/public/browser/cookie_store_factory.h"
27
#include "net/base/cache_type.h"
28
#include "net/cookies/cookie_monster.h"
29
#include "net/ftp/ftp_network_layer.h"
30
#include "net/http/http_cache.h"
31
#include "net/http/http_network_session.h"
32
#include "net/http/http_server_properties_impl.h"
33
#include "net/http/transport_security_state.h"
34
#include "net/ssl/default_server_bound_cert_store.h"
35
#include "net/ssl/server_bound_cert_service.h"
36
#include "net/ssl/server_bound_cert_store.h"
37
#include "net/url_request/data_protocol_handler.h"
38
#include "net/url_request/file_protocol_handler.h"
39
#include "net/url_request/ftp_protocol_handler.h"
40
#include "net/url_request/url_request_context.h"
41
#include "net/url_request/url_request_job_factory_impl.h"
43
#include "common/oxide_constants.h"
45
#include "oxide_browser_process_main.h"
46
#include "oxide_io_thread_delegate.h"
50
class DefaultURLRequestContext FINAL : public net::URLRequestContext {
52
DefaultURLRequestContext() :
57
Storage(DefaultURLRequestContext* owner) :
60
void set_net_log(net::NetLog* net_log) {
61
owner_->set_net_log(net_log);
64
void set_host_resolver(net::HostResolver* host_resolver) {
65
owner_->set_host_resolver(host_resolver);
68
void set_cert_verifier(net::CertVerifier* cert_verifier) {
69
owner_->set_cert_verifier(cert_verifier);
72
void set_server_bound_cert_service(
73
net::ServerBoundCertService* server_bound_cert_service) {
74
server_bound_cert_service_.reset(server_bound_cert_service);
75
owner_->set_server_bound_cert_service(server_bound_cert_service);
78
void set_fraudulent_certificate_reporter(
79
net::FraudulentCertificateReporter* fraudulent_certificate_reporter) {
80
owner_->set_fraudulent_certificate_reporter(
81
fraudulent_certificate_reporter);
84
void set_http_auth_handler_factory(
85
net::HttpAuthHandlerFactory* http_auth_handler_factory) {
86
owner_->set_http_auth_handler_factory(http_auth_handler_factory);
89
void set_proxy_service(net::ProxyService* proxy_service) {
90
owner_->set_proxy_service(proxy_service);
93
void set_ssl_config_service(net::SSLConfigService* ssl_config_service) {
94
owner_->set_ssl_config_service(ssl_config_service);
97
void set_network_delegate(net::NetworkDelegate* network_delegate) {
98
owner_->set_network_delegate(network_delegate);
101
void set_http_server_properties(
102
net::HttpServerProperties* http_server_properties) {
103
http_server_properties_.reset(http_server_properties);
104
owner_->set_http_server_properties(http_server_properties);
107
void set_http_user_agent_settings(
108
net::HttpUserAgentSettings* http_user_agent_settings) {
109
owner_->set_http_user_agent_settings(http_user_agent_settings);
112
void set_cookie_store(net::CookieStore* cookie_store) {
113
// We hold a strong reference to this, but net::URLRequestContext
114
// already has a scoped_refptr
115
owner_->set_cookie_store(cookie_store);
118
void set_transport_security_state(
119
net::TransportSecurityState* transport_security_state) {
120
transport_security_state_.reset(transport_security_state);
121
owner_->set_transport_security_state(transport_security_state);
124
void set_http_transaction_factory(
125
net::HttpTransactionFactory* http_transaction_factory) {
126
http_transaction_factory_.reset(http_transaction_factory);
127
owner_->set_http_transaction_factory(http_transaction_factory);
130
void set_job_factory(net::URLRequestJobFactory* job_factory) {
131
job_factory_.reset(job_factory);
132
owner_->set_job_factory(job_factory);
135
void set_throttler_manager(
136
net::URLRequestThrottlerManager* throttler_manager) {
137
owner_->set_throttler_manager(throttler_manager);
140
net::FtpTransactionFactory* ftp_transaction_factory() const {
141
return ftp_transaction_factory_.get();
144
void set_ftp_transaction_factory(
145
net::FtpTransactionFactory* ftp_transaction_factory) {
146
ftp_transaction_factory_.reset(ftp_transaction_factory);
150
DefaultURLRequestContext* owner_;
152
// This needs to outlive job_factory_
153
scoped_ptr<net::FtpTransactionFactory> ftp_transaction_factory_;
155
scoped_ptr<net::ServerBoundCertService> server_bound_cert_service_;
156
scoped_ptr<net::HttpServerProperties> http_server_properties_;
157
scoped_ptr<net::TransportSecurityState> transport_security_state_;
158
scoped_ptr<net::HttpTransactionFactory> http_transaction_factory_;
159
scoped_ptr<net::URLRequestJobFactory> job_factory_;
162
Storage* storage() { return &storage_; }
167
DISALLOW_COPY_AND_ASSIGN(DefaultURLRequestContext);
170
class DefaultURLRequestContextGetter FINAL :
171
public oxide::URLRequestContextGetter {
173
DefaultURLRequestContextGetter(
174
content::ProtocolHandlerMap* protocol_handlers,
175
base::FilePath data_path,
176
base::FilePath cache_path,
178
data_path_(data_path),
179
cache_path_(cache_path),
180
is_incognito_(is_incognito) {
181
std::swap(protocol_handlers_, *protocol_handlers);
184
net::URLRequestContext* GetURLRequestContext() OVERRIDE {
185
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
187
if (!url_request_context_) {
188
DefaultURLRequestContext* context = new DefaultURLRequestContext();
190
oxide::IOThreadDelegate* io_thread_delegate =
191
oxide::BrowserProcessMain::io_thread_delegate();
193
context->storage()->set_net_log(io_thread_delegate->net_log());
194
context->storage()->set_host_resolver(
195
io_thread_delegate->host_resolver());
196
context->storage()->set_cert_verifier(
197
io_thread_delegate->cert_verifier());
198
context->storage()->set_http_auth_handler_factory(
199
io_thread_delegate->http_auth_handler_factory());
200
context->storage()->set_proxy_service(
201
io_thread_delegate->proxy_service());
202
context->storage()->set_ssl_config_service(
203
io_thread_delegate->ssl_config_service());
204
context->storage()->set_network_delegate(
205
io_thread_delegate->network_delegate());
206
context->storage()->set_http_user_agent_settings(
207
io_thread_delegate->http_user_agent_settings());
208
context->storage()->set_throttler_manager(
209
io_thread_delegate->throttler_manager());
211
// TODO: We want persistent storage here (for non-incognito), but
212
// SQLiteServerBoundCertStore is part of chrome
213
context->storage()->set_server_bound_cert_service(
214
new net::ServerBoundCertService(
215
new net::DefaultServerBoundCertStore(NULL),
216
base::WorkerPool::GetTaskRunner(true)));
218
// TODO: We want persistent storage here (for non-incognito), but the
219
// persistent implementation used in Chrome uses the preferences
220
// system, which we don't want. We need our own implementation,
221
// backed either by sqlite or a text file
222
context->storage()->set_http_server_properties(
223
new net::HttpServerPropertiesImpl());
226
context->storage()->set_cookie_store(
227
new net::CookieMonster(NULL, NULL));
229
DCHECK(!data_path_.empty());
230
context->storage()->set_cookie_store(
231
content::CreatePersistentCookieStore(
232
data_path_.Append(oxide::kCookiesFilename),
238
context->storage()->set_transport_security_state(
239
new net::TransportSecurityState());
240
// TODO: Need to implement net::TransportSecurityState::Delegate in order
241
// to have persistence for non-incognito mode. There is an
242
// implementation in Chrome which is backed by a json file
244
net::HttpCache::BackendFactory* cache_backend = NULL;
246
cache_backend = net::HttpCache::DefaultBackend::InMemory(0);
248
DCHECK(!cache_path_.empty());
249
cache_backend = new net::HttpCache::DefaultBackend(
251
net::CACHE_BACKEND_DEFAULT,
252
cache_path_.Append(oxide::kCacheDirname),
253
0, // Use the default max size
254
content::BrowserThread::GetMessageLoopProxyForThread(
255
content::BrowserThread::CACHE));
258
net::HttpNetworkSession::Params session_params;
259
session_params.host_resolver = context->host_resolver();
260
session_params.cert_verifier = context->cert_verifier();
261
session_params.server_bound_cert_service =
262
context->server_bound_cert_service();
263
session_params.transport_security_state =
264
context->transport_security_state();
265
session_params.proxy_service = context->proxy_service();
266
session_params.ssl_config_service = context->ssl_config_service();
267
session_params.http_auth_handler_factory =
268
context->http_auth_handler_factory();
269
session_params.network_delegate = context->network_delegate();
270
session_params.http_server_properties =
271
context->http_server_properties();
272
session_params.net_log = context->net_log();
274
context->storage()->set_http_transaction_factory(
275
new net::HttpCache(session_params, cache_backend));
277
net::URLRequestJobFactoryImpl* job_factory =
278
new net::URLRequestJobFactoryImpl();
279
context->storage()->set_job_factory(job_factory);
281
bool set_protocol = false;
282
for (content::ProtocolHandlerMap::iterator it =
283
protocol_handlers_.begin();
284
it != protocol_handlers_.end();
286
set_protocol = job_factory->SetProtocolHandler(it->first,
287
it->second.release());
288
DCHECK(set_protocol);
291
set_protocol = job_factory->SetProtocolHandler(
293
new net::FileProtocolHandler());
294
DCHECK(set_protocol);
295
set_protocol = job_factory->SetProtocolHandler(
296
oxide::kDataScheme, new net::DataProtocolHandler());
297
DCHECK(set_protocol);
299
context->storage()->set_ftp_transaction_factory(
300
new net::FtpNetworkLayer(context->host_resolver()));
301
set_protocol = job_factory->SetProtocolHandler(
302
oxide::kFtpScheme, new net::FtpProtocolHandler(
303
context->storage()->ftp_transaction_factory()));
304
DCHECK(set_protocol);
306
protocol_handlers_.clear();
311
return url_request_context_.get();
315
content::ProtocolHandlerMap protocol_handlers_;
316
base::FilePath data_path_;
317
base::FilePath cache_path_;
320
DISALLOW_COPY_AND_ASSIGN(DefaultURLRequestContextGetter);
327
URLRequestContextGetter::URLRequestContextGetter() {}
330
URLRequestContextGetter* URLRequestContextGetter::Create(
331
content::ProtocolHandlerMap* protocol_handlers,
332
base::FilePath data_path,
333
base::FilePath cache_path,
335
return new DefaultURLRequestContextGetter(protocol_handlers,
341
scoped_refptr<base::SingleThreadTaskRunner>
342
URLRequestContextGetter::GetNetworkTaskRunner() const {
343
return content::BrowserThread::GetMessageLoopProxyForThread(
344
content::BrowserThread::IO);