upload_data_stream.h 6.3 KB

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