diff options
author | Anton Samokhvalov <pg83@yandex.ru> | 2022-02-10 16:45:17 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:17 +0300 |
commit | d3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch) | |
tree | dd4bd3ca0f36b817e96812825ffaf10d645803f2 /library/cpp/http/io/chunk.cpp | |
parent | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff) | |
download | ydb-d3a398281c6fd1d3672036cb2d63f842d2cb28c5.tar.gz |
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/http/io/chunk.cpp')
-rw-r--r-- | library/cpp/http/io/chunk.cpp | 398 |
1 files changed, 199 insertions, 199 deletions
diff --git a/library/cpp/http/io/chunk.cpp b/library/cpp/http/io/chunk.cpp index 80a423e7c9..6975d9eac1 100644 --- a/library/cpp/http/io/chunk.cpp +++ b/library/cpp/http/io/chunk.cpp @@ -1,70 +1,70 @@ -#include "chunk.h" - +#include "chunk.h" + #include "headers.h" -#include <util/string/cast.h> -#include <util/generic/utility.h> -#include <util/generic/yexception.h> - +#include <util/string/cast.h> +#include <util/generic/utility.h> +#include <util/generic/yexception.h> + static inline size_t ParseHex(const TString& s) { - if (s.empty()) { + if (s.empty()) { ythrow yexception() << "can not parse chunk length(empty string)"; - } - - size_t ret = 0; - + } + + size_t ret = 0; + for (TString::const_iterator c = s.begin(); c != s.end(); ++c) { - const char ch = *c; - - if (ch >= '0' && ch <= '9') { - ret *= 16; - ret += ch - '0'; - } else if (ch >= 'a' && ch <= 'f') { - ret *= 16; - ret += 10 + ch - 'a'; - } else if (ch >= 'A' && ch <= 'F') { - ret *= 16; - ret += 10 + ch - 'A'; - } else if (ch == ';') { - break; - } else if (isspace(ch)) { - continue; - } else { + const char ch = *c; + + if (ch >= '0' && ch <= '9') { + ret *= 16; + ret += ch - '0'; + } else if (ch >= 'a' && ch <= 'f') { + ret *= 16; + ret += 10 + ch - 'a'; + } else if (ch >= 'A' && ch <= 'F') { + ret *= 16; + ret += 10 + ch - 'A'; + } else if (ch == ';') { + break; + } else if (isspace(ch)) { + continue; + } else { ythrow yexception() << "can not parse chunk length(" << s.data() << ")"; - } - } - - return ret; -} - -static inline char* ToHex(size_t len, char* buf) { - do { - const size_t val = len % 16; - - *--buf = (val < 10) ? (val + '0') : (val - 10 + 'a'); - len /= 16; - } while (len); - - return buf; -} - -class TChunkedInput::TImpl { -public: + } + } + + return ret; +} + +static inline char* ToHex(size_t len, char* buf) { + do { + const size_t val = len % 16; + + *--buf = (val < 10) ? (val + '0') : (val - 10 + 'a'); + len /= 16; + } while (len); + + return buf; +} + +class TChunkedInput::TImpl { +public: inline TImpl(IInputStream* slave, TMaybe<THttpHeaders>* trailers) - : Slave_(slave) + : Slave_(slave) , Trailers_(trailers) - , Pending_(0) - , LastChunkReaded_(false) - { + , Pending_(0) + , LastChunkReaded_(false) + { if (Trailers_) { Trailers_->Clear(); } - } - + } + inline ~TImpl() { - } - - inline size_t Read(void* buf, size_t len) { + } + + inline size_t Read(void* buf, size_t len) { return Perform(len, [this, buf](size_t toRead) { return Slave_->Read(buf, toRead); }); } @@ -73,174 +73,174 @@ public: } private: - template <class Operation> + template <class Operation> inline size_t Perform(size_t len, const Operation& operation) { - if (!HavePendingData()) { - return 0; - } - + if (!HavePendingData()) { + return 0; + } + const size_t toProcess = Min(Pending_, len); - + if (toProcess) { const size_t processed = operation(toProcess); - + if (!processed) { - ythrow yexception() << "malformed http chunk"; - } - + ythrow yexception() << "malformed http chunk"; + } + Pending_ -= processed; - + return processed; - } - - return 0; - } - - inline bool HavePendingData() { - if (LastChunkReaded_) { - return false; - } - - if (!Pending_) { - if (!ProceedToNextChunk()) { - return false; - } - } - - return true; - } - - inline bool ProceedToNextChunk() { + } + + return 0; + } + + inline bool HavePendingData() { + if (LastChunkReaded_) { + return false; + } + + if (!Pending_) { + if (!ProceedToNextChunk()) { + return false; + } + } + + return true; + } + + inline bool ProceedToNextChunk() { TString len(Slave_->ReadLine()); - - if (len.empty()) { - /* - * skip crlf from previous chunk - */ - - len = Slave_->ReadLine(); - } - - Pending_ = ParseHex(len); - - if (Pending_) { - return true; - } - + + if (len.empty()) { + /* + * skip crlf from previous chunk + */ + + len = Slave_->ReadLine(); + } + + Pending_ = ParseHex(len); + + if (Pending_) { + return true; + } + if (Trailers_) { Trailers_->ConstructInPlace(Slave_); } - LastChunkReaded_ = true; - - return false; - } - -private: + LastChunkReaded_ = true; + + return false; + } + +private: IInputStream* Slave_; TMaybe<THttpHeaders>* Trailers_; - size_t Pending_; - bool LastChunkReaded_; -}; - + size_t Pending_; + bool LastChunkReaded_; +}; + TChunkedInput::TChunkedInput(IInputStream* slave, TMaybe<THttpHeaders>* trailers) : Impl_(new TImpl(slave, trailers)) -{ -} - +{ +} + TChunkedInput::~TChunkedInput() { -} - -size_t TChunkedInput::DoRead(void* buf, size_t len) { - return Impl_->Read(buf, len); -} - +} + +size_t TChunkedInput::DoRead(void* buf, size_t len) { + return Impl_->Read(buf, len); +} + size_t TChunkedInput::DoSkip(size_t len) { return Impl_->Skip(len); } -class TChunkedOutput::TImpl { +class TChunkedOutput::TImpl { typedef IOutputStream::TPart TPart; - -public: + +public: inline TImpl(IOutputStream* slave) - : Slave_(slave) - { - } - + : Slave_(slave) + { + } + inline ~TImpl() { - } - - inline void Write(const void* buf, size_t len) { - const char* ptr = (const char*)buf; - - while (len) { - const size_t portion = Min<size_t>(len, 1024 * 16); - - WriteImpl(ptr, portion); - - ptr += portion; - len -= portion; - } - } - - inline void WriteImpl(const void* buf, size_t len) { - char tmp[32]; - char* e = tmp + sizeof(tmp); - char* b = ToHex(len, e); - - const TPart parts[] = { - TPart(b, e - b), - TPart::CrLf(), - TPart(buf, len), - TPart::CrLf(), - }; - - Slave_->Write(parts, sizeof(parts) / sizeof(*parts)); - } - - inline void Flush() { - Slave_->Flush(); - } - - inline void Finish() { - Slave_->Write("0\r\n\r\n", 5); - - Flush(); - } - -private: + } + + inline void Write(const void* buf, size_t len) { + const char* ptr = (const char*)buf; + + while (len) { + const size_t portion = Min<size_t>(len, 1024 * 16); + + WriteImpl(ptr, portion); + + ptr += portion; + len -= portion; + } + } + + inline void WriteImpl(const void* buf, size_t len) { + char tmp[32]; + char* e = tmp + sizeof(tmp); + char* b = ToHex(len, e); + + const TPart parts[] = { + TPart(b, e - b), + TPart::CrLf(), + TPart(buf, len), + TPart::CrLf(), + }; + + Slave_->Write(parts, sizeof(parts) / sizeof(*parts)); + } + + inline void Flush() { + Slave_->Flush(); + } + + inline void Finish() { + Slave_->Write("0\r\n\r\n", 5); + + Flush(); + } + +private: IOutputStream* Slave_; -}; - +}; + TChunkedOutput::TChunkedOutput(IOutputStream* slave) - : Impl_(new TImpl(slave)) -{ -} - + : Impl_(new TImpl(slave)) +{ +} + TChunkedOutput::~TChunkedOutput() { - try { - Finish(); - } catch (...) { - } -} - -void TChunkedOutput::DoWrite(const void* buf, size_t len) { - if (Impl_.Get()) { - Impl_->Write(buf, len); - } else { + try { + Finish(); + } catch (...) { + } +} + +void TChunkedOutput::DoWrite(const void* buf, size_t len) { + if (Impl_.Get()) { + Impl_->Write(buf, len); + } else { ythrow yexception() << "can not write to finished stream"; - } -} - -void TChunkedOutput::DoFlush() { - if (Impl_.Get()) { - Impl_->Flush(); - } -} - -void TChunkedOutput::DoFinish() { - if (Impl_.Get()) { - Impl_->Finish(); - Impl_.Destroy(); - } -} + } +} + +void TChunkedOutput::DoFlush() { + if (Impl_.Get()) { + Impl_->Flush(); + } +} + +void TChunkedOutput::DoFinish() { + if (Impl_.Get()) { + Impl_->Finish(); + Impl_.Destroy(); + } +} |