#include <boost/algorithm/string/predicate.hpp>
#include <boost/asio/write.hpp>
-#include <beast/http/read.hpp>
#include "rgw_asio_client.h"
#define dout_context g_ceph_context
#define dout_subsys ceph_subsys_rgw
-#undef dout_prefix
-#define dout_prefix (*_dout << "asio: ")
-
using namespace rgw::asio;
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")) {
- env.set("CONTENT_LENGTH", value);
+ if (field == beast::http::field::content_length) {
+ env.set("CONTENT_LENGTH", value.to_string());
continue;
}
- if (boost::algorithm::iequals(name, "content-type")) {
- env.set("CONTENT_TYPE", value);
+ if (field == beast::http::field::content_type) {
+ env.set("CONTENT_TYPE", value.to_string());
continue;
}
- if (boost::algorithm::iequals(name, "connection")) {
- conn_keepalive = boost::algorithm::iequals(value, "keep-alive");
- conn_close = boost::algorithm::iequals(value, "close");
- }
static const boost::string_ref HTTP_{"HTTP_"};
}
*dest = '\0';
- env.set(buf, value);
+ env.set(buf, value.to_string());
}
- env.set("REQUEST_METHOD", request.method);
+ int major = request.version() / 10;
+ int minor = request.version() % 10;
+ env.set("HTTP_VERSION", std::to_string(major) + '.' + std::to_string(minor));
+
+ env.set("REQUEST_METHOD", request.method_string().to_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);
-
- env.set("REQUEST_URI", url);
- env.set("QUERY_STRING", query);
- env.set("SCRIPT_URI", url); /* FIXME */
+ if (pos != url.npos) {
+ auto query = url.substr(pos + 1);
+ env.set("QUERY_STRING", query.to_string());
+ url = url.substr(0, pos);
+ }
+ env.set("REQUEST_URI", url.to_string());
+ env.set("SCRIPT_URI", url.to_string()); /* FIXME */
char port_buf[16];
snprintf(port_buf, sizeof(port_buf), "%d", socket.local_endpoint().port());
env.set("SERVER_PORT", port_buf);
+ env.set("REMOTE_ADDR", socket.remote_endpoint().address().to_string());
// TODO: set SERVER_PORT_SECURE if using ssl
// TODO: set REMOTE_USER if authenticated
}
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);
- if (ec == boost::asio::error::connection_reset ||
- ec == boost::asio::error::eof ||
- ec == beast::http::error::partial_message) {
+ while (body_remaining.size && !parser.is_done()) {
+ boost::system::error_code ec;
+ beast::http::read_some(socket, buffer, parser, ec);
+ if (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()
sent += txbuf.sputn(timestr, strlen(timestr));
}
- if (conn_keepalive) {
+ if (parser.keep_alive()) {
constexpr char CONN_KEEP_ALIVE[] = "Connection: Keep-Alive\r\n";
sent += txbuf.sputn(CONN_KEEP_ALIVE, sizeof(CONN_KEEP_ALIVE) - 1);
- } else if (conn_close) {
+ } else {
constexpr char CONN_KEEP_CLOSE[] = "Connection: close\r\n";
sent += txbuf.sputn(CONN_KEEP_CLOSE, sizeof(CONN_KEEP_CLOSE) - 1);
}