Home | History | Annotate | Download | only in prerender
      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 
    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