Index: net/cookies/cookie_monster.cc |
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc |
index f2bd3e4558249f5b0651df1e7d3ab4fe537bd882..2f7da0619af82338fdc8ec49b42ae9e3c008bbe5 100644 |
--- a/net/cookies/cookie_monster.cc |
+++ b/net/cookies/cookie_monster.cc |
@@ -62,6 +62,7 @@ |
#include "base/strings/string_util.h" |
#include "base/strings/stringprintf.h" |
#include "base/threading/thread_task_runner_handle.h" |
+#include "base/time/time.h" |
#include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
#include "net/cookies/canonical_cookie.h" |
#include "net/cookies/cookie_util.h" |
@@ -678,6 +679,42 @@ int CookieMonster::DeleteCanonicalCookieTask::RunDeleteTask() { |
return this->cookie_monster()->DeleteCanonicalCookie(cookie_); |
} |
+// Task class for SetCanonicalCookie call. |
+class CookieMonster::SetCanonicalCookieTask : public CookieMonsterTask { |
+ public: |
+ SetCanonicalCookieTask(CookieMonster* cookie_monster, |
+ std::unique_ptr<CanonicalCookie> cookie, |
+ bool secure_source, |
+ bool modify_http_only, |
+ const SetCookiesCallback& callback) |
+ : CookieMonsterTask(cookie_monster), |
+ cookie_(std::move(cookie)), |
+ secure_source_(secure_source), |
+ modify_http_only_(modify_http_only), |
+ callback_(callback) {} |
+ |
+ // CookieMonsterTask: |
+ void Run() override; |
+ |
+ protected: |
+ ~SetCanonicalCookieTask() override {} |
+ |
+ private: |
+ std::unique_ptr<CanonicalCookie> cookie_; |
+ bool secure_source_; |
+ bool modify_http_only_; |
+ SetCookiesCallback callback_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SetCanonicalCookieTask); |
+}; |
+ |
+void CookieMonster::SetCanonicalCookieTask::Run() { |
+ bool result = this->cookie_monster()->SetCanonicalCookie( |
+ std::move(cookie_), secure_source_, modify_http_only_); |
+ if (!callback_.is_null()) |
+ callback_.Run(result); |
+} |
+ |
// Task class for SetCookieWithOptions call. |
class CookieMonster::SetCookieWithOptionsTask : public CookieMonsterTask { |
public: |
@@ -749,7 +786,7 @@ void CookieMonster::SetAllCookiesTask::Run() { |
bool result = true; |
if (positive_diff.size() > 0) |
- result = this->cookie_monster()->SetCanonicalCookies(list_); |
+ result = this->cookie_monster()->SetCanonicalCookiesInternal(list_); |
if (!callback_.is_null()) |
callback_.Run(result); |
@@ -882,6 +919,23 @@ void CookieMonster::SetAllCookiesAsync(const CookieList& list, |
DoCookieTask(task); |
} |
+void CookieMonster::SetCanonicalCookieAsync( |
+ const CanonicalCookie& cookie, |
+ bool secure_source, |
+ bool modify_http_only, |
+ const SetCookiesCallback& callback) { |
+ DCHECK(cookie.IsCanonical()); |
+ scoped_refptr<SetCanonicalCookieTask> task = new SetCanonicalCookieTask( |
+ this, base::MakeUnique<CanonicalCookie>(cookie), secure_source, |
+ modify_http_only, callback); |
+ |
+ // TODO(rdsmith): Switch to DoCookieTaskForURL (or the equivalent). |
+ // This is tricky because we don't have the scheme in this routine |
+ // and DoCookieTaskForURL uses cookie_util::GetEffectiveDomain(scheme, host) |
+ // to generate the database key to block behind. |
+ DoCookieTask(task); |
+} |
+ |
void CookieMonster::SetCookieWithOptionsAsync( |
const GURL& url, |
const std::string& cookie_line, |
@@ -1048,16 +1102,6 @@ bool CookieMonster::SetCookieWithDetails(const GURL& url, |
if (!HasCookieableScheme(url)) |
return false; |
- // TODO(mmenke): This class assumes each cookie to have a unique creation |
- // time. Allowing the caller to set the creation time violates that |
- // assumption. Worth fixing? Worth noting that time changes between browser |
- // restarts can cause the same issue. |
- base::Time actual_creation_time = creation_time; |
- if (creation_time.is_null()) { |
- actual_creation_time = CurrentTime(); |
- last_time_seen_ = actual_creation_time; |
- } |
- |
// Validate consistency of passed arguments. |
if (ParsedCookie::ParseTokenString(name) != name || |
ParsedCookie::ParseValueString(value) != value || |
@@ -1066,10 +1110,6 @@ bool CookieMonster::SetCookieWithDetails(const GURL& url, |
return false; |
} |
- // Validate passed arguments against URL. |
- if (secure && !url.SchemeIsCryptographic()) |
- return false; |
- |
std::string cookie_domain; |
if (!cookie_util::GetCookieDomainWithString(url, domain, &cookie_domain)) |
return false; |
@@ -1088,15 +1128,10 @@ bool CookieMonster::SetCookieWithDetails(const GURL& url, |
canon_path_component.len); |
std::unique_ptr<CanonicalCookie> cc(base::MakeUnique<CanonicalCookie>( |
- name, value, cookie_domain, cookie_path, actual_creation_time, |
- expiration_time, last_access_time, secure, http_only, same_site, |
- priority)); |
+ name, value, cookie_domain, cookie_path, creation_time, expiration_time, |
+ last_access_time, secure, http_only, same_site, priority)); |
- CookieOptions options; |
- options.set_include_httponly(); |
- options.set_same_site_cookie_mode( |
- CookieOptions::SameSiteCookieMode::INCLUDE_STRICT_AND_LAX); |
- return SetCanonicalCookie(std::move(cc), url, options); |
+ return SetCanonicalCookie(std::move(cc), url.SchemeIsCryptographic(), true); |
} |
CookieList CookieMonster::GetAllCookies() { |
@@ -1415,7 +1450,7 @@ void CookieMonster::StoreLoadedCookies( |
if (creation_times_.insert(cookie_creation_time).second) { |
CanonicalCookie* cookie_ptr = cookie.get(); |
CookieMap::iterator inserted = InternalInsertCookie( |
- GetKey(cookie_ptr->Domain()), std::move(cookie), GURL(), false); |
+ GetKey(cookie_ptr->Domain()), std::move(cookie), false, false); |
const Time cookie_access_time(cookie_ptr->LastAccessDate()); |
if (earliest_access_time_.is_null() || |
cookie_access_time < earliest_access_time_) |
@@ -1629,7 +1664,7 @@ void CookieMonster::FindCookiesForKey(const std::string& key, |
bool CookieMonster::DeleteAnyEquivalentCookie(const std::string& key, |
const CanonicalCookie& ecc, |
- const GURL& source_url, |
+ bool source_secure, |
bool skip_httponly, |
bool already_expired) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
@@ -1652,7 +1687,7 @@ bool CookieMonster::DeleteAnyEquivalentCookie(const std::string& key, |
// attribute. |
// |
// See: https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone |
- if (cc->IsSecure() && !source_url.SchemeIsCryptographic() && |
+ if (cc->IsSecure() && !source_secure && |
ecc.IsEquivalentForSecureCookieMatching(*cc)) { |
skipped_secure_cookie = true; |
histogram_cookie_delete_equivalent_->Add( |
@@ -1693,7 +1728,7 @@ bool CookieMonster::DeleteAnyEquivalentCookie(const std::string& key, |
CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie( |
const std::string& key, |
std::unique_ptr<CanonicalCookie> cc, |
- const GURL& source_url, |
+ bool source_secure, |
bool sync_to_store) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
CanonicalCookie* cc_ptr = cc.get(); |
@@ -1721,21 +1756,15 @@ CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie( |
// http:// URLs, but not cookies that are cleared by http:// URLs, to |
// understand if the former behavior can be deprecated for Secure |
// cookies. |
- if (!source_url.is_empty()) { |
- CookieSource cookie_source_sample; |
- if (source_url.SchemeIsCryptographic()) { |
- cookie_source_sample = |
- cc_ptr->IsSecure() |
- ? COOKIE_SOURCE_SECURE_COOKIE_CRYPTOGRAPHIC_SCHEME |
- : COOKIE_SOURCE_NONSECURE_COOKIE_CRYPTOGRAPHIC_SCHEME; |
- } else { |
- cookie_source_sample = |
- cc_ptr->IsSecure() |
- ? COOKIE_SOURCE_SECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME |
- : COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME; |
- } |
- histogram_cookie_source_scheme_->Add(cookie_source_sample); |
- } |
+ CookieSource cookie_source_sample = |
+ (source_secure |
+ ? (cc_ptr->IsSecure() |
+ ? COOKIE_SOURCE_SECURE_COOKIE_CRYPTOGRAPHIC_SCHEME |
+ : COOKIE_SOURCE_NONSECURE_COOKIE_CRYPTOGRAPHIC_SCHEME) |
+ : (cc_ptr->IsSecure() |
+ ? COOKIE_SOURCE_SECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME |
+ : COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME)); |
+ histogram_cookie_source_scheme_->Add(cookie_source_sample); |
RunCookieChangedCallbacks(*cc_ptr, CookieStore::ChangeCause::INSERTED); |
@@ -1764,20 +1793,34 @@ bool CookieMonster::SetCookieWithCreationTimeAndOptions( |
VLOG(kVlogSetCookies) << "WARNING: Failed to allocate CanonicalCookie"; |
return false; |
} |
- return SetCanonicalCookie(std::move(cc), url, options); |
+ return SetCanonicalCookie(std::move(cc), url.SchemeIsCryptographic(), |
+ !options.exclude_httponly()); |
mmenke
2017/05/22 18:51:27
This is a web-visible behavior change, right? Thi
mmenke
2017/05/22 19:07:04
If this is a web-visible behavior change, this sho
Randy Smith (Not in Mondays)
2017/05/22 21:54:03
Aw, drat, it looks like I refactored a check from
Randy Smith (Not in Mondays)
2017/05/25 20:45:35
Matt: I was digging into this issue more closely
Randy Smith (Not in Mondays)
2017/05/25 20:59:25
Followup: The only place where this might be a beh
|
} |
bool CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc, |
- const GURL& source_url, |
- const CookieOptions& options) { |
+ bool secure_source, |
+ bool modify_http_only) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- Time creation_time = cc->CreationDate(); |
+ // TODO(mmenke): This class assumes each cookie to have a unique creation |
+ // time. Allowing the caller to set the creation time violates that |
+ // assumption. Worth fixing? Worth noting that time changes between browser |
+ // restarts can cause the same issue. |
+ base::Time creation_date = cc->CreationDate(); |
+ if (cc->CreationDate().is_null()) { |
+ creation_date = CurrentTime(); |
+ cc->SetCreationDate(creation_date); |
+ last_time_seen_ = creation_date; |
+ } |
+ |
const std::string key(GetKey(cc->Domain())); |
- bool already_expired = cc->IsExpired(creation_time); |
+ bool already_expired = cc->IsExpired(creation_date); |
+ |
+ if (!secure_source && cc->IsSecure()) |
+ return false; |
- if (DeleteAnyEquivalentCookie(key, *cc, source_url, |
- options.exclude_httponly(), already_expired)) { |
+ if (DeleteAnyEquivalentCookie(key, *cc, secure_source, !modify_http_only, |
+ already_expired)) { |
std::string error; |
error = |
"SetCookie() not clobbering httponly cookie or secure cookie for " |
@@ -1796,10 +1839,10 @@ bool CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc, |
// See InitializeHistograms() for details. |
if (cc->IsPersistent()) { |
histogram_expiration_duration_minutes_->Add( |
- (cc->ExpiryDate() - creation_time).InMinutes()); |
+ (cc->ExpiryDate() - creation_date).InMinutes()); |
} |
- InternalInsertCookie(key, std::move(cc), source_url, true); |
+ InternalInsertCookie(key, std::move(cc), secure_source, true); |
} else { |
VLOG(kVlogSetCookies) << "SetCookie() not storing already expired cookie."; |
} |
@@ -1809,12 +1852,12 @@ bool CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc, |
// make sure that we garbage collect... We can also make the assumption that |
// if a cookie was set, in the common case it will be used soon after, |
// and we will purge the expired cookies in GetCookies(). |
- GarbageCollect(creation_time, key); |
+ GarbageCollect(creation_date, key); |
return true; |
} |
-bool CookieMonster::SetCanonicalCookies(const CookieList& list) { |
+bool CookieMonster::SetCanonicalCookiesInternal(const CookieList& list) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
CookieOptions options; |
@@ -1822,8 +1865,8 @@ bool CookieMonster::SetCanonicalCookies(const CookieList& list) { |
for (const auto& cookie : list) { |
// Use an empty GURL. This method does not support setting secure cookies. |
- if (!SetCanonicalCookie(base::MakeUnique<CanonicalCookie>(cookie), GURL(), |
- options)) { |
+ if (!SetCanonicalCookie(base::MakeUnique<CanonicalCookie>(cookie), false, |
+ true)) { |
return false; |
} |
} |
@@ -2255,7 +2298,7 @@ void CookieMonster::InitializeHistograms() { |
"Cookie.Type", 1, (1 << COOKIE_TYPE_LAST_ENTRY) - 1, |
1 << COOKIE_TYPE_LAST_ENTRY, base::Histogram::kUmaTargetedHistogramFlag); |
histogram_cookie_source_scheme_ = base::LinearHistogram::FactoryGet( |
- "Cookie.CookieSourceScheme", 1, COOKIE_SOURCE_LAST_ENTRY - 1, |
+ "Cookie.CookieSourceScheme2", 1, COOKIE_SOURCE_LAST_ENTRY - 1, |
COOKIE_SOURCE_LAST_ENTRY, base::Histogram::kUmaTargetedHistogramFlag); |
histogram_cookie_delete_equivalent_ = base::LinearHistogram::FactoryGet( |
"Cookie.CookieDeleteEquivalent", 1, |