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

Unified Diff: chrome/browser/extensions/extension_cookies_api.cc

Issue 2756003: Make CookieMonster NonThreadSafe. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Address eroman's and cindylau's comments. Created 10 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/extension_cookies_api.cc
diff --git a/chrome/browser/extensions/extension_cookies_api.cc b/chrome/browser/extensions/extension_cookies_api.cc
index 0cf9b0741ca69433bcff304774f857debd824b82..1bf61c70816e7e5cdea2760fe10bbebcffbb980e 100644
--- a/chrome/browser/extensions/extension_cookies_api.cc
+++ b/chrome/browser/extensions/extension_cookies_api.cc
@@ -7,7 +7,9 @@
#include "chrome/browser/extensions/extension_cookies_api.h"
#include "base/json/json_writer.h"
+#include "base/task.h"
#include "chrome/browser/browser_list.h"
+#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/extensions/extension_cookies_api_constants.h"
#include "chrome/browser/extensions/extension_cookies_helpers.h"
#include "chrome/browser/extensions/extension_message_service.h"
@@ -100,10 +102,10 @@ bool CookiesFunction::ParseUrl(const DictionaryValue* details, GURL* url,
return true;
}
-bool CookiesFunction::ParseCookieStore(const DictionaryValue* details,
- net::CookieStore** store,
- std::string* store_id) {
- DCHECK(details && (store || store_id));
+bool CookiesFunction::ParseStoreContext(const DictionaryValue* details,
+ URLRequestContextGetter** context,
+ std::string* store_id) {
+ DCHECK(details && (context || store_id));
Profile* store_profile = NULL;
if (details->HasKey(keys::kStoreIdKey)) {
// The store ID was explicitly specified in the details dictionary.
@@ -131,14 +133,17 @@ bool CookiesFunction::ParseCookieStore(const DictionaryValue* details,
store_profile = current_browser->profile();
}
DCHECK(store_profile);
- if (store)
- *store = store_profile->GetRequestContext()->GetCookieStore();
+
+ if (context)
+ *context = store_profile->GetRequestContext();
if (store_id)
- *store_id =
- extension_cookies_helpers::GetStoreIdFromProfile(store_profile);
+ *store_id = extension_cookies_helpers::GetStoreIdFromProfile(store_profile);
+
return true;
}
+GetCookieFunction::GetCookieFunction() {}
+
bool GetCookieFunction::RunImpl() {
// Return false if the arguments are malformed.
DictionaryValue* details;
@@ -146,62 +151,115 @@ bool GetCookieFunction::RunImpl() {
DCHECK(details);
// Read/validate input parameters.
- GURL url;
- if (!ParseUrl(details, &url, true))
+ if (!ParseUrl(details, &url_, true))
return false;
- std::string name;
// Get the cookie name string or return false.
- EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name));
+ EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name_));
- net::CookieStore* cookie_store;
- std::string store_id;
- if (!ParseCookieStore(details, &cookie_store, &store_id))
+ URLRequestContextGetter* store_context = NULL;
+ if (!ParseStoreContext(details, &store_context, &store_id_))
return false;
- DCHECK(cookie_store && !store_id.empty());
- net::CookieMonster::CookieList cookie_list =
- extension_cookies_helpers::GetCookieListFromStore(cookie_store, url);
+ DCHECK(store_context && !store_id_.empty());
+ store_context_ = store_context;
+
+ bool rv = ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &GetCookieFunction::GetCookieOnIOThread));
+ DCHECK(rv);
+
+ // Will finish asynchronously.
+ return true;
+}
+
+void GetCookieFunction::GetCookieOnIOThread() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ net::CookieStore* cookie_store = store_context_->GetCookieStore();
+ cookie_list_ =
+ extension_cookies_helpers::GetCookieListFromStore(cookie_store, url_);
+
+ bool rv = ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &GetCookieFunction::RespondOnUIThread));
+ DCHECK(rv);
+}
+
+void GetCookieFunction::RespondOnUIThread() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+
net::CookieMonster::CookieList::iterator it;
- for (it = cookie_list.begin(); it != cookie_list.end(); ++it) {
+ for (it = cookie_list_.begin(); it != cookie_list_.end(); ++it) {
// Return the first matching cookie. Relies on the fact that the
// CookieMonster retrieves them in reverse domain-length order.
const net::CookieMonster::CanonicalCookie& cookie = it->second;
- if (cookie.Name() == name) {
+ if (cookie.Name() == name_) {
result_.reset(
- extension_cookies_helpers::CreateCookieValue(*it, store_id));
- return true;
+ extension_cookies_helpers::CreateCookieValue(*it, store_id_));
+ break;
}
}
+
// The cookie doesn't exist; return null.
- result_.reset(Value::CreateNullValue());
- return true;
+ if (it == cookie_list_.end())
+ result_.reset(Value::CreateNullValue());
+
+ SendResponse(true);
}
+GetAllCookiesFunction::GetAllCookiesFunction() {}
+
bool GetAllCookiesFunction::RunImpl() {
// Return false if the arguments are malformed.
- DictionaryValue* details;
- EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details));
- DCHECK(details);
+ EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details_));
+ DCHECK(details_);
// Read/validate input parameters.
- GURL url;
- if (details->HasKey(keys::kUrlKey) && !ParseUrl(details, &url, false))
+ if (details_->HasKey(keys::kUrlKey) && !ParseUrl(details_, &url_, false))
return false;
- net::CookieStore* cookie_store;
- std::string store_id;
- if (!ParseCookieStore(details, &cookie_store, &store_id))
+ URLRequestContextGetter* store_context = NULL;
+ if (!ParseStoreContext(details_, &store_context, &store_id_))
return false;
- DCHECK(cookie_store);
+ DCHECK(store_context);
+ store_context_ = store_context;
- ListValue* matching_list = new ListValue();
- extension_cookies_helpers::AppendMatchingCookiesToList(
- cookie_store, store_id, url, details, GetExtension(), matching_list);
- result_.reset(matching_list);
+ bool rv = ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &GetAllCookiesFunction::GetAllCookiesOnIOThread));
+ DCHECK(rv);
+
+ // Will finish asynchronously.
return true;
}
+void GetAllCookiesFunction::GetAllCookiesOnIOThread() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ net::CookieStore* cookie_store = store_context_->GetCookieStore();
+ cookie_list_ =
+ extension_cookies_helpers::GetCookieListFromStore(cookie_store, url_);
+
+ bool rv = ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &GetAllCookiesFunction::RespondOnUIThread));
+ DCHECK(rv);
+}
+
+void GetAllCookiesFunction::RespondOnUIThread() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+
+ const Extension* extension = GetExtension();
+ if (extension) {
+ ListValue* matching_list = new ListValue();
+ extension_cookies_helpers::AppendMatchingCookiesToList(
+ cookie_list_, store_id_, url_, details_, GetExtension(), matching_list);
+ result_.reset(matching_list);
+ }
+ SendResponse(true);
+}
+
+SetCookieFunction::SetCookieFunction() : secure_(false), http_only_(false) {}
+
bool SetCookieFunction::RunImpl() {
// Return false if the arguments are malformed.
DictionaryValue* details;
@@ -209,36 +267,26 @@ bool SetCookieFunction::RunImpl() {
DCHECK(details);
// Read/validate input parameters.
- GURL url;
- if (!ParseUrl(details, &url, true))
+ if (!ParseUrl(details, &url_, true))
return false;
// The macros below return false if argument types are not as expected.
- std::string name;
- if (details->HasKey(keys::kNameKey)) {
- EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name));
- }
- std::string value;
- if (details->HasKey(keys::kValueKey)) {
- EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kValueKey, &value));
- }
- std::string domain;
- if (details->HasKey(keys::kDomainKey)) {
- EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kDomainKey, &domain));
- }
- std::string path;
- if (details->HasKey(keys::kPathKey)) {
- EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kPathKey, &path));
- }
- bool secure = false;
+ if (details->HasKey(keys::kNameKey))
+ EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name_));
+ if (details->HasKey(keys::kValueKey))
+ EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kValueKey, &value_));
+ if (details->HasKey(keys::kDomainKey))
+ EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kDomainKey, &domain_));
+ if (details->HasKey(keys::kPathKey))
+ EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kPathKey, &path_));
+
if (details->HasKey(keys::kSecureKey)) {
- EXTENSION_FUNCTION_VALIDATE(details->GetBoolean(keys::kSecureKey, &secure));
+ EXTENSION_FUNCTION_VALIDATE(
+ details->GetBoolean(keys::kSecureKey, &secure_));
}
- bool http_only = false;
if (details->HasKey(keys::kHttpOnlyKey)) {
EXTENSION_FUNCTION_VALIDATE(
- details->GetBoolean(keys::kHttpOnlyKey, &http_only));
+ details->GetBoolean(keys::kHttpOnlyKey, &http_only_));
}
- base::Time expiration_time;
if (details->HasKey(keys::kExpirationDateKey)) {
Value* expiration_date_value;
EXTENSION_FUNCTION_VALIDATE(details->Get(keys::kExpirationDateKey,
@@ -253,24 +301,73 @@ bool SetCookieFunction::RunImpl() {
EXTENSION_FUNCTION_VALIDATE(
expiration_date_value->GetAsReal(&expiration_date));
}
- expiration_time = base::Time::FromDoubleT(expiration_date);
+ expiration_time_ = base::Time::FromDoubleT(expiration_date);
}
- net::CookieStore* cookie_store;
- if (!ParseCookieStore(details, &cookie_store, NULL))
+ URLRequestContextGetter* store_context = NULL;
+ if (!ParseStoreContext(details, &store_context, NULL))
return false;
- DCHECK(cookie_store);
+ DCHECK(store_context);
+ store_context_ = store_context;
+
+ bool rv = ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &SetCookieFunction::SetCookieOnIOThread));
+ DCHECK(rv);
- if (!cookie_store->GetCookieMonster()->SetCookieWithDetails(
- url, name, value, domain, path, expiration_time, secure,
- http_only)) {
+ // Will finish asynchronously.
+ return true;
+}
+
+void SetCookieFunction::SetCookieOnIOThread() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ net::CookieMonster* cookie_monster =
+ store_context_->GetCookieStore()->GetCookieMonster();
+ success_ = cookie_monster->SetCookieWithDetails(
+ url_, name_, value_, domain_, path_, expiration_time_,
+ secure_, http_only_);
+
+ bool rv = ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &SetCookieFunction::RespondOnUIThread));
+ DCHECK(rv);
+}
+
+void SetCookieFunction::RespondOnUIThread() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ if (!success_) {
error_ = ExtensionErrorUtils::FormatErrorMessage(
- keys::kCookieSetFailedError, name);
- return false;
+ keys::kCookieSetFailedError, name_);
}
- return true;
+ SendResponse(success_);
}
+namespace {
+
+class RemoveCookieTask : public Task {
+ public:
+ RemoveCookieTask(const GURL& url,
+ const std::string& name,
+ const scoped_refptr<URLRequestContextGetter>& context_getter)
+ : url_(url),
+ name_(name),
+ context_getter_(context_getter) {}
+
+ virtual void Run() {
+ net::CookieStore* cookie_store = context_getter_->GetCookieStore();
+ cookie_store->DeleteCookie(url_, name_);
+ }
+
+ private:
+ const GURL url_;
+ const std::string name_;
+ const scoped_refptr<URLRequestContextGetter> context_getter_;
+
+ DISALLOW_COPY_AND_ASSIGN(RemoveCookieTask);
+};
+
+} // namespace
+
bool RemoveCookieFunction::RunImpl() {
// Return false if the arguments are malformed.
DictionaryValue* details;
@@ -286,12 +383,19 @@ bool RemoveCookieFunction::RunImpl() {
// Get the cookie name string or return false.
EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name));
- net::CookieStore* cookie_store;
- if (!ParseCookieStore(details, &cookie_store, NULL))
+ URLRequestContextGetter* store_context = NULL;
+ if (!ParseStoreContext(details, &store_context, NULL))
return false;
- DCHECK(cookie_store);
+ DCHECK(store_context);
+
+ // We don't bother to synchronously wait for the result here, because
+ // CookieMonster is only ever accessed on the IO thread, so any other accesses
+ // should happen after this.
+ bool rv = ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ new RemoveCookieTask(url, name, store_context));
+ DCHECK(rv);
- cookie_store->DeleteCookie(url, name);
return true;
}
« 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