Home | History | Annotate | Download | only in profiles
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/profiles/off_the_record_profile_io_data.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/stl_util-inl.h"
      9 #include "build/build_config.h"
     10 #include "chrome/browser/browser_process.h"
     11 #include "chrome/browser/io_thread.h"
     12 #include "chrome/browser/net/chrome_net_log.h"
     13 #include "chrome/browser/net/chrome_network_delegate.h"
     14 #include "chrome/browser/net/chrome_url_request_context.h"
     15 #include "chrome/common/extensions/extension.h"
     16 #include "chrome/common/url_constants.h"
     17 #include "content/browser/browser_thread.h"
     18 #include "content/browser/resource_context.h"
     19 #include "net/ftp/ftp_network_layer.h"
     20 #include "net/http/http_cache.h"
     21 #include "webkit/database/database_tracker.h"
     22 
     23 OffTheRecordProfileIOData::Handle::Handle(Profile* profile)
     24     : io_data_(new OffTheRecordProfileIOData),
     25       profile_(profile),
     26       initialized_(false) {
     27   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     28   DCHECK(profile);
     29 }
     30 
     31 OffTheRecordProfileIOData::Handle::~Handle() {
     32   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     33   if (main_request_context_getter_)
     34     main_request_context_getter_->CleanupOnUIThread();
     35   if (extensions_request_context_getter_)
     36     extensions_request_context_getter_->CleanupOnUIThread();
     37 
     38   // Clean up all isolated app request contexts.
     39   for (ChromeURLRequestContextGetterMap::iterator iter =
     40            app_request_context_getter_map_.begin();
     41        iter != app_request_context_getter_map_.end();
     42        ++iter) {
     43     iter->second->CleanupOnUIThread();
     44   }
     45 
     46   io_data_->ShutdownOnUIThread();
     47 }
     48 
     49 const content::ResourceContext&
     50 OffTheRecordProfileIOData::Handle::GetResourceContext() const {
     51   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     52   LazyInitialize();
     53   return io_data_->GetResourceContext();
     54 }
     55 
     56 scoped_refptr<ChromeURLRequestContextGetter>
     57 OffTheRecordProfileIOData::Handle::GetMainRequestContextGetter() const {
     58   // TODO(oshima): Re-enable when ChromeOS only accesses the profile on the UI
     59   // thread.
     60 #if !defined(OS_CHROMEOS)
     61   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     62 #endif  // defined(OS_CHROMEOS)
     63   LazyInitialize();
     64   if (!main_request_context_getter_) {
     65     main_request_context_getter_ =
     66         ChromeURLRequestContextGetter::CreateOffTheRecord(profile_, io_data_);
     67   }
     68   return main_request_context_getter_;
     69 }
     70 
     71 scoped_refptr<ChromeURLRequestContextGetter>
     72 OffTheRecordProfileIOData::Handle::GetExtensionsRequestContextGetter() const {
     73   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     74   LazyInitialize();
     75   if (!extensions_request_context_getter_) {
     76     extensions_request_context_getter_ =
     77         ChromeURLRequestContextGetter::CreateOffTheRecordForExtensions(
     78             profile_, io_data_);
     79   }
     80   return extensions_request_context_getter_;
     81 }
     82 
     83 scoped_refptr<ChromeURLRequestContextGetter>
     84 OffTheRecordProfileIOData::Handle::GetIsolatedAppRequestContextGetter(
     85     const std::string& app_id) const {
     86   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     87   DCHECK(!app_id.empty());
     88   LazyInitialize();
     89 
     90   // Keep a map of request context getters, one per requested app ID.
     91   ChromeURLRequestContextGetterMap::iterator iter =
     92       app_request_context_getter_map_.find(app_id);
     93   if (iter != app_request_context_getter_map_.end())
     94     return iter->second;
     95 
     96   ChromeURLRequestContextGetter* context =
     97       ChromeURLRequestContextGetter::CreateOffTheRecordForIsolatedApp(
     98           profile_, io_data_, app_id);
     99   app_request_context_getter_map_[app_id] = context;
    100 
    101   return context;
    102 }
    103 
    104 void OffTheRecordProfileIOData::Handle::LazyInitialize() const {
    105   if (!initialized_) {
    106     io_data_->InitializeProfileParams(profile_);
    107     ChromeNetworkDelegate::InitializeReferrersEnabled(
    108         io_data_->enable_referrers(), profile_->GetPrefs());
    109     initialized_ = true;
    110   }
    111 }
    112 
    113 OffTheRecordProfileIOData::OffTheRecordProfileIOData()
    114     : ProfileIOData(true) {}
    115 OffTheRecordProfileIOData::~OffTheRecordProfileIOData() {
    116   STLDeleteValues(&app_http_factory_map_);
    117 }
    118 
    119 void OffTheRecordProfileIOData::LazyInitializeInternal(
    120     ProfileParams* profile_params) const {
    121   ChromeURLRequestContext* main_context = main_request_context();
    122   ChromeURLRequestContext* extensions_context = extensions_request_context();
    123 
    124   IOThread* const io_thread = profile_params->io_thread;
    125   IOThread::Globals* const io_thread_globals = io_thread->globals();
    126 
    127   ApplyProfileParamsToContext(main_context);
    128   ApplyProfileParamsToContext(extensions_context);
    129 
    130   main_context->set_cookie_policy(cookie_policy());
    131   extensions_context->set_cookie_policy(cookie_policy());
    132 
    133   main_context->set_net_log(io_thread->net_log());
    134   extensions_context->set_net_log(io_thread->net_log());
    135 
    136   main_context->set_network_delegate(network_delegate());
    137 
    138   main_context->set_host_resolver(
    139       io_thread_globals->host_resolver.get());
    140   main_context->set_cert_verifier(
    141       io_thread_globals->cert_verifier.get());
    142   main_context->set_dnsrr_resolver(
    143       io_thread_globals->dnsrr_resolver.get());
    144   main_context->set_http_auth_handler_factory(
    145       io_thread_globals->http_auth_handler_factory.get());
    146   main_context->set_dns_cert_checker(dns_cert_checker());
    147   main_context->set_proxy_service(proxy_service());
    148 
    149   main_context->set_cookie_store(
    150       new net::CookieMonster(NULL, profile_params->cookie_monster_delegate));
    151   // All we care about for extensions is the cookie store. For incognito, we
    152   // use a non-persistent cookie store.
    153 
    154   net::CookieMonster* extensions_cookie_store =
    155       new net::CookieMonster(NULL, NULL);
    156   // Enable cookies for devtools and extension URLs.
    157   const char* schemes[] = {chrome::kChromeDevToolsScheme,
    158                            chrome::kExtensionScheme};
    159   extensions_cookie_store->SetCookieableSchemes(schemes, 2);
    160 
    161   extensions_context->set_cookie_store(
    162       new net::CookieMonster(NULL, NULL));
    163 
    164   net::HttpCache::BackendFactory* main_backend =
    165       net::HttpCache::DefaultBackend::InMemory(0);
    166   net::HttpCache* cache =
    167       new net::HttpCache(main_context->host_resolver(),
    168                          main_context->cert_verifier(),
    169                          main_context->dnsrr_resolver(),
    170                          main_context->dns_cert_checker(),
    171                          main_context->proxy_service(),
    172                          main_context->ssl_config_service(),
    173                          main_context->http_auth_handler_factory(),
    174                          main_context->network_delegate(),
    175                          main_context->net_log(),
    176                          main_backend);
    177 
    178   main_http_factory_.reset(cache);
    179   main_context->set_http_transaction_factory(cache);
    180   main_context->set_ftp_transaction_factory(
    181       new net::FtpNetworkLayer(main_context->host_resolver()));
    182 }
    183 
    184 scoped_refptr<ProfileIOData::RequestContext>
    185 OffTheRecordProfileIOData::InitializeAppRequestContext(
    186     scoped_refptr<ChromeURLRequestContext> main_context,
    187     const std::string& app_id) const {
    188   scoped_refptr<ProfileIOData::RequestContext> context = new RequestContext;
    189 
    190   // Copy most state from the main context.
    191   context->CopyFrom(main_context);
    192 
    193   // Use a separate in-memory cookie store for the app.
    194   // TODO(creis): We should have a cookie delegate for notifying the cookie
    195   // extensions API, but we need to update it to understand isolated apps first.
    196   context->set_cookie_store(
    197       new net::CookieMonster(NULL, NULL));
    198 
    199   // Use a separate in-memory cache for the app.
    200   net::HttpCache::BackendFactory* app_backend =
    201       net::HttpCache::DefaultBackend::InMemory(0);
    202   net::HttpNetworkSession* main_network_session =
    203       main_http_factory_->GetSession();
    204   net::HttpCache* app_http_cache =
    205       new net::HttpCache(main_network_session, app_backend);
    206 
    207   // Keep track of app_http_cache to delete it when we go away.
    208   DCHECK(!app_http_factory_map_[app_id]);
    209   app_http_factory_map_[app_id] = app_http_cache;
    210   context->set_http_transaction_factory(app_http_cache);
    211 
    212   return context;
    213 }
    214 
    215 scoped_refptr<ChromeURLRequestContext>
    216 OffTheRecordProfileIOData::AcquireMediaRequestContext() const {
    217   NOTREACHED();
    218   return NULL;
    219 }
    220 
    221 scoped_refptr<ChromeURLRequestContext>
    222 OffTheRecordProfileIOData::AcquireIsolatedAppRequestContext(
    223     scoped_refptr<ChromeURLRequestContext> main_context,
    224     const std::string& app_id) const {
    225   // We create per-app contexts on demand, unlike the others above.
    226   scoped_refptr<RequestContext> app_request_context =
    227       InitializeAppRequestContext(main_context, app_id);
    228   DCHECK(app_request_context);
    229   app_request_context->set_profile_io_data(this);
    230   return app_request_context;
    231 }
    232