diff --git a/src/rgw/rgw_asio_frontend.cc b/src/rgw/rgw_asio_frontend.cc index 000a0bc6a9f..beeb64d0cce 100644 --- a/src/rgw/rgw_asio_frontend.cc +++ b/src/rgw/rgw_asio_frontend.cc @@ -72,6 +72,7 @@ class StreamIO : public rgw::asio::ClientIO { timeout_timer& timeout; yield_context yield; parse_buffer& buffer; + boost::system::error_code fatal_ec; public: StreamIO(CephContext *cct, Stream& stream, timeout_timer& timeout, rgw::asio::parser_type& parser, yield_context yield, @@ -83,6 +84,8 @@ class StreamIO : public rgw::asio::ClientIO { buffer(buffer) {} + boost::system::error_code get_fatal_error_code() const { return fatal_ec; } + size_t write_data(const char* buf, size_t len) override { boost::system::error_code ec; timeout.start(); @@ -95,6 +98,9 @@ class StreamIO : public rgw::asio::ClientIO { boost::system::error_code ec_ignored; stream.lowest_layer().shutdown(tcp_socket::shutdown_both, ec_ignored); } + if (!fatal_ec) { + fatal_ec = ec; + } throw rgw::io::Exception(ec.value(), std::system_category()); } return bytes; @@ -116,6 +122,9 @@ class StreamIO : public rgw::asio::ClientIO { } if (ec) { ldout(cct, 4) << "failed to read body: " << ec.message() << dendl; + if (!fatal_ec) { + fatal_ec = ec; + } throw rgw::io::Exception(ec.value(), std::system_category()); } } @@ -288,6 +297,13 @@ void handle_connection(boost::asio::io_context& context, << latency << dendl; } + // process_request() can't distinguish between connection errors and + // http/s3 errors, so check StreamIO for fatal connection errors + ec = real_client.get_fatal_error_code(); + if (ec) { + return; + } + if (real_client.sent_100_continue()) { expect_continue = false; }