• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // This file declares HttpCache::Transaction, a private class of HttpCache so
6 // it should only be included by http_cache.cc
7 
8 #ifndef NET_HTTP_HTTP_CACHE_TRANSACTION_H_
9 #define NET_HTTP_HTTP_CACHE_TRANSACTION_H_
10 
11 #include <stddef.h>
12 #include <stdint.h>
13 
14 #include <memory>
15 #include <string>
16 
17 #include "base/memory/raw_ptr.h"
18 #include "base/memory/raw_ptr_exclusion.h"
19 #include "base/memory/scoped_refptr.h"
20 #include "base/memory/weak_ptr.h"
21 #include "base/time/time.h"
22 #include "net/base/completion_once_callback.h"
23 #include "net/base/completion_repeating_callback.h"
24 #include "net/base/io_buffer.h"
25 #include "net/base/ip_endpoint.h"
26 #include "net/base/load_states.h"
27 #include "net/base/net_error_details.h"
28 #include "net/base/net_errors.h"
29 #include "net/base/request_priority.h"
30 #include "net/http/http_cache.h"
31 #include "net/http/http_request_headers.h"
32 #include "net/http/http_response_headers.h"
33 #include "net/http/http_response_info.h"
34 #include "net/http/http_transaction.h"
35 #include "net/http/partial_data.h"
36 #include "net/log/net_log_with_source.h"
37 #include "net/socket/connection_attempts.h"
38 #include "net/websockets/websocket_handshake_stream_base.h"
39 
40 namespace crypto {
41 class SecureHash;
42 }  // namespace crypto
43 
44 namespace net {
45 
46 class PartialData;
47 struct HttpRequestInfo;
48 struct LoadTimingInfo;
49 class SSLPrivateKey;
50 
51 // This is the transaction that is returned by the HttpCache transaction
52 // factory.
53 class NET_EXPORT_PRIVATE HttpCache::Transaction : public HttpTransaction {
54  public:
55   // The transaction has the following modes, which apply to how it may access
56   // its cache entry.
57   //
58   //  o If the mode of the transaction is NONE, then it is in "pass through"
59   //    mode and all methods just forward to the inner network transaction.
60   //
61   //  o If the mode of the transaction is only READ, then it may only read from
62   //    the cache entry.
63   //
64   //  o If the mode of the transaction is only WRITE, then it may only write to
65   //    the cache entry.
66   //
67   //  o If the mode of the transaction is READ_WRITE, then the transaction may
68   //    optionally modify the cache entry (e.g., possibly corresponding to
69   //    cache validation).
70   //
71   //  o If the mode of the transaction is UPDATE, then the transaction may
72   //    update existing cache entries, but will never create a new entry or
73   //    respond using the entry read from the cache.
74   enum Mode {
75     NONE            = 0,
76     READ_META       = 1 << 0,
77     READ_DATA       = 1 << 1,
78     READ            = READ_META | READ_DATA,
79     WRITE           = 1 << 2,
80     READ_WRITE      = READ | WRITE,
81     UPDATE          = READ_META | WRITE,  // READ_WRITE & ~READ_DATA
82   };
83 
84   Transaction(RequestPriority priority,
85               HttpCache* cache);
86 
87   Transaction(const Transaction&) = delete;
88   Transaction& operator=(const Transaction&) = delete;
89 
90   ~Transaction() override;
91 
92   // Virtual so it can be extended for testing.
93   virtual Mode mode() const;
94 
method()95   const std::string& method() const { return method_; }
96 
key()97   const std::string& key() const { return cache_key_; }
98 
entry()99   HttpCache::ActiveEntry* entry() { return entry_; }
100 
101   // Returns the LoadState of the writer transaction of a given ActiveEntry. In
102   // other words, returns the LoadState of this transaction without asking the
103   // http cache, because this transaction should be the one currently writing
104   // to the cache entry.
105   LoadState GetWriterLoadState() const;
106 
io_callback()107   const CompletionRepeatingCallback& io_callback() { return io_callback_; }
108 
SetIOCallBackForTest(CompletionRepeatingCallback cb)109   void SetIOCallBackForTest(CompletionRepeatingCallback cb) {
110     io_callback_ = cb;
111   }
112 
113   const NetLogWithSource& net_log() const;
114 
115   // Bypasses the cache lock whenever there is lock contention.
BypassLockForTest()116   void BypassLockForTest() {
117     bypass_lock_for_test_ = true;
118   }
119 
BypassLockAfterHeadersForTest()120   void BypassLockAfterHeadersForTest() {
121     bypass_lock_after_headers_for_test_ = true;
122   }
123 
124   // Generates a failure when attempting to conditionalize a network request.
FailConditionalizationForTest()125   void FailConditionalizationForTest() {
126     fail_conditionalization_for_test_ = true;
127   }
128 
129   // HttpTransaction methods:
130   int Start(const HttpRequestInfo* request_info,
131             CompletionOnceCallback callback,
132             const NetLogWithSource& net_log) override;
133   int RestartIgnoringLastError(CompletionOnceCallback callback) override;
134   int RestartWithCertificate(scoped_refptr<X509Certificate> client_cert,
135                              scoped_refptr<SSLPrivateKey> client_private_key,
136                              CompletionOnceCallback callback) override;
137   int RestartWithAuth(const AuthCredentials& credentials,
138                       CompletionOnceCallback callback) override;
139   bool IsReadyToRestartForAuth() override;
140   int Read(IOBuffer* buf,
141            int buf_len,
142            CompletionOnceCallback callback) override;
143   void StopCaching() override;
144   int64_t GetTotalReceivedBytes() const override;
145   int64_t GetTotalSentBytes() const override;
146   void DoneReading() override;
147   const HttpResponseInfo* GetResponseInfo() const override;
148   LoadState GetLoadState() const override;
149   void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
150   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
151   bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
152   void PopulateNetErrorDetails(NetErrorDetails* details) const override;
153   void SetPriority(RequestPriority priority) override;
154   void SetWebSocketHandshakeStreamCreateHelper(
155       WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
156   void SetBeforeNetworkStartCallback(
157       BeforeNetworkStartCallback callback) override;
158   void SetConnectedCallback(const ConnectedCallback& callback) override;
159   void SetRequestHeadersCallback(RequestHeadersCallback callback) override;
160   void SetResponseHeadersCallback(ResponseHeadersCallback callback) override;
161   void SetEarlyResponseHeadersCallback(
162       ResponseHeadersCallback callback) override;
163   int ResumeNetworkStart() override;
164   ConnectionAttempts GetConnectionAttempts() const override;
165   void CloseConnectionOnDestruction() override;
166 
167   // Invoked when parallel validation cannot proceed due to response failure
168   // and this transaction needs to be restarted.
169   void SetValidatingCannotProceed();
170 
171   // Invoked to remove the association between a transaction waiting to be
172   // added to an entry and the entry.
ResetCachePendingState()173   void ResetCachePendingState() { cache_pending_ = false; }
174 
priority()175   RequestPriority priority() const { return priority_; }
partial()176   PartialData* partial() { return partial_.get(); }
is_truncated()177   bool is_truncated() { return truncated_; }
178 
179   // Invoked when this writer transaction is about to be removed from entry.
180   // If result is an error code, a future Read should fail with |result|.
181   void WriterAboutToBeRemovedFromEntry(int result);
182 
183   // Invoked when this transaction is about to become a reader because the cache
184   // entry has finished writing.
185   void WriteModeTransactionAboutToBecomeReader();
186 
187   // True if the passed checksum calculated from the response matches the
188   // expected value from the HttpRequestInfo. Consumes `checksum`.
189   bool ResponseChecksumMatches(
190       std::unique_ptr<crypto::SecureHash> checksum) const;
191 
192   // Add time spent writing data in the disk cache. Used for histograms.
193   void AddDiskCacheWriteTime(base::TimeDelta elapsed);
194 
195  private:
196   static const size_t kNumValidationHeaders = 2;
197   // Helper struct to pair a header name with its value, for
198   // headers used to validate cache entries.
199   struct ValidationHeaders {
200     ValidationHeaders() = default;
201 
202     std::string values[kNumValidationHeaders];
ResetValidationHeaders203     void Reset() {
204       initialized = false;
205       for (auto& value : values)
206         value.clear();
207     }
208     bool initialized = false;
209   };
210 
211   struct NetworkTransactionInfo {
212     NetworkTransactionInfo();
213 
214     NetworkTransactionInfo(const NetworkTransactionInfo&) = delete;
215     NetworkTransactionInfo& operator=(const NetworkTransactionInfo&) = delete;
216 
217     ~NetworkTransactionInfo();
218 
219     // Load timing information for the last network request, if any. Set in the
220     // 304 and 206 response cases, as the network transaction may be destroyed
221     // before the caller requests load timing information.
222     std::unique_ptr<LoadTimingInfo> old_network_trans_load_timing;
223     int64_t total_received_bytes = 0;
224     int64_t total_sent_bytes = 0;
225     ConnectionAttempts old_connection_attempts;
226     IPEndPoint old_remote_endpoint;
227   };
228 
229   enum State {
230     STATE_UNSET,
231 
232     // Normally, states are traversed in approximately this order.
233     STATE_NONE,
234     STATE_GET_BACKEND,
235     STATE_GET_BACKEND_COMPLETE,
236     STATE_INIT_ENTRY,
237     STATE_OPEN_OR_CREATE_ENTRY,
238     STATE_OPEN_OR_CREATE_ENTRY_COMPLETE,
239     STATE_DOOM_ENTRY,
240     STATE_DOOM_ENTRY_COMPLETE,
241     STATE_CREATE_ENTRY,
242     STATE_CREATE_ENTRY_COMPLETE,
243     STATE_ADD_TO_ENTRY,
244     STATE_ADD_TO_ENTRY_COMPLETE,
245     STATE_DONE_HEADERS_ADD_TO_ENTRY_COMPLETE,
246     STATE_CACHE_READ_RESPONSE,
247     STATE_CACHE_READ_RESPONSE_COMPLETE,
248     STATE_WRITE_UPDATED_PREFETCH_RESPONSE,
249     STATE_WRITE_UPDATED_PREFETCH_RESPONSE_COMPLETE,
250     STATE_CACHE_DISPATCH_VALIDATION,
251     STATE_CACHE_QUERY_DATA,
252     STATE_CACHE_QUERY_DATA_COMPLETE,
253     STATE_START_PARTIAL_CACHE_VALIDATION,
254     STATE_COMPLETE_PARTIAL_CACHE_VALIDATION,
255     STATE_CACHE_UPDATE_STALE_WHILE_REVALIDATE_TIMEOUT,
256     STATE_CACHE_UPDATE_STALE_WHILE_REVALIDATE_TIMEOUT_COMPLETE,
257     STATE_CONNECTED_CALLBACK,
258     STATE_CONNECTED_CALLBACK_COMPLETE,
259     STATE_SETUP_ENTRY_FOR_READ,
260     STATE_SEND_REQUEST,
261     STATE_SEND_REQUEST_COMPLETE,
262     STATE_SUCCESSFUL_SEND_REQUEST,
263     STATE_UPDATE_CACHED_RESPONSE,
264     STATE_CACHE_WRITE_UPDATED_RESPONSE,
265     STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE,
266     STATE_UPDATE_CACHED_RESPONSE_COMPLETE,
267     STATE_OVERWRITE_CACHED_RESPONSE,
268     STATE_CACHE_WRITE_RESPONSE,
269     STATE_CACHE_WRITE_RESPONSE_COMPLETE,
270     STATE_TRUNCATE_CACHED_DATA,
271     STATE_TRUNCATE_CACHED_DATA_COMPLETE,
272     STATE_TRUNCATE_CACHED_METADATA,
273     STATE_TRUNCATE_CACHED_METADATA_COMPLETE,
274     STATE_PARTIAL_HEADERS_RECEIVED,
275     STATE_HEADERS_PHASE_CANNOT_PROCEED,
276     STATE_FINISH_HEADERS,
277     STATE_FINISH_HEADERS_COMPLETE,
278 
279     // These states are entered from Read.
280     STATE_NETWORK_READ_CACHE_WRITE,
281     STATE_NETWORK_READ_CACHE_WRITE_COMPLETE,
282     STATE_CACHE_READ_DATA,
283     STATE_CACHE_READ_DATA_COMPLETE,
284     // These states are entered if the request should be handled exclusively
285     // by the network layer (skipping the cache entirely).
286     STATE_NETWORK_READ,
287     STATE_NETWORK_READ_COMPLETE,
288 
289     // These states are only entered a single-keyed cache entry needs to be
290     // marked unusable.
291     STATE_MARK_SINGLE_KEYED_CACHE_ENTRY_UNUSABLE,
292     STATE_MARK_SINGLE_KEYED_CACHE_ENTRY_UNUSABLE_COMPLETE,
293   };
294 
295   // Used for categorizing validation triggers in histograms.
296   // NOTE: This enumeration is used in histograms, so please do not add entries
297   // in the middle.
298   enum ValidationCause {
299     VALIDATION_CAUSE_UNDEFINED,
300     VALIDATION_CAUSE_VARY_MISMATCH,
301     VALIDATION_CAUSE_VALIDATE_FLAG,
302     VALIDATION_CAUSE_STALE,
303     VALIDATION_CAUSE_ZERO_FRESHNESS,
304     VALIDATION_CAUSE_MAX
305   };
306 
307   enum MemoryEntryDataHints {
308     // If this hint is set, the caching headers indicate we can't do anything
309     // with this entry (unless we are ignoring them thanks to a loadflag),
310     // i.e. it's expired and has nothing that permits validations.
311     HINT_UNUSABLE_PER_CACHING_HEADERS = (1 << 0),
312   };
313 
314   // Runs the state transition loop. Resets and calls |callback_| on exit,
315   // unless the return value is ERR_IO_PENDING.
316   int DoLoop(int result);
317 
318   // Each of these methods corresponds to a State value.  If there is an
319   // argument, the value corresponds to the return of the previous state or
320   // corresponding callback.
321   int DoGetBackend();
322   int DoGetBackendComplete(int result);
323   int DoInitEntry();
324   int DoOpenOrCreateEntry();
325   int DoOpenOrCreateEntryComplete(int result);
326   int DoDoomEntry();
327   int DoDoomEntryComplete(int result);
328   int DoCreateEntry();
329   int DoCreateEntryComplete(int result);
330   int DoAddToEntry();
331   int DoAddToEntryComplete(int result);
332   int DoDoneHeadersAddToEntryComplete(int result);
333   int DoCacheReadResponse();
334   int DoCacheReadResponseComplete(int result);
335   int DoCacheWriteUpdatedPrefetchResponse(int result);
336   int DoCacheWriteUpdatedPrefetchResponseComplete(int result);
337   int DoCacheDispatchValidation();
338   int DoCacheQueryData();
339   int DoCacheQueryDataComplete(int result);
340   int DoCacheUpdateStaleWhileRevalidateTimeout();
341   int DoCacheUpdateStaleWhileRevalidateTimeoutComplete(int result);
342   int DoConnectedCallback();
343   int DoConnectedCallbackComplete(int result);
344   int DoSetupEntryForRead();
345   int DoStartPartialCacheValidation();
346   int DoCompletePartialCacheValidation(int result);
347   int DoSendRequest();
348   int DoSendRequestComplete(int result);
349   int DoSuccessfulSendRequest();
350   int DoUpdateCachedResponse();
351   int DoCacheWriteUpdatedResponse();
352   int DoCacheWriteUpdatedResponseComplete(int result);
353   int DoUpdateCachedResponseComplete(int result);
354   int DoOverwriteCachedResponse();
355   int DoCacheWriteResponse();
356   int DoCacheWriteResponseComplete(int result);
357   int DoTruncateCachedData();
358   int DoTruncateCachedDataComplete(int result);
359   int DoTruncateCachedMetadata();
360   int DoTruncateCachedMetadataComplete(int result);
361   int DoPartialHeadersReceived();
362   int DoHeadersPhaseCannotProceed(int result);
363   int DoFinishHeaders(int result);
364   int DoFinishHeadersComplete(int result);
365   int DoNetworkReadCacheWrite();
366   int DoNetworkReadCacheWriteComplete(int result);
367   int DoCacheReadData();
368   int DoCacheReadDataComplete(int result);
369   int DoNetworkRead();
370   int DoNetworkReadComplete(int result);
371   int DoMarkSingleKeyedCacheEntryUnusable();
372   int DoMarkSingleKeyedCacheEntryUnusableComplete(int result);
373 
374   // Adds time out handling while waiting to be added to entry or after headers
375   // phase is complete.
376   void AddCacheLockTimeoutHandler(ActiveEntry* entry);
377 
378   // Sets request_ and fields derived from it.
379   void SetRequest(const NetLogWithSource& net_log);
380 
381   // Returns true if the request should be handled exclusively by the network
382   // layer (skipping the cache entirely).
383   bool ShouldPassThrough();
384 
385   // Called to begin reading from the cache.  Returns network error code.
386   int BeginCacheRead();
387 
388   // Called to begin validating the cache entry.  Returns network error code.
389   int BeginCacheValidation();
390 
391   // Called to begin validating an entry that stores partial content.  Returns
392   // a network error code.
393   int BeginPartialCacheValidation();
394 
395   // Validates the entry headers against the requested range and continues with
396   // the validation of the rest of the entry.  Returns a network error code.
397   int ValidateEntryHeadersAndContinue();
398 
399   // Returns whether the current externally conditionalized request's validation
400   // headers match the current cache entry's headers.
401   bool ExternallyConditionalizedValidationHeadersMatchEntry() const;
402 
403   // Called to start requests which were given an "if-modified-since" or
404   // "if-none-match" validation header by the caller (NOT when the request was
405   // conditionalized internally in response to LOAD_VALIDATE_CACHE).
406   // Returns a network error code.
407   int BeginExternallyConditionalizedRequest();
408 
409   // Called to restart a network transaction after an error.  Returns network
410   // error code.
411   int RestartNetworkRequest();
412 
413   // Called to restart a network transaction with a client certificate.
414   // Returns network error code.
415   int RestartNetworkRequestWithCertificate(
416       scoped_refptr<X509Certificate> client_cert,
417       scoped_refptr<SSLPrivateKey> client_private_key);
418 
419   // Called to restart a network transaction with authentication credentials.
420   // Returns network error code.
421   int RestartNetworkRequestWithAuth(const AuthCredentials& credentials);
422 
423   // Called to determine if we need to validate the cache entry before using it,
424   // and whether the validation should be synchronous or asynchronous.
425   ValidationType RequiresValidation();
426 
427   // Called to make the request conditional (to ask the server if the cached
428   // copy is valid).  Returns true if able to make the request conditional.
429   bool ConditionalizeRequest();
430 
431   // Determines if saved response permits conditionalization, and extracts
432   // etag/last-modified values. Only depends on |response_.headers|.
433   // |*etag_value| and |*last_modified_value| will be set if true is returned,
434   // but may also be modified in other cases.
435   bool IsResponseConditionalizable(std::string* etag_value,
436                                    std::string* last_modified_value) const;
437 
438   // Returns true if |method_| indicates that we should only try to open an
439   // entry and not attempt to create.
440   bool ShouldOpenOnlyMethods() const;
441 
442   // Returns true if the resource info MemoryEntryDataHints bit flags in
443   // |in_memory_info| and the current request & load flags suggest that
444   // the cache entry in question is not actually usable for HTTP
445   // (i.e. already expired, and nothing is forcing us to disregard that).
446   bool MaybeRejectBasedOnEntryInMemoryData(uint8_t in_memory_info);
447 
448   // Returns true if response_ is such that, if saved to cache, it would only
449   // be usable if load flags asked us to ignore caching headers.
450   // (return value of false makes no statement as to suitability of the entry).
451   bool ComputeUnusablePerCachingHeaders();
452 
453   // Makes sure that a 206 response is expected.  Returns true on success.
454   // On success, handling_206_ will be set to true if we are processing a
455   // partial entry.
456   bool ValidatePartialResponse();
457 
458   // Handles a response validation error by bypassing the cache.
459   void IgnoreRangeRequest();
460 
461   // Fixes the response headers to match expectations for a HEAD request.
462   void FixHeadersForHead();
463 
464   // Called to write a response to the cache entry. |truncated| indicates if the
465   // entry should be marked as incomplete.
466   int WriteResponseInfoToEntry(const HttpResponseInfo& response,
467                                bool truncated);
468 
469   // Helper function, should be called with result of WriteResponseInfoToEntry
470   // (or the result of the callback, when WriteResponseInfoToEntry returns
471   // ERR_IO_PENDING). Calls DoneWithEntry if |result| is not the right
472   // number of bytes. It is expected that the state that calls this will
473   // return whatever net error code this function returns, which currently
474   // is always "OK".
475   int OnWriteResponseInfoToEntryComplete(int result);
476 
477   // Configures the transaction to read from the network and stop writing to the
478   // entry. It will release the entry if possible. Returns true if caching could
479   // be stopped successfully. It will not be stopped if there are multiple
480   // transactions writing to the cache simultaneously.
481   bool StopCachingImpl(bool success);
482 
483   // Informs the HttpCache that this transaction is done with the entry and
484   // changes the mode to NONE. Set |entry_is_complete| to false if the
485   // transaction has not yet finished fully writing or reading the request
486   // to/from the entry. If |entry_is_complete| is false the result may be either
487   // a truncated or a doomed entry based on whether the stored response can be
488   // resumed or not.
489   void DoneWithEntry(bool entry_is_complete);
490 
491   // Informs the HttpCache that this transaction is done with the entry and
492   // resets related fields.
493   void DoneWithEntryForRestartWithCache();
494 
495   // Dooms the given entry so that it will not be re-used for other requests,
496   // then calls `DoneWithEntry()`.
497   //
498   // This happens when network conditions have changed since the entry was
499   // cached, which results in deterministic failures when trying to use the
500   // cache entry. In order to let future requests succeed, the cache entry
501   // should be doomed.
502   void DoomInconsistentEntry();
503 
504   // Returns an error to signal the caller that the current read failed. The
505   // current operation |result| is also logged. If |restart| is true, the
506   // transaction should be restarted.
507   int OnCacheReadError(int result, bool restart);
508 
509   // Called when the cache lock timeout fires.
510   void OnCacheLockTimeout(base::TimeTicks start_time);
511 
512   // Deletes the current partial cache entry (sparse), and optionally removes
513   // the control object (partial_).
514   void DoomPartialEntry(bool delete_object);
515 
516   // Performs the needed work after receiving data from the network, when
517   // working with range requests.
518   int DoPartialNetworkReadCompleted(int result);
519 
520   // Performs the needed work after receiving data from the cache, when
521   // working with range requests.
522   int DoPartialCacheReadCompleted(int result);
523 
524   // Restarts this transaction after deleting the cached data. It is meant to
525   // be used when the current request cannot be fulfilled due to conflicts
526   // between the byte range request and the cached entry.
527   int DoRestartPartialRequest();
528 
529   // Resets the relavant internal state to remove traces of internal processing
530   // related to range requests. Deletes |partial_| if |delete_object| is true.
531   void ResetPartialState(bool delete_object);
532 
533   // Resets |network_trans_|, which must be non-NULL.  Also updates
534   // |old_network_trans_load_timing_|, which must be NULL when this is called.
535   void ResetNetworkTransaction();
536 
537   // Returns the currently active network transaction.
538   const HttpTransaction* network_transaction() const;
539   HttpTransaction* network_transaction();
540 
541   // Returns the network transaction from |this| or from writers only if it was
542   // moved from |this| to writers. This is so that statistics of the network
543   // transaction are not attributed to any other writer member.
544   const HttpTransaction* GetOwnedOrMovedNetworkTransaction() const;
545 
546   // Returns true if we should bother attempting to resume this request if it is
547   // aborted while in progress. If |has_data| is true, the size of the stored
548   // data is considered for the result.
549   bool CanResume(bool has_data);
550 
551   // Setter for response_ and auth_response_. It updates its cache entry status,
552   // if needed.
553   void SetResponse(const HttpResponseInfo& new_response);
554   void SetAuthResponse(const HttpResponseInfo& new_response);
555 
556   void UpdateCacheEntryStatus(
557       HttpResponseInfo::CacheEntryStatus new_cache_entry_status);
558 
559   // Sets the response.cache_entry_status to the current cache_entry_status_.
560   void SyncCacheEntryStatusToResponse();
561 
562   // Logs histograms for this transaction. It is invoked when the transaction is
563   // either complete or is done writing to entry and will continue in
564   // network-only mode.
565   void RecordHistograms();
566 
567   // Returns true if this transaction is a member of entry_->writers.
568   bool InWriters() const;
569 
570   // Called to signal completion of asynchronous IO. Note that this callback is
571   // used in the conventional sense where one layer calls the callback of the
572   // layer above it e.g. this callback gets called from the network transaction
573   // layer. In addition, it is also used for HttpCache layer to let this
574   // transaction know when it is out of a queued state in ActiveEntry and can
575   // continue its processing.
576   void OnIOComplete(int result);
577 
578   // When in a DoLoop, use this to set the next state as it verifies that the
579   // state isn't set twice.
580   void TransitionToState(State state);
581 
582   // Helper function to decide the next reading state.
583   int TransitionToReadingState();
584 
585   // Saves network transaction info using |transaction|.
586   void SaveNetworkTransactionInfo(const HttpTransaction& transaction);
587 
588   // Determines whether caching should be disabled for a response, given its
589   // headers.
590   bool ShouldDisableCaching(const HttpResponseHeaders& headers) const;
591 
592   // Checksum headers in `request_` for matching against the single-keyed cache
593   // checksum. Initializes `checksum_`.
594   void ChecksumHeaders();
595 
596   // Finishes the checksum and validates that it matches the expected value.
597   // Returns true if the checksum matches. Returns false if it does not
598   // match. If no checksumming is taking place then returns true.
599   bool FinishAndCheckChecksum();
600 
601   // 304 revalidations of resources that set security headers and that get
602   // forwarded might need to set these headers again to avoid being blocked.
603   void UpdateSecurityHeadersBeforeForwarding();
604 
605   enum class DiskCacheAccessType {
606     kRead,
607     kWrite,
608   };
609   void BeginDiskCacheAccessTimeCount();
610   void EndDiskCacheAccessTimeCount(DiskCacheAccessType type);
611 
612   State next_state_{STATE_NONE};
613 
614   // Used for tracing.
615   const uint64_t trace_id_;
616 
617   // Initial request with which Start() was invoked.
618   raw_ptr<const HttpRequestInfo> initial_request_ = nullptr;
619 
620   // `custom_request_` is assigned to `request_` after allocation. It must be
621   // declared before `request_` so that it will be destroyed afterwards to
622   // prevent that pointer from dangling.
623   std::unique_ptr<HttpRequestInfo> custom_request_;
624 
625   raw_ptr<const HttpRequestInfo> request_ = nullptr;
626 
627   std::string method_;
628   RequestPriority priority_;
629   NetLogWithSource net_log_;
630   HttpRequestHeaders request_headers_copy_;
631   // If extra_headers specified a "if-modified-since" or "if-none-match",
632   // |external_validation_| contains the value of those headers.
633   ValidationHeaders external_validation_;
634   base::WeakPtr<HttpCache> cache_;
635   raw_ptr<HttpCache::ActiveEntry, DanglingUntriaged> entry_ = nullptr;
636   // This field is not a raw_ptr<> because it was filtered by the rewriter for:
637   // #addr-of
638   RAW_PTR_EXCLUSION HttpCache::ActiveEntry* new_entry_ = nullptr;
639   std::unique_ptr<HttpTransaction> network_trans_;
640   CompletionOnceCallback callback_;  // Consumer's callback.
641   HttpResponseInfo response_;
642   HttpResponseInfo auth_response_;
643 
644   // This is only populated when we want to modify a prefetch request in some
645   // way for future transactions, while leaving it untouched for the current
646   // one. DoCacheReadResponseComplete() sets this to a copy of |response_|,
647   // and modifies the members for future transactions. Then,
648   // WriteResponseInfoToEntry() writes |updated_prefetch_response_| to the cache
649   // entry if it is populated, or |response_| otherwise. Finally,
650   // WriteResponseInfoToEntry() resets this to absl::nullopt.
651   std::unique_ptr<HttpResponseInfo> updated_prefetch_response_;
652 
653   raw_ptr<const HttpResponseInfo, DanglingUntriaged> new_response_ = nullptr;
654   std::string cache_key_;
655   Mode mode_ = NONE;
656   bool reading_ = false;          // We are already reading. Never reverts to
657                                   // false once set.
658   bool invalid_range_ = false;    // We may bypass the cache for this request.
659   bool truncated_ = false;        // We don't have all the response data.
660   bool is_sparse_ = false;        // The data is stored in sparse byte ranges.
661   bool range_requested_ = false;  // The user requested a byte range.
662   bool handling_206_ = false;     // We must deal with this 206 response.
663   bool cache_pending_ = false;    // We are waiting for the HttpCache.
664 
665   // Headers have been received from the network and it's not a match with the
666   // existing entry.
667   bool done_headers_create_new_entry_ = false;
668 
669   bool vary_mismatch_ = false;  // The request doesn't match the stored vary
670                                 // data.
671   bool couldnt_conditionalize_request_ = false;
672   bool bypass_lock_for_test_ = false;  // A test is exercising the cache lock.
673   bool bypass_lock_after_headers_for_test_ = false;  // A test is exercising the
674                                                      // cache lock.
675   bool fail_conditionalization_for_test_ =
676       false;  // Fail ConditionalizeRequest.
677   bool mark_single_keyed_cache_entry_unusable_ =
678       false;  // Set single_keyed_cache_entry_unusable.
679   // This is initialised in Start().
680   bool use_single_keyed_cache_ = false;
681 
682   scoped_refptr<IOBuffer> read_buf_;
683 
684   // Length of the buffer passed in Read().
685   int read_buf_len_ = 0;
686 
687   int io_buf_len_ = 0;
688   int read_offset_ = 0;
689   int effective_load_flags_ = 0;
690   std::unique_ptr<PartialData> partial_;  // We are dealing with range requests.
691   CompletionRepeatingCallback io_callback_;
692 
693   // Error code to be returned from a subsequent Read call if shared writing
694   // failed in a separate transaction.
695   int shared_writing_error_ = OK;
696 
697   // Members used to track data for histograms.
698   // This cache_entry_status_ takes precedence over
699   // response_.cache_entry_status. In fact, response_.cache_entry_status must be
700   // kept in sync with cache_entry_status_ (via SetResponse and
701   // UpdateCacheEntryStatus).
702   HttpResponseInfo::CacheEntryStatus cache_entry_status_ =
703       HttpResponseInfo::CacheEntryStatus::ENTRY_UNDEFINED;
704   ValidationCause validation_cause_ = VALIDATION_CAUSE_UNDEFINED;
705   base::TimeTicks entry_lock_waiting_since_;
706   base::TimeTicks first_cache_access_since_;
707   base::TimeTicks send_request_since_;
708   base::TimeTicks read_headers_since_;
709   base::Time open_entry_last_used_;
710   base::TimeTicks last_disk_cache_access_start_time_;
711   base::TimeDelta total_disk_cache_read_time_;
712   base::TimeDelta total_disk_cache_write_time_;
713   bool recorded_histograms_ = false;
714   bool has_opened_or_created_entry_ = false;
715   bool record_entry_open_or_creation_time_ = false;
716 
717   NetworkTransactionInfo network_transaction_info_;
718 
719   // True if this transaction created the network transaction that is now being
720   // used by writers. This is used to check that only this transaction should
721   // account for the network bytes and other statistics of the network
722   // transaction.
723   // TODO(shivanisha) Note that if this transaction dies mid-way and there are
724   // other writer transactions, no transaction then accounts for those
725   // statistics.
726   bool moved_network_transaction_to_writers_ = false;
727 
728   // The helper object to use to create WebSocketHandshakeStreamBase
729   // objects. Only relevant when establishing a WebSocket connection.
730   // This is passed to the underlying network transaction. It is stored here in
731   // case the transaction does not exist yet.
732   raw_ptr<WebSocketHandshakeStreamBase::CreateHelper>
733       websocket_handshake_stream_base_create_helper_ = nullptr;
734 
735   // Set if we are currently calculating a checksum of the resource to validate
736   // it against the expected checksum for the single-keyed cache. Accumulates a
737   // hash of selected headers and the body of the response.
738   std::unique_ptr<crypto::SecureHash> checksum_;
739 
740   BeforeNetworkStartCallback before_network_start_callback_;
741   ConnectedCallback connected_callback_;
742   RequestHeadersCallback request_headers_callback_;
743   ResponseHeadersCallback early_response_headers_callback_;
744   ResponseHeadersCallback response_headers_callback_;
745 
746   // True if the Transaction is currently processing the DoLoop.
747   bool in_do_loop_ = false;
748 
749   base::WeakPtrFactory<Transaction> weak_factory_{this};
750 };
751 
752 }  // namespace net
753 
754 #endif  // NET_HTTP_HTTP_CACHE_TRANSACTION_H_
755