diff options
author | Mattes D <github@xoft.cz> | 2016-01-01 16:42:22 +0100 |
---|---|---|
committer | Mattes D <github@xoft.cz> | 2016-03-01 16:19:56 +0100 |
commit | fce68dc8f39dfceab3e80513390bae8fa936a6b9 (patch) | |
tree | b79948729243bd71d77d6eb6062145e82d3b9941 /src/HTTPServer/TransferEncodingParser.cpp | |
parent | Moved cHTTPRequest to a separate file, renamed to cHTTPRequestParser. (diff) | |
download | cuberite-fce68dc8f39dfceab3e80513390bae8fa936a6b9.tar cuberite-fce68dc8f39dfceab3e80513390bae8fa936a6b9.tar.gz cuberite-fce68dc8f39dfceab3e80513390bae8fa936a6b9.tar.bz2 cuberite-fce68dc8f39dfceab3e80513390bae8fa936a6b9.tar.lz cuberite-fce68dc8f39dfceab3e80513390bae8fa936a6b9.tar.xz cuberite-fce68dc8f39dfceab3e80513390bae8fa936a6b9.tar.zst cuberite-fce68dc8f39dfceab3e80513390bae8fa936a6b9.zip |
Diffstat (limited to 'src/HTTPServer/TransferEncodingParser.cpp')
-rw-r--r-- | src/HTTPServer/TransferEncodingParser.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/src/HTTPServer/TransferEncodingParser.cpp b/src/HTTPServer/TransferEncodingParser.cpp new file mode 100644 index 000000000..8b703fd42 --- /dev/null +++ b/src/HTTPServer/TransferEncodingParser.cpp @@ -0,0 +1,132 @@ + +// TransferEncodingParser.cpp + +// Implements the cTransferEncodingParser class and its descendants representing the parser for the various transfer encodings (chunked etc.) + +#include "Globals.h" +#include "TransferEncodingParser.h" + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cChunkedTEParser: + +class cChunkedTEParser: + public cTransferEncodingParser +{ + typedef cTransferEncodingParser Super; + +public: + cChunkedTEParser(cCallbacks & a_Callbacks): + Super(a_Callbacks), + m_IsFinished(false) + { + } + + +protected: + + /** True if the datastream has finished (zero-length chunk received). */ + bool m_IsFinished; + + + // cTransferEncodingParser overrides: + virtual size_t Parse(const char * a_Data, size_t a_Size) override + { + // TODO + m_Callbacks.OnError("cChunkedTEParser not implemented yet"); + return AString::npos; + } + + virtual void Finish(void) override + { + if (!m_IsFinished) + { + m_Callbacks.OnError("ChunkedTransferEncoding: Finish signal received before the data stream ended"); + } + m_IsFinished = true; + } +}; + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cIdentityTEParser: + +class cIdentityTEParser: + public cTransferEncodingParser +{ + typedef cTransferEncodingParser Super; + +public: + cIdentityTEParser(cCallbacks & a_Callbacks, size_t a_ContentLength): + Super(a_Callbacks), + m_BytesLeft(a_ContentLength) + { + } + + +protected: + /** How many bytes of content are left before the message ends. */ + size_t m_BytesLeft; + + // cTransferEncodingParser overrides: + virtual size_t Parse(const char * a_Data, size_t a_Size) override + { + auto size = std::min(a_Size, m_BytesLeft); + if (size > 0) + { + m_Callbacks.OnBodyData(a_Data, size); + } + m_BytesLeft -= size; + if (m_BytesLeft == 0) + { + m_Callbacks.OnBodyFinished(); + } + return a_Size - size; + } + + virtual void Finish(void) override + { + if (m_BytesLeft > 0) + { + m_Callbacks.OnError("IdentityTransferEncoding: body was truncated"); + } + else + { + // BodyFinished has already been called, just bail out + } + } +}; + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cTransferEncodingParser: + +cTransferEncodingParserPtr cTransferEncodingParser::Create( + cCallbacks & a_Callbacks, + const AString & a_TransferEncoding, + size_t a_ContentLength +) +{ + if (a_TransferEncoding == "chunked") + { + return std::make_shared<cChunkedTEParser>(a_Callbacks); + } + if (a_TransferEncoding.empty()) + { + return std::make_shared<cIdentityTEParser>(a_Callbacks, a_ContentLength); + } + return nullptr; +} + + + + |