summaryrefslogtreecommitdiff
path: root/protocols/Telegram/tdlib/td/tdnet/td/net/HttpChunkedByteFlow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Telegram/tdlib/td/tdnet/td/net/HttpChunkedByteFlow.cpp')
-rw-r--r--protocols/Telegram/tdlib/td/tdnet/td/net/HttpChunkedByteFlow.cpp63
1 files changed, 32 insertions, 31 deletions
diff --git a/protocols/Telegram/tdlib/td/tdnet/td/net/HttpChunkedByteFlow.cpp b/protocols/Telegram/tdlib/td/tdnet/td/net/HttpChunkedByteFlow.cpp
index 2edd225bfa..259e1fafbd 100644
--- a/protocols/Telegram/tdlib/td/tdnet/td/net/HttpChunkedByteFlow.cpp
+++ b/protocols/Telegram/tdlib/td/tdnet/td/net/HttpChunkedByteFlow.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -8,76 +8,77 @@
#include "td/utils/find_boundary.h"
#include "td/utils/format.h"
-#include "td/utils/logging.h"
#include "td/utils/misc.h"
+#include "td/utils/SliceBuilder.h"
#include "td/utils/Status.h"
namespace td {
-void HttpChunkedByteFlow::loop() {
- bool was_updated = false;
- size_t need_size;
- while (true) {
- if (state_ == ReadChunkLength) {
+bool HttpChunkedByteFlow::loop() {
+ bool result = false;
+ do {
+ if (state_ == State::ReadChunkLength) {
bool ok = find_boundary(input_->clone(), "\r\n", len_);
if (len_ > 10) {
- return finish(Status::Error(PSLICE() << "Too long length in chunked "
- << input_->cut_head(len_).move_as_buffer_slice().as_slice()));
+ finish(Status::Error(PSLICE() << "Too long length in chunked "
+ << input_->cut_head(len_).move_as_buffer_slice().as_slice()));
+ return false;
}
if (!ok) {
- need_size = input_->size() + 1;
+ set_need_size(input_->size() + 1);
break;
}
auto s_len = input_->cut_head(len_).move_as_buffer_slice();
input_->advance(2);
len_ = hex_to_integer<size_t>(s_len.as_slice());
if (len_ > MAX_CHUNK_SIZE) {
- return finish(Status::Error(PSLICE() << "Invalid chunk size " << tag("size", len_)));
+ finish(Status::Error(PSLICE() << "Invalid chunk size " << tag("size", len_)));
+ return false;
}
save_len_ = len_;
- state_ = ReadChunkContent;
+ state_ = State::ReadChunkContent;
}
auto size = input_->size();
auto ready = min(len_, size);
- need_size = min(MIN_UPDATE_SIZE, len_ + 2);
+ auto need_size = min(MIN_UPDATE_SIZE, len_ + 2);
if (size < need_size) {
+ set_need_size(need_size);
break;
}
- total_size_ += ready;
- uncommited_size_ += ready;
- if (total_size_ > MAX_SIZE) {
- return finish(Status::Error(PSLICE() << "Too big query " << tag("size", input_->size())));
+ if (total_size_ > MAX_SIZE - ready) {
+ finish(Status::Error(PSLICE() << "Too big query " << tag("size", input_->size())));
+ return false;
}
+ total_size_ += ready;
+ uncommitted_size_ += ready;
output_.append(input_->cut_head(ready));
+ result = true;
len_ -= ready;
- if (uncommited_size_ >= MIN_UPDATE_SIZE) {
- uncommited_size_ = 0;
- was_updated = true;
+ if (uncommitted_size_ >= MIN_UPDATE_SIZE) {
+ uncommitted_size_ = 0;
}
if (len_ == 0) {
if (input_->size() < 2) {
- need_size = 2;
+ set_need_size(2);
break;
}
- input_->cut_head(2);
+ input_->advance(2);
total_size_ += 2;
if (save_len_ == 0) {
- return finish(Status::OK());
+ finish(Status::OK());
+ return false;
}
- state_ = ReadChunkLength;
+ state_ = State::ReadChunkLength;
len_ = 0;
}
+ } while (false);
+ if (!is_input_active_ && !result) {
+ finish(Status::Error("Unexpected end of stream"));
}
- if (was_updated) {
- on_output_updated();
- }
- if (!is_input_active_) {
- return finish(Status::Error("Unexpected end of stream"));
- }
- set_need_size(need_size);
+ return result;
}
} // namespace td