xref: /aosp_15_r20/external/cronet/net/base/upload_file_element_reader.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 #ifndef NET_BASE_UPLOAD_FILE_ELEMENT_READER_H_
6 #define NET_BASE_UPLOAD_FILE_ELEMENT_READER_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 
12 #include "base/compiler_specific.h"
13 #include "base/files/file.h"
14 #include "base/files/file_path.h"
15 #include "base/gtest_prod_util.h"
16 #include "base/memory/scoped_refptr.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/time/time.h"
19 #include "net/base/net_export.h"
20 #include "net/base/upload_element_reader.h"
21 
22 namespace base {
23 class TaskRunner;
24 }
25 
26 namespace net {
27 
28 class FileStream;
29 
30 // An UploadElementReader implementation for file.
31 class NET_EXPORT UploadFileElementReader : public UploadElementReader {
32  public:
33   // |file| must be valid and opened for reading. On Windows, the file must have
34   // been opened with File::FLAG_ASYNC, and elsewhere it must have ben opened
35   // without it. |path| is never validated or used to re-open the file. It's
36   // only used as the return value for path().
37   // |task_runner| is used to perform file operations. It must not be NULL.
38   //
39   // TODO(mmenke): Remove |task_runner| argument, and use the ThreadPool
40   // instead.
41   UploadFileElementReader(base::TaskRunner* task_runner,
42                           base::File file,
43                           const base::FilePath& path,
44                           uint64_t range_offset,
45                           uint64_t range_length,
46                           const base::Time& expected_modification_time);
47 
48   // Same a above, but takes a FilePath instead.
49   // TODO(mmenke): Remove if all consumers can be switched to the first
50   // constructor.
51   UploadFileElementReader(base::TaskRunner* task_runner,
52                           const base::FilePath& path,
53                           uint64_t range_offset,
54                           uint64_t range_length,
55                           const base::Time& expected_modification_time);
56 
57   UploadFileElementReader(const UploadFileElementReader&) = delete;
58   UploadFileElementReader& operator=(const UploadFileElementReader&) = delete;
59   ~UploadFileElementReader() override;
60 
path()61   const base::FilePath& path() const { return path_; }
range_offset()62   uint64_t range_offset() const { return range_offset_; }
range_length()63   uint64_t range_length() const { return range_length_; }
expected_modification_time()64   const base::Time& expected_modification_time() const {
65     return expected_modification_time_;
66   }
67 
68   // UploadElementReader overrides:
69   const UploadFileElementReader* AsFileReader() const override;
70   int Init(CompletionOnceCallback callback) override;
71   uint64_t GetContentLength() const override;
72   uint64_t BytesRemaining() const override;
73   int Read(IOBuffer* buf,
74            int buf_length,
75            CompletionOnceCallback callback) override;
76 
77  private:
78   enum class State {
79     // No async operation is pending.
80     IDLE,
81 
82     // The ordered sequence of events started by calling Init().
83 
84     // Opens file. State is skipped if file already open.
85     OPEN,
86     OPEN_COMPLETE,
87     SEEK,
88     GET_FILE_INFO,
89     GET_FILE_INFO_COMPLETE,
90 
91     // There is no READ state as reads are always started immediately on Read().
92     READ_COMPLETE,
93   };
94   FRIEND_TEST_ALL_PREFIXES(ElementsUploadDataStreamTest, FileSmallerThanLength);
95   FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
96                            UploadFileSmallerThanLength);
97 
98   int DoLoop(int result);
99 
100   int DoOpen();
101   int DoOpenComplete(int result);
102   int DoSeek();
103   int DoGetFileInfo(int result);
104   int DoGetFileInfoComplete(int result);
105   int DoReadComplete(int result);
106 
107   void OnIOComplete(int result);
108 
109   // Sets an value to override the result for GetContentLength().
110   // Used for tests.
111   struct NET_EXPORT_PRIVATE ScopedOverridingContentLengthForTests {
112     explicit ScopedOverridingContentLengthForTests(uint64_t value);
113     ~ScopedOverridingContentLengthForTests();
114   };
115 
116   scoped_refptr<base::TaskRunner> task_runner_;
117   const base::FilePath path_;
118   const uint64_t range_offset_;
119   const uint64_t range_length_;
120   const base::Time expected_modification_time_;
121   std::unique_ptr<FileStream> file_stream_;
122   uint64_t content_length_ = 0;
123   uint64_t bytes_remaining_ = 0;
124 
125   // File information. Only valid during GET_FILE_INFO_COMPLETE state.
126   base::File::Info file_info_;
127 
128   State next_state_ = State::IDLE;
129   CompletionOnceCallback pending_callback_;
130   // True if Init() was called while an async operation was in progress.
131   bool init_called_while_operation_pending_ = false;
132 
133   base::WeakPtrFactory<UploadFileElementReader> weak_ptr_factory_{this};
134 };
135 
136 }  // namespace net
137 
138 #endif  // NET_BASE_UPLOAD_FILE_ELEMENT_READER_H_
139