diff options
author | tburkard@chromium.org <tburkard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-12 20:00:29 +0000 |
---|---|---|
committer | tburkard@chromium.org <tburkard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-12 20:00:29 +0000 |
commit | 035e748c7a4615f83beb7e97f4a5e0ca83f48aa9 (patch) | |
tree | 34c531c0b428c560003fb514346bc4632d1e64d8 /net | |
parent | 5846e5f9563a1d344e1225aa0f690fc6eb1a05ec (diff) | |
download | chromium_src-035e748c7a4615f83beb7e97f4a5e0ca83f48aa9.zip chromium_src-035e748c7a4615f83beb7e97f4a5e0ca83f48aa9.tar.gz chromium_src-035e748c7a4615f83beb7e97f4a5e0ca83f48aa9.tar.bz2 |
Only commit cookie changes in prerenders after a prerender is shown
Will create a PrerenderCookieStore for each prerender, retaining all cookie
operations of a prerender until the prerender is shown to the user.
Forces prerenders to be in a new render process by themselves for this to work.
BUG=371003
This is a resubmission of https://codereview.chromium.org/233353003, which had
to be reverted due to build breaks. See LGTM's there.
Review URL: https://codereview.chromium.org/278403003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269855 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/cookies/canonical_cookie.cc | 16 | ||||
-rw-r--r-- | net/cookies/canonical_cookie.h | 9 | ||||
-rw-r--r-- | net/cookies/cookie_monster.cc | 63 | ||||
-rw-r--r-- | net/cookies/cookie_monster.h | 24 | ||||
-rw-r--r-- | net/cookies/cookie_monster_store_test.cc | 2 | ||||
-rw-r--r-- | net/cookies/cookie_monster_store_test.h | 2 |
6 files changed, 110 insertions, 6 deletions
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc index 5d67ebc..54a9565 100644 --- a/net/cookies/canonical_cookie.cc +++ b/net/cookies/canonical_cookie.cc @@ -394,4 +394,20 @@ std::string CanonicalCookie::DebugString() const { static_cast<int64>(creation_date_.ToTimeT())); } +CanonicalCookie* CanonicalCookie::Duplicate() { + CanonicalCookie* cc = new CanonicalCookie(); + cc->source_ = source_; + cc->name_ = name_; + cc->value_ = value_; + cc->domain_ = domain_; + cc->path_ = path_; + cc->creation_date_ = creation_date_; + cc->expiry_date_ = expiry_date_; + cc->last_access_date_ = last_access_date_; + cc->secure_ = secure_; + cc->httponly_ = httponly_; + cc->priority_ = priority_; + return cc; +} + } // namespace net diff --git a/net/cookies/canonical_cookie.h b/net/cookies/canonical_cookie.h index a78eece..a556740 100644 --- a/net/cookies/canonical_cookie.h +++ b/net/cookies/canonical_cookie.h @@ -125,6 +125,9 @@ class NET_EXPORT CanonicalCookie { std::string DebugString() const; + // Returns a duplicate of this cookie. + CanonicalCookie* Duplicate(); + // Returns the cookie source when cookies are set for |url|. This function // is public for unit test purposes only. static std::string GetCookieSourceFromURL(const GURL& url); @@ -134,6 +137,9 @@ class NET_EXPORT CanonicalCookie { const base::Time& server_time); private: + // NOTE: When any new members are added below, the implementation of + // Duplicate() must be updated to copy the new member accordingly. + // The source member of a canonical cookie is the origin of the URL that tried // to set this cookie, minus the port number if any. This field is not // persistent though; its only used in the in-tab cookies dialog to show the @@ -153,6 +159,9 @@ class NET_EXPORT CanonicalCookie { bool secure_; bool httponly_; CookiePriority priority_; + // NOTE: When any new members are added above this comment, the + // implementation of Duplicate() must be updated to copy the new member + // accordingly. }; typedef std::vector<CanonicalCookie> CookieList; diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc index f2023b6..7aed8f8 100644 --- a/net/cookies/cookie_monster.cc +++ b/net/cookies/cookie_monster.cc @@ -53,6 +53,7 @@ #include "base/callback.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" #include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop_proxy.h" #include "base/metrics/histogram.h" @@ -311,7 +312,7 @@ std::string BuildCookieLine(const CanonicalCookieVector& cookies) { CookieMonster::CookieMonster(PersistentCookieStore* store, CookieMonsterDelegate* delegate) : initialized_(false), - loaded_(false), + loaded_(store == NULL), store_(store), last_access_threshold_( TimeDelta::FromSeconds(kDefaultAccessUpdateThresholdSeconds)), @@ -327,7 +328,7 @@ CookieMonster::CookieMonster(PersistentCookieStore* store, CookieMonsterDelegate* delegate, int last_access_threshold_milliseconds) : initialized_(false), - loaded_(false), + loaded_(store == NULL), store_(store), last_access_threshold_(base::TimeDelta::FromMilliseconds( last_access_threshold_milliseconds)), @@ -1433,6 +1434,11 @@ void CookieMonster::InitStore() { store_->Load(base::Bind(&CookieMonster::OnLoaded, this, TimeTicks::Now())); } +void CookieMonster::ReportLoaded() { + if (delegate_.get()) + delegate_->OnLoaded(); +} + void CookieMonster::OnLoaded(TimeTicks beginning_time, const std::vector<CanonicalCookie*>& cookies) { StoreLoadedCookies(cookies); @@ -1440,6 +1446,8 @@ void CookieMonster::OnLoaded(TimeTicks beginning_time, // Invoke the task queue of cookie request. InvokeQueue(); + + ReportLoaded(); } void CookieMonster::OnKeyLoaded(const std::string& key, @@ -2245,4 +2253,55 @@ Time CookieMonster::CurrentTime() { Time::FromInternalValue(last_time_seen_.ToInternalValue() + 1)); } +bool CookieMonster::CopyCookiesForKeyToOtherCookieMonster( + std::string key, + CookieMonster* other) { + ScopedVector<CanonicalCookie> duplicated_cookies; + + { + base::AutoLock autolock(lock_); + DCHECK(other); + if (!loaded_) + return false; + + for (CookieMapItPair its = cookies_.equal_range(key); + its.first != its.second; + ++its.first) { + CookieMap::iterator curit = its.first; + CanonicalCookie* cc = curit->second; + + duplicated_cookies.push_back(cc->Duplicate()); + } + } + + { + base::AutoLock autolock(other->lock_); + if (!other->loaded_) + return false; + + // There must not exist any entries for the key to be copied in |other|. + CookieMapItPair its = other->cookies_.equal_range(key); + if (its.first != its.second) + return false; + + // Store the copied cookies in |other|. + for (ScopedVector<CanonicalCookie>::const_iterator it = + duplicated_cookies.begin(); + it != duplicated_cookies.end(); + ++it) { + other->InternalInsertCookie(key, *it, true); + } + + // Since the cookies are owned by |other| now, weak clear must be used. + duplicated_cookies.weak_clear(); + } + + return true; +} + +bool CookieMonster::loaded() { + base::AutoLock autolock(lock_); + return loaded_; +} + } // namespace net diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h index 5a06922..b719c32 100644 --- a/net/cookies/cookie_monster.h +++ b/net/cookies/cookie_monster.h @@ -307,6 +307,19 @@ class NET_EXPORT CookieMonster : public CookieStore { static const char* kDefaultCookieableSchemes[]; static const int kDefaultCookieableSchemesCount; + // Copies all keys for the given |key| to another cookie monster |other|. + // Both |other| and |this| must be loaded for this operation to succeed. + // Furthermore, there may not be any cookies stored in |other| for |key|. + // Returns false if any of these conditions is not met. + bool CopyCookiesForKeyToOtherCookieMonster(std::string key, + CookieMonster* other); + + // Find the key (for lookup in cookies_) based on the given domain. + // See comment on keys before the CookieMap typedef. + std::string GetKey(const std::string& domain) const; + + bool loaded(); + private: // For queueing the cookie monster calls. class CookieMonsterTask; @@ -455,6 +468,7 @@ class NET_EXPORT CookieMonster : public CookieStore { InitStore(); } else { loaded_ = true; + ReportLoaded(); } initialized_ = true; } @@ -464,6 +478,9 @@ class NET_EXPORT CookieMonster : public CookieStore { // Should only be called by InitIfNecessary(). void InitStore(); + // Reports to the delegate that the cookie monster was loaded. + void ReportLoaded(); + // Stores cookies loaded from the backing store and invokes any deferred // calls. |beginning_time| should be the moment PersistentCookieStore::Load // was invoked and is used for reporting histogram_time_blocked_on_load_. @@ -576,10 +593,6 @@ class NET_EXPORT CookieMonster : public CookieStore { CookieItVector::iterator cookie_its_begin, CookieItVector::iterator cookie_its_end); - // Find the key (for lookup in cookies_) based on the given domain. - // See comment on keys before the CookieMap typedef. - std::string GetKey(const std::string& domain) const; - bool HasCookieableScheme(const GURL& url); // Statistics support @@ -720,6 +733,9 @@ class NET_EXPORT CookieMonsterDelegate virtual void OnCookieChanged(const CanonicalCookie& cookie, bool removed, ChangeCause cause) = 0; + // Indicates that the cookie store has fully loaded. + virtual void OnLoaded() = 0; + protected: friend class base::RefCountedThreadSafe<CookieMonsterDelegate>; virtual ~CookieMonsterDelegate() {} diff --git a/net/cookies/cookie_monster_store_test.cc b/net/cookies/cookie_monster_store_test.cc index 350a015..226242a 100644 --- a/net/cookies/cookie_monster_store_test.cc +++ b/net/cookies/cookie_monster_store_test.cc @@ -97,6 +97,8 @@ void MockCookieMonsterDelegate::OnCookieChanged( changes_.push_back(notification); } +void MockCookieMonsterDelegate::OnLoaded() {} + MockCookieMonsterDelegate::~MockCookieMonsterDelegate() {} CanonicalCookie BuildCanonicalCookie(const std::string& key, diff --git a/net/cookies/cookie_monster_store_test.h b/net/cookies/cookie_monster_store_test.h index ec40de6..efbcbe5 100644 --- a/net/cookies/cookie_monster_store_test.h +++ b/net/cookies/cookie_monster_store_test.h @@ -132,6 +132,8 @@ class MockCookieMonsterDelegate : public CookieMonsterDelegate { bool removed, CookieMonsterDelegate::ChangeCause cause) OVERRIDE; + virtual void OnLoaded() OVERRIDE; + private: virtual ~MockCookieMonsterDelegate(); |