upload_data_stream.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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. #include "net/base/upload_data_stream.h"
  5. #include "base/check_op.h"
  6. #include "base/values.h"
  7. #include "net/base/io_buffer.h"
  8. #include "net/base/net_errors.h"
  9. #include "net/log/net_log_event_type.h"
  10. namespace net {
  11. namespace {
  12. base::Value NetLogInitEndInfoParams(int result,
  13. int total_size,
  14. bool is_chunked) {
  15. base::Value::Dict dict;
  16. dict.Set("net_error", result);
  17. dict.Set("total_size", total_size);
  18. dict.Set("is_chunked", is_chunked);
  19. return base::Value(std::move(dict));
  20. }
  21. base::Value CreateReadInfoParams(int current_position) {
  22. base::Value::Dict dict;
  23. dict.Set("current_position", current_position);
  24. return base::Value(std::move(dict));
  25. }
  26. } // namespace
  27. UploadDataStream::UploadDataStream(bool is_chunked, int64_t identifier)
  28. : UploadDataStream(is_chunked, /*has_null_source=*/false, identifier) {}
  29. UploadDataStream::UploadDataStream(bool is_chunked,
  30. bool has_null_source,
  31. int64_t identifier)
  32. : identifier_(identifier),
  33. is_chunked_(is_chunked),
  34. has_null_source_(has_null_source) {}
  35. UploadDataStream::~UploadDataStream() = default;
  36. int UploadDataStream::Init(CompletionOnceCallback callback,
  37. const NetLogWithSource& net_log) {
  38. Reset();
  39. DCHECK(!initialized_successfully_);
  40. DCHECK(callback_.is_null());
  41. DCHECK(!callback.is_null() || IsInMemory());
  42. net_log_ = net_log;
  43. net_log_.BeginEvent(NetLogEventType::UPLOAD_DATA_STREAM_INIT);
  44. int result = InitInternal(net_log_);
  45. if (result == ERR_IO_PENDING) {
  46. DCHECK(!IsInMemory());
  47. callback_ = std::move(callback);
  48. } else {
  49. OnInitCompleted(result);
  50. }
  51. return result;
  52. }
  53. int UploadDataStream::Read(IOBuffer* buf,
  54. int buf_len,
  55. CompletionOnceCallback callback) {
  56. DCHECK(!callback.is_null() || IsInMemory());
  57. DCHECK(initialized_successfully_);
  58. DCHECK_GT(buf_len, 0);
  59. net_log_.BeginEvent(NetLogEventType::UPLOAD_DATA_STREAM_READ,
  60. [&] { return CreateReadInfoParams(current_position_); });
  61. int result = 0;
  62. if (!is_eof_)
  63. result = ReadInternal(buf, buf_len);
  64. if (result == ERR_IO_PENDING) {
  65. DCHECK(!IsInMemory());
  66. callback_ = std::move(callback);
  67. } else {
  68. OnReadCompleted(result);
  69. }
  70. return result;
  71. }
  72. bool UploadDataStream::IsEOF() const {
  73. DCHECK(initialized_successfully_);
  74. DCHECK(is_chunked_ || is_eof_ == (current_position_ == total_size_));
  75. return is_eof_;
  76. }
  77. void UploadDataStream::Reset() {
  78. // If there's a pending callback, there's a pending init or read call that is
  79. // being canceled.
  80. if (!callback_.is_null()) {
  81. if (!initialized_successfully_) {
  82. // If initialization has not yet succeeded, this call is aborting
  83. // initialization.
  84. net_log_.EndEventWithNetErrorCode(
  85. NetLogEventType::UPLOAD_DATA_STREAM_INIT, ERR_ABORTED);
  86. } else {
  87. // Otherwise, a read is being aborted.
  88. net_log_.EndEventWithNetErrorCode(
  89. NetLogEventType::UPLOAD_DATA_STREAM_READ, ERR_ABORTED);
  90. }
  91. }
  92. current_position_ = 0;
  93. initialized_successfully_ = false;
  94. is_eof_ = false;
  95. total_size_ = 0;
  96. callback_.Reset();
  97. ResetInternal();
  98. }
  99. void UploadDataStream::SetSize(uint64_t size) {
  100. DCHECK(!initialized_successfully_);
  101. DCHECK(!is_chunked_);
  102. total_size_ = size;
  103. }
  104. void UploadDataStream::SetIsFinalChunk() {
  105. DCHECK(initialized_successfully_);
  106. DCHECK(is_chunked_);
  107. DCHECK(!is_eof_);
  108. is_eof_ = true;
  109. }
  110. bool UploadDataStream::IsInMemory() const {
  111. return false;
  112. }
  113. const std::vector<std::unique_ptr<UploadElementReader>>*
  114. UploadDataStream::GetElementReaders() const {
  115. return nullptr;
  116. }
  117. void UploadDataStream::OnInitCompleted(int result) {
  118. DCHECK_NE(ERR_IO_PENDING, result);
  119. DCHECK(!initialized_successfully_);
  120. DCHECK_EQ(0u, current_position_);
  121. DCHECK(!is_eof_);
  122. if (result == OK) {
  123. initialized_successfully_ = true;
  124. if (!is_chunked_ && total_size_ == 0)
  125. is_eof_ = true;
  126. }
  127. net_log_.EndEvent(NetLogEventType::UPLOAD_DATA_STREAM_INIT, [&] {
  128. return NetLogInitEndInfoParams(result, total_size_, is_chunked_);
  129. });
  130. if (!callback_.is_null())
  131. std::move(callback_).Run(result);
  132. }
  133. void UploadDataStream::OnReadCompleted(int result) {
  134. DCHECK(initialized_successfully_);
  135. DCHECK(result != 0 || is_eof_);
  136. DCHECK_NE(ERR_IO_PENDING, result);
  137. if (result > 0) {
  138. current_position_ += result;
  139. if (!is_chunked_) {
  140. DCHECK_LE(current_position_, total_size_);
  141. if (current_position_ == total_size_)
  142. is_eof_ = true;
  143. }
  144. }
  145. net_log_.EndEventWithNetErrorCode(NetLogEventType::UPLOAD_DATA_STREAM_READ,
  146. result);
  147. if (!callback_.is_null())
  148. std::move(callback_).Run(result);
  149. }
  150. UploadProgress UploadDataStream::GetUploadProgress() const {
  151. // While initialization / rewinding is in progress, return nothing.
  152. if (!initialized_successfully_)
  153. return UploadProgress();
  154. return UploadProgress(current_position_, total_size_);
  155. }
  156. bool UploadDataStream::AllowHTTP1() const {
  157. return true;
  158. }
  159. } // namespace net