xref: /aosp_15_r20/external/cronet/net/base/upload_data_stream.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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