From: Radoslaw Zarzynski Date: Wed, 3 Aug 2016 13:27:56 +0000 (+0200) Subject: rgw: implement RGWStreamIOChunkingEngine. X-Git-Tag: v11.1.0~454^2~45 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e2bfd3e2a87274210160fa3733819b3a49a71485;p=ceph.git rgw: implement RGWStreamIOChunkingEngine. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/rgw/rgw_client_io_decoimpl.h b/src/rgw/rgw_client_io_decoimpl.h index c5434f398cc..08a392cc8d5 100644 --- a/src/rgw/rgw_client_io_decoimpl.h +++ b/src/rgw/rgw_client_io_decoimpl.h @@ -250,6 +250,62 @@ int RGWStreamIOBufferingEngine::complete_request() } +template +class RGWStreamIOChunkingEngine : public RGWDecoratedStreamIO { + template friend class RGWDecoratedStreamIO; +protected: + bool has_content_length; + bool chunking_enabled; + + int write_data(const char* const buf, const int len) override { + if (! chunking_enabled) { + return RGWDecoratedStreamIO::write_data(buf, len); + } else { + constexpr char HEADER_END[] = "\r\n"; + char sizebuf[32]; + snprintf(sizebuf, sizeof(buf), "%" PRIx64 "\r\n", len); + + RGWDecoratedStreamIO::write_data(sizebuf, strlen(sizebuf)); + RGWDecoratedStreamIO::write_data(buf, len); + return RGWDecoratedStreamIO::write_data(HEADER_END, sizeof(HEADER_END) - 1); + } + } + +public: + template + RGWStreamIOChunkingEngine(U&& decoratee) + : RGWDecoratedStreamIO(std::move(decoratee)), + has_content_length(false), + chunking_enabled(false) { + } + + using RGWDecoratedStreamIO::send_content_length; + int send_content_length(const uint64_t len) override { + has_content_length = true; + return RGWDecoratedStreamIO::send_content_length(len); + } + + int complete_header() override { + size_t sent = 0; + + if (! has_content_length) { + constexpr char TRANSFER_CHUNKED[] = "Transfer-Enconding: chunked\r\n"; + + sent += RGWDecoratedStreamIO::write_data(TRANSFER_CHUNKED, + sizeof(TRANSFER_CHUNKED) - 1); + chunking_enabled = true; + } + + return sent + RGWDecoratedStreamIO::complete_header(); + } +}; + +template +RGWStreamIOChunkingEngine add_chunking(T&& t) { + return RGWStreamIOChunkingEngine(std::move(t)); +} + + /* Class that controls and inhibits the process of sending Content-Length HTTP * header where RFC 7230 requests so. The cases worth our attention are 204 No * Content as well as 304 Not Modified. */