From: Casey Bodley Date: Mon, 17 Jul 2017 14:12:07 +0000 (-0400) Subject: rgw: beast frontend discards unread body before next header X-Git-Tag: v13.0.1~300^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c6bc7e1b0cbaf553f000aaa2893fa1486fc02a75;p=ceph.git rgw: beast frontend discards unread body before next header Signed-off-by: Casey Bodley --- diff --git a/src/rgw/rgw_asio_frontend.cc b/src/rgw/rgw_asio_frontend.cc index 45008656fa1e..cee0594679d0 100644 --- a/src/rgw/rgw_asio_frontend.cc +++ b/src/rgw/rgw_asio_frontend.cc @@ -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 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(); } }