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