-Subproject commit d8db5f1a0d607aa78e6e857daa0410b0d5326978
+Subproject commit dca65932a8055dd3e240633c6a058db8aa7f7915
#include <boost/algorithm/string/predicate.hpp>
#include <boost/asio/write.hpp>
-#include <beast/http/read.hpp>
#include "rgw_asio_client.h"
ClientIO::ClientIO(tcp::socket& socket,
parser_type& parser,
- beast::flat_streambuf& buffer)
+ beast::flat_buffer& buffer)
: socket(socket), parser(parser), buffer(buffer), txbuf(*this)
{
}
env.init(cct);
const auto& request = parser.get();
- const auto& headers = request.fields;
+ const auto& headers = request;
for (auto header = headers.begin(); header != headers.end(); ++header) {
- const auto& name = header->name();
+ const auto& field = header->name(); // enum type for known headers
+ const auto& name = header->name_string();
const auto& value = header->value();
- if (boost::algorithm::iequals(name, "content-length")) {
+ if (field == beast::http::field::content_length) {
env.set("CONTENT_LENGTH", value);
continue;
}
- if (boost::algorithm::iequals(name, "content-type")) {
+ if (field == beast::http::field::content_type) {
env.set("CONTENT_TYPE", value);
continue;
}
- if (boost::algorithm::iequals(name, "connection")) {
+ if (field == beast::http::field::connection) {
conn_keepalive = boost::algorithm::iequals(value, "keep-alive");
conn_close = boost::algorithm::iequals(value, "close");
}
env.set(buf, value);
}
- int major = request.version / 10;
- int minor = request.version % 10;
+ int major = request.version() / 10;
+ int minor = request.version() % 10;
std::string http_version = std::to_string(major) + '.' + std::to_string(minor);
env.set("HTTP_VERSION", http_version);
- env.set("REQUEST_METHOD", request.method);
+ env.set("REQUEST_METHOD", request.method_string());
// split uri from query
- auto url = boost::string_ref{request.url};
+ auto url = request.target();
auto pos = url.find('?');
auto query = url.substr(pos + 1);
url = url.substr(0, pos);
size_t ClientIO::read_data(char* buf, size_t max)
{
auto& message = parser.get();
- auto& body_remaining = message.body;
- body_remaining = boost::asio::mutable_buffer{buf, max};
-
- boost::system::error_code ec;
+ auto& body_remaining = message.body();
+ body_remaining.data = buf;
+ body_remaining.size = max;
dout(30) << this << " read_data for " << max << " with "
<< buffer.size() << " bytes buffered" << dendl;
- while (boost::asio::buffer_size(body_remaining) && !parser.is_complete()) {
- auto bytes = beast::http::read_some(socket, buffer, parser, ec);
- buffer.consume(bytes);
+ while (body_remaining.size && !parser.is_done()) {
+ boost::system::error_code ec;
+ beast::http::read_some(socket, buffer, parser, ec);
if (ec == boost::asio::error::connection_reset ||
ec == boost::asio::error::eof ||
- ec == beast::http::error::partial_message) {
+ ec == beast::http::error::partial_message ||
+ ec == beast::http::error::need_buffer) {
break;
}
if (ec) {
throw rgw::io::Exception(ec.value(), std::system_category());
}
}
- return max - boost::asio::buffer_size(body_remaining);
+ return max - body_remaining.size;
}
size_t ClientIO::complete_request()
#define RGW_ASIO_CLIENT_H
#include <boost/asio/ip/tcp.hpp>
-#include <beast/http/message.hpp>
-#include <beast/http/message_parser.hpp>
-#include <beast/core/flat_streambuf.hpp>
+#include <boost/beast/core.hpp>
+#include <boost/beast/http.hpp>
#include "include/assert.h"
#include "rgw_client_io.h"
namespace rgw {
namespace asio {
-/// streaming message body interface
-struct streaming_body {
- using value_type = boost::asio::mutable_buffer;
-
- class reader {
- value_type& buffer;
- public:
- using mutable_buffers_type = boost::asio::mutable_buffers_1;
-
- static const bool is_direct{true}; // reads directly into user buffer
-
- template<bool isRequest, class Fields>
- explicit reader(beast::http::message<isRequest, streaming_body, Fields>& m)
- : buffer(m.body)
- {}
-
- void init() {}
- void init(uint64_t content_length) {}
- void finish() {}
-
- mutable_buffers_type prepare(size_t n) {
- n = std::min(n, boost::asio::buffer_size(buffer));
- auto position = boost::asio::buffer_cast<char*>(buffer);
- return {position, n};
- }
-
- void commit(size_t n) {
- buffer = buffer + n;
- }
- };
-};
-
-using header_type = beast::http::fields;
-using parser_type = beast::http::message_parser<true, streaming_body, header_type>;
+namespace beast = boost::beast;
+using parser_type = beast::http::request_parser<beast::http::buffer_body>;
class ClientIO : public io::RestfulClient,
public io::BuffererSink {
using tcp = boost::asio::ip::tcp;
tcp::socket& socket;
parser_type& parser;
- beast::flat_streambuf& buffer; //< parse buffer
+ beast::flat_buffer& buffer; //< parse buffer
bool conn_keepalive{false};
bool conn_close{false};
public:
ClientIO(tcp::socket& socket, parser_type& parser,
- beast::flat_streambuf& buffer);
+ beast::flat_buffer& buffer);
~ClientIO() override;
bool get_conn_close() const { return conn_close; }
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
-#include <beast/core/placeholders.hpp>
-#include <beast/http/read.hpp>
-#include <beast/http/string_body.hpp>
-#include <beast/http/write.hpp>
-
-#include "rgw_asio_frontend.h"
#include "rgw_asio_client.h"
+#include "rgw_asio_frontend.h"
#define dout_subsys ceph_subsys_rgw
-#undef dout_prefix
-#define dout_prefix (*_dout << "asio: ")
+//#undef dout_prefix
+//#define dout_prefix (*_dout << "asio: ")
namespace {
}
using tcp = boost::asio::ip::tcp;
+namespace beast = boost::beast;
// coroutine to handle a client connection to completion
static void handle_connection(RGWProcessEnv& env, tcp::socket socket,
auto cct = env.store->ctx();
boost::system::error_code ec;
- beast::flat_streambuf buffer{1024};
+ beast::flat_buffer buffer{4096};
// read messages from the socket until eof
for (;;) {
// parse the header
rgw::asio::parser_type parser;
- do {
- auto bytes = beast::http::async_read_some(socket, buffer, parser, yield[ec]);
- buffer.consume(bytes);
- } while (!ec && !parser.got_header());
+ beast::http::async_read_header(socket, buffer, parser, yield[ec]);
if (ec == boost::asio::error::connection_reset ||
ec == boost::asio::error::eof) {
ldout(cct, 1) << "read failed: " << ec.message() << dendl;
ldout(cct, 1) << "====== req done http_status=400 ======" << dendl;
beast::http::response<beast::http::string_body> response;
- response.status = 400;
- response.reason = "Bad Request";
- response.version = message.version == 10 ? 10 : 11;
- beast::http::prepare(response);
- beast::http::async_write(socket, std::move(response), yield[ec]);
+ response.result(beast::http::status::bad_request);
+ response.reason("Bad Request");
+ response.version(message.version() == 10 ? 10 : 11);
+ response.prepare_payload();
+ beast::http::async_write(socket, response, yield[ec]);
// ignore ec
return;
}
void RGWEnv::set(const boost::string_ref& name, const boost::string_ref& val)
{
- env_map[std::string{name}] = std::string{val};
+ env_map[name.to_string()] = val.to_string();
}
void RGWEnv::init(CephContext *cct, char **envp)