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