~oxide-developers/oxide/1.2

« back to all changes in this revision

Viewing changes to oxide/browser/oxide_url_request_context.cc

  • Committer: Chris Coulson
  • Date: 2013-07-23 11:40:24 UTC
  • Revision ID: chris.coulson@canonical.com-20130723114024-p7z00cs9p0s5te6e
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// vim:expandtab:shiftwidth=2:tabstop=2:
 
2
// Copyright (C) 2013 Canonical Ltd.
 
3
 
 
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.
 
8
 
 
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.
 
13
 
 
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
 
17
 
 
18
#include "oxide_url_request_context.h"
 
19
 
 
20
#include <algorithm>
 
21
 
 
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"
 
42
 
 
43
#include "common/oxide_constants.h"
 
44
 
 
45
#include "oxide_browser_process_main.h"
 
46
#include "oxide_io_thread_delegate.h"
 
47
 
 
48
namespace {
 
49
 
 
50
class DefaultURLRequestContext FINAL : public net::URLRequestContext {
 
51
 public:
 
52
  DefaultURLRequestContext() :
 
53
      storage_(this) {}
 
54
 
 
55
  class Storage FINAL {
 
56
   public:
 
57
    Storage(DefaultURLRequestContext* owner) :
 
58
        owner_(owner) {}
 
59
 
 
60
    void set_net_log(net::NetLog* net_log) {
 
61
      owner_->set_net_log(net_log);
 
62
    }
 
63
 
 
64
    void set_host_resolver(net::HostResolver* host_resolver) {
 
65
      owner_->set_host_resolver(host_resolver);
 
66
    }
 
67
 
 
68
    void set_cert_verifier(net::CertVerifier* cert_verifier) {
 
69
      owner_->set_cert_verifier(cert_verifier);
 
70
    }
 
71
 
 
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);
 
76
    }
 
77
 
 
78
    void set_fraudulent_certificate_reporter(
 
79
        net::FraudulentCertificateReporter* fraudulent_certificate_reporter) {
 
80
      owner_->set_fraudulent_certificate_reporter(
 
81
          fraudulent_certificate_reporter);
 
82
    }
 
83
 
 
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);
 
87
    }
 
88
 
 
89
    void set_proxy_service(net::ProxyService* proxy_service) {
 
90
      owner_->set_proxy_service(proxy_service);
 
91
    }
 
92
 
 
93
    void set_ssl_config_service(net::SSLConfigService* ssl_config_service) {
 
94
      owner_->set_ssl_config_service(ssl_config_service);
 
95
    }
 
96
 
 
97
    void set_network_delegate(net::NetworkDelegate* network_delegate) {
 
98
      owner_->set_network_delegate(network_delegate);
 
99
    }
 
100
 
 
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);
 
105
    }
 
106
 
 
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);
 
110
    }
 
111
 
 
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);
 
116
    }
 
117
 
 
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);
 
122
    }
 
123
 
 
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);
 
128
    }
 
129
 
 
130
    void set_job_factory(net::URLRequestJobFactory* job_factory) {
 
131
      job_factory_.reset(job_factory);
 
132
      owner_->set_job_factory(job_factory);
 
133
    }
 
134
 
 
135
    void set_throttler_manager(
 
136
        net::URLRequestThrottlerManager* throttler_manager) {
 
137
      owner_->set_throttler_manager(throttler_manager);
 
138
    }
 
139
 
 
140
    net::FtpTransactionFactory* ftp_transaction_factory() const {
 
141
      return ftp_transaction_factory_.get();
 
142
    }
 
143
 
 
144
    void set_ftp_transaction_factory(
 
145
        net::FtpTransactionFactory* ftp_transaction_factory) {
 
146
      ftp_transaction_factory_.reset(ftp_transaction_factory);
 
147
    }
 
148
 
 
149
   private:
 
150
    DefaultURLRequestContext* owner_;
 
151
 
 
152
    // This needs to outlive job_factory_
 
153
    scoped_ptr<net::FtpTransactionFactory> ftp_transaction_factory_;
 
154
 
 
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_;
 
160
  };
 
161
 
 
162
  Storage* storage() { return &storage_; }
 
163
 
 
164
 private:
 
165
  Storage storage_;
 
166
 
 
167
  DISALLOW_COPY_AND_ASSIGN(DefaultURLRequestContext);
 
168
};
 
169
 
 
170
class DefaultURLRequestContextGetter FINAL :
 
