]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: implement RGWStreamIOChunkingEngine.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Wed, 3 Aug 2016 13:27:56 +0000 (15:27 +0200)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Fri, 21 Oct 2016 20:57:19 +0000 (22:57 +0200)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_client_io_decoimpl.h

index c5434f398cc63b315b4be4fc5bd98f93c3d518f3..08a392cc8d538f1c7b1f53d8bd8397da548c5330 100644 (file)
@@ -250,6 +250,62 @@ int RGWStreamIOBufferingEngine<T>::complete_request()
 }
 
 
+template <typename T>
+class RGWStreamIOChunkingEngine : public RGWDecoratedStreamIO<T> {
+  template<typename Td> 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<T>::write_data(buf, len);
+    } else {
+      constexpr char HEADER_END[] = "\r\n";
+      char sizebuf[32];
+      snprintf(sizebuf, sizeof(buf), "%" PRIx64 "\r\n", len);
+
+      RGWDecoratedStreamIO<T>::write_data(sizebuf, strlen(sizebuf));
+      RGWDecoratedStreamIO<T>::write_data(buf, len);
+      return RGWDecoratedStreamIO<T>::write_data(HEADER_END, sizeof(HEADER_END) - 1);
+    }
+  }
+
+public:
+  template <typename U>
+  RGWStreamIOChunkingEngine(U&& decoratee)
+    : RGWDecoratedStreamIO<T>(std::move(decoratee)),
+      has_content_length(false),
+      chunking_enabled(false) {
+  }
+
+  using RGWDecoratedStreamIO<T>::send_content_length;
+  int send_content_length(const uint64_t len) override {
+    has_content_length = true;
+    return RGWDecoratedStreamIO<T>::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<T>::write_data(TRANSFER_CHUNKED,
+                                                  sizeof(TRANSFER_CHUNKED) - 1);
+      chunking_enabled = true;
+    }
+
+    return sent + RGWDecoratedStreamIO<T>::complete_header();
+  }
+};
+
+template <typename T>
+RGWStreamIOChunkingEngine<T> add_chunking(T&& t) {
+  return RGWStreamIOChunkingEngine<T>(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. */