1// Copyright (c) 2012 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// This file declares a HttpTransactionFactory implementation that can be
6// layered on top of another HttpTransactionFactory to add HTTP caching.  The
7// caching logic follows RFC 2616 (any exceptions are called out in the code).
8//
9// The HttpCache takes a disk_cache::Backend as a parameter, and uses that for
10// the cache storage.
11//
12// See HttpTransactionFactory and HttpTransaction for more details.
13
14#ifndef NET_HTTP_HTTP_CACHE_H_
15#define NET_HTTP_HTTP_CACHE_H_
16
17#include <list>
18#include <set>
19#include <string>
20
21#include "base/basictypes.h"
22#include "base/containers/hash_tables.h"
23#include "base/files/file_path.h"
24#include "base/memory/scoped_ptr.h"
25#include "base/memory/weak_ptr.h"
26#include "base/threading/non_thread_safe.h"
27#include "base/time/time.h"
28#include "net/base/cache_type.h"
29#include "net/base/completion_callback.h"
30#include "net/base/load_states.h"
31#include "net/base/net_export.h"
32#include "net/base/request_priority.h"
33#include "net/http/http_network_session.h"
34#include "net/http/http_transaction_factory.h"
35
36class GURL;
37
38namespace base {
39class SingleThreadTaskRunner;
40}  // namespace base
41
42namespace disk_cache {
43class Backend;
44class Entry;
45}  // namespace disk_cache
46
47namespace net {
48
49class CertVerifier;
50class ChannelIDService;
51class DiskBasedCertCache;
52class HostResolver;
53class HttpAuthHandlerFactory;
54class HttpNetworkSession;
55class HttpResponseInfo;
56class HttpServerProperties;
57class IOBuffer;
58class NetLog;
59class NetworkDelegate;
60class ProxyService;
61class SSLConfigService;
62class TransportSecurityState;
63class ViewCacheHelper;
64struct HttpRequestInfo;
65
66class NET_EXPORT HttpCache : public HttpTransactionFactory,
67                             NON_EXPORTED_BASE(public base::NonThreadSafe) {
68 public:
69  // The cache mode of operation.
70  enum Mode {
71    // Normal mode just behaves like a standard web cache.
72    NORMAL = 0,
73    // Record mode caches everything for purposes of offline playback.
74    RECORD,
75    // Playback mode replays from a cache without considering any
76    // standard invalidations.
77    PLAYBACK,
78    // Disables reads and writes from the cache.
79    // Equivalent to setting LOAD_DISABLE_CACHE on every request.
80    DISABLE
81  };
82
83  // A BackendFactory creates a backend object to be used by the HttpCache.
84  class NET_EXPORT BackendFactory {
85   public:
86    virtual ~BackendFactory() {}
87
88    // The actual method to build the backend. Returns a net error code. If
89    // ERR_IO_PENDING is returned, the |callback| will be notified when the
90    // operation completes, and |backend| must remain valid until the
91    // notification arrives.
92    // The implementation must not access the factory object after invoking the
93    // |callback| because the object can be deleted from within the callback.
94    virtual int CreateBackend(NetLog* net_log,
95                              scoped_ptr<disk_cache::Backend>* backend,
96                              const CompletionCallback& callback) = 0;
97  };
98
99  // A default backend factory for the common use cases.
100  class NET_EXPORT DefaultBackend : public BackendFactory {
101   public:
102    // |path| is the destination for any files used by the backend, and
103    // |thread| is the thread where disk operations should take place. If
104    // |max_bytes| is  zero, a default value will be calculated automatically.
105    DefaultBackend(CacheType type,
106                   BackendType backend_type,
107                   const base::FilePath& path,
108                   int max_bytes,
109                   const scoped_refptr<base::SingleThreadTaskRunner>& thread);
110    virtual ~DefaultBackend();
111
112    // Returns a factory for an in-memory cache.
113    static BackendFactory* InMemory(int max_bytes);
114
115    // BackendFactory implementation.
116    virtual int CreateBackend(NetLog* net_log,
117                              scoped_ptr<disk_cache::Backend>* backend,
118                              const CompletionCallback& callback) OVERRIDE;
119
120   private:
121    CacheType type_;
122    BackendType backend_type_;
123    const base::FilePath path_;
124    int max_bytes_;
125    scoped_refptr<base::SingleThreadTaskRunner> thread_;
126  };
127
128  // The disk cache is initialized lazily (by CreateTransaction) in this case.
129  // The HttpCache takes ownership of the |backend_factory|.
130  HttpCache(const net::HttpNetworkSession::Params& params,
131            BackendFactory* backend_factory);
132
133  // The disk cache is initialized lazily (by CreateTransaction) in this case.
134  // Provide an existing HttpNetworkSession, the cache can construct a
135  // network layer with a shared HttpNetworkSession in order for multiple
136  // network layers to share information (e.g. authentication data). The
137  // HttpCache takes ownership of the |backend_factory|.
138  HttpCache(HttpNetworkSession* session, BackendFactory* backend_factory);
139
140  // Initialize the cache from its component parts. The lifetime of the
141  // |network_layer| and |backend_factory| are managed by the HttpCache and
142  // will be destroyed using |delete| when the HttpCache is destroyed.
143  HttpCache(HttpTransactionFactory* network_layer,
144            NetLog* net_log,
145            BackendFactory* backend_factory);
146
147  virtual ~HttpCache();
148
149  HttpTransactionFactory* network_layer() { return network_layer_.get(); }
150
151  DiskBasedCertCache* cert_cache() const { return cert_cache_.get(); }
152
153  // Retrieves the cache backend for this HttpCache instance. If the backend
154  // is not initialized yet, this method will initialize it. The return value is
155  // a network error code, and it could be ERR_IO_PENDING, in which case the
156  // |callback| will be notified when the operation completes. The pointer that
157  // receives the |backend| must remain valid until the operation completes.
158  int GetBackend(disk_cache::Backend** backend,
159                 const net::CompletionCallback& callback);
160
161  // Returns the current backend (can be NULL).
162  disk_cache::Backend* GetCurrentBackend() const;
163
164  // Given a header data blob, convert it to a response info object.
165  static bool ParseResponseInfo(const char* data, int len,
166                                HttpResponseInfo* response_info,
167                                bool* response_truncated);
168
169  // Writes |buf_len| bytes of metadata stored in |buf| to the cache entry
170  // referenced by |url|, as long as the entry's |expected_response_time| has
171  // not changed. This method returns without blocking, and the operation will
172  // be performed asynchronously without any completion notification.
173  void WriteMetadata(const GURL& url,
174                     RequestPriority priority,
175                     base::Time expected_response_time,
176                     IOBuffer* buf,
177                     int buf_len);
178
179  // Get/Set the cache's mode.
180  void set_mode(Mode value) { mode_ = value; }
181  Mode mode() { return mode_; }
182
183  // Close currently active sockets so that fresh page loads will not use any
184  // recycled connections.  For sockets currently in use, they may not close
185  // immediately, but they will not be reusable. This is for debugging.
186  void CloseAllConnections();
187
188  // Close all idle connections. Will close all sockets not in active use.
189  void CloseIdleConnections();
190
191  // Called whenever an external cache in the system reuses the resource
192  // referred to by |url| and |http_method|.
193  void OnExternalCacheHit(const GURL& url, const std::string& http_method);
194
195  // Initializes the Infinite Cache, if selected by the field trial.
196  void InitializeInfiniteCache(const base::FilePath& path);
197
198  // Causes all transactions created after this point to effectively bypass
199  // the cache lock whenever there is lock contention.
200  void BypassLockForTest() {
201    bypass_lock_for_test_ = true;
202  }
203
204  // HttpTransactionFactory implementation:
205  virtual int CreateTransaction(RequestPriority priority,
206                                scoped_ptr<HttpTransaction>* trans) OVERRIDE;
207  virtual HttpCache* GetCache() OVERRIDE;
208  virtual HttpNetworkSession* GetSession() OVERRIDE;
209
210  base::WeakPtr<HttpCache> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
211
212  // Resets the network layer to allow for tests that probe
213  // network changes (e.g. host unreachable).  The old network layer is
214  // returned to allow for filter patterns that only intercept
215  // some creation requests.  Note ownership exchange.
216  scoped_ptr<HttpTransactionFactory>
217      SetHttpNetworkTransactionFactoryForTesting(
218          scoped_ptr<HttpTransactionFactory> new_network_layer);
219
220 private:
221  // Types --------------------------------------------------------------------
222
223  // Disk cache entry data indices.
224  enum {
225    kResponseInfoIndex = 0,
226    kResponseContentIndex,
227    kMetadataIndex,
228
229    // Must remain at the end of the enum.
230    kNumCacheEntryDataIndices
231  };
232
233  class MetadataWriter;
234  class QuicServerInfoFactoryAdaptor;
235  class Transaction;
236  class WorkItem;
237  friend class Transaction;
238  friend class ViewCacheHelper;
239  struct PendingOp;  // Info for an entry under construction.
240
241  typedef std::list<Transaction*> TransactionList;
242  typedef std::list<WorkItem*> WorkItemList;
243
244  struct ActiveEntry {
245    explicit ActiveEntry(disk_cache::Entry* entry);
246    ~ActiveEntry();
247
248    disk_cache::Entry* disk_entry;
249    Transaction*       writer;
250    TransactionList    readers;
251    TransactionList    pending_queue;
252    bool               will_process_pending_queue;
253    bool               doomed;
254  };
255
256  typedef base::hash_map<std::string, ActiveEntry*> ActiveEntriesMap;
257  typedef base::hash_map<std::string, PendingOp*> PendingOpsMap;
258  typedef std::set<ActiveEntry*> ActiveEntriesSet;
259  typedef base::hash_map<std::string, int> PlaybackCacheMap;
260
261  // Methods ------------------------------------------------------------------
262
263  // Creates the |backend| object and notifies the |callback| when the operation
264  // completes. Returns an error code.
265  int CreateBackend(disk_cache::Backend** backend,
266                    const net::CompletionCallback& callback);
267
268  // Makes sure that the backend creation is complete before allowing the
269  // provided transaction to use the object. Returns an error code.  |trans|
270  // will be notified via its IO callback if this method returns ERR_IO_PENDING.
271  // The transaction is free to use the backend directly at any time after
272  // receiving the notification.
273  int GetBackendForTransaction(Transaction* trans);
274
275  // Generates the cache key for this request.
276  std::string GenerateCacheKey(const HttpRequestInfo*);
277
278  // Dooms the entry selected by |key|, if it is currently in the list of active
279  // entries.
280  void DoomActiveEntry(const std::string& key);
281
282  // Dooms the entry selected by |key|. |trans| will be notified via its IO
283  // callback if this method returns ERR_IO_PENDING. The entry can be
284  // currently in use or not.
285  int DoomEntry(const std::string& key, Transaction* trans);
286
287  // Dooms the entry selected by |key|. |trans| will be notified via its IO
288  // callback if this method returns ERR_IO_PENDING. The entry should not
289  // be currently in use.
290  int AsyncDoomEntry(const std::string& key, Transaction* trans);
291
292  // Dooms the entry associated with a GET for a given |url|.
293  void DoomMainEntryForUrl(const GURL& url);
294
295  // Closes a previously doomed entry.
296  void FinalizeDoomedEntry(ActiveEntry* entry);
297
298  // Returns an entry that is currently in use and not doomed, or NULL.
299  ActiveEntry* FindActiveEntry(const std::string& key);
300
301  // Creates a new ActiveEntry and starts tracking it. |disk_entry| is the disk
302  // cache entry.
303  ActiveEntry* ActivateEntry(disk_cache::Entry* disk_entry);
304
305  // Deletes an ActiveEntry.
306  void DeactivateEntry(ActiveEntry* entry);
307
308  // Deletes an ActiveEntry using an exhaustive search.
309  void SlowDeactivateEntry(ActiveEntry* entry);
310
311  // Returns the PendingOp for the desired |key|. If an entry is not under
312  // construction already, a new PendingOp structure is created.
313  PendingOp* GetPendingOp(const std::string& key);
314
315  // Deletes a PendingOp.
316  void DeletePendingOp(PendingOp* pending_op);
317
318  // Opens the disk cache entry associated with |key|, returning an ActiveEntry
319  // in |*entry|. |trans| will be notified via its IO callback if this method
320  // returns ERR_IO_PENDING.
321  int OpenEntry(const std::string& key, ActiveEntry** entry,
322                Transaction* trans);
323
324  // Creates the disk cache entry associated with |key|, returning an
325  // ActiveEntry in |*entry|. |trans| will be notified via its IO callback if
326  // this method returns ERR_IO_PENDING.
327  int CreateEntry(const std::string& key, ActiveEntry** entry,
328                  Transaction* trans);
329
330  // Destroys an ActiveEntry (active or doomed).
331  void DestroyEntry(ActiveEntry* entry);
332
333  // Adds a transaction to an ActiveEntry. If this method returns ERR_IO_PENDING
334  // the transaction will be notified about completion via its IO callback. This
335  // method returns ERR_CACHE_RACE to signal the transaction that it cannot be
336  // added to the provided entry, and it should retry the process with another
337  // one (in this case, the entry is no longer valid).
338  int AddTransactionToEntry(ActiveEntry* entry, Transaction* trans);
339
340  // Called when the transaction has finished working with this entry. |cancel|
341  // is true if the operation was cancelled by the caller instead of running
342  // to completion.
343  void DoneWithEntry(ActiveEntry* entry, Transaction* trans, bool cancel);
344
345  // Called when the transaction has finished writing to this entry. |success|
346  // is false if the cache entry should be deleted.
347  void DoneWritingToEntry(ActiveEntry* entry, bool success);
348
349  // Called when the transaction has finished reading from this entry.
350  void DoneReadingFromEntry(ActiveEntry* entry, Transaction* trans);
351
352  // Converts the active writer transaction to a reader so that other
353  // transactions can start reading from this entry.
354  void ConvertWriterToReader(ActiveEntry* entry);
355
356  // Returns the LoadState of the provided pending transaction.
357  LoadState GetLoadStateForPendingTransaction(const Transaction* trans);
358
359  // Removes the transaction |trans|, from the pending list of an entry
360  // (PendingOp, active or doomed entry).
361  void RemovePendingTransaction(Transaction* trans);
362
363  // Removes the transaction |trans|, from the pending list of |entry|.
364  bool RemovePendingTransactionFromEntry(ActiveEntry* entry,
365                                         Transaction* trans);
366
367  // Removes the transaction |trans|, from the pending list of |pending_op|.
368  bool RemovePendingTransactionFromPendingOp(PendingOp* pending_op,
369                                             Transaction* trans);
370
371  // Instantiates and sets QUIC server info factory.
372  void SetupQuicServerInfoFactory(HttpNetworkSession* session);
373
374  // Resumes processing the pending list of |entry|.
375  void ProcessPendingQueue(ActiveEntry* entry);
376
377  // Events (called via PostTask) ---------------------------------------------
378
379  void OnProcessPendingQueue(ActiveEntry* entry);
380
381  // Callbacks ----------------------------------------------------------------
382
383  // Processes BackendCallback notifications.
384  void OnIOComplete(int result, PendingOp* entry);
385
386  // Helper to conditionally delete |pending_op| if the HttpCache object it
387  // is meant for has been deleted.
388  //
389  // TODO(ajwong): The PendingOp lifetime management is very tricky.  It might
390  // be possible to simplify it using either base::Owned() or base::Passed()
391  // with the callback.
392  static void OnPendingOpComplete(const base::WeakPtr<HttpCache>& cache,
393                                  PendingOp* pending_op,
394                                  int result);
395
396  // Processes the backend creation notification.
397  void OnBackendCreated(int result, PendingOp* pending_op);
398
399  // Variables ----------------------------------------------------------------
400
401  NetLog* net_log_;
402
403  // Used when lazily constructing the disk_cache_.
404  scoped_ptr<BackendFactory> backend_factory_;
405  bool building_backend_;
406  bool bypass_lock_for_test_;
407
408  Mode mode_;
409
410  scoped_ptr<QuicServerInfoFactoryAdaptor> quic_server_info_factory_;
411
412  scoped_ptr<HttpTransactionFactory> network_layer_;
413
414  scoped_ptr<disk_cache::Backend> disk_cache_;
415
416  scoped_ptr<DiskBasedCertCache> cert_cache_;
417
418  // The set of active entries indexed by cache key.
419  ActiveEntriesMap active_entries_;
420
421  // The set of doomed entries.
422  ActiveEntriesSet doomed_entries_;
423
424  // The set of entries "under construction".
425  PendingOpsMap pending_ops_;
426
427  scoped_ptr<PlaybackCacheMap> playback_cache_map_;
428
429  base::WeakPtrFactory<HttpCache> weak_factory_;
430
431  DISALLOW_COPY_AND_ASSIGN(HttpCache);
432};
433
434}  // namespace net
435
436#endif  // NET_HTTP_HTTP_CACHE_H_
437