]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: beast frontend discards unread body before next header
authorCasey Bodley <cbodley@redhat.com>
Mon, 17 Jul 2017 14:12:07 +0000 (10:12 -0400)
committerCasey Bodley <cbodley@redhat.com>
Mon, 8 Jan 2018 21:29:58 +0000 (16:29 -0500)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
(cherry picked from commit c6bc7e1b0cbaf553f000aaa2893fa1486fc02a75)

src/rgw/rgw_asio_frontend.cc

index 9a1f01d84a36127b22f739ef36c898f6615f0fac..699ab96e28c04e9fa117e52991172b88be276bf9 100644 (file)
@@ -98,6 +98,38 @@ class Connection {
                       std::placeholders::_1)));
   }
 
+  void discard_unread_message() {
+    if (parser->is_done()) {
+      // nothing left to discard, start reading the next message
+      read_header();
+      return;
+    }
+
+    // read the rest of the request into a static buffer. multiple clients could
+    // write at the same time, but this is okay because we never read it back
+    static std::array<char, 1024> discard_buffer;
+
+    auto& body = parser->get().body();
+    body.size = discard_buffer.size();
+    body.data = discard_buffer.data();
+
+    beast::http::async_read_some(socket, buffer, *parser, strand.wrap(
+            std::bind(&Connection::on_discard_unread, Ref{this},
+                      std::placeholders::_1)));
+  }
+
+  void on_discard_unread(boost::system::error_code ec) {
+    if (ec == boost::asio::error::connection_reset) {
+      return;
+    }
+    if (ec) {
+      ldout(ctx(), 5) << "discard_unread_message failed: "
+          << ec.message() << dendl;
+      return;
+    }
+    discard_unread_message();
+  }
+
   void on_write_error(boost::system::error_code ec) {
     if (ec) {
       ldout(ctx(), 5) << "failed to write response: " << ec.message() << dendl;
@@ -137,9 +169,10 @@ class Connection {
     process_request(env.store, env.rest, &req, env.uri_prefix,
                     *env.auth_registry, &client, env.olog);
 
-    if (!real_client.get_conn_close()) {
-      // read next header
-      read_header();
+    if (parser->is_keep_alive()) {
+      // parse any unread bytes from the previous message (in case we replied
+      // before reading the entire body) before reading the next
+      discard_unread_message();
     }
   }