xref: /aosp_15_r20/external/cronet/net/http/partial_data.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef NET_HTTP_PARTIAL_DATA_H_
6*6777b538SAndroid Build Coastguard Worker #define NET_HTTP_PARTIAL_DATA_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h"
11*6777b538SAndroid Build Coastguard Worker #include "net/base/completion_once_callback.h"
12*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/disk_cache.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/http/http_byte_range.h"
14*6777b538SAndroid Build Coastguard Worker #include "net/http/http_request_headers.h"
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker namespace net {
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker class HttpResponseHeaders;
20*6777b538SAndroid Build Coastguard Worker class IOBuffer;
21*6777b538SAndroid Build Coastguard Worker 
22*6777b538SAndroid Build Coastguard Worker // This class provides support for dealing with range requests and the
23*6777b538SAndroid Build Coastguard Worker // subsequent partial-content responses. We use sparse cache entries to store
24*6777b538SAndroid Build Coastguard Worker // these requests. This class is tightly integrated with HttpCache::Transaction
25*6777b538SAndroid Build Coastguard Worker // and it is intended to allow a cleaner implementation of that class.
26*6777b538SAndroid Build Coastguard Worker //
27*6777b538SAndroid Build Coastguard Worker // In order to fulfill range requests, we may have to perform a sequence of
28*6777b538SAndroid Build Coastguard Worker // reads from the cache, interleaved with reads from the network / writes to the
29*6777b538SAndroid Build Coastguard Worker // cache. This class basically keeps track of the data required to perform each
30*6777b538SAndroid Build Coastguard Worker // of those individual network / cache requests.
31*6777b538SAndroid Build Coastguard Worker class PartialData {
32*6777b538SAndroid Build Coastguard Worker  public:
33*6777b538SAndroid Build Coastguard Worker   PartialData();
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker   PartialData(const PartialData&) = delete;
36*6777b538SAndroid Build Coastguard Worker   PartialData& operator=(const PartialData&) = delete;
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker   ~PartialData();
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker   // Performs initialization of the object by examining the request |headers|
41*6777b538SAndroid Build Coastguard Worker   // and verifying that we can process the requested range. Returns true if
42*6777b538SAndroid Build Coastguard Worker   // we can process the requested range, and false otherwise.
43*6777b538SAndroid Build Coastguard Worker   bool Init(const HttpRequestHeaders& headers);
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker   // Sets the headers that we should use to make byte range requests. This is a
46*6777b538SAndroid Build Coastguard Worker   // subset of the request extra headers, with byte-range related headers
47*6777b538SAndroid Build Coastguard Worker   // removed.
48*6777b538SAndroid Build Coastguard Worker   void SetHeaders(const HttpRequestHeaders& headers);
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker   // Restores the byte-range headers, by appending the byte range to the headers
51*6777b538SAndroid Build Coastguard Worker   // provided to SetHeaders().
52*6777b538SAndroid Build Coastguard Worker   void RestoreHeaders(HttpRequestHeaders* headers) const;
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker   // Starts the checks to perform a cache validation. Returns 0 when there is no
55*6777b538SAndroid Build Coastguard Worker   // need to perform more operations because we reached the end of the request
56*6777b538SAndroid Build Coastguard Worker   // (so 0 bytes should be actually returned to the user), a positive number to
57*6777b538SAndroid Build Coastguard Worker   // indicate that PrepareCacheValidation should be called, or an appropriate
58*6777b538SAndroid Build Coastguard Worker   // error code. If this method returns ERR_IO_PENDING, the |callback| will be
59*6777b538SAndroid Build Coastguard Worker   // notified when the result is ready.
60*6777b538SAndroid Build Coastguard Worker   int ShouldValidateCache(disk_cache::Entry* entry,
61*6777b538SAndroid Build Coastguard Worker                           CompletionOnceCallback callback);
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker   // Builds the required |headers| to perform the proper cache validation for
64*6777b538SAndroid Build Coastguard Worker   // the next range to be fetched.
65*6777b538SAndroid Build Coastguard Worker   void PrepareCacheValidation(disk_cache::Entry* entry,
66*6777b538SAndroid Build Coastguard Worker                               HttpRequestHeaders* headers);
67*6777b538SAndroid Build Coastguard Worker 
68*6777b538SAndroid Build Coastguard Worker   // Returns true if the current range is stored in the cache.
69*6777b538SAndroid Build Coastguard Worker   bool IsCurrentRangeCached() const;
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker   // Returns true if the current range is the last one needed to fulfill the
72*6777b538SAndroid Build Coastguard Worker   // user's request.
73*6777b538SAndroid Build Coastguard Worker   bool IsLastRange() const;
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker   // Extracts info from headers already stored in the cache. Returns false if
76*6777b538SAndroid Build Coastguard Worker   // there is any problem with the headers. |truncated| should be true if we
77*6777b538SAndroid Build Coastguard Worker   // have an incomplete 200 entry due to a transfer having been interrupted.
78*6777b538SAndroid Build Coastguard Worker   // |writing_in_progress| should be set to true if a transfer for this entry's
79*6777b538SAndroid Build Coastguard Worker   // payload is still in progress.
80*6777b538SAndroid Build Coastguard Worker   bool UpdateFromStoredHeaders(const HttpResponseHeaders* headers,
81*6777b538SAndroid Build Coastguard Worker                                disk_cache::Entry* entry,
82*6777b538SAndroid Build Coastguard Worker                                bool truncated,
83*6777b538SAndroid Build Coastguard Worker                                bool writing_in_progress);
84*6777b538SAndroid Build Coastguard Worker 
85*6777b538SAndroid Build Coastguard Worker   // Sets the byte current range to start again at zero (for a truncated entry).
86*6777b538SAndroid Build Coastguard Worker   void SetRangeToStartDownload();
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker   // Returns true if the requested range is valid given the stored data.
89*6777b538SAndroid Build Coastguard Worker   bool IsRequestedRangeOK();
90*6777b538SAndroid Build Coastguard Worker 
91*6777b538SAndroid Build Coastguard Worker   // Returns true if the response headers match what we expect, false otherwise.
92*6777b538SAndroid Build Coastguard Worker   bool ResponseHeadersOK(const HttpResponseHeaders* headers);
93*6777b538SAndroid Build Coastguard Worker 
94*6777b538SAndroid Build Coastguard Worker   // Fixes the response headers to include the right content length and range.
95*6777b538SAndroid Build Coastguard Worker   // |success| is the result of the whole request so if it's false, we'll change
96*6777b538SAndroid Build Coastguard Worker   // the result code to be 416.
97*6777b538SAndroid Build Coastguard Worker   void FixResponseHeaders(HttpResponseHeaders* headers, bool success);
98*6777b538SAndroid Build Coastguard Worker 
99*6777b538SAndroid Build Coastguard Worker   // Fixes the content length that we want to store in the cache.
100*6777b538SAndroid Build Coastguard Worker   void FixContentLength(HttpResponseHeaders* headers);
101*6777b538SAndroid Build Coastguard Worker 
102*6777b538SAndroid Build Coastguard Worker   // Reads up to |data_len| bytes from the cache and stores them in the provided
103*6777b538SAndroid Build Coastguard Worker   // buffer (|data|). Basically, this is just a wrapper around the API of the
104*6777b538SAndroid Build Coastguard Worker   // cache that provides the right arguments for the current range. When the IO
105*6777b538SAndroid Build Coastguard Worker   // operation completes, OnCacheReadCompleted() must be called with the result
106*6777b538SAndroid Build Coastguard Worker   // of the operation.
107*6777b538SAndroid Build Coastguard Worker   int CacheRead(disk_cache::Entry* entry,
108*6777b538SAndroid Build Coastguard Worker                 IOBuffer* data,
109*6777b538SAndroid Build Coastguard Worker                 int data_len,
110*6777b538SAndroid Build Coastguard Worker                 CompletionOnceCallback callback);
111*6777b538SAndroid Build Coastguard Worker 
112*6777b538SAndroid Build Coastguard Worker   // Writes |data_len| bytes to cache. This is basically a wrapper around the
113*6777b538SAndroid Build Coastguard Worker   // API of the cache that provides the right arguments for the current range.
114*6777b538SAndroid Build Coastguard Worker   int CacheWrite(disk_cache::Entry* entry,
115*6777b538SAndroid Build Coastguard Worker                  IOBuffer* data,
116*6777b538SAndroid Build Coastguard Worker                  int data_len,
117*6777b538SAndroid Build Coastguard Worker                  CompletionOnceCallback callback);
118*6777b538SAndroid Build Coastguard Worker 
119*6777b538SAndroid Build Coastguard Worker   // This method should be called when CacheRead() finishes the read, to update
120*6777b538SAndroid Build Coastguard Worker   // the internal state about the current range.
121*6777b538SAndroid Build Coastguard Worker   void OnCacheReadCompleted(int result);
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker   // This method should be called after receiving data from the network, to
124*6777b538SAndroid Build Coastguard Worker   // update the internal state about the current range.
125*6777b538SAndroid Build Coastguard Worker   void OnNetworkReadCompleted(int result);
126*6777b538SAndroid Build Coastguard Worker 
initial_validation()127*6777b538SAndroid Build Coastguard Worker   bool initial_validation() const { return initial_validation_; }
128*6777b538SAndroid Build Coastguard Worker 
range_requested()129*6777b538SAndroid Build Coastguard Worker   bool range_requested() const { return range_requested_; }
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker  private:
132*6777b538SAndroid Build Coastguard Worker   // Returns the length to use when scanning the cache.
133*6777b538SAndroid Build Coastguard Worker   int GetNextRangeLen();
134*6777b538SAndroid Build Coastguard Worker 
135*6777b538SAndroid Build Coastguard Worker   // Completion routine for our callback.
136*6777b538SAndroid Build Coastguard Worker   void GetAvailableRangeCompleted(const disk_cache::RangeResult& result);
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker   // The portion we're trying to get, either from cache or network.
139*6777b538SAndroid Build Coastguard Worker   int64_t current_range_start_ = 0;
140*6777b538SAndroid Build Coastguard Worker   int64_t current_range_end_ = 0;
141*6777b538SAndroid Build Coastguard Worker 
142*6777b538SAndroid Build Coastguard Worker   // Next portion available in the cache --- this may be what's currently being
143*6777b538SAndroid Build Coastguard Worker   // read, or the next thing that will be read if the current network portion
144*6777b538SAndroid Build Coastguard Worker   // succeeds.
145*6777b538SAndroid Build Coastguard Worker   //
146*6777b538SAndroid Build Coastguard Worker   // |cached_start_| represents the beginning of the range, while
147*6777b538SAndroid Build Coastguard Worker   // |cached_min_len_| the data not yet read (possibly overestimated). It may
148*6777b538SAndroid Build Coastguard Worker   // also have an error code latched into it.
149*6777b538SAndroid Build Coastguard Worker   int64_t cached_start_ = 0;
150*6777b538SAndroid Build Coastguard Worker   int cached_min_len_ = 0;
151*6777b538SAndroid Build Coastguard Worker 
152*6777b538SAndroid Build Coastguard Worker   // The size of the whole file.
153*6777b538SAndroid Build Coastguard Worker   int64_t resource_size_ = 0;
154*6777b538SAndroid Build Coastguard Worker   HttpByteRange user_byte_range_;  // The range requested by the user.
155*6777b538SAndroid Build Coastguard Worker   HttpByteRange byte_range_;       // Range requested by user potentially
156*6777b538SAndroid Build Coastguard Worker                                    // interpreted in context of stored length.
157*6777b538SAndroid Build Coastguard Worker   // The clean set of extra headers (no ranges).
158*6777b538SAndroid Build Coastguard Worker   HttpRequestHeaders extra_headers_;
159*6777b538SAndroid Build Coastguard Worker   bool range_requested_ = false;  // ###
160*6777b538SAndroid Build Coastguard Worker   bool range_present_ = false;    // True if next range entry is already stored.
161*6777b538SAndroid Build Coastguard Worker   bool final_range_ = false;
162*6777b538SAndroid Build Coastguard Worker   bool sparse_entry_ = true;
163*6777b538SAndroid Build Coastguard Worker   bool truncated_ = false;           // We have an incomplete 200 stored.
164*6777b538SAndroid Build Coastguard Worker   bool initial_validation_ = false;  // Only used for truncated entries.
165*6777b538SAndroid Build Coastguard Worker   CompletionOnceCallback callback_;
166*6777b538SAndroid Build Coastguard Worker   base::WeakPtrFactory<PartialData> weak_factory_{this};
167*6777b538SAndroid Build Coastguard Worker };
168*6777b538SAndroid Build Coastguard Worker 
169*6777b538SAndroid Build Coastguard Worker }  // namespace net
170*6777b538SAndroid Build Coastguard Worker 
171*6777b538SAndroid Build Coastguard Worker #endif  // NET_HTTP_PARTIAL_DATA_H_
172