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