diff options
Diffstat (limited to 'protocols/Telegram/tdlib/td/tdnet/td/net/HttpChunkedByteFlow.cpp')
-rw-r--r-- | protocols/Telegram/tdlib/td/tdnet/td/net/HttpChunkedByteFlow.cpp | 63 |
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 |