1 // Copyright 2018 The Chromium Authors. All rights reserved. 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 SERVICES_NETWORK_CHUNKED_DATA_PIPE_UPLOAD_DATA_STREAM_H_ 6 #define SERVICES_NETWORK_CHUNKED_DATA_PIPE_UPLOAD_DATA_STREAM_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 12 #include "base/component_export.h" 13 #include "base/macros.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/optional.h" 16 #include "mojo/public/cpp/bindings/pending_remote.h" 17 #include "mojo/public/cpp/bindings/remote.h" 18 #include "mojo/public/cpp/system/data_pipe.h" 19 #include "mojo/public/cpp/system/simple_watcher.h" 20 #include "net/base/completion_once_callback.h" 21 #include "net/base/net_errors.h" 22 #include "net/base/upload_data_stream.h" 23 #include "services/network/public/cpp/resource_request_body.h" 24 #include "services/network/public/mojom/chunked_data_pipe_getter.mojom.h" 25 26 namespace net { 27 class IOBuffer; 28 } 29 30 namespace network { 31 32 // A subclass of net::UploadDataStream to read data pipes and provide the result 33 // as a chunked upload. COMPONENT_EXPORT(NETWORK_SERVICE)34class COMPONENT_EXPORT(NETWORK_SERVICE) ChunkedDataPipeUploadDataStream 35 : public net::UploadDataStream { 36 public: 37 // |resource_request_body| is just passed in to keep the object around for the 38 // life of the UploadDataStream. 39 ChunkedDataPipeUploadDataStream( 40 scoped_refptr<ResourceRequestBody> resource_request_body, 41 mojo::PendingRemote<mojom::ChunkedDataPipeGetter> 42 chunked_data_pipe_getter); 43 44 ~ChunkedDataPipeUploadDataStream() override; 45 46 private: 47 // net::UploadDataStream implementation. 48 int InitInternal(const net::NetLogWithSource& net_log) override; 49 int ReadInternal(net::IOBuffer* buf, int buf_len) override; 50 void ResetInternal() override; 51 52 // Callback invoked by ChunkedDataPipeGetter::GetSize. Can be called any time 53 // - could be called before any of the body is read, could be called after the 54 // entire body is read, could end up not being called, in the case the other 55 // end of the pipe is torn down before the entire upload body is received. 56 void OnSizeReceived(int32_t status, uint64_t size); 57 58 // Called by |handle_watcher_| when data is available or the pipe was closed, 59 // and there's a pending Read() call. 60 void OnHandleReadable(MojoResult result); 61 62 void OnDataPipeGetterClosed(); 63 64 scoped_refptr<ResourceRequestBody> resource_request_body_; 65 mojo::Remote<mojom::ChunkedDataPipeGetter> chunked_data_pipe_getter_; 66 mojo::ScopedDataPipeConsumerHandle data_pipe_; 67 // Watcher for |data_pipe_|. Only armed while there's a pending read. 68 mojo::SimpleWatcher handle_watcher_; 69 70 // Write buffer and its length. Populated when Read() is called but returns 71 // ERR_IO_PENDING. Cleared once the read completes, or ResetInternal() is 72 // invoked. 73 scoped_refptr<net::IOBuffer> buf_; 74 int buf_len_ = 0; 75 76 // Total size of input, as passed to ReadCallback(). nullptr until size is 77 // received. 78 base::Optional<uint64_t> size_; 79 80 uint64_t bytes_read_ = 0; 81 82 // Set to a net::Error other than net::OK if the DataPipeGetter returns an 83 // error. 84 int status_ = net::OK; 85 86 DISALLOW_COPY_AND_ASSIGN(ChunkedDataPipeUploadDataStream); 87 }; 88 89 } // namespace network 90 91 #endif // SERVICES_NETWORK_CHUNKED_DATA_PIPE_UPLOAD_DATA_STREAM_H_ 92