Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Side by Side Diff: chrome/browser/extensions/extension_cookies_api.cc

Issue 2845031: Reland r50296 which removes some uses of CookieMonster on the UI thread. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Get rid of spurious whitespace. Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Implements the Chrome Extensions Cookies API. 5 // Implements the Chrome Extensions Cookies API.
6 6
7 #include "chrome/browser/extensions/extension_cookies_api.h" 7 #include "chrome/browser/extensions/extension_cookies_api.h"
8 8
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/task.h"
10 #include "chrome/browser/browser_list.h" 11 #include "chrome/browser/browser_list.h"
12 #include "chrome/browser/chrome_thread.h"
11 #include "chrome/browser/extensions/extension_cookies_api_constants.h" 13 #include "chrome/browser/extensions/extension_cookies_api_constants.h"
12 #include "chrome/browser/extensions/extension_cookies_helpers.h" 14 #include "chrome/browser/extensions/extension_cookies_helpers.h"
13 #include "chrome/browser/extensions/extension_message_service.h" 15 #include "chrome/browser/extensions/extension_message_service.h"
14 #include "chrome/browser/profile.h" 16 #include "chrome/browser/profile.h"
15 #include "chrome/common/extensions/extension_error_utils.h" 17 #include "chrome/common/extensions/extension_error_utils.h"
16 #include "chrome/common/net/url_request_context_getter.h" 18 #include "chrome/common/net/url_request_context_getter.h"
17 #include "chrome/common/notification_type.h" 19 #include "chrome/common/notification_type.h"
18 #include "chrome/common/notification_service.h" 20 #include "chrome/common/notification_service.h"
19 #include "net/base/cookie_monster.h" 21 #include "net/base/cookie_monster.h"
20 22
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 // Check against host permissions if needed. 94 // Check against host permissions if needed.
93 if (check_host_permissions && 95 if (check_host_permissions &&
94 !GetExtension()->HasHostPermission(*url)) { 96 !GetExtension()->HasHostPermission(*url)) {
95 error_ = ExtensionErrorUtils::FormatErrorMessage( 97 error_ = ExtensionErrorUtils::FormatErrorMessage(
96 keys::kNoHostPermissionsError, url->spec()); 98 keys::kNoHostPermissionsError, url->spec());
97 return false; 99 return false;
98 } 100 }
99 return true; 101 return true;
100 } 102 }
101 103
102 bool CookiesFunction::ParseCookieStore(const DictionaryValue* details, 104 bool CookiesFunction::ParseStoreContext(const DictionaryValue* details,
103 net::CookieStore** store, 105 URLRequestContextGetter** context,
104 std::string* store_id) { 106 std::string* store_id) {
105 DCHECK(details && (store || store_id)); 107 DCHECK(details && (context || store_id));
106 Profile* store_profile = NULL; 108 Profile* store_profile = NULL;
107 if (details->HasKey(keys::kStoreIdKey)) { 109 if (details->HasKey(keys::kStoreIdKey)) {
108 // The store ID was explicitly specified in the details dictionary. 110 // The store ID was explicitly specified in the details dictionary.
109 // Retrieve its corresponding cookie store. 111 // Retrieve its corresponding cookie store.
110 std::string store_id_value; 112 std::string store_id_value;
111 // Get the store ID string or return false. 113 // Get the store ID string or return false.
112 EXTENSION_FUNCTION_VALIDATE( 114 EXTENSION_FUNCTION_VALIDATE(
113 details->GetString(keys::kStoreIdKey, &store_id_value)); 115 details->GetString(keys::kStoreIdKey, &store_id_value));
114 store_profile = extension_cookies_helpers::ChooseProfileFromStoreId( 116 store_profile = extension_cookies_helpers::ChooseProfileFromStoreId(
115 store_id_value, profile(), include_incognito()); 117 store_id_value, profile(), include_incognito());
116 if (!store_profile) { 118 if (!store_profile) {
117 error_ = ExtensionErrorUtils::FormatErrorMessage( 119 error_ = ExtensionErrorUtils::FormatErrorMessage(
118 keys::kInvalidStoreIdError, store_id_value); 120 keys::kInvalidStoreIdError, store_id_value);
119 return false; 121 return false;
120 } 122 }
121 } else { 123 } else {
122 // The store ID was not specified; use the current execution context's 124 // The store ID was not specified; use the current execution context's
123 // cookie store by default. 125 // cookie store by default.
124 // GetCurrentBrowser() already takes into account incognito settings. 126 // GetCurrentBrowser() already takes into account incognito settings.
125 Browser* current_browser = GetCurrentBrowser(); 127 Browser* current_browser = GetCurrentBrowser();
126 if (!current_browser) { 128 if (!current_browser) {
127 error_ = keys::kNoCookieStoreFoundError; 129 error_ = keys::kNoCookieStoreFoundError;
128 return false; 130 return false;
129 } 131 }
130 store_profile = current_browser->profile(); 132 store_profile = current_browser->profile();
131 } 133 }
132 DCHECK(store_profile); 134 DCHECK(store_profile);
133 if (store) 135
134 *store = store_profile->GetRequestContext()->GetCookieStore(); 136 if (context)
137 *context = store_profile->GetRequestContext();
135 if (store_id) 138 if (store_id)
136 *store_id = 139 *store_id = extension_cookies_helpers::GetStoreIdFromProfile(store_profile);
137 extension_cookies_helpers::GetStoreIdFromProfile(store_profile); 140
138 return true; 141 return true;
139 } 142 }
140 143
144 GetCookieFunction::GetCookieFunction() {}
145
141 bool GetCookieFunction::RunImpl() { 146 bool GetCookieFunction::RunImpl() {
142 // Return false if the arguments are malformed. 147 // Return false if the arguments are malformed.
143 DictionaryValue* details; 148 DictionaryValue* details;
144 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); 149 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details));
145 DCHECK(details); 150 DCHECK(details);
146 151
147 // Read/validate input parameters. 152 // Read/validate input parameters.
148 GURL url; 153 if (!ParseUrl(details, &url_, true))
149 if (!ParseUrl(details, &url, true))
150 return false; 154 return false;
151 155
152 std::string name;
153 // Get the cookie name string or return false. 156 // Get the cookie name string or return false.
154 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name)); 157 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name_));
155 158
156 net::CookieStore* cookie_store; 159 URLRequestContextGetter* store_context = NULL;
157 std::string store_id; 160 if (!ParseStoreContext(details, &store_context, &store_id_))
158 if (!ParseCookieStore(details, &cookie_store, &store_id))
159 return false; 161 return false;
160 DCHECK(cookie_store && !store_id.empty());
161 162
162 net::CookieMonster::CookieList cookie_list = 163 DCHECK(store_context && !store_id_.empty());
163 extension_cookies_helpers::GetCookieListFromStore(cookie_store, url); 164 store_context_ = store_context;
165
166 bool rv = ChromeThread::PostTask(
167 ChromeThread::IO, FROM_HERE,
168 NewRunnableMethod(this, &GetCookieFunction::GetCookieOnIOThread));
169 DCHECK(rv);
170
171 // Will finish asynchronously.
172 return true;
173 }
174
175 void GetCookieFunction::GetCookieOnIOThread() {
176 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
177 net::CookieStore* cookie_store = store_context_->GetCookieStore();
178 cookie_list_ =
179 extension_cookies_helpers::GetCookieListFromStore(cookie_store, url_);
180
181 bool rv = ChromeThread::PostTask(
182 ChromeThread::UI, FROM_HERE,
183 NewRunnableMethod(this, &GetCookieFunction::RespondOnUIThread));
184 DCHECK(rv);
185 }
186
187 void GetCookieFunction::RespondOnUIThread() {
188 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
189
164 net::CookieMonster::CookieList::iterator it; 190 net::CookieMonster::CookieList::iterator it;
165 for (it = cookie_list.begin(); it != cookie_list.end(); ++it) { 191 for (it = cookie_list_.begin(); it != cookie_list_.end(); ++it) {
166 // Return the first matching cookie. Relies on the fact that the 192 // Return the first matching cookie. Relies on the fact that the
167 // CookieMonster retrieves them in reverse domain-length order. 193 // CookieMonster retrieves them in reverse domain-length order.
168 const net::CookieMonster::CanonicalCookie& cookie = it->second; 194 const net::CookieMonster::CanonicalCookie& cookie = it->second;
169 if (cookie.Name() == name) { 195 if (cookie.Name() == name_) {
170 result_.reset( 196 result_.reset(
171 extension_cookies_helpers::CreateCookieValue(*it, store_id)); 197 extension_cookies_helpers::CreateCookieValue(*it, store_id_));
172 return true; 198 break;
173 } 199 }
174 } 200 }
201
175 // The cookie doesn't exist; return null. 202 // The cookie doesn't exist; return null.
176 result_.reset(Value::CreateNullValue()); 203 if (it == cookie_list_.end())
204 result_.reset(Value::CreateNullValue());
205
206 SendResponse(true);
207 }
208
209 GetAllCookiesFunction::GetAllCookiesFunction() {}
210
211 bool GetAllCookiesFunction::RunImpl() {
212 // Return false if the arguments are malformed.
213 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details_));
214 DCHECK(details_);
215
216 // Read/validate input parameters.
217 if (details_->HasKey(keys::kUrlKey) && !ParseUrl(details_, &url_, false))
218 return false;
219
220 URLRequestContextGetter* store_context = NULL;
221 if (!ParseStoreContext(details_, &store_context, &store_id_))
222 return false;
223 DCHECK(store_context);
224 store_context_ = store_context;
225
226 bool rv = ChromeThread::PostTask(
227 ChromeThread::IO, FROM_HERE,
228 NewRunnableMethod(this, &GetAllCookiesFunction::GetAllCookiesOnIOThread));
229 DCHECK(rv);
230
231 // Will finish asynchronously.
177 return true; 232 return true;
178 } 233 }
179 234
180 bool GetAllCookiesFunction::RunImpl() { 235 void GetAllCookiesFunction::GetAllCookiesOnIOThread() {
181 // Return false if the arguments are malformed. 236 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
182 DictionaryValue* details; 237 net::CookieStore* cookie_store = store_context_->GetCookieStore();
183 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); 238 cookie_list_ =
184 DCHECK(details); 239 extension_cookies_helpers::GetCookieListFromStore(cookie_store, url_);
185 240
186 // Read/validate input parameters. 241 bool rv = ChromeThread::PostTask(
187 GURL url; 242 ChromeThread::UI, FROM_HERE,
188 if (details->HasKey(keys::kUrlKey) && !ParseUrl(details, &url, false)) 243 NewRunnableMethod(this, &GetAllCookiesFunction::RespondOnUIThread));
189 return false; 244 DCHECK(rv);
245 }
190 246
191 net::CookieStore* cookie_store; 247 void GetAllCookiesFunction::RespondOnUIThread() {
192 std::string store_id; 248 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
193 if (!ParseCookieStore(details, &cookie_store, &store_id))
194 return false;
195 DCHECK(cookie_store);
196 249
197 ListValue* matching_list = new ListValue(); 250 const Extension* extension = GetExtension();
198 extension_cookies_helpers::AppendMatchingCookiesToList( 251 if (extension) {
199 cookie_store, store_id, url, details, GetExtension(), matching_list); 252 ListValue* matching_list = new ListValue();
200 result_.reset(matching_list); 253 extension_cookies_helpers::AppendMatchingCookiesToList(
201 return true; 254 cookie_list_, store_id_, url_, details_, GetExtension(), matching_list);
255 result_.reset(matching_list);
256 }
257 SendResponse(true);
202 } 258 }
203 259
260 SetCookieFunction::SetCookieFunction() : secure_(false), http_only_(false) {}
261
204 bool SetCookieFunction::RunImpl() { 262 bool SetCookieFunction::RunImpl() {
205 // Return false if the arguments are malformed. 263 // Return false if the arguments are malformed.
206 DictionaryValue* details; 264 DictionaryValue* details;
207 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); 265 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details));
208 DCHECK(details); 266 DCHECK(details);
209 267
210 // Read/validate input parameters. 268 // Read/validate input parameters.
211 GURL url; 269 if (!ParseUrl(details, &url_, true))
212 if (!ParseUrl(details, &url, true))
213 return false; 270 return false;
214 // The macros below return false if argument types are not as expected. 271 // The macros below return false if argument types are not as expected.
215 std::string name; 272 if (details->HasKey(keys::kNameKey))
216 if (details->HasKey(keys::kNameKey)) { 273 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name_));
217 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name)); 274 if (details->HasKey(keys::kValueKey))
275 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kValueKey, &value_));
276 if (details->HasKey(keys::kDomainKey))
277 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kDomainKey, &domain_));
278 if (details->HasKey(keys::kPathKey))
279 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kPathKey, &path_));
280
281 if (details->HasKey(keys::kSecureKey)) {
282 EXTENSION_FUNCTION_VALIDATE(
283 details->GetBoolean(keys::kSecureKey, &secure_));
218 } 284 }
219 std::string value;
220 if (details->HasKey(keys::kValueKey)) {
221 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kValueKey, &value));
222 }
223 std::string domain;
224 if (details->HasKey(keys::kDomainKey)) {
225 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kDomainKey, &domain));
226 }
227 std::string path;
228 if (details->HasKey(keys::kPathKey)) {
229 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kPathKey, &path));
230 }
231 bool secure = false;
232 if (details->HasKey(keys::kSecureKey)) {
233 EXTENSION_FUNCTION_VALIDATE(details->GetBoolean(keys::kSecureKey, &secure));
234 }
235 bool http_only = false;
236 if (details->HasKey(keys::kHttpOnlyKey)) { 285 if (details->HasKey(keys::kHttpOnlyKey)) {
237 EXTENSION_FUNCTION_VALIDATE( 286 EXTENSION_FUNCTION_VALIDATE(
238 details->GetBoolean(keys::kHttpOnlyKey, &http_only)); 287 details->GetBoolean(keys::kHttpOnlyKey, &http_only_));
239 } 288 }
240 base::Time expiration_time;
241 if (details->HasKey(keys::kExpirationDateKey)) { 289 if (details->HasKey(keys::kExpirationDateKey)) {
242 Value* expiration_date_value; 290 Value* expiration_date_value;
243 EXTENSION_FUNCTION_VALIDATE(details->Get(keys::kExpirationDateKey, 291 EXTENSION_FUNCTION_VALIDATE(details->Get(keys::kExpirationDateKey,
244 &expiration_date_value)); 292 &expiration_date_value));
245 double expiration_date; 293 double expiration_date;
246 if (expiration_date_value->IsType(Value::TYPE_INTEGER)) { 294 if (expiration_date_value->IsType(Value::TYPE_INTEGER)) {
247 int expiration_date_int; 295 int expiration_date_int;
248 EXTENSION_FUNCTION_VALIDATE( 296 EXTENSION_FUNCTION_VALIDATE(
249 expiration_date_value->GetAsInteger(&expiration_date_int)); 297 expiration_date_value->GetAsInteger(&expiration_date_int));
250 expiration_date = static_cast<double>(expiration_date_int); 298 expiration_date = static_cast<double>(expiration_date_int);
251 } else { 299 } else {
252 EXTENSION_FUNCTION_VALIDATE( 300 EXTENSION_FUNCTION_VALIDATE(
253 expiration_date_value->GetAsReal(&expiration_date)); 301 expiration_date_value->GetAsReal(&expiration_date));
254 } 302 }
255 expiration_time = base::Time::FromDoubleT(expiration_date); 303 expiration_time_ = base::Time::FromDoubleT(expiration_date);
256 } 304 }
257 305
258 net::CookieStore* cookie_store; 306 URLRequestContextGetter* store_context = NULL;
259 if (!ParseCookieStore(details, &cookie_store, NULL)) 307 if (!ParseStoreContext(details, &store_context, NULL))
260 return false; 308 return false;
261 DCHECK(cookie_store); 309 DCHECK(store_context);
310 store_context_ = store_context;
262 311
263 if (!cookie_store->GetCookieMonster()->SetCookieWithDetails( 312 bool rv = ChromeThread::PostTask(
264 url, name, value, domain, path, expiration_time, secure, 313 ChromeThread::IO, FROM_HERE,
265 http_only)) { 314 NewRunnableMethod(this, &SetCookieFunction::SetCookieOnIOThread));
266 error_ = ExtensionErrorUtils::FormatErrorMessage( 315 DCHECK(rv);
267 keys::kCookieSetFailedError, name); 316
268 return false; 317 // Will finish asynchronously.
269 }
270 return true; 318 return true;
271 } 319 }
272 320
321 void SetCookieFunction::SetCookieOnIOThread() {
322 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
323 net::CookieMonster* cookie_monster =
324 store_context_->GetCookieStore()->GetCookieMonster();
325 success_ = cookie_monster->SetCookieWithDetails(
326 url_, name_, value_, domain_, path_, expiration_time_,
327 secure_, http_only_);
328
329 bool rv = ChromeThread::PostTask(
330 ChromeThread::UI, FROM_HERE,
331 NewRunnableMethod(this, &SetCookieFunction::RespondOnUIThread));
332 DCHECK(rv);
333 }
334
335 void SetCookieFunction::RespondOnUIThread() {
336 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
337 if (!success_) {
338 error_ = ExtensionErrorUtils::FormatErrorMessage(
339 keys::kCookieSetFailedError, name_);
340 }
341 SendResponse(success_);
342 }
343
344 namespace {
345
346 class RemoveCookieTask : public Task {
347 public:
348 RemoveCookieTask(const GURL& url,
349 const std::string& name,
350 const scoped_refptr<URLRequestContextGetter>& context_getter)
351 : url_(url),
352 name_(name),
353 context_getter_(context_getter) {}
354
355 virtual void Run() {
356 net::CookieStore* cookie_store = context_getter_->GetCookieStore();
357 cookie_store->DeleteCookie(url_, name_);
358 }
359
360 private:
361 const GURL url_;
362 const std::string name_;
363 const scoped_refptr<URLRequestContextGetter> context_getter_;
364
365 DISALLOW_COPY_AND_ASSIGN(RemoveCookieTask);
366 };
367
368 } // namespace
369
273 bool RemoveCookieFunction::RunImpl() { 370 bool RemoveCookieFunction::RunImpl() {
274 // Return false if the arguments are malformed. 371 // Return false if the arguments are malformed.
275 DictionaryValue* details; 372 DictionaryValue* details;
276 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); 373 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details));
277 DCHECK(details); 374 DCHECK(details);
278 375
279 // Read/validate input parameters. 376 // Read/validate input parameters.
280 GURL url; 377 GURL url;
281 if (!ParseUrl(details, &url, true)) 378 if (!ParseUrl(details, &url, true))
282 return false; 379 return false;
283 380
284 std::string name; 381 std::string name;
285 // Get the cookie name string or return false. 382 // Get the cookie name string or return false.
286 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name)); 383 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name));
287 384
288 net::CookieStore* cookie_store; 385 URLRequestContextGetter* store_context = NULL;
289 if (!ParseCookieStore(details, &cookie_store, NULL)) 386 if (!ParseStoreContext(details, &store_context, NULL))
290 return false; 387 return false;
291 DCHECK(cookie_store); 388 DCHECK(store_context);
292 389
293 cookie_store->DeleteCookie(url, name); 390 // We don't bother to synchronously wait for the result here, because
391 // CookieMonster is only ever accessed on the IO thread, so any other accesses
392 // should happen after this.
393 bool rv = ChromeThread::PostTask(
394 ChromeThread::IO, FROM_HERE,
395 new RemoveCookieTask(url, name, store_context));
396 DCHECK(rv);
397
294 return true; 398 return true;
295 } 399 }
296 400
297 bool GetAllCookieStoresFunction::RunImpl() { 401 bool GetAllCookieStoresFunction::RunImpl() {
298 Profile* original_profile = profile()->GetOriginalProfile(); 402 Profile* original_profile = profile()->GetOriginalProfile();
299 DCHECK(original_profile); 403 DCHECK(original_profile);
300 scoped_ptr<ListValue> original_tab_ids(new ListValue()); 404 scoped_ptr<ListValue> original_tab_ids(new ListValue());
301 Profile* incognito_profile = NULL; 405 Profile* incognito_profile = NULL;
302 scoped_ptr<ListValue> incognito_tab_ids; 406 scoped_ptr<ListValue> incognito_tab_ids;
303 if (include_incognito()) { 407 if (include_incognito()) {
(...skipping 24 matching lines...) Expand all
328 original_profile, original_tab_ids.release())); 432 original_profile, original_tab_ids.release()));
329 } 433 }
330 if (incognito_tab_ids.get() && incognito_tab_ids->GetSize() > 0) { 434 if (incognito_tab_ids.get() && incognito_tab_ids->GetSize() > 0) {
331 cookie_store_list->Append( 435 cookie_store_list->Append(
332 extension_cookies_helpers::CreateCookieStoreValue( 436 extension_cookies_helpers::CreateCookieStoreValue(
333 incognito_profile, incognito_tab_ids.release())); 437 incognito_profile, incognito_tab_ids.release()));
334 } 438 }
335 result_.reset(cookie_store_list); 439 result_.reset(cookie_store_list);
336 return true; 440 return true;
337 } 441 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_cookies_api.h ('k') | chrome/browser/extensions/extension_cookies_helpers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698