• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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 7234 (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 <memory>
20 #include <string>
21 #include <unordered_map>
22 #include <unordered_set>
23 
24 #include "base/files/file_path.h"
25 #include "base/functional/callback.h"
26 #include "base/gtest_prod_util.h"
27 #include "base/memory/raw_ptr.h"
28 #include "base/memory/weak_ptr.h"
29 #include "base/threading/thread_checker.h"
30 #include "base/time/clock.h"
31 #include "build/build_config.h"
32 #include "net/base/cache_type.h"
33 #include "net/base/completion_once_callback.h"
34 #include "net/base/load_states.h"
35 #include "net/base/net_errors.h"
36 #include "net/base/net_export.h"
37 #include "net/base/request_priority.h"
38 #include "net/disk_cache/disk_cache.h"
39 #include "net/http/http_transaction_factory.h"
40 #include "third_party/abseil-cpp/absl/types/optional.h"
41 
42 class GURL;
43 
44 namespace net {
45 
46 class HttpNetworkSession;
47 class HttpResponseInfo;
48 class NetLog;
49 class NetworkIsolationKey;
50 struct HttpRequestInfo;
51 
52 class NET_EXPORT HttpCache : public HttpTransactionFactory {
53  public:
54   // The cache mode of operation.
55   enum Mode {
56     // Normal mode just behaves like a standard web cache.
57     NORMAL = 0,
58     // Disables reads and writes from the cache.
59     // Equivalent to setting LOAD_DISABLE_CACHE on every request.
60     DISABLE
61   };
62 
63   // A BackendFactory creates a backend object to be used by the HttpCache.
64   class NET_EXPORT BackendFactory {
65    public:
66     virtual ~BackendFactory() = default;
67 
68     // The actual method to build the backend. The return value and `callback`
69     // conventions match disk_cache::CreateCacheBackend
70     //
71     // The implementation must not access the factory object after invoking the
72     // `callback` because the object can be deleted from within the callback.
73     virtual disk_cache::BackendResult CreateBackend(
74         NetLog* net_log,
75         base::OnceCallback<void(disk_cache::BackendResult)> callback) = 0;
76 
77 #if BUILDFLAG(IS_ANDROID)
SetAppStatusListenerGetter(disk_cache::ApplicationStatusListenerGetter app_status_listener_getter)78     virtual void SetAppStatusListenerGetter(
79         disk_cache::ApplicationStatusListenerGetter
80             app_status_listener_getter) {}
81 #endif
82   };
83 
84   // A default backend factory for the common use cases.
85   class NET_EXPORT DefaultBackend : public BackendFactory {
86    public:
87     // `file_operations_factory` can be null, in that case
88     // TrivialFileOperationsFactory is used. `path` is the destination for any
89     // files used by the backend. If `max_bytes` is  zero, a default value
90     // will be calculated automatically.
91     DefaultBackend(CacheType type,
92                    BackendType backend_type,
93                    scoped_refptr<disk_cache::BackendFileOperationsFactory>
94                        file_operations_factory,
95                    const base::FilePath& path,
96                    int max_bytes,
97                    bool hard_reset);
98     ~DefaultBackend() override;
99 
100     // Returns a factory for an in-memory cache.
101     static std::unique_ptr<BackendFactory> InMemory(int max_bytes);
102 
103     // BackendFactory implementation.
104     disk_cache::BackendResult CreateBackend(
105         NetLog* net_log,
106         base::OnceCallback<void(disk_cache::BackendResult)> callback) override;
107 
108 #if BUILDFLAG(IS_ANDROID)
109     void SetAppStatusListenerGetter(disk_cache::ApplicationStatusListenerGetter
110                                         app_status_listener_getter) override;
111 #endif
112 
113    private:
114     CacheType type_;
115     BackendType backend_type_;
116     const scoped_refptr<disk_cache::BackendFileOperationsFactory>
117         file_operations_factory_;
118     const base::FilePath path_;
119     int max_bytes_;
120     bool hard_reset_;
121 #if BUILDFLAG(IS_ANDROID)
122     disk_cache::ApplicationStatusListenerGetter app_status_listener_getter_;
123 #endif
124   };
125 
126   // Whether a transaction can join parallel writing or not is a function of the
127   // transaction as well as the current writers (if present). This enum
128   // captures that decision as well as when a Writers object is first created.
129   // This is also used to log metrics so should be consistent with the values in
130   // enums.xml and should only be appended to.
131   enum ParallelWritingPattern {
132     // Used as the default value till the transaction is in initial headers
133     // phase.
134     PARALLEL_WRITING_NONE,
135     // The transaction creates a writers object. This is only logged for
136     // transactions that did not fail to join existing writers earlier.
137     PARALLEL_WRITING_CREATE,
138     // The transaction joins existing writers.
139     PARALLEL_WRITING_JOIN,
140     // The transaction cannot join existing writers since either itself or
141     // existing writers instance is serving a range request.
142     PARALLEL_WRITING_NOT_JOIN_RANGE,
143     // The transaction cannot join existing writers since either itself or
144     // existing writers instance is serving a non GET request.
145     PARALLEL_WRITING_NOT_JOIN_METHOD_NOT_GET,
146     // The transaction cannot join existing writers since it does not have cache
147     // write privileges.
148     PARALLEL_WRITING_NOT_JOIN_READ_ONLY,
149     // Writers does not exist and the transaction does not need to create one
150     // since it is going to read from the cache.
151     PARALLEL_WRITING_NONE_CACHE_READ,
152     // Unable to join since the entry is too big for cache backend to handle.
153     PARALLEL_WRITING_NOT_JOIN_TOO_BIG_FOR_CACHE,
154     // On adding a value here, make sure to add in enums.xml as well.
155     PARALLEL_WRITING_MAX
156   };
157 
158   // The number of minutes after a resource is prefetched that it can be used
159   // again without validation.
160   static const int kPrefetchReuseMins = 5;
161 
162   // Initialize the cache from its component parts. |network_layer| and
163   // |backend_factory| will be destroyed when the HttpCache is.
164   HttpCache(std::unique_ptr<HttpTransactionFactory> network_layer,
165             std::unique_ptr<BackendFactory> backend_factory);
166 
167   HttpCache(const HttpCache&) = delete;
168   HttpCache& operator=(const HttpCache&) = delete;
169 
170   ~HttpCache() override;
171 
network_layer()172   HttpTransactionFactory* network_layer() { return network_layer_.get(); }
173 
174   // Retrieves the cache backend for this HttpCache instance. If the backend
175   // is not initialized yet, this method will initialize it. The return value is
176   // a network error code, and it could be ERR_IO_PENDING, in which case the
177   // `callback` will be notified when the operation completes. The pointer that
178   // receives the `backend` must remain valid until the operation completes.
179   // `callback` will get cancelled if the HttpCache is destroyed.
180   int GetBackend(disk_cache::Backend** backend,
181                  CompletionOnceCallback callback);
182 
183   // Returns the current backend (can be NULL).
184   disk_cache::Backend* GetCurrentBackend() const;
185 
186   // Given a header data blob, convert it to a response info object.
187   static bool ParseResponseInfo(const char* data,
188                                 int len,
189                                 HttpResponseInfo* response_info,
190                                 bool* response_truncated);
191 
192   // Get/Set the cache's mode.
set_mode(Mode value)193   void set_mode(Mode value) { mode_ = value; }
mode()194   Mode mode() { return mode_; }
195 
196   // Get/Set the cache's clock. These are public only for testing.
SetClockForTesting(base::Clock * clock)197   void SetClockForTesting(base::Clock* clock) { clock_ = clock; }
clock()198   base::Clock* clock() const { return clock_; }
199 
200   // Close currently active sockets so that fresh page loads will not use any
201   // recycled connections.  For sockets currently in use, they may not close
202   // immediately, but they will not be reusable. This is for debugging.
203   void CloseAllConnections(int net_error, const char* net_log_reason_utf8);
204 
205   // Close all idle connections. Will close all sockets not in active use.
206   void CloseIdleConnections(const char* net_log_reason_utf8);
207 
208   // Called whenever an external cache in the system reuses the resource
209   // referred to by |url| and |http_method| and |network_isolation_key|.
210   void OnExternalCacheHit(const GURL& url,
211                           const std::string& http_method,
212                           const NetworkIsolationKey& network_isolation_key,
213                           bool is_subframe_document_resource,
214                           bool include_credentials);
215 
216   // Causes all transactions created after this point to simulate lock timeout
217   // and effectively bypass the cache lock whenever there is lock contention.
SimulateCacheLockTimeoutForTesting()218   void SimulateCacheLockTimeoutForTesting() { bypass_lock_for_test_ = true; }
219 
220   // Causes all transactions created after this point to simulate lock timeout
221   // and effectively bypass the cache lock whenever there is lock contention
222   // after the transaction has completed its headers phase.
SimulateCacheLockTimeoutAfterHeadersForTesting()223   void SimulateCacheLockTimeoutAfterHeadersForTesting() {
224     bypass_lock_after_headers_for_test_ = true;
225   }
226 
DelayAddTransactionToEntryForTesting()227   void DelayAddTransactionToEntryForTesting() {
228     delay_add_transaction_to_entry_for_test_ = true;
229   }
230 
231   // Causes all transactions created after this point to generate a failure
232   // when attempting to conditionalize a network request.
FailConditionalizationForTest()233   void FailConditionalizationForTest() {
234     fail_conditionalization_for_test_ = true;
235   }
236 
237   // HttpTransactionFactory implementation:
238   int CreateTransaction(RequestPriority priority,
239                         std::unique_ptr<HttpTransaction>* transaction) override;
240   HttpCache* GetCache() override;
241   HttpNetworkSession* GetSession() override;
242 
GetWeakPtr()243   base::WeakPtr<HttpCache> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
244 
245   // Resets the network layer to allow for tests that probe
246   // network changes (e.g. host unreachable).  The old network layer is
247   // returned to allow for filter patterns that only intercept
248   // some creation requests.  Note ownership exchange.
249   std::unique_ptr<HttpTransactionFactory>
250   SetHttpNetworkTransactionFactoryForTesting(
251       std::unique_ptr<HttpTransactionFactory> new_network_layer);
252 
253   // Get the URL from the entry's cache key.
254   static std::string GetResourceURLFromHttpCacheKey(const std::string& key);
255 
256   // Generates the cache key for a request. Returns nullopt if the cache is
257   // configured to be split by the NetworkIsolationKey, and the
258   // NetworkIsolationKey is transient, in which case nothing should generally be
259   // stored to disk.
260   static absl::optional<std::string> GenerateCacheKey(
261       const GURL& url,
262       int load_flags,
263       const NetworkIsolationKey& network_isolation_key,
264       int64_t upload_data_identifier,
265       bool is_subframe_document_resource);
266   static absl::optional<std::string> GenerateCacheKeyForRequest(
267       const HttpRequestInfo* request);
268 
269   // Enable split cache feature if not already overridden in the feature list.
270   // Should only be invoked during process initialization before the HTTP
271   // cache is initialized.
272   static void SplitCacheFeatureEnableByDefault();
273 
274   // Returns true if split cache is enabled either by default or by other means
275   // like command line or field trials.
276   static bool IsSplitCacheEnabled();
277 
278   // Resets g_init_cache and g_enable_split_cache for tests.
279   static void ClearGlobalsForTesting();
280 
281  private:
282   // Types --------------------------------------------------------------------
283 
284   // The type of operation represented by a work item.
285   enum WorkItemOperation {
286     WI_CREATE_BACKEND,
287     WI_OPEN_OR_CREATE_ENTRY,
288     WI_OPEN_ENTRY,
289     WI_CREATE_ENTRY,
290     WI_DOOM_ENTRY
291   };
292 
293   // Disk cache entry data indices.
294   enum {
295     kResponseInfoIndex = 0,
296     kResponseContentIndex,
297     kDeprecatedMetadataIndex,
298     // Must remain at the end of the enum.
299     kNumCacheEntryDataIndices
300   };
301 
302   class QuicServerInfoFactoryAdaptor;
303   class Transaction;
304   class WorkItem;
305   class Writers;
306 
307   friend class WritersTest;
308   friend class TestHttpCacheTransaction;
309   friend class TestHttpCache;
310   friend class Transaction;
311   struct PendingOp;  // Info for an entry under construction.
312 
313   // To help with testing.
314   friend class MockHttpCache;
315   friend class HttpCacheIOCallbackTest;
316 
317   FRIEND_TEST_ALL_PREFIXES(HttpCacheTest_SplitCacheFeatureEnabled,
318                            SplitCacheWithNetworkIsolationKey);
319   FRIEND_TEST_ALL_PREFIXES(HttpCacheTest, NonSplitCache);
320   FRIEND_TEST_ALL_PREFIXES(HttpCacheTest_SplitCacheFeatureEnabled, SplitCache);
321   FRIEND_TEST_ALL_PREFIXES(HttpCacheTest_SplitCacheFeatureEnabled,
322                            SplitCacheUsesRegistrableDomain);
323 
324   using TransactionList = std::list<Transaction*>;
325   using TransactionSet = std::unordered_set<Transaction*>;
326   typedef std::list<std::unique_ptr<WorkItem>> WorkItemList;
327 
328   // We implement a basic reader/writer lock for the disk cache entry. If there
329   // is a writer, then all transactions must wait to read the body. But the
330   // waiting transactions can start their headers phase in parallel. Headers
331   // phase is allowed for one transaction at a time so that if it doesn't match
332   // the existing headers, remaining transactions do not also try to match the
333   // existing entry in parallel leading to wasted network requests. If the
334   // headers do not match, this entry will be doomed.
335   //
336   // A transaction goes through these state transitions.
337   //
338   // Write mode transactions eligible for shared writing:
339   // add_to_entry_queue-> headers_transaction -> writers (first writer)
340   // add_to_entry_queue-> headers_transaction -> done_headers_queue -> writers
341   // (subsequent writers)
342   // add_to_entry_queue-> headers_transaction -> done_headers_queue -> readers
343   // (transactions not eligible for shared writing - once the data is written to
344   // the cache by writers)
345   //
346   // Read only transactions:
347   // add_to_entry_queue-> headers_transaction -> done_headers_queue -> readers
348   // (once the data is written to the cache by writers)
349 
350   struct NET_EXPORT_PRIVATE ActiveEntry {
351     ActiveEntry(disk_cache::Entry* entry, bool opened_in);
352     ~ActiveEntry();
353 
354     // Returns true if no transactions are associated with this entry.
355     bool HasNoTransactions();
356 
357     // Returns true if no transactions are associated with this entry and
358     // writers is not present.
359     bool SafeToDestroy();
360 
361     bool TransactionInReaders(Transaction* transaction) const;
362 
GetEntryActiveEntry363     disk_cache::Entry* GetEntry() { return disk_entry.get(); }
364 
365     disk_cache::ScopedEntryPtr disk_entry;
366 
367     // Indicates if the disk_entry was opened or not (i.e.: created).
368     // It is set to true when a transaction is added to an entry so that other,
369     // queued, transactions do not mistake it for a newly created entry.
370     bool opened = false;
371 
372     // Transactions waiting to be added to entry.
373     TransactionList add_to_entry_queue;
374 
375     // Transaction currently in the headers phase, either validating the
376     // response or getting new headers. This can exist simultaneously with
377     // writers or readers while validating existing headers.
378     raw_ptr<Transaction> headers_transaction = nullptr;
379 
380     // Transactions that have completed their headers phase and are waiting
381     // to read the response body or write the response body.
382     TransactionList done_headers_queue;
383 
384     // Transactions currently reading from the network and writing to the cache.
385     std::unique_ptr<Writers> writers;
386 
387     // Transactions that can only read from the cache. Only one of writers or
388     // readers can be non-empty at a time.
389     TransactionSet readers;
390 
391     // The following variables are true if OnProcessQueuedTransactions is posted
392     bool will_process_queued_transactions = false;
393 
394     // True if entry is doomed.
395     bool doomed = false;
396   };
397 
398   using ActiveEntriesMap =
399       std::unordered_map<std::string, std::unique_ptr<ActiveEntry>>;
400   using PendingOpsMap = std::unordered_map<std::string, PendingOp*>;
401   using ActiveEntriesSet = std::map<ActiveEntry*, std::unique_ptr<ActiveEntry>>;
402 
403   // Methods ------------------------------------------------------------------
404 
405   // Creates a WorkItem and sets it as the |pending_op|'s writer, or adds it to
406   // the queue if a writer already exists.
407   net::Error CreateAndSetWorkItem(ActiveEntry** entry,
408                                   Transaction* transaction,
409                                   WorkItemOperation operation,
410                                   PendingOp* pending_op);
411 
412   // Creates the `disk_cache_` object and notifies the `callback` when the
413   // operation completes. Returns an error code.
414   int CreateBackend(CompletionOnceCallback callback);
415 
416   void ReportGetBackendResult(disk_cache::Backend** backend,
417                               CompletionOnceCallback callback,
418                               int net_error);
419 
420   // Makes sure that the backend creation is complete before allowing the
421   // provided transaction to use the object. Returns an error code.
422   // |transaction| will be notified via its Cache IO callback if this method
423   // returns ERR_IO_PENDING. The transaction is free to use the backend
424   // directly at any time after receiving the notification.
425   int GetBackendForTransaction(Transaction* transaction);
426 
427   // Dooms the entry selected by |key|, if it is currently in the list of active
428   // entries.
429   void DoomActiveEntry(const std::string& key);
430 
431   // Dooms the entry selected by |key|. |transaction| will be notified via its
432   // Cache IO callback if this method returns ERR_IO_PENDING. The entry can be
433   // currently in use or not. If entry is in use and the invoking transaction
434   // is associated with this entry and this entry is already doomed, this API
435   // should not be invoked.
436   int DoomEntry(const std::string& key, Transaction* transaction);
437 
438   // Dooms the entry selected by |key|. |transaction| will be notified via its
439   // Cache IO callback if this method returns ERR_IO_PENDING. The entry should
440   // not be currently in use.
441   int AsyncDoomEntry(const std::string& key, Transaction* transaction);
442 
443   // Dooms the entry associated with a GET for a given url and network
444   // isolation key.
445   void DoomMainEntryForUrl(const GURL& url,
446                            const NetworkIsolationKey& isolation_key,
447                            bool is_subframe_document_resource);
448 
449   // Closes a previously doomed entry.
450   void FinalizeDoomedEntry(ActiveEntry* entry);
451 
452   // Returns an entry that is currently in use and not doomed, or NULL.
453   ActiveEntry* FindActiveEntry(const std::string& key);
454 
455   // Creates a new ActiveEntry and starts tracking it. |disk_entry| is the disk
456   // cache entry.
457   ActiveEntry* ActivateEntry(disk_cache::Entry* disk_entry, bool opened);
458 
459   // Deletes an ActiveEntry.
460   void DeactivateEntry(ActiveEntry* entry);
461 
462   // Deletes an ActiveEntry using an exhaustive search.
463   void SlowDeactivateEntry(ActiveEntry* entry);
464 
465   // Returns the PendingOp for the desired |key|. If an entry is not under
466   // construction already, a new PendingOp structure is created.
467   PendingOp* GetPendingOp(const std::string& key);
468 
469   // Deletes a PendingOp.
470   void DeletePendingOp(PendingOp* pending_op);
471 
472   // Opens the disk cache entry associated with |key|, creating the entry if it
473   // does not already exist, returning an ActiveEntry in |*entry|. |transaction|
474   // will be notified via its Cache IO callback if this method returns
475   // ERR_IO_PENDING. This should not be called if there already is an active
476   // entry associated with |key|, e.g. you should call FindActiveEntry first.
477   int OpenOrCreateEntry(const std::string& key,
478                         ActiveEntry** entry,
479                         Transaction* transaction);
480 
481   // Opens the disk cache entry associated with |key|, returning an ActiveEntry
482   // in |*entry|. |transaction| will be notified via its Cache IO callback if
483   // this method returns ERR_IO_PENDING. This should not be called if there
484   // already is an active entry associated with |key|, e.g. you should call
485   // FindActiveEntry first.
486   int OpenEntry(const std::string& key,
487                 ActiveEntry** entry,
488                 Transaction* transaction);
489 
490   // Creates the disk cache entry associated with |key|, returning an
491   // ActiveEntry in |*entry|. |transaction| will be notified via its Cache IO
492   // callback if this method returns ERR_IO_PENDING.
493   int CreateEntry(const std::string& key,
494                   ActiveEntry** entry,
495                   Transaction* transaction);
496 
497   // Destroys an ActiveEntry (active or doomed). Should only be called if
498   // entry->SafeToDestroy() returns true.
499   bool IsSafeToDestroyAndDestroyEntry(ActiveEntry* entry);
500 
501   // Adds a transaction to an ActiveEntry. This method returns ERR_IO_PENDING
502   // and the transaction will be notified about completion via a callback to
503   // cache_io_callback().
504   // In a failure case, the callback will be invoked with ERR_CACHE_RACE.
505   int AddTransactionToEntry(ActiveEntry* entry, Transaction* transaction);
506 
507   // Transaction invokes this when its response headers phase is complete
508   // If the transaction is responsible for writing the response body,
509   // it becomes the writer and returns OK. In other cases ERR_IO_PENDING is
510   // returned and the transaction will be notified about completion via its
511   // Cache IO callback. In a failure case, the callback will be invoked with
512   // ERR_CACHE_RACE.
513   int DoneWithResponseHeaders(ActiveEntry* entry,
514                               Transaction* transaction,
515                               bool is_partial);
516 
517   // Called when the transaction has finished working with this entry.
518   // |entry_is_complete| is true if the transaction finished reading/writing
519   // from the entry successfully, else it's false.
520   void DoneWithEntry(ActiveEntry* entry,
521                      Transaction* transaction,
522                      bool entry_is_complete,
523                      bool is_partial);
524 
525   // Invoked when writers wants to doom the entry and restart any queued and
526   // headers transactions.
527   // Virtual so that it can be extended in tests.
528   virtual void WritersDoomEntryRestartTransactions(ActiveEntry* entry);
529 
530   // Invoked when current transactions in writers have completed writing to the
531   // cache. It may be successful completion of the response or failure as given
532   // by |success|. Must delete the writers object.
533   // |entry| is the owner of writers.
534   // |should_keep_entry| indicates if the entry should be doomed/destroyed.
535   // Virtual so that it can be extended in tests.
536   virtual void WritersDoneWritingToEntry(ActiveEntry* entry,
537                                          bool success,
538                                          bool should_keep_entry,
539                                          TransactionSet make_readers);
540 
541   // Called when the transaction has received a non-matching response to
542   // validation and it's not the transaction responsible for writing the
543   // response body.
544   void DoomEntryValidationNoMatch(ActiveEntry* entry);
545 
546   // Removes and returns all queued transactions in |entry| in FIFO order. This
547   // includes transactions that have completed the headers phase and those that
548   // have not been added to the entry yet in that order. |list| is the output
549   // argument.
550   void RemoveAllQueuedTransactions(ActiveEntry* entry, TransactionList* list);
551 
552   // Processes either writer's failure to write response body or
553   // headers_transactions's failure to write headers.
554   void ProcessEntryFailure(ActiveEntry* entry);
555 
556   // Restarts headers_transaction and done_headers_queue transactions.
557   void RestartHeadersPhaseTransactions(ActiveEntry* entry);
558 
559   // Restarts the headers_transaction by setting its state. Since the
560   // headers_transaction is awaiting an asynchronous operation completion,
561   // it will be restarted when it's Cache IO callback is invoked.
562   void RestartHeadersTransaction(ActiveEntry* entry);
563 
564   // Resumes processing the queued transactions of |entry|.
565   void ProcessQueuedTransactions(ActiveEntry* entry);
566 
567   // Checks if a transaction can be added to the entry. If yes, it will
568   // invoke the Cache IO callback of the transaction. This is a helper function
569   // for OnProcessQueuedTransactions. It will take a transaction from
570   // add_to_entry_queue and make it a headers_transaction, if one doesn't exist
571   // already.
572   void ProcessAddToEntryQueue(ActiveEntry* entry);
573 
574   // The implementation is split into a separate function so that it can be
575   // called with a delay for testing.
576   void ProcessAddToEntryQueueImpl(ActiveEntry* entry);
577 
578   // Returns if the transaction can join other transactions for writing to
579   // the cache simultaneously. It is only supported for non-Read only,
580   // GET requests which are not range requests.
581   ParallelWritingPattern CanTransactionJoinExistingWriters(
582       Transaction* transaction);
583 
584   // Invoked when a transaction that has already completed the response headers
585   // phase can resume reading/writing the response body. It will invoke the IO
586   // callback of the transaction. This is a helper function for
587   // OnProcessQueuedTransactions.
588   void ProcessDoneHeadersQueue(ActiveEntry* entry);
589 
590   // Adds a transaction to writers.
591   void AddTransactionToWriters(ActiveEntry* entry,
592                                Transaction* transaction,
593                                ParallelWritingPattern parallel_writing_pattern);
594 
595   // Returns true if this transaction can write headers to the entry.
596   bool CanTransactionWriteResponseHeaders(ActiveEntry* entry,
597                                           Transaction* transaction,
598                                           bool is_partial,
599                                           bool is_match) const;
600 
601   // Returns true if a transaction is currently writing the response body.
602   bool IsWritingInProgress(ActiveEntry* entry) const;
603 
604   // Returns the LoadState of the provided pending transaction.
605   LoadState GetLoadStateForPendingTransaction(const Transaction* transaction);
606 
607   // Removes the transaction |transaction|, from the pending list of an entry
608   // (PendingOp, active or doomed entry).
609   void RemovePendingTransaction(Transaction* transaction);
610 
611   // Removes the transaction |transaction|, from the pending list of |entry|.
612   bool RemovePendingTransactionFromEntry(ActiveEntry* entry,
613                                          Transaction* transaction);
614 
615   // Removes the transaction |transaction|, from the pending list of
616   // |pending_op|.
617   bool RemovePendingTransactionFromPendingOp(PendingOp* pending_op,
618                                              Transaction* transaction);
619 
620   // Events (called via PostTask) ---------------------------------------------
621 
622   void OnProcessQueuedTransactions(ActiveEntry* entry);
623 
624   // Callbacks ----------------------------------------------------------------
625 
626   // Processes BackendCallback notifications.
627   void OnIOComplete(int result, PendingOp* entry);
628 
629   // Helper to conditionally delete |pending_op| if HttpCache has been deleted.
630   // This is necessary because |pending_op| owns a disk_cache::Backend that has
631   // been passed in to CreateCacheBackend(), therefore must live until callback
632   // is called.
633   static void OnPendingOpComplete(base::WeakPtr<HttpCache> cache,
634                                   PendingOp* pending_op,
635                                   int result);
636 
637   // Variant for Open/Create method family, which has a different signature.
638   static void OnPendingCreationOpComplete(base::WeakPtr<HttpCache> cache,
639                                           PendingOp* pending_op,
640                                           disk_cache::EntryResult result);
641 
642   // Variant for CreateCacheBackend, which has a different signature.
643   static void OnPendingBackendCreationOpComplete(
644       base::WeakPtr<HttpCache> cache,
645       PendingOp* pending_op,
646       disk_cache::BackendResult result);
647 
648   // Processes the backend creation notification.
649   void OnBackendCreated(int result, PendingOp* pending_op);
650 
651   // Constants ----------------------------------------------------------------
652 
653   // Used when generating and accessing keys if cache is split.
654   static const char kDoubleKeyPrefix[];
655   static const char kDoubleKeySeparator[];
656   static const char kSubframeDocumentResourcePrefix[];
657 
658   // Used for single-keyed entries if the cache is split.
659   static const char kSingleKeyPrefix[];
660   static const char kSingleKeySeparator[];
661 
662   // Variables ----------------------------------------------------------------
663 
664   raw_ptr<NetLog> net_log_;
665 
666   // Used when lazily constructing the disk_cache_.
667   std::unique_ptr<BackendFactory> backend_factory_;
668   bool building_backend_ = false;
669   bool bypass_lock_for_test_ = false;
670   bool bypass_lock_after_headers_for_test_ = false;
671   bool delay_add_transaction_to_entry_for_test_ = false;
672   bool fail_conditionalization_for_test_ = false;
673 
674   Mode mode_ = NORMAL;
675 
676   std::unique_ptr<HttpTransactionFactory> network_layer_;
677 
678   std::unique_ptr<disk_cache::Backend> disk_cache_;
679 
680   // The set of active entries indexed by cache key.
681   ActiveEntriesMap active_entries_;
682 
683   // The set of doomed entries.
684   ActiveEntriesSet doomed_entries_;
685 
686   // The set of entries "under construction".
687   PendingOpsMap pending_ops_;
688 
689   // A clock that can be swapped out for testing.
690   raw_ptr<base::Clock> clock_;
691 
692   THREAD_CHECKER(thread_checker_);
693 
694   base::WeakPtrFactory<HttpCache> weak_factory_{this};
695 };
696 
697 }  // namespace net
698 
699 #endif  // NET_HTTP_HTTP_CACHE_H_
700