1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 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_BASE_UPLOAD_DATA_STREAM_H_ 6*6777b538SAndroid Build Coastguard Worker #define NET_BASE_UPLOAD_DATA_STREAM_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 <memory> 11*6777b538SAndroid Build Coastguard Worker #include <vector> 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Worker #include "net/base/completion_once_callback.h" 14*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h" 15*6777b538SAndroid Build Coastguard Worker #include "net/base/upload_progress.h" 16*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_with_source.h" 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker namespace net { 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard Worker class IOBuffer; 21*6777b538SAndroid Build Coastguard Worker class UploadElementReader; 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker // A class for retrieving all data to be sent as a request body. Supports both 24*6777b538SAndroid Build Coastguard Worker // chunked and non-chunked uploads. 25*6777b538SAndroid Build Coastguard Worker class NET_EXPORT UploadDataStream { 26*6777b538SAndroid Build Coastguard Worker public: 27*6777b538SAndroid Build Coastguard Worker // |identifier| identifies a particular upload instance, which is used by the 28*6777b538SAndroid Build Coastguard Worker // cache to formulate a cache key. This value should be unique across browser 29*6777b538SAndroid Build Coastguard Worker // sessions. A value of 0 is used to indicate an unspecified identifier. 30*6777b538SAndroid Build Coastguard Worker UploadDataStream(bool is_chunked, int64_t identifier); 31*6777b538SAndroid Build Coastguard Worker UploadDataStream(bool is_chunked, bool has_null_source, int64_t identifier); 32*6777b538SAndroid Build Coastguard Worker 33*6777b538SAndroid Build Coastguard Worker UploadDataStream(const UploadDataStream&) = delete; 34*6777b538SAndroid Build Coastguard Worker UploadDataStream& operator=(const UploadDataStream&) = delete; 35*6777b538SAndroid Build Coastguard Worker 36*6777b538SAndroid Build Coastguard Worker virtual ~UploadDataStream(); 37*6777b538SAndroid Build Coastguard Worker 38*6777b538SAndroid Build Coastguard Worker // Initializes the stream. This function must be called before calling any 39*6777b538SAndroid Build Coastguard Worker // other method. It is not valid to call any method (other than the 40*6777b538SAndroid Build Coastguard Worker // destructor) if Init() fails. This method can be called multiple times. 41*6777b538SAndroid Build Coastguard Worker // Calling this method after an Init() success results in resetting the 42*6777b538SAndroid Build Coastguard Worker // state (i.e. the stream is rewound). 43*6777b538SAndroid Build Coastguard Worker // 44*6777b538SAndroid Build Coastguard Worker // Does the initialization synchronously and returns the result if possible, 45*6777b538SAndroid Build Coastguard Worker // otherwise returns ERR_IO_PENDING and runs the callback with the result. 46*6777b538SAndroid Build Coastguard Worker // 47*6777b538SAndroid Build Coastguard Worker // Returns OK on success. Returns ERR_UPLOAD_FILE_CHANGED if the expected 48*6777b538SAndroid Build Coastguard Worker // file modification time is set (usually not set, but set for sliced 49*6777b538SAndroid Build Coastguard Worker // files) and the target file is changed. 50*6777b538SAndroid Build Coastguard Worker int Init(CompletionOnceCallback callback, const NetLogWithSource& net_log); 51*6777b538SAndroid Build Coastguard Worker 52*6777b538SAndroid Build Coastguard Worker // When possible, reads up to |buf_len| bytes synchronously from the upload 53*6777b538SAndroid Build Coastguard Worker // data stream to |buf| and returns the number of bytes read; otherwise, 54*6777b538SAndroid Build Coastguard Worker // returns ERR_IO_PENDING and calls |callback| with the number of bytes read. 55*6777b538SAndroid Build Coastguard Worker // Partial reads are allowed. Zero is returned on a call to Read when there 56*6777b538SAndroid Build Coastguard Worker // are no remaining bytes in the stream, and IsEof() will return true 57*6777b538SAndroid Build Coastguard Worker // hereafter. 58*6777b538SAndroid Build Coastguard Worker // 59*6777b538SAndroid Build Coastguard Worker // If there's less data to read than we initially observed (i.e. the actual 60*6777b538SAndroid Build Coastguard Worker // upload data is smaller than size()), zeros are padded to ensure that 61*6777b538SAndroid Build Coastguard Worker // size() bytes can be read, which can happen for TYPE_FILE payloads. 62*6777b538SAndroid Build Coastguard Worker // 63*6777b538SAndroid Build Coastguard Worker // TODO(mmenke): Investigate letting reads fail. 64*6777b538SAndroid Build Coastguard Worker int Read(IOBuffer* buf, int buf_len, CompletionOnceCallback callback); 65*6777b538SAndroid Build Coastguard Worker 66*6777b538SAndroid Build Coastguard Worker // Returns the total size of the data stream and the current position. 67*6777b538SAndroid Build Coastguard Worker // When the data is chunked, always returns zero. Must always return the same 68*6777b538SAndroid Build Coastguard Worker // value after each call to Initialize(). size()69*6777b538SAndroid Build Coastguard Worker uint64_t size() const { return total_size_; } position()70*6777b538SAndroid Build Coastguard Worker uint64_t position() const { return current_position_; } 71*6777b538SAndroid Build Coastguard Worker 72*6777b538SAndroid Build Coastguard Worker // See constructor for description. identifier()73*6777b538SAndroid Build Coastguard Worker int64_t identifier() const { return identifier_; } 74*6777b538SAndroid Build Coastguard Worker is_chunked()75*6777b538SAndroid Build Coastguard Worker bool is_chunked() const { return is_chunked_; } 76*6777b538SAndroid Build Coastguard Worker 77*6777b538SAndroid Build Coastguard Worker // Returns true if the stream has a null source which is defined at 78*6777b538SAndroid Build Coastguard Worker // https://fetch.spec.whatwg.org/#concept-body-source. has_null_source()79*6777b538SAndroid Build Coastguard Worker bool has_null_source() const { return has_null_source_; } 80*6777b538SAndroid Build Coastguard Worker 81*6777b538SAndroid Build Coastguard Worker // Returns true if all data has been consumed from this upload data 82*6777b538SAndroid Build Coastguard Worker // stream. For chunked uploads, returns false until the first read attempt. 83*6777b538SAndroid Build Coastguard Worker // This makes some state machines a little simpler. 84*6777b538SAndroid Build Coastguard Worker bool IsEOF() const; 85*6777b538SAndroid Build Coastguard Worker 86*6777b538SAndroid Build Coastguard Worker // Cancels all pending callbacks, and resets state. Any IOBuffer currently 87*6777b538SAndroid Build Coastguard Worker // being read to is not safe for future use, as it may be in use on another 88*6777b538SAndroid Build Coastguard Worker // thread. 89*6777b538SAndroid Build Coastguard Worker void Reset(); 90*6777b538SAndroid Build Coastguard Worker 91*6777b538SAndroid Build Coastguard Worker // Returns true if the upload data in the stream is entirely in memory, and 92*6777b538SAndroid Build Coastguard Worker // all read requests will succeed synchronously. Expected to return false for 93*6777b538SAndroid Build Coastguard Worker // chunked requests. 94*6777b538SAndroid Build Coastguard Worker virtual bool IsInMemory() const; 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker // Returns a list of element readers owned by |this|, if it has any. 97*6777b538SAndroid Build Coastguard Worker virtual const std::vector<std::unique_ptr<UploadElementReader>>* 98*6777b538SAndroid Build Coastguard Worker GetElementReaders() const; 99*6777b538SAndroid Build Coastguard Worker 100*6777b538SAndroid Build Coastguard Worker // Returns the upload progress. If the stream was not initialized 101*6777b538SAndroid Build Coastguard Worker // successfully, or has been reset and not yet re-initialized, returns an 102*6777b538SAndroid Build Coastguard Worker // empty UploadProgress. 103*6777b538SAndroid Build Coastguard Worker virtual UploadProgress GetUploadProgress() const; 104*6777b538SAndroid Build Coastguard Worker 105*6777b538SAndroid Build Coastguard Worker // Indicates whether fetch upload streaming is allowed/rejected over H/1. 106*6777b538SAndroid Build Coastguard Worker // Even if this is false but there is a QUIC/H2 stream, the upload is allowed. 107*6777b538SAndroid Build Coastguard Worker virtual bool AllowHTTP1() const; 108*6777b538SAndroid Build Coastguard Worker 109*6777b538SAndroid Build Coastguard Worker protected: 110*6777b538SAndroid Build Coastguard Worker // Must be called by subclasses when InitInternal and ReadInternal complete 111*6777b538SAndroid Build Coastguard Worker // asynchronously. 112*6777b538SAndroid Build Coastguard Worker void OnInitCompleted(int result); 113*6777b538SAndroid Build Coastguard Worker void OnReadCompleted(int result); 114*6777b538SAndroid Build Coastguard Worker 115*6777b538SAndroid Build Coastguard Worker // Must be called before InitInternal completes, for non-chunked uploads. 116*6777b538SAndroid Build Coastguard Worker // Must not be called for chunked uploads. 117*6777b538SAndroid Build Coastguard Worker void SetSize(uint64_t size); 118*6777b538SAndroid Build Coastguard Worker 119*6777b538SAndroid Build Coastguard Worker // Must be called for chunked uploads before the final ReadInternal call 120*6777b538SAndroid Build Coastguard Worker // completes. Must not be called for non-chunked uploads. 121*6777b538SAndroid Build Coastguard Worker void SetIsFinalChunk(); 122*6777b538SAndroid Build Coastguard Worker 123*6777b538SAndroid Build Coastguard Worker private: 124*6777b538SAndroid Build Coastguard Worker // See Init(). If it returns ERR_IO_PENDING, OnInitCompleted must be called 125*6777b538SAndroid Build Coastguard Worker // once it completes. If the upload is not chunked, SetSize must be called 126*6777b538SAndroid Build Coastguard Worker // before it completes. 127*6777b538SAndroid Build Coastguard Worker virtual int InitInternal(const NetLogWithSource& net_log) = 0; 128*6777b538SAndroid Build Coastguard Worker 129*6777b538SAndroid Build Coastguard Worker // See Read(). For chunked uploads, must call SetIsFinalChunk if this is the 130*6777b538SAndroid Build Coastguard Worker // final chunk. For non-chunked uploads, the UploadDataStream determins which 131*6777b538SAndroid Build Coastguard Worker // read is the last based on size. Must read 1 or more bytes on every call, 132*6777b538SAndroid Build Coastguard Worker // though the final chunk may be 0 bytes, for chunked requests. If it returns 133*6777b538SAndroid Build Coastguard Worker // ERR_IO_PENDING, OnInitCompleted must be called once it completes. Must not 134*6777b538SAndroid Build Coastguard Worker // return any error, other than ERR_IO_PENDING. 135*6777b538SAndroid Build Coastguard Worker virtual int ReadInternal(IOBuffer* buf, int buf_len) = 0; 136*6777b538SAndroid Build Coastguard Worker 137*6777b538SAndroid Build Coastguard Worker // Resets state and cancels any pending callbacks. Guaranteed to be called 138*6777b538SAndroid Build Coastguard Worker // at least once before every call to InitInternal. 139*6777b538SAndroid Build Coastguard Worker virtual void ResetInternal() = 0; 140*6777b538SAndroid Build Coastguard Worker 141*6777b538SAndroid Build Coastguard Worker uint64_t total_size_ = 0; 142*6777b538SAndroid Build Coastguard Worker uint64_t current_position_ = 0; 143*6777b538SAndroid Build Coastguard Worker 144*6777b538SAndroid Build Coastguard Worker const int64_t identifier_; 145*6777b538SAndroid Build Coastguard Worker 146*6777b538SAndroid Build Coastguard Worker const bool is_chunked_; 147*6777b538SAndroid Build Coastguard Worker const bool has_null_source_; 148*6777b538SAndroid Build Coastguard Worker 149*6777b538SAndroid Build Coastguard Worker // True if the initialization was successful. 150*6777b538SAndroid Build Coastguard Worker bool initialized_successfully_ = false; 151*6777b538SAndroid Build Coastguard Worker 152*6777b538SAndroid Build Coastguard Worker bool is_eof_ = false; 153*6777b538SAndroid Build Coastguard Worker 154*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback_; 155*6777b538SAndroid Build Coastguard Worker 156*6777b538SAndroid Build Coastguard Worker NetLogWithSource net_log_; 157*6777b538SAndroid Build Coastguard Worker }; 158*6777b538SAndroid Build Coastguard Worker 159*6777b538SAndroid Build Coastguard Worker } // namespace net 160*6777b538SAndroid Build Coastguard Worker 161*6777b538SAndroid Build Coastguard Worker #endif // NET_BASE_UPLOAD_DATA_STREAM_H_ 162