1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PRERENDER_PRERENDER_COOKIE_STORE_H_
#define CHROME_BROWSER_PRERENDER_PRERENDER_COOKIE_STORE_H_
#include <set>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store.h"
#include "url/gurl.h"
namespace prerender {
// A cookie store which keeps track of provisional changes to the cookie monster
// of an underlying request context (called the default cookie monster).
// Initially, it will proxy read requests to the default cookie monster, and
// copy on write keys that are being modified into a private cookie monster.
// Reads for these will then happen from the private cookie monster.
// Should keys be modified in the default cookie store, the corresponding
// prerender should be aborted.
// This class also keeps a log of all cookie transactions. Once ApplyChanges
// is called, the changes will be applied to the default cookie monster,
// and any future requests to this object will simply be forwarded to the
// default cookie monster. After ApplyChanges is called, the prerender tracker,
// which "owns" the PrerenderCookieStore reference, will remove its entry for
// the PrerenderCookieStore. Therefore, after ApplyChanges is called, the
// object will only stick around (and exhibit forwarding mode) as long as
// eg pending requests hold on to its reference.
class PrerenderCookieStore : public net::CookieStore {
public:
// Creates a PrerenderCookieStore using the default cookie monster provided
// by the URLRequestContext. The underlying cookie store must be loaded,
// ie it's call to loaded() must return true.
// Otherwise, copying cookie data between the prerender cookie store
// (used to only commit cookie changes once a prerender is shown) would
// not work synchronously, which would complicate the code.
// |cookie_conflict_cb| will be called when a cookie conflict is detected.
// The callback will be run on the UI thread.
PrerenderCookieStore(scoped_refptr<net::CookieMonster> default_cookie_store_,
const base::Closure& cookie_conflict_cb);
// CookieStore implementation
void SetCookieWithOptionsAsync(const GURL& url,
const std::string& cookie_line,
const net::CookieOptions& options,
const SetCookiesCallback& callback) override;
void GetCookiesWithOptionsAsync(const GURL& url,
const net::CookieOptions& options,
const GetCookiesCallback& callback) override;
void GetAllCookiesForURLAsync(const GURL& url,
const GetCookieListCallback& callback) override;
void DeleteCookieAsync(const GURL& url,
const std::string& cookie_name,
const base::Closure& callback) override;
// All the following methods should not be used in the scenarios where
// a PrerenderCookieStore is used. This will be checked via NOTREACHED().
// Should PrerenderCookieStore used in contexts requiring these, they will
// need to be implemented first. They are only intended to be called on the
// IO thread.
void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin,
const base::Time& delete_end,
const DeleteCallback& callback) override;
void DeleteAllCreatedBetweenForHostAsync(
const base::Time delete_begin,
const base::Time delete_end,
const GURL& url,
const DeleteCallback& callback) override;
void DeleteSessionCookiesAsync(const DeleteCallback&) override;
net::CookieMonster* GetCookieMonster() override;
scoped_ptr<net::CookieStore::CookieChangedSubscription> AddCallbackForCookie(
const GURL& url,
const std::string& name,
const CookieChangedCallback& callback) override;
// Commits the changes made to the underlying cookie store, and switches
// into forwarding mode. To be called on the IO thread.
// |cookie_change_urls| will be populated with all URLs for which cookies
// were updated.
void ApplyChanges(std::vector<GURL>* cookie_change_urls);
// Called when a cookie for a URL is changed in the underlying default cookie
// store. To be called on the IO thread. If the key corresponding to the URL
// was copied or read, the prerender will be cancelled.
void OnCookieChangedForURL(net::CookieMonster* cookie_monster,
const GURL& url);
net::CookieMonster* default_cookie_monster() {
return default_cookie_monster_.get();
}
private:
enum CookieOperationType {
COOKIE_OP_SET_COOKIE_WITH_OPTIONS_ASYNC,
COOKIE_OP_GET_COOKIES_WITH_OPTIONS_ASYNC,
COOKIE_OP_GET_ALL_COOKIES_FOR_URL_ASYNC,
COOKIE_OP_DELETE_COOKIE_ASYNC,
COOKIE_OP_MAX
};
struct CookieOperation {
CookieOperationType op;
GURL url;
net::CookieOptions options;
std::string cookie_line;
std::string cookie_name;
CookieOperation();
~CookieOperation();
};
~PrerenderCookieStore() override;
// Gets the appropriate cookie store for the operation provided, and pushes
// it back on the log of cookie operations performed.
net::CookieStore* GetCookieStoreForCookieOpAndLog(const CookieOperation& op);
// Indicates whether the changes have already been applied (ie the prerender
// has been shown), and we are merely in forwarding mode;
bool in_forwarding_mode_;
// The default cookie monster.
scoped_refptr<net::CookieMonster> default_cookie_monster_;
// A cookie monster storing changes made by the prerender.
// Entire keys are copied from default_cookie_monster_ on change, and then
// modified.
scoped_refptr<net::CookieMonster> changes_cookie_monster_;
// Log of cookie operations performed
std::vector<CookieOperation> cookie_ops_;
// The keys which have been copied on write to |changes_cookie_monster_|.
std::set<std::string> copied_keys_;
// Keys which have been read (but not necessarily been modified).
std::set<std::string> read_keys_;
// Callback when a cookie conflict was detected
base::Closure cookie_conflict_cb_;
// Indicates whether a cookie conflict has been detected yet.
bool cookie_conflict_;
DISALLOW_COPY_AND_ASSIGN(PrerenderCookieStore);
};
} // namespace prerender
#endif // CHROME_BROWSER_PRERENDER_PRERENDER_COOKIE_STORE_H_
|