1 // Copyright 2014 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_CHUNKED_UPLOAD_DATA_STREAM_H_ 6 #define NET_BASE_CHUNKED_UPLOAD_DATA_STREAM_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 #include <vector> 13 14 #include "base/memory/scoped_refptr.h" 15 #include "base/memory/weak_ptr.h" 16 #include "net/base/net_export.h" 17 #include "net/base/upload_data_stream.h" 18 19 namespace net { 20 21 class IOBuffer; 22 23 // Class with a push-based interface for uploading data. Buffers all data until 24 // the request is completed. Not recommended for uploading large amounts of 25 // seekable data, due to this buffering behavior. 26 class NET_EXPORT ChunkedUploadDataStream : public UploadDataStream { 27 public: 28 // Utility class that allows writing data to a particular 29 // ChunkedUploadDataStream. It can outlive the associated 30 // ChunkedUploadDataStream, and the URLRequest it is associated with, and 31 // still be safely used. This allows the consumer to not have to worry about 32 // the lifetime of the ChunkedUploadDataStream, which the owning URLRequest 33 // may delete without warning. 34 // 35 // The writer may only be used on the ChunkedUploadDataStream's thread. 36 class NET_EXPORT Writer { 37 public: 38 Writer(const Writer&) = delete; 39 Writer& operator=(const Writer&) = delete; 40 ~Writer(); 41 42 // Adds data to the stream. |is_done| should be true if this is the last 43 // data to be appended. |data_len| must not be 0 unless |is_done| is true. 44 // Once called with |is_done| being true, must never be called again. 45 // Returns true if write was passed successfully on to the next layer, 46 // though the data may not actually have been written to the underlying 47 // URLRequest. Returns false if unable to write the data failed because the 48 // underlying ChunkedUploadDataStream was destroyed. 49 bool AppendData(const char* data, int data_len, bool is_done); 50 51 private: 52 friend class ChunkedUploadDataStream; 53 54 explicit Writer(base::WeakPtr<ChunkedUploadDataStream> upload_data_stream); 55 56 const base::WeakPtr<ChunkedUploadDataStream> upload_data_stream_; 57 }; 58 59 explicit ChunkedUploadDataStream(int64_t identifier, 60 bool has_null_source = false); 61 62 ChunkedUploadDataStream(const ChunkedUploadDataStream&) = delete; 63 ChunkedUploadDataStream& operator=(const ChunkedUploadDataStream&) = delete; 64 ~ChunkedUploadDataStream() override; 65 66 // Creates a Writer for appending data to |this|. It's generally expected 67 // that only one writer is created per stream, though multiple writers are 68 // allowed. All writers write to the same stream, and once one of them 69 // appends data with |is_done| being true, no other writers may be used to 70 // append data. 71 std::unique_ptr<Writer> CreateWriter(); 72 73 // Adds data to the stream. |is_done| should be true if this is the last 74 // data to be appended. |data_len| must not be 0 unless |is_done| is true. 75 // Once called with |is_done| being true, must never be called again. 76 // TODO(mmenke): Consider using IOBuffers instead, to reduce data copies. 77 // TODO(mmenke): Consider making private, and having all consumers use 78 // Writers. 79 void AppendData(const char* data, int data_len, bool is_done); 80 81 private: 82 // UploadDataStream implementation. 83 int InitInternal(const NetLogWithSource& net_log) override; 84 int ReadInternal(IOBuffer* buf, int buf_len) override; 85 void ResetInternal() override; 86 87 int ReadChunk(IOBuffer* buf, int buf_len); 88 89 // Index and offset of next element of |upload_data_| to be read. 90 size_t read_index_ = 0; 91 size_t read_offset_ = 0; 92 93 // True once all data has been appended to the stream. 94 bool all_data_appended_ = false; 95 96 std::vector<std::unique_ptr<std::vector<char>>> upload_data_; 97 98 // Buffer to write the next read's data to. Only set when a call to 99 // ReadInternal reads no data. 100 scoped_refptr<IOBuffer> read_buffer_; 101 int read_buffer_len_ = 0; 102 103 base::WeakPtrFactory<ChunkedUploadDataStream> weak_factory_{this}; 104 }; 105 106 } // namespace net 107 108 #endif // NET_BASE_CHUNKED_UPLOAD_DATA_STREAM_H_ 109