blob: 8b4c183659adf6244483c14b09e7a8b85ce9ca56 [file] [log] [blame]
Avi Drissman64595482022-09-14 20:52:291// Copyright 2012 The Chromium Authors
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
5#include "net/base/upload_data_stream.h"
6
Hans Wennborg0924470b2020-04-27 21:08:057#include "base/check_op.h"
maksim.sisov819ba852016-08-17 08:22:528#include "base/values.h"
[email protected]597cf6e2009-05-29 09:43:269#include "net/base/io_buffer.h"
[email protected]9396b252008-09-29 17:29:3810#include "net/base/net_errors.h"
mikecirone8b85c432016-09-08 19:11:0011#include "net/log/net_log_event_type.h"
[email protected]1eb89e82008-08-15 12:27:0312
initial.commit586acc5fe2008-07-26 22:42:5213namespace net {
14
maksim.sisov819ba852016-08-17 08:22:5215namespace {
16
Liam Brady0c651722023-02-24 23:48:2017base::Value::Dict NetLogInitEndInfoParams(int result,
18 int total_size,
19 bool is_chunked) {
Matt Menkef523f552022-06-02 17:07:5820 base::Value::Dict dict;
maksim.sisov819ba852016-08-17 08:22:5221
Matt Menkef523f552022-06-02 17:07:5822 dict.Set("net_error", result);
23 dict.Set("total_size", total_size);
24 dict.Set("is_chunked", is_chunked);
Liam Brady0c651722023-02-24 23:48:2025 return dict;
maksim.sisov819ba852016-08-17 08:22:5226}
27
Liam Brady0c651722023-02-24 23:48:2028base::Value::Dict CreateReadInfoParams(int current_position) {
Matt Menkef523f552022-06-02 17:07:5829 base::Value::Dict dict;
maksim.sisov819ba852016-08-17 08:22:5230
Matt Menkef523f552022-06-02 17:07:5831 dict.Set("current_position", current_position);
Liam Brady0c651722023-02-24 23:48:2032 return dict;
maksim.sisov819ba852016-08-17 08:22:5233}
34
35} // namespace
36
wtc69f8ea82015-06-04 00:08:1337UploadDataStream::UploadDataStream(bool is_chunked, int64_t identifier)
Yutaka Hiranoc267fb242022-07-05 01:27:1738 : UploadDataStream(is_chunked, /*has_null_source=*/false, identifier) {}
39UploadDataStream::UploadDataStream(bool is_chunked,
40 bool has_null_source,
41 int64_t identifier)
42 : identifier_(identifier),
43 is_chunked_(is_chunked),
44 has_null_source_(has_null_source) {}
[email protected]0ab2e242012-02-08 06:07:0045
Chris Watkins68b15032017-12-01 03:07:1346UploadDataStream::~UploadDataStream() = default;
[email protected]d100e44f2011-01-26 22:47:1147
Matt Menkecc1d3a902018-02-05 18:27:3348int UploadDataStream::Init(CompletionOnceCallback callback,
tfarina428341112016-09-22 13:38:2049 const NetLogWithSource& net_log) {
[email protected]e5d477342012-11-02 15:18:4650 Reset();
mmenkecbc2b712014-10-09 20:29:0751 DCHECK(!initialized_successfully_);
52 DCHECK(callback_.is_null());
53 DCHECK(!callback.is_null() || IsInMemory());
maksim.sisov819ba852016-08-17 08:22:5254 net_log_ = net_log;
mikecirone8b85c432016-09-08 19:11:0055 net_log_.BeginEvent(NetLogEventType::UPLOAD_DATA_STREAM_INIT);
maksim.sisov819ba852016-08-17 08:22:5256
57 int result = InitInternal(net_log_);
mmenkecbc2b712014-10-09 20:29:0758 if (result == ERR_IO_PENDING) {
59 DCHECK(!IsInMemory());
Matt Menkecc1d3a902018-02-05 18:27:3360 callback_ = std::move(callback);
mmenkecbc2b712014-10-09 20:29:0761 } else {
62 OnInitCompleted(result);
63 }
maksim.sisov819ba852016-08-17 08:22:5264
mmenkecbc2b712014-10-09 20:29:0765 return result;
[email protected]df7adc62012-09-18 14:01:5366}
67
[email protected]5b76814b2012-10-17 10:15:1768int UploadDataStream::Read(IOBuffer* buf,
69 int buf_len,
Matt Menkecc1d3a902018-02-05 18:27:3370 CompletionOnceCallback callback) {
mmenkecbc2b712014-10-09 20:29:0771 DCHECK(!callback.is_null() || IsInMemory());
[email protected]d98961652012-09-11 20:27:2172 DCHECK(initialized_successfully_);
Yoichi Osato079c77d62025-06-13 02:27:5173 CHECK(buf);
[email protected]5b76814b2012-10-17 10:15:1774 DCHECK_GT(buf_len, 0);
maksim.sisov819ba852016-08-17 08:22:5275
mikecirone8b85c432016-09-08 19:11:0076 net_log_.BeginEvent(NetLogEventType::UPLOAD_DATA_STREAM_READ,
Eric Roman06bd9742019-07-13 15:19:1377 [&] { return CreateReadInfoParams(current_position_); });
maksim.sisov819ba852016-08-17 08:22:5278
79 int result = 0;
80 if (!is_eof_)
81 result = ReadInternal(buf, buf_len);
82
mmenkecbc2b712014-10-09 20:29:0783 if (result == ERR_IO_PENDING) {
84 DCHECK(!IsInMemory());
Matt Menkecc1d3a902018-02-05 18:27:3385 callback_ = std::move(callback);
mmenkecbc2b712014-10-09 20:29:0786 } else {
Yoichi Osato490169c2024-06-24 08:46:0987 if (result < ERR_IO_PENDING) {
88 LOG(ERROR) << "ReadInternal failed with Error: " << result;
89 }
mmenkecbc2b712014-10-09 20:29:0790 OnReadCompleted(result);
91 }
maksim.sisov819ba852016-08-17 08:22:5292
mmenkecbc2b712014-10-09 20:29:0793 return result;
[email protected]5b76814b2012-10-17 10:15:1794}
95
[email protected]135e4292012-01-24 17:45:1896bool UploadDataStream::IsEOF() const {
[email protected]d98961652012-09-11 20:27:2197 DCHECK(initialized_successfully_);
mmenkecbc2b712014-10-09 20:29:0798 DCHECK(is_chunked_ || is_eof_ == (current_position_ == total_size_));
99 return is_eof_;
[email protected]b2d26cfd2012-12-11 10:36:06100}
101
[email protected]e5d477342012-11-02 15:18:46102void UploadDataStream::Reset() {
maksim.sisov819ba852016-08-17 08:22:52103 // If there's a pending callback, there's a pending init or read call that is
104 // being canceled.
105 if (!callback_.is_null()) {
106 if (!initialized_successfully_) {
107 // If initialization has not yet succeeded, this call is aborting
108 // initialization.
mikecirone8b85c432016-09-08 19:11:00109 net_log_.EndEventWithNetErrorCode(
110 NetLogEventType::UPLOAD_DATA_STREAM_INIT, ERR_ABORTED);
maksim.sisov819ba852016-08-17 08:22:52111 } else {
112 // Otherwise, a read is being aborted.
mikecirone8b85c432016-09-08 19:11:00113 net_log_.EndEventWithNetErrorCode(
114 NetLogEventType::UPLOAD_DATA_STREAM_READ, ERR_ABORTED);
maksim.sisov819ba852016-08-17 08:22:52115 }
116 }
117
[email protected]e5d477342012-11-02 15:18:46118 current_position_ = 0;
mmenkecbc2b712014-10-09 20:29:07119 initialized_successfully_ = false;
120 is_eof_ = false;
[email protected]e5d477342012-11-02 15:18:46121 total_size_ = 0;
mmenkecbc2b712014-10-09 20:29:07122 callback_.Reset();
123 ResetInternal();
[email protected]e5d477342012-11-02 15:18:46124}
[email protected]df7adc62012-09-18 14:01:53125
wtc69f8ea82015-06-04 00:08:13126void UploadDataStream::SetSize(uint64_t size) {
[email protected]e5d477342012-11-02 15:18:46127 DCHECK(!initialized_successfully_);
mmenkecbc2b712014-10-09 20:29:07128 DCHECK(!is_chunked_);
129 total_size_ = size;
[email protected]e5d477342012-11-02 15:18:46130}
131
mmenkecbc2b712014-10-09 20:29:07132void UploadDataStream::SetIsFinalChunk() {
133 DCHECK(initialized_successfully_);
134 DCHECK(is_chunked_);
135 DCHECK(!is_eof_);
136 is_eof_ = true;
137}
138
139bool UploadDataStream::IsInMemory() const {
140 return false;
141}
142
danakj7f767e62016-04-16 23:20:23143const std::vector<std::unique_ptr<UploadElementReader>>*
mmenkecbc2b712014-10-09 20:29:07144UploadDataStream::GetElementReaders() const {
Raul Tambre94493c652019-03-11 17:18:35145 return nullptr;
mmenkecbc2b712014-10-09 20:29:07146}
147
148void UploadDataStream::OnInitCompleted(int result) {
149 DCHECK_NE(ERR_IO_PENDING, result);
[email protected]e5d477342012-11-02 15:18:46150 DCHECK(!initialized_successfully_);
mmenkecbc2b712014-10-09 20:29:07151 DCHECK_EQ(0u, current_position_);
152 DCHECK(!is_eof_);
[email protected]e5d477342012-11-02 15:18:46153
mmenkecbc2b712014-10-09 20:29:07154 if (result == OK) {
155 initialized_successfully_ = true;
156 if (!is_chunked_ && total_size_ == 0)
157 is_eof_ = true;
[email protected]e5d477342012-11-02 15:18:46158 }
maksim.sisov819ba852016-08-17 08:22:52159
Eric Roman06bd9742019-07-13 15:19:13160 net_log_.EndEvent(NetLogEventType::UPLOAD_DATA_STREAM_INIT, [&] {
161 return NetLogInitEndInfoParams(result, total_size_, is_chunked_);
162 });
maksim.sisov819ba852016-08-17 08:22:52163
mmenkecbc2b712014-10-09 20:29:07164 if (!callback_.is_null())
Matt Menkecc1d3a902018-02-05 18:27:33165 std::move(callback_).Run(result);
[email protected]df7adc62012-09-18 14:01:53166}
167
mmenkecbc2b712014-10-09 20:29:07168void UploadDataStream::OnReadCompleted(int result) {
[email protected]5b76814b2012-10-17 10:15:17169 DCHECK(initialized_successfully_);
maksim.sisov52fcdc52016-06-23 06:28:52170 DCHECK(result != 0 || is_eof_);
171 DCHECK_NE(ERR_IO_PENDING, result);
[email protected]5b76814b2012-10-17 10:15:17172
maksim.sisov52fcdc52016-06-23 06:28:52173 if (result > 0) {
174 current_position_ += result;
175 if (!is_chunked_) {
176 DCHECK_LE(current_position_, total_size_);
177 if (current_position_ == total_size_)
178 is_eof_ = true;
179 }
[email protected]fac16e22012-12-29 18:46:31180 }
181
mikecirone8b85c432016-09-08 19:11:00182 net_log_.EndEventWithNetErrorCode(NetLogEventType::UPLOAD_DATA_STREAM_READ,
maksim.sisov819ba852016-08-17 08:22:52183 result);
184
mmenkecbc2b712014-10-09 20:29:07185 if (!callback_.is_null())
Matt Menkecc1d3a902018-02-05 18:27:33186 std::move(callback_).Run(result);
[email protected]fac16e22012-12-29 18:46:31187}
188
shivanishab9a143952016-09-19 17:23:41189UploadProgress UploadDataStream::GetUploadProgress() const {
190 // While initialization / rewinding is in progress, return nothing.
191 if (!initialized_successfully_)
192 return UploadProgress();
193
194 return UploadProgress(current_position_, total_size_);
195}
196
Yoichi Osato4c75c0c2020-06-24 08:03:57197bool UploadDataStream::AllowHTTP1() const {
198 return true;
199}
200
initial.commit586acc5fe2008-07-26 22:42:52201} // namespace net