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