OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2006-2008 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/net/chrome_url_request_context.h" |
| 6 |
| 7 #include "base/command_line.h" |
| 8 #include "base/string_util.h" |
| 9 #include "chrome/browser/browser_process.h" |
| 10 #include "chrome/browser/chrome_thread.h" |
| 11 #include "chrome/browser/extensions/extensions_service.h" |
| 12 #include "chrome/browser/profile.h" |
| 13 #include "chrome/common/chrome_constants.h" |
| 14 #include "chrome/common/chrome_switches.h" |
| 15 #include "chrome/common/pref_names.h" |
| 16 #include "net/http/http_cache.h" |
| 17 #include "net/proxy/proxy_service.h" |
| 18 #include "webkit/glue/webkit_glue.h" |
| 19 |
| 20 // Sets up proxy info if it was specified, otherwise returns NULL. The |
| 21 // returned pointer MUST be deleted by the caller if non-NULL. |
| 22 static net::ProxyInfo* CreateProxyInfo() { |
| 23 net::ProxyInfo* proxy_info = NULL; |
| 24 |
| 25 CommandLine command_line; |
| 26 if (command_line.HasSwitch(switches::kProxyServer)) { |
| 27 proxy_info = new net::ProxyInfo(); |
| 28 const std::wstring& proxy_server = |
| 29 command_line.GetSwitchValue(switches::kProxyServer); |
| 30 proxy_info->UseNamedProxy(WideToASCII(proxy_server)); |
| 31 } |
| 32 |
| 33 return proxy_info; |
| 34 } |
| 35 |
| 36 // static |
| 37 ChromeURLRequestContext* ChromeURLRequestContext::CreateOriginal( |
| 38 Profile* profile, const std::wstring& cookie_store_path, |
| 39 const std::wstring& disk_cache_path) { |
| 40 DCHECK(!profile->IsOffTheRecord()); |
| 41 ChromeURLRequestContext* context = new ChromeURLRequestContext(profile); |
| 42 |
| 43 scoped_ptr<net::ProxyInfo> proxy_info(CreateProxyInfo()); |
| 44 context->proxy_service_ = net::ProxyService::Create(proxy_info.get()); |
| 45 |
| 46 net::HttpCache* cache = |
| 47 new net::HttpCache(context->proxy_service_, disk_cache_path, 0); |
| 48 |
| 49 CommandLine command_line; |
| 50 bool record_mode = chrome::kRecordModeEnabled && |
| 51 command_line.HasSwitch(switches::kRecordMode); |
| 52 bool playback_mode = command_line.HasSwitch(switches::kPlaybackMode); |
| 53 |
| 54 if (record_mode || playback_mode) { |
| 55 // Don't use existing cookies and use an in-memory store. |
| 56 context->cookie_store_ = new net::CookieMonster(); |
| 57 cache->set_mode( |
| 58 record_mode ? net::HttpCache::RECORD : net::HttpCache::PLAYBACK); |
| 59 } |
| 60 context->http_transaction_factory_ = cache; |
| 61 |
| 62 // setup cookie store |
| 63 if (!context->cookie_store_) { |
| 64 DCHECK(!cookie_store_path.empty()); |
| 65 context->cookie_db_.reset(new SQLitePersistentCookieStore( |
| 66 cookie_store_path, g_browser_process->db_thread()->message_loop())); |
| 67 context->cookie_store_ = new net::CookieMonster(context->cookie_db_.get()); |
| 68 } |
| 69 |
| 70 return context; |
| 71 } |
| 72 |
| 73 // static |
| 74 ChromeURLRequestContext* ChromeURLRequestContext::CreateOffTheRecord( |
| 75 Profile* profile) { |
| 76 DCHECK(profile->IsOffTheRecord()); |
| 77 ChromeURLRequestContext* context = new ChromeURLRequestContext(profile); |
| 78 |
| 79 // Share the same proxy service as the original profile. This proxy |
| 80 // service's lifespan is dependent on the lifespan of the original profile, |
| 81 // which we reference (see above). |
| 82 context->proxy_service_ = |
| 83 profile->GetOriginalProfile()->GetRequestContext()->proxy_service(); |
| 84 |
| 85 context->http_transaction_factory_ = |
| 86 new net::HttpCache(context->proxy_service_, 0); |
| 87 context->cookie_store_ = new net::CookieMonster; |
| 88 |
| 89 return context; |
| 90 } |
| 91 |
| 92 ChromeURLRequestContext::ChromeURLRequestContext(Profile* profile) |
| 93 : prefs_(profile->GetPrefs()), |
| 94 is_off_the_record_(profile->IsOffTheRecord()) { |
| 95 user_agent_ = webkit_glue::GetUserAgent(); |
| 96 |
| 97 // set up Accept-Language and Accept-Charset header values |
| 98 // TODO(jungshik) : This may slow down http requests. Perhaps, |
| 99 // we have to come up with a better way to set up these values. |
| 100 accept_language_ = WideToASCII(prefs_->GetString(prefs::kAcceptLanguages)); |
| 101 accept_charset_ = WideToASCII(prefs_->GetString(prefs::kDefaultCharset)); |
| 102 accept_charset_ += ",*,utf-8"; |
| 103 |
| 104 cookie_policy_.SetType(net::CookiePolicy::FromInt( |
| 105 prefs_->GetInteger(prefs::kCookieBehavior))); |
| 106 |
| 107 const ExtensionList* extensions = |
| 108 profile->GetExtensionsService()->extensions(); |
| 109 for (ExtensionList::const_iterator iter = extensions->begin(); |
| 110 iter != extensions->end(); ++iter) { |
| 111 extension_paths_[(*iter)->id()] = (*iter)->path(); |
| 112 } |
| 113 |
| 114 prefs_->AddPrefObserver(prefs::kAcceptLanguages, this); |
| 115 prefs_->AddPrefObserver(prefs::kCookieBehavior, this); |
| 116 |
| 117 NotificationService::current()->AddObserver( |
| 118 this, NOTIFY_EXTENSIONS_LOADED, NotificationService::AllSources()); |
| 119 } |
| 120 |
| 121 // NotificationObserver implementation. |
| 122 void ChromeURLRequestContext::Observe(NotificationType type, |
| 123 const NotificationSource& source, |
| 124 const NotificationDetails& details) { |
| 125 if (NOTIFY_PREF_CHANGED == type) { |
| 126 std::wstring* pref_name_in = Details<std::wstring>(details).ptr(); |
| 127 PrefService* prefs = Source<PrefService>(source).ptr(); |
| 128 DCHECK(pref_name_in && prefs); |
| 129 if (*pref_name_in == prefs::kAcceptLanguages) { |
| 130 std::string accept_language = |
| 131 WideToASCII(prefs->GetString(prefs::kAcceptLanguages)); |
| 132 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, |
| 133 NewRunnableMethod(this, |
| 134 &ChromeURLRequestContext::OnAcceptLanguageChange, |
| 135 accept_language)); |
| 136 } else if (*pref_name_in == prefs::kCookieBehavior) { |
| 137 net::CookiePolicy::Type type = net::CookiePolicy::FromInt( |
| 138 prefs_->GetInteger(prefs::kCookieBehavior)); |
| 139 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, |
| 140 NewRunnableMethod(this, |
| 141 &ChromeURLRequestContext::OnCookiePolicyChange, |
| 142 type)); |
| 143 } |
| 144 } else if (NOTIFY_EXTENSIONS_LOADED == type) { |
| 145 ExtensionPaths* new_paths = new ExtensionPaths; |
| 146 ExtensionList* extensions = Details<ExtensionList>(details).ptr(); |
| 147 DCHECK(extensions); |
| 148 for (ExtensionList::const_iterator iter = extensions->begin(); |
| 149 iter != extensions->end(); ++iter) { |
| 150 new_paths->insert(ExtensionPaths::value_type((*iter)->id(), |
| 151 (*iter)->path())); |
| 152 } |
| 153 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, |
| 154 NewRunnableMethod(this, &ChromeURLRequestContext::OnNewExtensions, |
| 155 new_paths)); |
| 156 } else { |
| 157 NOTREACHED(); |
| 158 } |
| 159 } |
| 160 |
| 161 void ChromeURLRequestContext::CleanupOnUIThread() { |
| 162 // Unregister for pref notifications. |
| 163 prefs_->RemovePrefObserver(prefs::kAcceptLanguages, this); |
| 164 prefs_->RemovePrefObserver(prefs::kCookieBehavior, this); |
| 165 prefs_ = NULL; |
| 166 |
| 167 NotificationService::current()->RemoveObserver( |
| 168 this, NOTIFY_EXTENSIONS_LOADED, NotificationService::AllSources()); |
| 169 } |
| 170 |
| 171 FilePath ChromeURLRequestContext::GetPathForExtension(const std::string& id) { |
| 172 ExtensionPaths::iterator iter = extension_paths_.find(id); |
| 173 if (iter != extension_paths_.end()) { |
| 174 return iter->second; |
| 175 } else { |
| 176 return FilePath(); |
| 177 } |
| 178 } |
| 179 |
| 180 void ChromeURLRequestContext::OnAcceptLanguageChange(std::string accept_language
) { |
| 181 DCHECK(MessageLoop::current() == |
| 182 ChromeThread::GetMessageLoop(ChromeThread::IO)); |
| 183 accept_language_ = accept_language; |
| 184 } |
| 185 |
| 186 void ChromeURLRequestContext::OnCookiePolicyChange(net::CookiePolicy::Type type)
{ |
| 187 DCHECK(MessageLoop::current() == |
| 188 ChromeThread::GetMessageLoop(ChromeThread::IO)); |
| 189 cookie_policy_.SetType(type); |
| 190 } |
| 191 |
| 192 void ChromeURLRequestContext::OnNewExtensions(ExtensionPaths* new_paths) { |
| 193 extension_paths_.insert(new_paths->begin(), new_paths->end()); |
| 194 delete new_paths; |
| 195 } |
| 196 |
| 197 ChromeURLRequestContext::~ChromeURLRequestContext() { |
| 198 DCHECK(NULL == prefs_); |
| 199 |
| 200 NotificationService::current()->Notify(NOTIFY_URL_REQUEST_CONTEXT_RELEASED, |
| 201 Source<URLRequestContext>(this), |
| 202 NotificationService::NoDetails()); |
| 203 |
| 204 delete cookie_store_; |
| 205 delete http_transaction_factory_; |
| 206 |
| 207 // Do not delete the proxy service in the case of OTR, as it is owned by the |
| 208 // original URLRequestContext. |
| 209 if (!is_off_the_record_) |
| 210 delete proxy_service_; |
| 211 } |
OLD | NEW |