36 connection(std::shared_ptr<spdlog::logger> logger,
const std::uint64_t body_limit) :
37 m_logger(std::move(logger))
41 throw std::invalid_argument(
"no valid logger provided.");
44 m_parser.body_limit(body_limit);
52 boost::asio::awaitable< request_result<Filter> >
59 auto executor =
co_await boost::asio::this_coro::executor;
62 auto resolver = boost::asio::ip::tcp::resolver{ executor };
63 const auto [ec1, results] =
co_await resolver.async_resolve(
64 req.base()[malloy::http::field::host],
65 std::to_string(req.
port()),
66 boost::asio::as_tuple(boost::asio::use_awaitable)
73 set_stream_timeout(std::chrono::seconds(30));
74 co_await boost::beast::get_lowest_layer(derived().stream()).async_connect(results, boost::asio::redirect_error(boost::asio::use_awaitable, ec2));
79 co_await derived().hook_connected();
82 set_stream_timeout(std::chrono::seconds(30));
83 co_await boost::beast::http::async_write(derived().stream(), req);
93 auto bodies = filter.body_for(m_parser.get().base());
94 auto resp =
co_await std::visit(
96 using body_t = std::decay_t<
decltype(body)>;
98 auto parser = std::make_shared<boost::beast::http::response_parser<body_t>>(std::move(m_parser));
99 filter.setup_body(parser->get().base(), parser->get().body());
101 boost::beast::flat_buffer buffer;
103 co_await boost::beast::http::async_read(
107 boost::asio::use_awaitable
117 set_stream_timeout(std::chrono::seconds(30));
119 boost::beast::get_lowest_layer(derived().stream()).socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
124 if (ec && ec != boost::beast::errc::not_connected)
125 m_logger->error(
"shutdown: {}", ec.message());
139 std::shared_ptr<spdlog::logger> m_logger;
141 template<
typename Rep,
typename Period>
143 set_stream_timeout(
const std::chrono::duration<Rep, Period> duration)
148 boost::beast::get_lowest_layer(derived().stream()).expires_after(duration);
152 boost::beast::http::response_parser<boost::beast::http::empty_body> m_parser;
159 return static_cast<Derived&
>(*this);