15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Portions of this code based on Mozilla:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   (netwerk/cookie/src/nsCookieService.cpp)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ***** BEGIN LICENSE BLOCK *****
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Version: MPL 1.1/GPL 2.0/LGPL 2.1
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The contents of this file are subject to the Mozilla Public License Version
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1.1 (the "License"); you may not use this file except in compliance with
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the License. You may obtain a copy of the License at
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.mozilla.org/MPL/
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Software distributed under the License is distributed on an "AS IS" basis,
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for the specific language governing rights and limitations under the
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Original Code is mozilla.org code.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Initial Developer of the Original Code is
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Netscape Communications Corporation.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Portions created by the Initial Developer are Copyright (C) 2003
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the Initial Developer. All Rights Reserved.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Contributor(s):
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   Daniel Witte (dwitte@stanford.edu)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   Michiel van Leeuwen (mvl@exedo.nl)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Alternatively, the contents of this file may be used under the terms of
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * either the GNU General Public License Version 2 or later (the "GPL"), or
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in which case the provisions of the GPL or the LGPL are applicable instead
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of those above. If you wish to allow use of your version of this file only
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * under the terms of either the GPL or the LGPL, and not to allow others to
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * use your version of this file under the terms of the MPL, indicate your
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * decision by deleting the provisions above and replace them with the notice
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and other provisions required by the GPL or the LGPL. If you do not delete
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the provisions above, a recipient may use your version of this file under
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the terms of any one of the MPL, the GPL or the LGPL.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ***** END LICENSE BLOCK ***** */
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_monster.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <functional>
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/scoped_vector.h"
579ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
605e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
615e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
635e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "net/cookies/canonical_cookie.h"
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_util.h"
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/parsed_cookie.h"
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In steady state, most cookie requests can be satisfied by the in memory
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cookie monster store.  However, if a request comes in during the initial
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cookie load, it must be delayed until that load completes. That is done by
75a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// queueing it on CookieMonster::tasks_pending_ and running it when notification
76a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// of cookie load completion is received via CookieMonster::OnLoaded. This
77a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// callback is passed to the persistent store from CookieMonster::InitStore(),
78a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// which is called on the first operation invoked on the CookieMonster.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On the browser critical paths (e.g. for loading initial web pages in a
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// session restore) it may take too long to wait for the full load. If a cookie
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// request is for a specific URL, DoCookieTaskForURL is called, which triggers a
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// priority load if the key is not loaded yet by calling PersistentCookieStore
84a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// :: LoadCookiesForKey. The request is queued in
85a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// CookieMonster::tasks_pending_for_key_ and executed upon receiving
86a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// notification of key load completion via CookieMonster::OnKeyLoaded(). If
87a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// multiple requests for the same eTLD+1 are received before key load
88a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// completion, only the first request calls
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PersistentCookieStore::LoadCookiesForKey, all subsequent requests are queued
90a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// in CookieMonster::tasks_pending_for_key_ and executed upon receiving
91a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// notification of key load completion triggered by the first request for the
92a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// same eTLD+1.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMinutesInTenYears = 10 * 365 * 24 * 60;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See comments at declaration of these variables in cookie_monster.h
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for details.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t CookieMonster::kDomainMaxCookies           = 180;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t CookieMonster::kDomainPurgeCookies         = 30;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t CookieMonster::kMaxCookies                 = 3300;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t CookieMonster::kPurgeCookies               = 300;
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const size_t CookieMonster::kDomainCookiesQuotaLow    = 30;
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const size_t CookieMonster::kDomainCookiesQuotaMedium = 50;
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const size_t CookieMonster::kDomainCookiesQuotaHigh   =
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    kDomainMaxCookies - kDomainPurgeCookies
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    - kDomainCookiesQuotaLow - kDomainCookiesQuotaMedium;
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int CookieMonster::kSafeFromGlobalPurgeDays       = 30;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool ContainsControlCharacter(const std::string& s) {
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if ((*i >= 0) && (*i <= 31))
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return true;
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return false;
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::vector<CanonicalCookie*> CanonicalCookieVector;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Default minimum delay after updating a cookie's LastAccessDate before we
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will update it again.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDefaultAccessUpdateThresholdSeconds = 60;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Comparator to sort cookies from highest creation date to lowest
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// creation date.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct OrderByCreationTimeDesc {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool operator()(const CookieMonster::CookieMap::iterator& a,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const CookieMonster::CookieMap::iterator& b) const {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return a->second->CreationDate() > b->second->CreationDate();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constants for use in VLOG
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kVlogPerCookieMonster = 1;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kVlogPeriodic = 3;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kVlogGarbageCollection = 5;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kVlogSetCookies = 7;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kVlogGetCookies = 9;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mozilla sorts on the path length (longest first), and then it
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sorts by creation time (oldest first).
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The RFC says the sort order for the domain attribute is undefined.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CookieSorter(CanonicalCookie* cc1, CanonicalCookie* cc2) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cc1->Path().length() == cc2->Path().length())
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return cc1->CreationDate() < cc2->CreationDate();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cc1->Path().length() > cc2->Path().length();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool LRACookieSorter(const CookieMonster::CookieMap::iterator& it1,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const CookieMonster::CookieMap::iterator& it2) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cookies accessed less recently should be deleted first.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it1->second->LastAccessDate() != it2->second->LastAccessDate())
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return it1->second->LastAccessDate() < it2->second->LastAccessDate();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In rare cases we might have two cookies with identical last access times.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // To preserve the stability of the sort, in these cases prefer to delete
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // older cookies over newer ones.  CreationDate() is guaranteed to be unique.
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return it1->second->CreationDate() < it2->second->CreationDate();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Our strategy to find duplicates is:
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (1) Build a map from (cookiename, cookiepath) to
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     {list of cookies with this signature, sorted by creation time}.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (2) For each list with more than 1 entry, keep the cookie having the
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     most recent creation time, and delete the others.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Two cookies are considered equivalent if they have the same domain,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// name, and path.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CookieSignature {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CookieSignature(const std::string& name,
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  const std::string& domain,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const std::string& path)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : name(name), domain(domain), path(path) {
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // To be a key for a map this class needs to be assignable, copyable,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and have an operator<.  The default assignment operator
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and copy constructor are exactly what we want.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool operator<(const CookieSignature& cs) const {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Name compare dominates, then domain, then path.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int diff = name.compare(cs.name);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (diff != 0)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return diff < 0;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    diff = domain.compare(cs.domain);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (diff != 0)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return diff < 0;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return path.compare(cs.path) < 0;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string domain;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string path;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// For a CookieItVector iterator range [|it_begin|, |it_end|),
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// sorts the first |num_sort| + 1 elements by LastAccessDate().
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The + 1 element exists so for any interval of length <= |num_sort| starting
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// from |cookies_its_begin|, a LastAccessDate() bound can be found.
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SortLeastRecentlyAccessed(
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CookieMonster::CookieItVector::iterator it_begin,
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CookieMonster::CookieItVector::iterator it_end,
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    size_t num_sort) {
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_LT(static_cast<int>(num_sort), it_end - it_begin);
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::partial_sort(it_begin, it_begin + num_sort + 1, it_end, LRACookieSorter);
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Predicate to support PartitionCookieByPriority().
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct CookiePriorityEqualsTo
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : std::unary_function<const CookieMonster::CookieMap::iterator, bool> {
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CookiePriorityEqualsTo(CookiePriority priority)
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : priority_(priority) {}
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool operator()(const CookieMonster::CookieMap::iterator it) const {
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return it->second->Priority() == priority_;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const CookiePriority priority_;
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// For a CookieItVector iterator range [|it_begin|, |it_end|),
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// moves all cookies with a given |priority| to the beginning of the list.
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Returns: An iterator in [it_begin, it_end) to the first element with
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// priority != |priority|, or |it_end| if all have priority == |priority|.
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CookieMonster::CookieItVector::iterator PartitionCookieByPriority(
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CookieMonster::CookieItVector::iterator it_begin,
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CookieMonster::CookieItVector::iterator it_end,
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CookiePriority priority) {
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return std::partition(it_begin, it_end, CookiePriorityEqualsTo(priority));
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool LowerBoundAccessDateComparator(
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const CookieMonster::CookieMap::iterator it, const Time& access_date) {
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return it->second->LastAccessDate() < access_date;
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// For a CookieItVector iterator range [|it_begin|, |it_end|)
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// from a CookieItVector sorted by LastAccessDate(), returns the
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// first iterator with access date >= |access_date|, or cookie_its_end if this
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// holds for all.
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CookieMonster::CookieItVector::iterator LowerBoundAccessDate(
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const CookieMonster::CookieItVector::iterator its_begin,
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const CookieMonster::CookieItVector::iterator its_end,
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const Time& access_date) {
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return std::lower_bound(its_begin, its_end, access_date,
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          LowerBoundAccessDateComparator);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Mapping between DeletionCause and CookieMonsterDelegate::ChangeCause; the
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// mapping also provides a boolean that specifies whether or not an
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// OnCookieChanged notification ought to be generated.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct ChangeCausePair_struct {
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CookieMonsterDelegate::ChangeCause cause;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool notify;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} ChangeCausePair;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChangeCausePair ChangeCauseMapping[] = {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DELETE_COOKIE_EXPLICIT
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_EXPLICIT, true },
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DELETE_COOKIE_OVERWRITE
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_OVERWRITE, true },
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DELETE_COOKIE_EXPIRED
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_EXPIRED, true },
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DELETE_COOKIE_EVICTED
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_EVICTED, true },
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DELETE_COOKIE_DUPLICATE_IN_BACKING_STORE
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_EXPLICIT, false },
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DELETE_COOKIE_DONT_RECORD
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_EXPLICIT, false },
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DELETE_COOKIE_EVICTED_DOMAIN
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_EVICTED, true },
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DELETE_COOKIE_EVICTED_GLOBAL
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_EVICTED, true },
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DELETE_COOKIE_EVICTED_DOMAIN_PRE_SAFE
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_EVICTED, true },
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DELETE_COOKIE_EVICTED_DOMAIN_POST_SAFE
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_EVICTED, true },
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DELETE_COOKIE_EXPIRED_OVERWRITE
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_EXPIRED_OVERWRITE, true },
28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // DELETE_COOKIE_CONTROL_CHAR
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_EVICTED, true},
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DELETE_COOKIE_LAST_ENTRY
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { CookieMonsterDelegate::CHANGE_COOKIE_EXPLICIT, false }
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string BuildCookieLine(const CanonicalCookieVector& cookies) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cookie_line;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CanonicalCookieVector::const_iterator it = cookies.begin();
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != cookies.end(); ++it) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it != cookies.begin())
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_line += "; ";
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // In Mozilla if you set a cookie like AAAA, it will have an empty token
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and a value of AAAA.  When it sends the cookie back, it will send AAAA,
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // so we need to avoid sending =AAAA for a blank token value.
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(*it)->Name().empty())
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_line += (*it)->Name() + "=";
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cookie_line += (*it)->Value();
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cookie_line;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CookieMonster::CookieMonster(PersistentCookieStore* store,
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             CookieMonsterDelegate* delegate)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : initialized_(false),
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      loaded_(store == NULL),
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      store_(store),
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_access_threshold_(
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          TimeDelta::FromSeconds(kDefaultAccessUpdateThresholdSeconds)),
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate),
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_statistic_record_time_(Time::Now()),
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      keep_expired_cookies_(false),
3220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      persist_session_cookies_(false) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeHistograms();
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetDefaultCookieableSchemes();
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CookieMonster::CookieMonster(PersistentCookieStore* store,
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             CookieMonsterDelegate* delegate,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int last_access_threshold_milliseconds)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : initialized_(false),
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      loaded_(store == NULL),
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      store_(store),
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_access_threshold_(base::TimeDelta::FromMilliseconds(
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          last_access_threshold_milliseconds)),
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate),
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_statistic_record_time_(base::Time::Now()),
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      keep_expired_cookies_(false),
3380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      persist_session_cookies_(false) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeHistograms();
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetDefaultCookieableSchemes();
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task classes for queueing the coming request.
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CookieMonster::CookieMonsterTask
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::RefCountedThreadSafe<CookieMonsterTask> {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Runs the task and invokes the client callback on the thread that
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // originally constructed the task.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Run() = 0;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit CookieMonsterTask(CookieMonster* cookie_monster);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~CookieMonsterTask();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invokes the callback immediately, if the current thread is the one
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that originated the task, or queues the callback for execution on the
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // appropriate thread. Maintains a reference to this CookieMonsterTask
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instance until the callback completes.
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InvokeCallback(base::Closure callback);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CookieMonster* cookie_monster() {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return cookie_monster_;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCountedThreadSafe<CookieMonsterTask>;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CookieMonster* cookie_monster_;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> thread_;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CookieMonsterTask);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CookieMonster::CookieMonsterTask::CookieMonsterTask(
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMonster* cookie_monster)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : cookie_monster_(cookie_monster),
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      thread_(base::MessageLoopProxy::current()) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CookieMonster::CookieMonsterTask::~CookieMonsterTask() {}
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Unfortunately, one cannot re-bind a Callback with parameters into a closure.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Therefore, the closure passed to InvokeCallback is a clumsy binding of
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Callback::Run on a wrapped Callback instance. Since Callback is not
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reference counted, we bind to an instance that is a member of the
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CookieMonsterTask subclass. Then, we cannot simply post the callback to a
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message loop because the underlying instance may be destroyed (along with the
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CookieMonsterTask instance) in the interim. Therefore, we post a callback
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bound to the CookieMonsterTask, which *is* reference counted (thus preventing
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destruction of the original callback), and which invokes the closure (which
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// invokes the original callback with the returned data).
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::CookieMonsterTask::InvokeCallback(base::Closure callback) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (thread_->BelongsToCurrentThread()) {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run();
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    thread_->PostTask(FROM_HERE, base::Bind(
3994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        &CookieMonsterTask::InvokeCallback, this, callback));
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task class for SetCookieWithDetails call.
4044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CookieMonster::SetCookieWithDetailsTask : public CookieMonsterTask {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetCookieWithDetailsTask(CookieMonster* cookie_monster,
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const GURL& url,
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const std::string& name,
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const std::string& value,
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const std::string& domain,
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const std::string& path,
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const base::Time& expiration_time,
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           bool secure,
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           bool http_only,
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           CookiePriority priority,
4164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           const SetCookiesCallback& callback)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : CookieMonsterTask(cookie_monster),
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url_(url),
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name_(name),
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        value_(value),
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        domain_(domain),
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        path_(path),
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        expiration_time_(expiration_time),
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        secure_(secure),
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        http_only_(http_only),
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        priority_(priority),
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback_(callback) {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // CookieMonsterTask:
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Run() OVERRIDE;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SetCookieWithDetailsTask() {}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name_;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string value_;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string domain_;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string path_;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time expiration_time_;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool secure_;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool http_only_;
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CookiePriority priority_;
4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetCookiesCallback callback_;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SetCookieWithDetailsTask);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::SetCookieWithDetailsTask::Run() {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = this->cookie_monster()->
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetCookieWithDetails(url_, name_, value_, domain_, path_,
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           expiration_time_, secure_, http_only_, priority_);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!callback_.is_null()) {
4564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    this->InvokeCallback(base::Bind(&SetCookiesCallback::Run,
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Unretained(&callback_), success));
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task class for GetAllCookies call.
4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CookieMonster::GetAllCookiesTask : public CookieMonsterTask {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetAllCookiesTask(CookieMonster* cookie_monster,
4654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                    const GetCookieListCallback& callback)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : CookieMonsterTask(cookie_monster),
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback_(callback) {
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // CookieMonsterTask
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Run() OVERRIDE;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~GetAllCookiesTask() {}
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetCookieListCallback callback_;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GetAllCookiesTask);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::GetAllCookiesTask::Run() {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!callback_.is_null()) {
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieList cookies = this->cookie_monster()->GetAllCookies();
4854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    this->InvokeCallback(base::Bind(&GetCookieListCallback::Run,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Unretained(&callback_), cookies));
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task class for GetAllCookiesForURLWithOptions call.
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CookieMonster::GetAllCookiesForURLWithOptionsTask
4924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : public CookieMonsterTask {
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetAllCookiesForURLWithOptionsTask(
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CookieMonster* cookie_monster,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const CookieOptions& options,
4984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const GetCookieListCallback& callback)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : CookieMonsterTask(cookie_monster),
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url_(url),
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        options_(options),
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback_(callback) {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // CookieMonsterTask:
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Run() OVERRIDE;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~GetAllCookiesForURLWithOptionsTask() {}
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CookieOptions options_;
5144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetCookieListCallback callback_;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GetAllCookiesForURLWithOptionsTask);
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::GetAllCookiesForURLWithOptionsTask::Run() {
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!callback_.is_null()) {
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieList cookies = this->cookie_monster()->
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetAllCookiesForURLWithOptions(url_, options_);
5234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    this->InvokeCallback(base::Bind(&GetCookieListCallback::Run,
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Unretained(&callback_), cookies));
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)template <typename Result> struct CallbackType {
5294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  typedef base::Callback<void(Result)> Type;
5304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
5314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)template <> struct CallbackType<void> {
5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  typedef base::Closure Type;
5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Base task class for Delete*Task.
5374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)template <typename Result>
5384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CookieMonster::DeleteTask : public CookieMonsterTask {
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
5404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DeleteTask(CookieMonster* cookie_monster,
5414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             const typename CallbackType<Result>::Type& callback)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : CookieMonsterTask(cookie_monster),
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback_(callback) {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // CookieMonsterTask:
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Run() OVERRIDE;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Runs the delete task and returns a result.
5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual Result RunDeleteTask() = 0;
5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::Closure RunDeleteTaskAndBindCallback();
5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void FlushDone(const base::Closure& callback);
5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  typename CallbackType<Result>::Type callback_;
5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteTask);
5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
5594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)template <typename Result>
5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)base::Closure CookieMonster::DeleteTask<Result>::
5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)RunDeleteTaskAndBindCallback() {
5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Result result = RunDeleteTask();
5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (callback_.is_null())
5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return base::Closure();
5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return base::Bind(callback_, result);
5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)template <>
5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)base::Closure CookieMonster::DeleteTask<void>::RunDeleteTaskAndBindCallback() {
5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RunDeleteTask();
5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return callback_;
5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)template <typename Result>
5764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CookieMonster::DeleteTask<Result>::Run() {
5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this->cookie_monster()->FlushStore(
5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&DeleteTask<Result>::FlushDone, this,
5794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 RunDeleteTaskAndBindCallback()));
5804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)template <typename Result>
5834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CookieMonster::DeleteTask<Result>::FlushDone(
5844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const base::Closure& callback) {
5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!callback.is_null()) {
5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    this->InvokeCallback(callback);
5874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Task class for DeleteAll call.
5914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CookieMonster::DeleteAllTask : public DeleteTask<int> {
5924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DeleteAllTask(CookieMonster* cookie_monster,
5944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                const DeleteCallback& callback)
595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : DeleteTask<int>(cookie_monster, callback) {
5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // DeleteTask:
5994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int RunDeleteTask() OVERRIDE;
6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DeleteAllTask() {}
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteAllTask);
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int CookieMonster::DeleteAllTask::RunDeleteTask() {
6094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return this->cookie_monster()->DeleteAll(true);
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task class for DeleteAllCreatedBetween call.
6134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CookieMonster::DeleteAllCreatedBetweenTask : public DeleteTask<int> {
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeleteAllCreatedBetweenTask(CookieMonster* cookie_monster,
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const Time& delete_begin,
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const Time& delete_end,
6184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              const DeleteCallback& callback)
619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : DeleteTask<int>(cookie_monster, callback),
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delete_begin_(delete_begin),
6214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        delete_end_(delete_end) {
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // DeleteTask:
6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int RunDeleteTask() OVERRIDE;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DeleteAllCreatedBetweenTask() {}
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time delete_begin_;
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time delete_end_;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteAllCreatedBetweenTask);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int CookieMonster::DeleteAllCreatedBetweenTask::RunDeleteTask() {
6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return this->cookie_monster()->
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DeleteAllCreatedBetween(delete_begin_, delete_end_);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task class for DeleteAllForHost call.
6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CookieMonster::DeleteAllForHostTask : public DeleteTask<int> {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeleteAllForHostTask(CookieMonster* cookie_monster,
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const GURL& url,
6474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       const DeleteCallback& callback)
648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : DeleteTask<int>(cookie_monster, callback),
6494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        url_(url) {
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // DeleteTask:
6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int RunDeleteTask() OVERRIDE;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DeleteAllForHostTask() {}
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_;
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteAllForHostTask);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int CookieMonster::DeleteAllForHostTask::RunDeleteTask() {
6654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return this->cookie_monster()->DeleteAllForHost(url_);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Task class for DeleteAllCreatedBetweenForHost call.
6693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochclass CookieMonster::DeleteAllCreatedBetweenForHostTask
6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : public DeleteTask<int> {
6713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch public:
6723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  DeleteAllCreatedBetweenForHostTask(
6733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      CookieMonster* cookie_monster,
6743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      Time delete_begin,
6753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      Time delete_end,
6763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      const GURL& url,
6774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const DeleteCallback& callback)
678f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : DeleteTask<int>(cookie_monster, callback),
6793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        delete_begin_(delete_begin),
6803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        delete_end_(delete_end),
6814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        url_(url) {
6823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
6833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // DeleteTask:
6854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int RunDeleteTask() OVERRIDE;
6863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch protected:
6883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  virtual ~DeleteAllCreatedBetweenForHostTask() {}
6893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch private:
6913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  Time delete_begin_;
6923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  Time delete_end_;
6933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  GURL url_;
6943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(DeleteAllCreatedBetweenForHostTask);
6963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch};
6973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int CookieMonster::DeleteAllCreatedBetweenForHostTask::RunDeleteTask() {
6994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return this->cookie_monster()->DeleteAllCreatedBetweenForHost(
7003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      delete_begin_, delete_end_, url_);
7013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
7023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task class for DeleteCanonicalCookie call.
7044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CookieMonster::DeleteCanonicalCookieTask : public DeleteTask<bool> {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeleteCanonicalCookieTask(CookieMonster* cookie_monster,
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            const CanonicalCookie& cookie,
7084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            const DeleteCookieCallback& callback)
709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : DeleteTask<bool>(cookie_monster, callback),
7104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        cookie_(cookie) {
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // DeleteTask:
7144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool RunDeleteTask() OVERRIDE;
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DeleteCanonicalCookieTask() {}
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CanonicalCookie cookie_;
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteCanonicalCookieTask);
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool CookieMonster::DeleteCanonicalCookieTask::RunDeleteTask() {
7264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return this->cookie_monster()->DeleteCanonicalCookie(cookie_);
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task class for SetCookieWithOptions call.
7304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CookieMonster::SetCookieWithOptionsTask : public CookieMonsterTask {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetCookieWithOptionsTask(CookieMonster* cookie_monster,
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const GURL& url,
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string& cookie_line,
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const CookieOptions& options,
7364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           const SetCookiesCallback& callback)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : CookieMonsterTask(cookie_monster),
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url_(url),
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cookie_line_(cookie_line),
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        options_(options),
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback_(callback) {
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // CookieMonsterTask:
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Run() OVERRIDE;
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SetCookieWithOptionsTask() {}
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_;
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cookie_line_;
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CookieOptions options_;
7544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetCookiesCallback callback_;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SetCookieWithOptionsTask);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::SetCookieWithOptionsTask::Run() {
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = this->cookie_monster()->
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetCookieWithOptions(url_, cookie_line_, options_);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!callback_.is_null()) {
7634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    this->InvokeCallback(base::Bind(&SetCookiesCallback::Run,
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Unretained(&callback_), result));
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task class for GetCookiesWithOptions call.
7694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CookieMonster::GetCookiesWithOptionsTask : public CookieMonsterTask {
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCookiesWithOptionsTask(CookieMonster* cookie_monster,
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const GURL& url,
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const CookieOptions& options,
7744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            const GetCookiesCallback& callback)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : CookieMonsterTask(cookie_monster),
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url_(url),
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        options_(options),
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback_(callback) {
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // CookieMonsterTask:
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Run() OVERRIDE;
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~GetCookiesWithOptionsTask() {}
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_;
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CookieOptions options_;
7904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetCookiesCallback callback_;
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GetCookiesWithOptionsTask);
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::GetCookiesWithOptionsTask::Run() {
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cookie = this->cookie_monster()->
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetCookiesWithOptions(url_, options_);
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!callback_.is_null()) {
7994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    this->InvokeCallback(base::Bind(&GetCookiesCallback::Run,
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Unretained(&callback_), cookie));
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task class for DeleteCookie call.
8054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CookieMonster::DeleteCookieTask : public DeleteTask<void> {
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeleteCookieTask(CookieMonster* cookie_monster,
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const GURL& url,
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const std::string& cookie_name,
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const base::Closure& callback)
811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : DeleteTask<void>(cookie_monster, callback),
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url_(url),
8134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        cookie_name_(cookie_name) {
8144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // DeleteTask:
8174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void RunDeleteTask() OVERRIDE;
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DeleteCookieTask() {}
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cookie_name_;
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteCookieTask);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CookieMonster::DeleteCookieTask::RunDeleteTask() {
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this->cookie_monster()->DeleteCookie(url_, cookie_name_);
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task class for DeleteSessionCookies call.
8344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CookieMonster::DeleteSessionCookiesTask : public DeleteTask<int> {
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeleteSessionCookiesTask(CookieMonster* cookie_monster,
8374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           const DeleteCallback& callback)
838f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : DeleteTask<int>(cookie_monster, callback) {
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // DeleteTask:
8424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int RunDeleteTask() OVERRIDE;
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DeleteSessionCookiesTask() {}
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteSessionCookiesTask);
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int CookieMonster::DeleteSessionCookiesTask::RunDeleteTask() {
8534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return this->cookie_monster()->DeleteSessionCookies();
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Task class for HasCookiesForETLDP1Task call.
8574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CookieMonster::HasCookiesForETLDP1Task : public CookieMonsterTask {
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HasCookiesForETLDP1Task(
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CookieMonster* cookie_monster,
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& etldp1,
8624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const HasCookiesForETLDP1Callback& callback)
863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : CookieMonsterTask(cookie_monster),
864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        etldp1_(etldp1),
865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        callback_(callback) {
866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // CookieMonsterTask:
869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Run() OVERRIDE;
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~HasCookiesForETLDP1Task() {}
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string etldp1_;
8764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HasCookiesForETLDP1Callback callback_;
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HasCookiesForETLDP1Task);
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CookieMonster::HasCookiesForETLDP1Task::Run() {
882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool result = this->cookie_monster()->HasCookiesForETLDP1(etldp1_);
883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!callback_.is_null()) {
884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    this->InvokeCallback(
8854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::Bind(&HasCookiesForETLDP1Callback::Run,
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(&callback_), result));
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Asynchronous CookieMonster API
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::SetCookieWithDetailsAsync(
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& url,
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& name,
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& value,
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& domain,
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& path,
8983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const Time& expiration_time,
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool secure,
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool http_only,
901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CookiePriority priority,
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SetCookiesCallback& callback) {
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SetCookieWithDetailsTask> task =
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new SetCookieWithDetailsTask(this, url, name, value, domain, path,
905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   expiration_time, secure, http_only, priority,
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   callback);
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCookieTaskForURL(task, url);
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::GetAllCookiesAsync(const GetCookieListCallback& callback) {
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<GetAllCookiesTask> task =
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new GetAllCookiesTask(this, callback);
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCookieTask(task);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::GetAllCookiesForURLWithOptionsAsync(
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CookieOptions& options,
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GetCookieListCallback& callback) {
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<GetAllCookiesForURLWithOptionsTask> task =
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new GetAllCookiesForURLWithOptionsTask(this, url, options, callback);
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCookieTaskForURL(task, url);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::GetAllCookiesForURLAsync(
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url, const GetCookieListCallback& callback) {
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CookieOptions options;
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.set_include_httponly();
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<GetAllCookiesForURLWithOptionsTask> task =
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new GetAllCookiesForURLWithOptionsTask(this, url, options, callback);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCookieTaskForURL(task, url);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CookieMonster::HasCookiesForETLDP1Async(
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& etldp1,
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const HasCookiesForETLDP1Callback& callback) {
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HasCookiesForETLDP1Task> task =
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new HasCookiesForETLDP1Task(this, etldp1, callback);
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DoCookieTaskForURL(task, GURL("http://" + etldp1));
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::DeleteAllAsync(const DeleteCallback& callback) {
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<DeleteAllTask> task =
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeleteAllTask(this, callback);
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCookieTask(task);
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::DeleteAllCreatedBetweenAsync(
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Time& delete_begin, const Time& delete_end,
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DeleteCallback& callback) {
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<DeleteAllCreatedBetweenTask> task =
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeleteAllCreatedBetweenTask(this, delete_begin, delete_end,
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      callback);
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCookieTask(task);
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid CookieMonster::DeleteAllCreatedBetweenForHostAsync(
9663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const Time delete_begin,
9673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const Time delete_end,
9683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const GURL& url,
9693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const DeleteCallback& callback) {
9703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_refptr<DeleteAllCreatedBetweenForHostTask> task =
9713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      new DeleteAllCreatedBetweenForHostTask(
9723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          this, delete_begin, delete_end, url, callback);
9733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
9743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  DoCookieTaskForURL(task, url);
9753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
9763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::DeleteAllForHostAsync(
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url, const DeleteCallback& callback) {
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<DeleteAllForHostTask> task =
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeleteAllForHostTask(this, url, callback);
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCookieTaskForURL(task, url);
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::DeleteCanonicalCookieAsync(
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CanonicalCookie& cookie,
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DeleteCookieCallback& callback) {
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<DeleteCanonicalCookieTask> task =
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeleteCanonicalCookieTask(this, cookie, callback);
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCookieTask(task);
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::SetCookieWithOptionsAsync(
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& cookie_line,
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CookieOptions& options,
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SetCookiesCallback& callback) {
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SetCookieWithOptionsTask> task =
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new SetCookieWithOptionsTask(this, url, cookie_line, options, callback);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCookieTaskForURL(task, url);
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::GetCookiesWithOptionsAsync(
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CookieOptions& options,
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GetCookiesCallback& callback) {
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<GetCookiesWithOptionsTask> task =
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new GetCookiesWithOptionsTask(this, url, options, callback);
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCookieTaskForURL(task, url);
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::DeleteCookieAsync(const GURL& url,
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const std::string& cookie_name,
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const base::Closure& callback) {
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<DeleteCookieTask> task =
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeleteCookieTask(this, url, cookie_name, callback);
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCookieTaskForURL(task, url);
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::DeleteSessionCookiesAsync(
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CookieStore::DeleteCallback& callback) {
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<DeleteSessionCookiesTask> task =
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeleteSessionCookiesTask(this, callback);
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCookieTask(task);
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::DoCookieTask(
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<CookieMonsterTask>& task_item) {
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock autolock(lock_);
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitIfNecessary();
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!loaded_) {
1038a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      tasks_pending_.push(task_item);
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_item->Run();
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::DoCookieTaskForURL(
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<CookieMonsterTask>& task_item,
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url) {
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock autolock(lock_);
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitIfNecessary();
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If cookies for the requested domain key (eTLD+1) have been loaded from DB
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // then run the task, otherwise load from DB.
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!loaded_) {
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Checks if the domain key has been loaded.
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string key(cookie_util::GetEffectiveDomain(url.scheme(),
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       url.host()));
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (keys_loaded_.find(key) == keys_loaded_.end()) {
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::map<std::string, std::deque<scoped_refptr<CookieMonsterTask> > >
1060a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          ::iterator it = tasks_pending_for_key_.find(key);
1061a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        if (it == tasks_pending_for_key_.end()) {
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          store_->LoadCookiesForKey(key,
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::Bind(&CookieMonster::OnKeyLoaded, this, key));
1064a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          it = tasks_pending_for_key_.insert(std::make_pair(key,
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            std::deque<scoped_refptr<CookieMonsterTask> >())).first;
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        it->second.push_back(task_item);
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_item->Run();
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool CookieMonster::SetCookieWithDetails(const GURL& url,
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const std::string& name,
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const std::string& value,
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const std::string& domain,
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const std::string& path,
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const base::Time& expiration_time,
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool secure,
1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         bool http_only,
1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         CookiePriority priority) {
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasCookieableScheme(url))
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time creation_time = CurrentTime();
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_time_seen_ = creation_time;
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<CanonicalCookie> cc;
1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  cc.reset(CanonicalCookie::Create(url, name, value, domain, path,
1094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   creation_time, expiration_time,
1095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   secure, http_only, priority));
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cc.get())
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CookieOptions options;
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.set_include_httponly();
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SetCanonicalCookie(&cc, creation_time, options);
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CookieMonster::InitializeFrom(const CookieList& list) {
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitIfNecessary();
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (net::CookieList::const_iterator iter = list.begin();
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           iter != list.end(); ++iter) {
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<CanonicalCookie> cookie(new CanonicalCookie(*iter));
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::CookieOptions options;
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    options.set_include_httponly();
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SetCanonicalCookie(&cookie, cookie->CreationDate(), options))
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CookieList CookieMonster::GetAllCookies() {
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This function is being called to scrape the cookie list for management UI
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or similar.  We shouldn't show expired cookies in this list since it will
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just be confusing to users, and this function is called rarely enough (and
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is already slow enough) that it's OK to take the time to garbage collect
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the expired cookies now.
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that this does not prune cookies to be below our limits (if we've
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // exceeded them) the way that calling GarbageCollect() would.
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GarbageCollectExpired(Time::Now(),
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        CookieMapItPair(cookies_.begin(), cookies_.end()),
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        NULL);
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copy the CanonicalCookie pointers from the map so that we can use the same
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sorter as elsewhere, then copy the result out.
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<CanonicalCookie*> cookie_ptrs;
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_ptrs.reserve(cookies_.size());
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end(); ++it)
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cookie_ptrs.push_back(it->second);
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(cookie_ptrs.begin(), cookie_ptrs.end(), CookieSorter);
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CookieList cookie_list;
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_list.reserve(cookie_ptrs.size());
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<CanonicalCookie*>::const_iterator it = cookie_ptrs.begin();
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != cookie_ptrs.end(); ++it)
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cookie_list.push_back(**it);
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cookie_list;
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CookieList CookieMonster::GetAllCookiesForURLWithOptions(
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CookieOptions& options) {
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<CanonicalCookie*> cookie_ptrs;
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindCookiesForHostAndDomain(url, options, false, &cookie_ptrs);
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(cookie_ptrs.begin(), cookie_ptrs.end(), CookieSorter);
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CookieList cookies;
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<CanonicalCookie*>::const_iterator it = cookie_ptrs.begin();
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != cookie_ptrs.end(); it++)
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cookies.push_back(**it);
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cookies;
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CookieList CookieMonster::GetAllCookiesForURL(const GURL& url) {
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CookieOptions options;
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.set_include_httponly();
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetAllCookiesForURLWithOptions(url, options);
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CookieMonster::DeleteAll(bool sync_to_store) {
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_deleted = 0;
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMap::iterator curit = it;
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++it;
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InternalDeleteCookie(curit, sync_to_store,
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         sync_to_store ? DELETE_COOKIE_EXPLICIT :
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             DELETE_COOKIE_DONT_RECORD /* Destruction. */);
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++num_deleted;
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return num_deleted;
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CookieMonster::DeleteAllCreatedBetween(const Time& delete_begin,
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const Time& delete_end) {
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_deleted = 0;
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMap::iterator curit = it;
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CanonicalCookie* cc = curit->second;
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++it;
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cc->CreationDate() >= delete_begin &&
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (delete_end.is_null() || cc->CreationDate() < delete_end)) {
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InternalDeleteCookie(curit,
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           true,  /*sync_to_store*/
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           DELETE_COOKIE_EXPLICIT);
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++num_deleted;
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return num_deleted;
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochint CookieMonster::DeleteAllCreatedBetweenForHost(const Time delete_begin,
12143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                                  const Time delete_end,
12153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                                  const GURL& url) {
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasCookieableScheme(url))
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string host(url.host());
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We store host cookies in the store by their canonical host name;
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // domain cookies are stored with a leading ".".  So this is a pretty
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // simple lookup and per-cookie delete.
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_deleted = 0;
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CookieMapItPair its = cookies_.equal_range(GetKey(host));
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       its.first != its.second;) {
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMap::iterator curit = its.first;
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++its.first;
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CanonicalCookie* const cc = curit->second;
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Delete only on a match as a host cookie.
12353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (cc->IsHostCookie() && cc->IsDomainMatch(host) &&
12363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        cc->CreationDate() >= delete_begin &&
12373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        // The assumption that null |delete_end| is equivalent to
12383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        // Time::Max() is confusing.
12393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        (delete_end.is_null() || cc->CreationDate() < delete_end)) {
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_deleted++;
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InternalDeleteCookie(curit, true, DELETE_COOKIE_EXPLICIT);
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return num_deleted;
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochint CookieMonster::DeleteAllForHost(const GURL& url) {
12493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return DeleteAllCreatedBetweenForHost(Time(), Time::Max(), url);
12503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
12513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
12523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CookieMonster::DeleteCanonicalCookie(const CanonicalCookie& cookie) {
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CookieMapItPair its = cookies_.equal_range(GetKey(cookie.Domain()));
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       its.first != its.second; ++its.first) {
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The creation date acts as our unique index...
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (its.first->second->CreationDate() == cookie.CreationDate()) {
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InternalDeleteCookie(its.first, true, DELETE_COOKIE_EXPLICIT);
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookieMonster::SetCookieableSchemes(const char* schemes[],
12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         size_t num_schemes) {
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cookieable Schemes must be set before first use of function.
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!initialized_);
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookieable_schemes_.clear();
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookieable_schemes_.insert(cookieable_schemes_.end(),
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             schemes, schemes + num_schemes);
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::SetEnableFileScheme(bool accept) {
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This assumes "file" is always at the end of the array. See the comment
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // above kDefaultCookieableSchemes.
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_schemes = accept ? kDefaultCookieableSchemesCount :
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kDefaultCookieableSchemesCount - 1;
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetCookieableSchemes(kDefaultCookieableSchemes, num_schemes);
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::SetKeepExpiredCookies() {
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keep_expired_cookies_ = true;
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::FlushStore(const base::Closure& callback) {
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
1293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (initialized_ && store_.get())
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    store_->Flush(callback);
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (!callback.is_null())
129690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE, callback);
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CookieMonster::SetCookieWithOptions(const GURL& url,
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const std::string& cookie_line,
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const CookieOptions& options) {
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasCookieableScheme(url)) {
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SetCookieWithCreationTimeAndOptions(url, cookie_line, Time(), options);
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string CookieMonster::GetCookiesWithOptions(const GURL& url,
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 const CookieOptions& options) {
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasCookieableScheme(url))
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::string();
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks start_time(TimeTicks::Now());
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<CanonicalCookie*> cookies;
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindCookiesForHostAndDomain(url, options, true, &cookies);
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(cookies.begin(), cookies.end(), CookieSorter);
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cookie_line = BuildCookieLine(cookies);
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_time_get_->AddTime(TimeTicks::Now() - start_time);
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(kVlogGetCookies) << "GetCookies() result: " << cookie_line;
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cookie_line;
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::DeleteCookie(const GURL& url,
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const std::string& cookie_name) {
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasCookieableScheme(url))
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CookieOptions options;
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.set_include_httponly();
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the cookies for this host and its domain(s).
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<CanonicalCookie*> cookies;
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindCookiesForHostAndDomain(url, options, true, &cookies);
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<CanonicalCookie*> matching_cookies;
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<CanonicalCookie*>::const_iterator it = cookies.begin();
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != cookies.end(); ++it) {
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*it)->Name() != cookie_name)
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (url.path().find((*it)->Path()))
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    matching_cookies.insert(*it);
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMap::iterator curit = it;
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++it;
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (matching_cookies.find(curit->second) != matching_cookies.end()) {
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InternalDeleteCookie(curit, true, DELETE_COOKIE_EXPLICIT);
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CookieMonster::DeleteSessionCookies() {
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_deleted = 0;
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMap::iterator curit = it;
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CanonicalCookie* cc = curit->second;
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++it;
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!cc->IsPersistent()) {
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InternalDeleteCookie(curit,
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           true,  /*sync_to_store*/
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           DELETE_COOKIE_EXPIRED);
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++num_deleted;
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return num_deleted;
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool CookieMonster::HasCookiesForETLDP1(const std::string& etldp1) {
1386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::AutoLock autolock(lock_);
1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string key(GetKey(etldp1));
1389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CookieMapItPair its = cookies_.equal_range(key);
1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return its.first != its.second;
1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CookieMonster* CookieMonster::GetCookieMonster() {
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This function must be called before the CookieMonster is used.
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::SetPersistSessionCookies(bool persist_session_cookies) {
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!initialized_);
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  persist_session_cookies_ = persist_session_cookies;
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::SetForceKeepSessionState() {
1405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (store_.get()) {
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    store_->SetForceKeepSessionState();
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CookieMonster::~CookieMonster() {
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeleteAll(false);
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CookieMonster::SetCookieWithCreationTime(const GURL& url,
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const std::string& cookie_line,
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const base::Time& creation_time) {
1417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!store_.get()) << "This method is only to be used by unit-tests.";
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasCookieableScheme(url)) {
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitIfNecessary();
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SetCookieWithCreationTimeAndOptions(url, cookie_line, creation_time,
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             CookieOptions());
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::InitStore() {
1430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(store_.get()) << "Store must exist to initialize";
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We bind in the current time so that we can report the wall-clock time for
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // loading cookies.
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_->Load(base::Bind(&CookieMonster::OnLoaded, this, TimeTicks::Now()));
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void CookieMonster::ReportLoaded() {
1438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (delegate_.get())
1439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    delegate_->OnLoaded();
1440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::OnLoaded(TimeTicks beginning_time,
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::vector<CanonicalCookie*>& cookies) {
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StoreLoadedCookies(cookies);
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_time_blocked_on_load_->AddTime(TimeTicks::Now() - beginning_time);
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoke the task queue of cookie request.
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InvokeQueue();
1449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ReportLoaded();
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::OnKeyLoaded(const std::string& key,
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::vector<CanonicalCookie*>& cookies) {
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This function does its own separate locking.
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StoreLoadedCookies(cookies);
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1458a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::deque<scoped_refptr<CookieMonsterTask> > tasks_pending_for_key;
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // We need to do this repeatedly until no more tasks were added to the queue
14611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // during the period where we release the lock.
14621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  while (true) {
14631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    {
14641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::AutoLock autolock(lock_);
14651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      std::map<std::string, std::deque<scoped_refptr<CookieMonsterTask> > >
14661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        ::iterator it = tasks_pending_for_key_.find(key);
14671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (it == tasks_pending_for_key_.end()) {
14681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        keys_loaded_.insert(key);
14691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        return;
14701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      }
14711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (it->second.empty()) {
14721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        keys_loaded_.insert(key);
14731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        tasks_pending_for_key_.erase(it);
14741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        return;
14751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      }
14761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      it->second.swap(tasks_pending_for_key);
14771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
14781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
14791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    while (!tasks_pending_for_key.empty()) {
14801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      scoped_refptr<CookieMonsterTask> task = tasks_pending_for_key.front();
14811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      task->Run();
14821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      tasks_pending_for_key.pop_front();
14831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::StoreLoadedCookies(
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<CanonicalCookie*>& cookies) {
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize the store and sync in any saved persistent cookies.  We don't
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // care if it's expired, insert it so it can be garbage collected, removed,
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and sync'd.
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
149468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  CookieItVector cookies_with_control_chars;
149568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<CanonicalCookie*>::const_iterator it = cookies.begin();
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != cookies.end(); ++it) {
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 cookie_creation_time = (*it)->CreationDate().ToInternalValue();
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (creation_times_.insert(cookie_creation_time).second) {
150168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      CookieMap::iterator inserted =
150268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          InternalInsertCookie(GetKey((*it)->Domain()), *it, false);
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const Time cookie_access_time((*it)->LastAccessDate());
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (earliest_access_time_.is_null() ||
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          cookie_access_time < earliest_access_time_)
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        earliest_access_time_ = cookie_access_time;
150768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
150868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (ContainsControlCharacter((*it)->Name()) ||
150968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          ContainsControlCharacter((*it)->Value())) {
151068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          cookies_with_control_chars.push_back(inserted);
151168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      }
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << base::StringPrintf("Found cookies with duplicate creation "
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       "times in backing store: "
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       "{name='%s', domain='%s', path='%s'}",
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       (*it)->Name().c_str(),
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       (*it)->Domain().c_str(),
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       (*it)->Path().c_str());
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We've been given ownership of the cookie and are throwing it
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // away; reclaim the space.
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete (*it);
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
152568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Any cookies that contain control characters that we have loaded from the
152668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // persistent store should be deleted. See http://crbug.com/238041.
152768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (CookieItVector::iterator it = cookies_with_control_chars.begin();
152868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)       it != cookies_with_control_chars.end();) {
152968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CookieItVector::iterator curit = it;
153068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ++it;
153168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
153268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    InternalDeleteCookie(*curit, true, DELETE_COOKIE_CONTROL_CHAR);
153368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
153468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After importing cookies from the PersistentCookieStore, verify that
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // none of our other constraints are violated.
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In particular, the backing store might have given us duplicate cookies.
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method could be called multiple times due to priority loading, thus
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cookies loaded in previous runs will be validated again, but this is OK
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since they are expected to be much fewer than total DB.
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnsureCookiesMapIsValid();
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::InvokeQueue() {
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (true) {
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<CookieMonsterTask> request_task;
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::AutoLock autolock(lock_);
1550a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      if (tasks_pending_.empty()) {
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        loaded_ = true;
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        creation_times_.clear();
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keys_loaded_.clear();
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1556a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      request_task = tasks_pending_.front();
1557a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      tasks_pending_.pop();
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_task->Run();
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::EnsureCookiesMapIsValid() {
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_duplicates_trimmed = 0;
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Iterate through all the of the cookies, grouped by host.
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CookieMap::iterator prev_range_end = cookies_.begin();
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (prev_range_end != cookies_.end()) {
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMap::iterator cur_range_begin = prev_range_end;
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string key = cur_range_begin->first;  // Keep a copy.
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMap::iterator cur_range_end = cookies_.upper_bound(key);
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prev_range_end = cur_range_end;
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure no equivalent cookies for this host.
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    num_duplicates_trimmed +=
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TrimDuplicateCookiesForKey(key, cur_range_begin, cur_range_end);
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Record how many duplicates were found in the database.
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See InitializeHistograms() for details.
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_cookie_deletion_cause_->Add(num_duplicates_trimmed);
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CookieMonster::TrimDuplicateCookiesForKey(
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMap::iterator begin,
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMap::iterator end) {
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set of cookies ordered by creation time.
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::set<CookieMap::iterator, OrderByCreationTimeDesc> CookieSet;
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper map we populate to find the duplicates.
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<CookieSignature, CookieSet> EquivalenceMap;
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EquivalenceMap equivalent_cookies;
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The number of duplicate cookies that have been found.
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_duplicates = 0;
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Iterate through all of the cookies in our range, and insert them into
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the equivalence map.
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CookieMap::iterator it = begin; it != end; ++it) {
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_EQ(key, it->first);
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CanonicalCookie* cookie = it->second;
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieSignature signature(cookie->Name(), cookie->Domain(),
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              cookie->Path());
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieSet& set = equivalent_cookies[signature];
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We found a duplicate!
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!set.empty())
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_duplicates++;
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We save the iterator into |cookies_| rather than the actual cookie
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // pointer, since we may need to delete it later.
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool insert_success = set.insert(it).second;
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(insert_success) <<
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "Duplicate creation times found in duplicate cookie name scan.";
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there were no duplicates, we are done!
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (num_duplicates == 0)
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we find everything below that we did above.
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_duplicates_found = 0;
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Otherwise, delete all the duplicate cookies, both from our in-memory store
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and from the backing store.
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (EquivalenceMap::iterator it = equivalent_cookies.begin();
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != equivalent_cookies.end();
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++it) {
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CookieSignature& signature = it->first;
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieSet& dupes = it->second;
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dupes.size() <= 1)
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;  // This cookiename/path has no duplicates.
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    num_duplicates_found += dupes.size() - 1;
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Since |dups| is sorted by creation time (descending), the first cookie
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // is the most recent one, so we will keep it. The rest are duplicates.
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dupes.erase(dupes.begin());
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << base::StringPrintf(
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "Found %d duplicate cookies for host='%s', "
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "with {name='%s', domain='%s', path='%s'}",
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<int>(dupes.size()),
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        key.c_str(),
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        signature.name.c_str(),
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        signature.domain.c_str(),
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        signature.path.c_str());
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Remove all the cookies identified by |dupes|. It is valid to delete our
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // list of iterators one at a time, since |cookies_| is a multimap (they
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // don't invalidate existing iterators following deletion).
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (CookieSet::iterator dupes_it = dupes.begin();
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         dupes_it != dupes.end();
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         ++dupes_it) {
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InternalDeleteCookie(*dupes_it, true,
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           DELETE_COOKIE_DUPLICATE_IN_BACKING_STORE);
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(num_duplicates, num_duplicates_found);
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return num_duplicates;
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: file must be the last scheme.
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* CookieMonster::kDefaultCookieableSchemes[] =
1672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    { "http", "https", "ws", "wss", "file" };
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int CookieMonster::kDefaultCookieableSchemesCount =
16744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    arraysize(kDefaultCookieableSchemes);
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::SetDefaultCookieableSchemes() {
16775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Always disable file scheme unless SetEnableFileScheme(true) is called.
16785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetCookieableSchemes(kDefaultCookieableSchemes,
16795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       kDefaultCookieableSchemesCount - 1);
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::FindCookiesForHostAndDomain(
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CookieOptions& options,
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool update_access_time,
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<CanonicalCookie*>* cookies) {
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Time current_time(CurrentTime());
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Probe to save statistics relatively frequently.  We do it here rather
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // than in the set path as many websites won't set cookies, and we
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // want to collect statistics whenever the browser's being used.
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RecordPeriodicStats(current_time);
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Can just dispatch to FindCookiesForKey
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string key(GetKey(url.host()));
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindCookiesForKey(key, url, options, current_time,
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    update_access_time, cookies);
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookieMonster::FindCookiesForKey(const std::string& key,
17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const GURL& url,
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const CookieOptions& options,
17052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const Time& current,
17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      bool update_access_time,
17072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      std::vector<CanonicalCookie*>* cookies) {
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CookieMapItPair its = cookies_.equal_range(key);
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       its.first != its.second; ) {
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMap::iterator curit = its.first;
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CanonicalCookie* cc = curit->second;
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++its.first;
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the cookie is expired, delete it.
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cc->IsExpired(current) && !keep_expired_cookies_) {
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InternalDeleteCookie(curit, true, DELETE_COOKIE_EXPIRED);
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Filter out cookies that should not be included for a request to the
17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // given |url|. HTTP only cookies are filtered depending on the passed
17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // cookie |options|.
17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!cc->IncludeForRequestURL(url, options))
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Add this cookie to the set of matching cookies. Update the access
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // time if we've been requested to do so.
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (update_access_time) {
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InternalUpdateCookieAccessTime(cc, current);
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cookies->push_back(cc);
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CookieMonster::DeleteAnyEquivalentCookie(const std::string& key,
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const CanonicalCookie& ecc,
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              bool skip_httponly,
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              bool already_expired) {
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool found_equivalent_cookie = false;
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool skipped_httponly = false;
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CookieMapItPair its = cookies_.equal_range(key);
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       its.first != its.second; ) {
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMap::iterator curit = its.first;
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CanonicalCookie* cc = curit->second;
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++its.first;
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ecc.IsEquivalent(*cc)) {
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We should never have more than one equivalent cookie, since they should
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // overwrite each other.
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK(!found_equivalent_cookie) <<
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "Duplicate equivalent cookies found, cookie store is corrupted.";
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (skip_httponly && cc->IsHttpOnly()) {
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        skipped_httponly = true;
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        InternalDeleteCookie(curit, true, already_expired ?
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DELETE_COOKIE_EXPIRED_OVERWRITE : DELETE_COOKIE_OVERWRITE);
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      found_equivalent_cookie = true;
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return skipped_httponly;
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
176868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie(
176968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& key,
177068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CanonicalCookie* cc,
177168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    bool sync_to_store) {
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if ((cc->IsPersistent() || persist_session_cookies_) && store_.get() &&
1775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sync_to_store)
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    store_->AddCookie(*cc);
177768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  CookieMap::iterator inserted =
177868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      cookies_.insert(CookieMap::value_type(key, cc));
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_.get()) {
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnCookieChanged(
17815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        *cc, false, CookieMonsterDelegate::CHANGE_COOKIE_EXPLICIT);
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
178368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
178468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return inserted;
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CookieMonster::SetCookieWithCreationTimeAndOptions(
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& cookie_line,
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Time& creation_time_or_null,
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CookieOptions& options) {
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(kVlogSetCookies) << "SetCookie() line: " << cookie_line;
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time creation_time = creation_time_or_null;
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (creation_time.is_null()) {
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    creation_time = CurrentTime();
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_time_seen_ = creation_time;
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<CanonicalCookie> cc(
18032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CanonicalCookie::Create(url, cookie_line, creation_time, options));
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cc.get()) {
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VLOG(kVlogSetCookies) << "WARNING: Failed to allocate CanonicalCookie";
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SetCanonicalCookie(&cc, creation_time, options);
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CookieMonster::SetCanonicalCookie(scoped_ptr<CanonicalCookie>* cc,
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const Time& creation_time,
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const CookieOptions& options) {
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string key(GetKey((*cc)->Domain()));
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool already_expired = (*cc)->IsExpired(creation_time);
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (DeleteAnyEquivalentCookie(key, **cc, options.exclude_httponly(),
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                already_expired)) {
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VLOG(kVlogSetCookies) << "SetCookie() not clobbering httponly cookie";
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(kVlogSetCookies) << "SetCookie() key: " << key << " cc: "
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        << (*cc)->DebugString();
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Realize that we might be setting an expired cookie, and the only point
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // was to delete the cookie which we've already done.
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!already_expired || keep_expired_cookies_) {
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // See InitializeHistograms() for details.
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*cc)->IsPersistent()) {
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      histogram_expiration_duration_minutes_->Add(
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ((*cc)->ExpiryDate() - creation_time).InMinutes());
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InternalInsertCookie(key, cc->release(), true);
18362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
18372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VLOG(kVlogSetCookies) << "SetCookie() not storing already expired cookie.";
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We assume that hopefully setting a cookie will be less common than
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // querying a cookie.  Since setting a cookie can put us over our limits,
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // make sure that we garbage collect...  We can also make the assumption that
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // if a cookie was set, in the common case it will be used soon after,
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and we will purge the expired cookies in GetCookies().
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GarbageCollect(creation_time, key);
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::InternalUpdateCookieAccessTime(CanonicalCookie* cc,
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   const Time& current) {
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Based off the Mozilla code.  When a cookie has been accessed recently,
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // don't bother updating its access time again.  This reduces the number of
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // updates we do during pageload, which in turn reduces the chance our storage
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // backend will hit its batch thresholds and be forced to update.
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((current - cc->LastAccessDate()) < last_access_threshold_)
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See InitializeHistograms() for details.
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_between_access_interval_minutes_->Add(
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (current - cc->LastAccessDate()).InMinutes());
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cc->SetLastAccessDate(current);
1866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if ((cc->IsPersistent() || persist_session_cookies_) && store_.get())
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    store_->UpdateCookieAccessTime(*cc);
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
187068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// InternalDeleteCookies must not invalidate iterators other than the one being
187168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// deleted.
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::InternalDeleteCookie(CookieMap::iterator it,
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         bool sync_to_store,
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         DeletionCause deletion_cause) {
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ideally, this would be asserted up where we define ChangeCauseMapping,
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but DeletionCause's visibility (or lack thereof) forces us to make
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this check here.
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(arraysize(ChangeCauseMapping) == DELETE_COOKIE_LAST_ENTRY + 1,
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ChangeCauseMapping_size_not_eq_DeletionCause_enum_size);
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See InitializeHistograms() for details.
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (deletion_cause != DELETE_COOKIE_DONT_RECORD)
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    histogram_cookie_deletion_cause_->Add(deletion_cause);
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CanonicalCookie* cc = it->second;
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(kVlogSetCookies) << "InternalDeleteCookie() cc: " << cc->DebugString();
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if ((cc->IsPersistent() || persist_session_cookies_) && store_.get() &&
1891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sync_to_store)
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    store_->DeleteCookie(*cc);
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_.get()) {
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChangeCausePair mapping = ChangeCauseMapping[deletion_cause];
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mapping.notify)
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->OnCookieChanged(*cc, true, mapping.cause);
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookies_.erase(it);
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete cc;
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Domain expiry behavior is unchanged by key/expiry scheme (the
1904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// meaning of the key is different, but that's not visible to this routine).
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CookieMonster::GarbageCollect(const Time& current,
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const std::string& key) {
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_deleted = 0;
1910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Time safe_date(
1911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Time::Now() - TimeDelta::FromDays(kSafeFromGlobalPurgeDays));
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Collect garbage for this key, minding cookie priorities.
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cookies_.count(key) > kDomainMaxCookies) {
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VLOG(kVlogGarbageCollection) << "GarbageCollect() key: " << key;
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CookieItVector cookie_its;
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    num_deleted += GarbageCollectExpired(
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current, cookies_.equal_range(key), &cookie_its);
1920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (cookie_its.size() > kDomainMaxCookies) {
1921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      VLOG(kVlogGarbageCollection) << "Deep Garbage Collect domain.";
1922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_t purge_goal =
1923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          cookie_its.size() - (kDomainMaxCookies - kDomainPurgeCookies);
1924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DCHECK(purge_goal > kDomainPurgeCookies);
1925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Boundary iterators into |cookie_its| for different priorities.
1927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CookieItVector::iterator it_bdd[4];
1928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Intialize |it_bdd| while sorting |cookie_its| by priorities.
1929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Schematic: [MLLHMHHLMM] => [LLL|MMMM|HHH], with 4 boundaries.
1930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      it_bdd[0] = cookie_its.begin();
1931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      it_bdd[3] = cookie_its.end();
1932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      it_bdd[1] = PartitionCookieByPriority(it_bdd[0], it_bdd[3],
1933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                            COOKIE_PRIORITY_LOW);
1934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      it_bdd[2] = PartitionCookieByPriority(it_bdd[1], it_bdd[3],
1935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                            COOKIE_PRIORITY_MEDIUM);
1936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_t quota[3] = {
1937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        kDomainCookiesQuotaLow,
1938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        kDomainCookiesQuotaMedium,
1939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        kDomainCookiesQuotaHigh
1940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      };
1941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Purge domain cookies in 3 rounds.
1943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Round 1: consider low-priority cookies only: evict least-recently
1944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      //   accessed, while protecting quota[0] of these from deletion.
1945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Round 2: consider {low, medium}-priority cookies, evict least-recently
1946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      //   accessed, while protecting quota[0] + quota[1].
1947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Round 3: consider all cookies, evict least-recently accessed.
1948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_t accumulated_quota = 0;
1949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CookieItVector::iterator it_purge_begin = it_bdd[0];
1950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (int i = 0; i < 3 && purge_goal > 0; ++i) {
1951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        accumulated_quota += quota[i];
1952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        size_t num_considered = it_bdd[i + 1] - it_purge_begin;
1954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (num_considered <= accumulated_quota)
1955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          continue;
1956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Number of cookies that will be purged in this round.
1958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        size_t round_goal =
1959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            std::min(purge_goal, num_considered - accumulated_quota);
1960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        purge_goal -= round_goal;
1961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        SortLeastRecentlyAccessed(it_purge_begin, it_bdd[i + 1], round_goal);
1963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Cookies accessed on or after |safe_date| would have been safe from
1964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // global purge, and we want to keep track of this.
1965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CookieItVector::iterator it_purge_end = it_purge_begin + round_goal;
1966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CookieItVector::iterator it_purge_middle =
1967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            LowerBoundAccessDate(it_purge_begin, it_purge_end, safe_date);
1968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Delete cookies accessed before |safe_date|.
1969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        num_deleted += GarbageCollectDeleteRange(
1970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            current,
1971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            DELETE_COOKIE_EVICTED_DOMAIN_PRE_SAFE,
1972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            it_purge_begin,
1973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            it_purge_middle);
1974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Delete cookies accessed on or after |safe_date|.
1975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        num_deleted += GarbageCollectDeleteRange(
1976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            current,
1977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            DELETE_COOKIE_EVICTED_DOMAIN_POST_SAFE,
1978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            it_purge_middle,
1979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            it_purge_end);
1980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        it_purge_begin = it_purge_end;
1981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
1982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DCHECK_EQ(0U, purge_goal);
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Collect garbage for everything. With firefox style we want to preserve
1987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // cookies accessed in kSafeFromGlobalPurgeDays, otherwise evict.
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cookies_.size() > kMaxCookies &&
1989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      earliest_access_time_ < safe_date) {
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VLOG(kVlogGarbageCollection) << "GarbageCollect() everything";
1991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CookieItVector cookie_its;
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    num_deleted += GarbageCollectExpired(
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current, CookieMapItPair(cookies_.begin(), cookies_.end()),
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &cookie_its);
1995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (cookie_its.size() > kMaxCookies) {
1996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      VLOG(kVlogGarbageCollection) << "Deep Garbage Collect everything.";
1997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_t purge_goal = cookie_its.size() - (kMaxCookies - kPurgeCookies);
1998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DCHECK(purge_goal > kPurgeCookies);
1999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Sorts up to *and including* |cookie_its[purge_goal]|, so
2000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // |earliest_access_time| will be properly assigned even if
2001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // |global_purge_it| == |cookie_its.begin() + purge_goal|.
2002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SortLeastRecentlyAccessed(cookie_its.begin(), cookie_its.end(),
2003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                purge_goal);
2004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Find boundary to cookies older than safe_date.
2005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CookieItVector::iterator global_purge_it =
2006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          LowerBoundAccessDate(cookie_its.begin(),
2007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               cookie_its.begin() + purge_goal,
2008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               safe_date);
2009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Only delete the old cookies.
2010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      num_deleted += GarbageCollectDeleteRange(
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          current,
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          DELETE_COOKIE_EVICTED_GLOBAL,
2013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          cookie_its.begin(),
2014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          global_purge_it);
2015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Set access day to the oldest cookie that wasn't deleted.
2016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      earliest_access_time_ = (*global_purge_it)->second->LastAccessDate();
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return num_deleted;
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CookieMonster::GarbageCollectExpired(
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Time& current,
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CookieMapItPair& itpair,
2026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CookieItVector* cookie_its) {
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (keep_expired_cookies_)
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_deleted = 0;
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CookieMap::iterator it = itpair.first, end = itpair.second; it != end;) {
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMap::iterator curit = it;
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++it;
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (curit->second->IsExpired(current)) {
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InternalDeleteCookie(curit, true, DELETE_COOKIE_EXPIRED);
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++num_deleted;
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (cookie_its) {
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_its->push_back(curit);
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return num_deleted;
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int CookieMonster::GarbageCollectDeleteRange(
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Time& current,
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeletionCause cause,
20514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CookieItVector::iterator it_begin,
20524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CookieItVector::iterator it_end) {
2053c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (CookieItVector::iterator it = it_begin; it != it_end; it++) {
2054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    histogram_evicted_last_access_minutes_->Add(
2055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        (current - (*it)->second->LastAccessDate()).InMinutes());
2056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    InternalDeleteCookie((*it), true, cause);
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return it_end - it_begin;
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2061a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// A wrapper around registry_controlled_domains::GetDomainAndRegistry
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to make clear we're creating a key for our local map.  Here and
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in FindCookiesForHostAndDomain() are the only two places where
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we need to conditionalize based on key type.
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that this key algorithm explicitly ignores the scheme.  This is
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// because when we're entering cookies into the map from the backing store,
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we in general won't have the scheme at that point.
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In practical terms, this means that file cookies will be stored
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the map either by an empty string or by UNC name (and will be
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// limited by kMaxCookiesPerHost), and extension cookies will be stored
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// based on the single extension id, as the extension id won't have the
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// form of a DNS host and hence GetKey() will return it unchanged.
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Arguably the right thing to do here is to make the key
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// algorithm dependent on the scheme, and make sure that the scheme is
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// available everywhere the key must be obtained (specfically at backing
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// store load time).  This would require either changing the backing store
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// database schema to include the scheme (far more trouble than it's worth), or
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// separating out file cookies into their own CookieMonster instance and
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thus restricting each scheme to a single cookie monster (which might
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be worth it, but is still too much trouble to solve what is currently a
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// non-problem).
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string CookieMonster::GetKey(const std::string& domain) const {
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string effective_domain(
2086a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      registry_controlled_domains::GetDomainAndRegistry(
20875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          domain, registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (effective_domain.empty())
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    effective_domain = domain;
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!effective_domain.empty() && effective_domain[0] == '.')
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return effective_domain.substr(1);
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return effective_domain;
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CookieMonster::IsCookieableScheme(const std::string& scheme) {
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock autolock(lock_);
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::find(cookieable_schemes_.begin(), cookieable_schemes_.end(),
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   scheme) != cookieable_schemes_.end();
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CookieMonster::HasCookieableScheme(const GURL& url) {
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the request is on a cookie-able url scheme.
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < cookieable_schemes_.size(); ++i) {
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We matched a scheme.
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (url.SchemeIs(cookieable_schemes_[i].c_str())) {
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We've matched a supported scheme.
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The scheme didn't match any in our whitelist.
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(kVlogPerCookieMonster) << "WARNING: Unsupported cookie scheme: "
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              << url.scheme();
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test to see if stats should be recorded, and record them if so.
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The goal here is to get sampling for the average browser-hour of
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// activity.  We won't take samples when the web isn't being surfed,
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and when the web is being surfed, we'll take samples about every
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// kRecordStatisticsIntervalSeconds.
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// last_statistic_record_time_ is initialized to Now() rather than null
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the constructor so that we won't take statistics right after
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// startup, to avoid bias from browsers that are started but not used.
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::RecordPeriodicStats(const base::Time& current_time) {
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::TimeDelta kRecordStatisticsIntervalTime(
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromSeconds(kRecordStatisticsIntervalSeconds));
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we've taken statistics recently, return.
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_time - last_statistic_record_time_ <=
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRecordStatisticsIntervalTime) {
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See InitializeHistograms() for details.
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_count_->Add(cookies_.size());
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // More detailed statistics on cookie counts at different granularities.
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks beginning_of_time(TimeTicks::Now());
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (CookieMap::const_iterator it_key = cookies_.begin();
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it_key != cookies_.end(); ) {
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key(it_key->first);
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int key_count = 0;
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef std::map<std::string, unsigned int> DomainMap;
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DomainMap domain_map;
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieMapItPair its_cookies = cookies_.equal_range(key);
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (its_cookies.first != its_cookies.second) {
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key_count++;
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& cookie_domain(its_cookies.first->second->Domain());
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      domain_map[cookie_domain]++;
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      its_cookies.first++;
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    histogram_etldp1_count_->Add(key_count);
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    histogram_domain_per_etldp1_count_->Add(domain_map.size());
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (DomainMap::const_iterator domain_map_it = domain_map.begin();
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         domain_map_it != domain_map.end(); domain_map_it++)
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      histogram_domain_count_->Add(domain_map_it->second);
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    it_key = its_cookies.second;
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(kVlogPeriodic)
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Time for recording cookie stats (us): "
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << (TimeTicks::Now() - beginning_of_time).InMicroseconds();
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_statistic_record_time_ = current_time;
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initialize all histogram counter variables used in this class.
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Normal histogram usage involves using the macros defined in
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// histogram.h, which automatically takes care of declaring these
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// variables (as statics), initializing them, and accumulating into
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// them, all from a single entry point.  Unfortunately, that solution
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// doesn't work for the CookieMonster, as it's vulnerable to races between
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// separate threads executing the same functions and hence initializing the
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// same static variables.  There isn't a race danger in the histogram
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// accumulation calls; they are written to be resilient to simultaneous
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// calls from multiple threads.
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The solution taken here is to have per-CookieMonster instance
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// variables that are constructed during CookieMonster construction.
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that these variables refer to the same underlying histogram,
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// so we still race (but safely) with other CookieMonster instances
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for accumulation.
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// To do this we've expanded out the individual histogram macros calls,
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with declarations of the variables in the class decl, initialization here
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (done from the class constructor) and direct calls to the accumulation
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// methods where needed.  The specific histogram macro calls on which the
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// initialization is based are included in comments below.
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CookieMonster::InitializeHistograms() {
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // From UMA_HISTOGRAM_CUSTOM_COUNTS
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_expiration_duration_minutes_ = base::Histogram::FactoryGet(
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cookie.ExpirationDurationMinutes",
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, kMinutesInTenYears, 50,
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Histogram::kUmaTargetedHistogramFlag);
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_between_access_interval_minutes_ = base::Histogram::FactoryGet(
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cookie.BetweenAccessIntervalMinutes",
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, kMinutesInTenYears, 50,
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Histogram::kUmaTargetedHistogramFlag);
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_evicted_last_access_minutes_ = base::Histogram::FactoryGet(
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cookie.EvictedLastAccessMinutes",
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, kMinutesInTenYears, 50,
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Histogram::kUmaTargetedHistogramFlag);
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_count_ = base::Histogram::FactoryGet(
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cookie.Count", 1, 4000, 50,
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Histogram::kUmaTargetedHistogramFlag);
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_domain_count_ = base::Histogram::FactoryGet(
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cookie.DomainCount", 1, 4000, 50,
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Histogram::kUmaTargetedHistogramFlag);
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_etldp1_count_ = base::Histogram::FactoryGet(
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cookie.Etldp1Count", 1, 4000, 50,
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Histogram::kUmaTargetedHistogramFlag);
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_domain_per_etldp1_count_ = base::Histogram::FactoryGet(
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cookie.DomainPerEtldp1Count", 1, 4000, 50,
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Histogram::kUmaTargetedHistogramFlag);
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // From UMA_HISTOGRAM_COUNTS_10000 & UMA_HISTOGRAM_CUSTOM_COUNTS
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_number_duplicate_db_cookies_ = base::Histogram::FactoryGet(
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Net.NumDuplicateCookiesInDb", 1, 10000, 50,
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Histogram::kUmaTargetedHistogramFlag);
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // From UMA_HISTOGRAM_ENUMERATION
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_cookie_deletion_cause_ = base::LinearHistogram::FactoryGet(
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cookie.DeletionCause", 1,
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DELETE_COOKIE_LAST_ENTRY - 1, DELETE_COOKIE_LAST_ENTRY,
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Histogram::kUmaTargetedHistogramFlag);
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // From UMA_HISTOGRAM_{CUSTOM_,}TIMES
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_time_get_ = base::Histogram::FactoryTimeGet("Cookie.TimeGet",
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50, base::Histogram::kUmaTargetedHistogramFlag);
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_time_blocked_on_load_ = base::Histogram::FactoryTimeGet(
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Cookie.TimeBlockedOnLoad",
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50, base::Histogram::kUmaTargetedHistogramFlag);
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The system resolution is not high enough, so we can have multiple
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// set cookies that result in the same system time.  When this happens, we
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// increment by one Time unit.  Let's hope computers don't get too fast.
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time CookieMonster::CurrentTime() {
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::max(Time::Now(),
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::FromInternalValue(last_time_seen_.ToInternalValue() + 1));
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool CookieMonster::CopyCookiesForKeyToOtherCookieMonster(
2257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::string key,
2258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CookieMonster* other) {
2259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ScopedVector<CanonicalCookie> duplicated_cookies;
2260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  {
2262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::AutoLock autolock(lock_);
2263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(other);
2264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!loaded_)
2265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return false;
2266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (CookieMapItPair its = cookies_.equal_range(key);
2268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         its.first != its.second;
2269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         ++its.first) {
2270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      CookieMap::iterator curit = its.first;
2271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      CanonicalCookie* cc = curit->second;
2272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      duplicated_cookies.push_back(cc->Duplicate());
2274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
2275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  {
2278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::AutoLock autolock(other->lock_);
2279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!other->loaded_)
2280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return false;
2281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // There must not exist any entries for the key to be copied in |other|.
2283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CookieMapItPair its = other->cookies_.equal_range(key);
2284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (its.first != its.second)
2285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return false;
2286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Store the copied cookies in |other|.
2288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (ScopedVector<CanonicalCookie>::const_iterator it =
2289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             duplicated_cookies.begin();
2290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         it != duplicated_cookies.end();
2291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         ++it) {
2292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      other->InternalInsertCookie(key, *it, true);
2293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
2294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Since the cookies are owned by |other| now, weak clear must be used.
2296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    duplicated_cookies.weak_clear();
2297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
2300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool CookieMonster::loaded() {
2303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::AutoLock autolock(lock_);
2304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return loaded_;
2305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
2308