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