1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/base/upload_data_stream.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
9*6777b538SAndroid Build Coastguard Worker #include "net/base/io_buffer.h"
10*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
11*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_event_type.h"
12*6777b538SAndroid Build Coastguard Worker
13*6777b538SAndroid Build Coastguard Worker namespace net {
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Worker namespace {
16*6777b538SAndroid Build Coastguard Worker
NetLogInitEndInfoParams(int result,int total_size,bool is_chunked)17*6777b538SAndroid Build Coastguard Worker base::Value::Dict NetLogInitEndInfoParams(int result,
18*6777b538SAndroid Build Coastguard Worker int total_size,
19*6777b538SAndroid Build Coastguard Worker bool is_chunked) {
20*6777b538SAndroid Build Coastguard Worker base::Value::Dict dict;
21*6777b538SAndroid Build Coastguard Worker
22*6777b538SAndroid Build Coastguard Worker dict.Set("net_error", result);
23*6777b538SAndroid Build Coastguard Worker dict.Set("total_size", total_size);
24*6777b538SAndroid Build Coastguard Worker dict.Set("is_chunked", is_chunked);
25*6777b538SAndroid Build Coastguard Worker return dict;
26*6777b538SAndroid Build Coastguard Worker }
27*6777b538SAndroid Build Coastguard Worker
CreateReadInfoParams(int current_position)28*6777b538SAndroid Build Coastguard Worker base::Value::Dict CreateReadInfoParams(int current_position) {
29*6777b538SAndroid Build Coastguard Worker base::Value::Dict dict;
30*6777b538SAndroid Build Coastguard Worker
31*6777b538SAndroid Build Coastguard Worker dict.Set("current_position", current_position);
32*6777b538SAndroid Build Coastguard Worker return dict;
33*6777b538SAndroid Build Coastguard Worker }
34*6777b538SAndroid Build Coastguard Worker
35*6777b538SAndroid Build Coastguard Worker } // namespace
36*6777b538SAndroid Build Coastguard Worker
UploadDataStream(bool is_chunked,int64_t identifier)37*6777b538SAndroid Build Coastguard Worker UploadDataStream::UploadDataStream(bool is_chunked, int64_t identifier)
38*6777b538SAndroid Build Coastguard Worker : UploadDataStream(is_chunked, /*has_null_source=*/false, identifier) {}
UploadDataStream(bool is_chunked,bool has_null_source,int64_t identifier)39*6777b538SAndroid Build Coastguard Worker UploadDataStream::UploadDataStream(bool is_chunked,
40*6777b538SAndroid Build Coastguard Worker bool has_null_source,
41*6777b538SAndroid Build Coastguard Worker int64_t identifier)
42*6777b538SAndroid Build Coastguard Worker : identifier_(identifier),
43*6777b538SAndroid Build Coastguard Worker is_chunked_(is_chunked),
44*6777b538SAndroid Build Coastguard Worker has_null_source_(has_null_source) {}
45*6777b538SAndroid Build Coastguard Worker
46*6777b538SAndroid Build Coastguard Worker UploadDataStream::~UploadDataStream() = default;
47*6777b538SAndroid Build Coastguard Worker
Init(CompletionOnceCallback callback,const NetLogWithSource & net_log)48*6777b538SAndroid Build Coastguard Worker int UploadDataStream::Init(CompletionOnceCallback callback,
49*6777b538SAndroid Build Coastguard Worker const NetLogWithSource& net_log) {
50*6777b538SAndroid Build Coastguard Worker Reset();
51*6777b538SAndroid Build Coastguard Worker DCHECK(!initialized_successfully_);
52*6777b538SAndroid Build Coastguard Worker DCHECK(callback_.is_null());
53*6777b538SAndroid Build Coastguard Worker DCHECK(!callback.is_null() || IsInMemory());
54*6777b538SAndroid Build Coastguard Worker net_log_ = net_log;
55*6777b538SAndroid Build Coastguard Worker net_log_.BeginEvent(NetLogEventType::UPLOAD_DATA_STREAM_INIT);
56*6777b538SAndroid Build Coastguard Worker
57*6777b538SAndroid Build Coastguard Worker int result = InitInternal(net_log_);
58*6777b538SAndroid Build Coastguard Worker if (result == ERR_IO_PENDING) {
59*6777b538SAndroid Build Coastguard Worker DCHECK(!IsInMemory());
60*6777b538SAndroid Build Coastguard Worker callback_ = std::move(callback);
61*6777b538SAndroid Build Coastguard Worker } else {
62*6777b538SAndroid Build Coastguard Worker OnInitCompleted(result);
63*6777b538SAndroid Build Coastguard Worker }
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker return result;
66*6777b538SAndroid Build Coastguard Worker }
67*6777b538SAndroid Build Coastguard Worker
Read(IOBuffer * buf,int buf_len,CompletionOnceCallback callback)68*6777b538SAndroid Build Coastguard Worker int UploadDataStream::Read(IOBuffer* buf,
69*6777b538SAndroid Build Coastguard Worker int buf_len,
70*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback) {
71*6777b538SAndroid Build Coastguard Worker DCHECK(!callback.is_null() || IsInMemory());
72*6777b538SAndroid Build Coastguard Worker DCHECK(initialized_successfully_);
73*6777b538SAndroid Build Coastguard Worker DCHECK_GT(buf_len, 0);
74*6777b538SAndroid Build Coastguard Worker
75*6777b538SAndroid Build Coastguard Worker net_log_.BeginEvent(NetLogEventType::UPLOAD_DATA_STREAM_READ,
76*6777b538SAndroid Build Coastguard Worker [&] { return CreateReadInfoParams(current_position_); });
77*6777b538SAndroid Build Coastguard Worker
78*6777b538SAndroid Build Coastguard Worker int result = 0;
79*6777b538SAndroid Build Coastguard Worker if (!is_eof_)
80*6777b538SAndroid Build Coastguard Worker result = ReadInternal(buf, buf_len);
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker if (result == ERR_IO_PENDING) {
83*6777b538SAndroid Build Coastguard Worker DCHECK(!IsInMemory());
84*6777b538SAndroid Build Coastguard Worker callback_ = std::move(callback);
85*6777b538SAndroid Build Coastguard Worker } else {
86*6777b538SAndroid Build Coastguard Worker OnReadCompleted(result);
87*6777b538SAndroid Build Coastguard Worker }
88*6777b538SAndroid Build Coastguard Worker
89*6777b538SAndroid Build Coastguard Worker return result;
90*6777b538SAndroid Build Coastguard Worker }
91*6777b538SAndroid Build Coastguard Worker
IsEOF() const92*6777b538SAndroid Build Coastguard Worker bool UploadDataStream::IsEOF() const {
93*6777b538SAndroid Build Coastguard Worker DCHECK(initialized_successfully_);
94*6777b538SAndroid Build Coastguard Worker DCHECK(is_chunked_ || is_eof_ == (current_position_ == total_size_));
95*6777b538SAndroid Build Coastguard Worker return is_eof_;
96*6777b538SAndroid Build Coastguard Worker }
97*6777b538SAndroid Build Coastguard Worker
Reset()98*6777b538SAndroid Build Coastguard Worker void UploadDataStream::Reset() {
99*6777b538SAndroid Build Coastguard Worker // If there's a pending callback, there's a pending init or read call that is
100*6777b538SAndroid Build Coastguard Worker // being canceled.
101*6777b538SAndroid Build Coastguard Worker if (!callback_.is_null()) {
102*6777b538SAndroid Build Coastguard Worker if (!initialized_successfully_) {
103*6777b538SAndroid Build Coastguard Worker // If initialization has not yet succeeded, this call is aborting
104*6777b538SAndroid Build Coastguard Worker // initialization.
105*6777b538SAndroid Build Coastguard Worker net_log_.EndEventWithNetErrorCode(
106*6777b538SAndroid Build Coastguard Worker NetLogEventType::UPLOAD_DATA_STREAM_INIT, ERR_ABORTED);
107*6777b538SAndroid Build Coastguard Worker } else {
108*6777b538SAndroid Build Coastguard Worker // Otherwise, a read is being aborted.
109*6777b538SAndroid Build Coastguard Worker net_log_.EndEventWithNetErrorCode(
110*6777b538SAndroid Build Coastguard Worker NetLogEventType::UPLOAD_DATA_STREAM_READ, ERR_ABORTED);
111*6777b538SAndroid Build Coastguard Worker }
112*6777b538SAndroid Build Coastguard Worker }
113*6777b538SAndroid Build Coastguard Worker
114*6777b538SAndroid Build Coastguard Worker current_position_ = 0;
115*6777b538SAndroid Build Coastguard Worker initialized_successfully_ = false;
116*6777b538SAndroid Build Coastguard Worker is_eof_ = false;
117*6777b538SAndroid Build Coastguard Worker total_size_ = 0;
118*6777b538SAndroid Build Coastguard Worker callback_.Reset();
119*6777b538SAndroid Build Coastguard Worker ResetInternal();
120*6777b538SAndroid Build Coastguard Worker }
121*6777b538SAndroid Build Coastguard Worker
SetSize(uint64_t size)122*6777b538SAndroid Build Coastguard Worker void UploadDataStream::SetSize(uint64_t size) {
123*6777b538SAndroid Build Coastguard Worker DCHECK(!initialized_successfully_);
124*6777b538SAndroid Build Coastguard Worker DCHECK(!is_chunked_);
125*6777b538SAndroid Build Coastguard Worker total_size_ = size;
126*6777b538SAndroid Build Coastguard Worker }
127*6777b538SAndroid Build Coastguard Worker
SetIsFinalChunk()128*6777b538SAndroid Build Coastguard Worker void UploadDataStream::SetIsFinalChunk() {
129*6777b538SAndroid Build Coastguard Worker DCHECK(initialized_successfully_);
130*6777b538SAndroid Build Coastguard Worker DCHECK(is_chunked_);
131*6777b538SAndroid Build Coastguard Worker DCHECK(!is_eof_);
132*6777b538SAndroid Build Coastguard Worker is_eof_ = true;
133*6777b538SAndroid Build Coastguard Worker }
134*6777b538SAndroid Build Coastguard Worker
IsInMemory() const135*6777b538SAndroid Build Coastguard Worker bool UploadDataStream::IsInMemory() const {
136*6777b538SAndroid Build Coastguard Worker return false;
137*6777b538SAndroid Build Coastguard Worker }
138*6777b538SAndroid Build Coastguard Worker
139*6777b538SAndroid Build Coastguard Worker const std::vector<std::unique_ptr<UploadElementReader>>*
GetElementReaders() const140*6777b538SAndroid Build Coastguard Worker UploadDataStream::GetElementReaders() const {
141*6777b538SAndroid Build Coastguard Worker return nullptr;
142*6777b538SAndroid Build Coastguard Worker }
143*6777b538SAndroid Build Coastguard Worker
OnInitCompleted(int result)144*6777b538SAndroid Build Coastguard Worker void UploadDataStream::OnInitCompleted(int result) {
145*6777b538SAndroid Build Coastguard Worker DCHECK_NE(ERR_IO_PENDING, result);
146*6777b538SAndroid Build Coastguard Worker DCHECK(!initialized_successfully_);
147*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(0u, current_position_);
148*6777b538SAndroid Build Coastguard Worker DCHECK(!is_eof_);
149*6777b538SAndroid Build Coastguard Worker
150*6777b538SAndroid Build Coastguard Worker if (result == OK) {
151*6777b538SAndroid Build Coastguard Worker initialized_successfully_ = true;
152*6777b538SAndroid Build Coastguard Worker if (!is_chunked_ && total_size_ == 0)
153*6777b538SAndroid Build Coastguard Worker is_eof_ = true;
154*6777b538SAndroid Build Coastguard Worker }
155*6777b538SAndroid Build Coastguard Worker
156*6777b538SAndroid Build Coastguard Worker net_log_.EndEvent(NetLogEventType::UPLOAD_DATA_STREAM_INIT, [&] {
157*6777b538SAndroid Build Coastguard Worker return NetLogInitEndInfoParams(result, total_size_, is_chunked_);
158*6777b538SAndroid Build Coastguard Worker });
159*6777b538SAndroid Build Coastguard Worker
160*6777b538SAndroid Build Coastguard Worker if (!callback_.is_null())
161*6777b538SAndroid Build Coastguard Worker std::move(callback_).Run(result);
162*6777b538SAndroid Build Coastguard Worker }
163*6777b538SAndroid Build Coastguard Worker
OnReadCompleted(int result)164*6777b538SAndroid Build Coastguard Worker void UploadDataStream::OnReadCompleted(int result) {
165*6777b538SAndroid Build Coastguard Worker DCHECK(initialized_successfully_);
166*6777b538SAndroid Build Coastguard Worker DCHECK(result != 0 || is_eof_);
167*6777b538SAndroid Build Coastguard Worker DCHECK_NE(ERR_IO_PENDING, result);
168*6777b538SAndroid Build Coastguard Worker
169*6777b538SAndroid Build Coastguard Worker if (result > 0) {
170*6777b538SAndroid Build Coastguard Worker current_position_ += result;
171*6777b538SAndroid Build Coastguard Worker if (!is_chunked_) {
172*6777b538SAndroid Build Coastguard Worker DCHECK_LE(current_position_, total_size_);
173*6777b538SAndroid Build Coastguard Worker if (current_position_ == total_size_)
174*6777b538SAndroid Build Coastguard Worker is_eof_ = true;
175*6777b538SAndroid Build Coastguard Worker }
176*6777b538SAndroid Build Coastguard Worker }
177*6777b538SAndroid Build Coastguard Worker
178*6777b538SAndroid Build Coastguard Worker net_log_.EndEventWithNetErrorCode(NetLogEventType::UPLOAD_DATA_STREAM_READ,
179*6777b538SAndroid Build Coastguard Worker result);
180*6777b538SAndroid Build Coastguard Worker
181*6777b538SAndroid Build Coastguard Worker if (!callback_.is_null())
182*6777b538SAndroid Build Coastguard Worker std::move(callback_).Run(result);
183*6777b538SAndroid Build Coastguard Worker }
184*6777b538SAndroid Build Coastguard Worker
GetUploadProgress() const185*6777b538SAndroid Build Coastguard Worker UploadProgress UploadDataStream::GetUploadProgress() const {
186*6777b538SAndroid Build Coastguard Worker // While initialization / rewinding is in progress, return nothing.
187*6777b538SAndroid Build Coastguard Worker if (!initialized_successfully_)
188*6777b538SAndroid Build Coastguard Worker return UploadProgress();
189*6777b538SAndroid Build Coastguard Worker
190*6777b538SAndroid Build Coastguard Worker return UploadProgress(current_position_, total_size_);
191*6777b538SAndroid Build Coastguard Worker }
192*6777b538SAndroid Build Coastguard Worker
AllowHTTP1() const193*6777b538SAndroid Build Coastguard Worker bool UploadDataStream::AllowHTTP1() const {
194*6777b538SAndroid Build Coastguard Worker return true;
195*6777b538SAndroid Build Coastguard Worker }
196*6777b538SAndroid Build Coastguard Worker
197*6777b538SAndroid Build Coastguard Worker } // namespace net
198