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