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