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