171
    public oxide::URLRequestContextGetter {
 
172
 public:
 
173
  DefaultURLRequestContextGetter(
 
174
      content::ProtocolHandlerMap* protocol_handlers,
 
175
      base::FilePath data_path,
 
176
      base::FilePath cache_path,
 
177
      bool is_incognito) :
 
178
      data_path_(data_path),
 
179
      cache_path_(cache_path),
 
180
      is_incognito_(is_incognito) {
 
181
    std::swap(protocol_handlers_, *protocol_handlers);
 
182
  }
 
183
 
 
184
  net::URLRequestContext* GetURLRequestContext() OVERRIDE {
 
185
    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
 
186
 
 
187
    if (!url_request_context_) {
 
188
      DefaultURLRequestContext* context = new DefaultURLRequestContext();
 
189
 
 
190
      oxide::IOThreadDelegate* io_thread_delegate =
 
191
          oxide::BrowserProcessMain::io_thread_delegate();
 
192
 
 
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());
 
210
 
 
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)));
 
217
 
 
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());
 
224
 
 
225
      if (is_incognito_) {
 
226
        context->storage()->set_cookie_store(
 
227
            new net::CookieMonster(NULL, NULL));
 
228
      } else {
 
229
        DCHECK(!data_path_.empty());
 
230
        context->storage()->set_cookie_store(
 
231
            content::CreatePersistentCookieStore(
 
232
                data_path_.Append(oxide::kCookiesFilename),
 
233
                false,
 
234
                NULL,
 
235
                NULL));
 
236
      }
 
237
 
 
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
 
243
 
 
244
      net::HttpCache::BackendFactory* cache_backend = NULL;
 
245
      if (is_incognito_) {
 
246
        cache_backend = net::HttpCache::DefaultBackend::InMemory(0);
 
247
      } else {
 
248
        DCHECK(!cache_path_.empty());
 
249
        cache_backend = new net::HttpCache::DefaultBackend(
 
250
              net::DISK_CACHE,
 
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));
 
256
      }
 
257
 
 
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();
 
273
 
 
274
      context->storage()->set_http_transaction_factory(
 
275
          new net::HttpCache(session_params, cache_backend));
 
276
 
 
277
      net::URLRequestJobFactoryImpl* job_factory =
 
278
          new net::URLRequestJobFactoryImpl();
 
279
      context->storage()->set_job_factory(job_factory);
 
280
 
 
281
      bool set_protocol = false;
 
282
      for (content::ProtocolHandlerMap::iterator it =
 
283
               protocol_handlers_.begin();
 
284
           it != protocol_handlers_.end();
 
285
           ++it) {
 
286
        set_protocol = job_factory->SetProtocolHandler(it->first,
 
287
                                                       it->second.release());
 
288
        DCHECK(set_protocol);
 
289
      }
 
290
 
 
291
      set_protocol = job_factory->SetProtocolHandler(
 
292
          oxide::kFileScheme,
 
293
          new net::FileProtocolHandler());
 
294
      DCHECK(set_protocol);
 
295
      set_protocol = job_factory->SetProtocolHandler(
 
296
          oxide::kDataScheme, new net::DataProtocolHandler());
 
297
      DCHECK(set_protocol);
 
298
 
 
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);
 
305
 
 
306
      protocol_handlers_.clear();
 
307
      data_path_.clear();
 
308
      cache_path_.clear();
 
309
    }
 
310
 
 
311
    return url_request_context_.get();
 
312
  }
 
313
 
 
314
 private:
 
315
  content::ProtocolHandlerMap protocol_handlers_;
 
316
  base::FilePath data_path_;
 
317
  base::FilePath cache_path_;
 
318
  bool is_incognito_;
 
319
 
 
320
  DISALLOW_COPY_AND_ASSIGN(DefaultURLRequestContextGetter);
 
321
};
 
322
 
 
323
}
 
324
 
 
325
namespace oxide {
 
326
 
 
327
URLRequestContextGetter::URLRequestContextGetter() {}
 
328
 
 
329
// static
 
330
URLRequestContextGetter* URLRequestContextGetter::Create(
 
331
    content::ProtocolHandlerMap* protocol_handlers,
 
332
    base::FilePath data_path,
 
333
    base::FilePath cache_path,
 
334
    bool is_incognito) {
 
335
  return new DefaultURLRequestContextGetter(protocol_handlers,
 
336
                                            data_path,
 
337
                                            cache_path,
 
338
                                            is_incognito);
 
339
}
 
340
 
 
341
scoped_refptr<base::SingleThreadTaskRunner>
 
342
URLRequestContextGetter::GetNetworkTaskRunner() const {
 
343
  return content::BrowserThread::GetMessageLoopProxyForThread(
 
344
      content::BrowserThread::IO);
 
345
}
 
346
 
 
347
} // namespace oxide