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