3#include "../tcp/stream.hpp"
4#include "../type_traits.hpp"
6#include <boost/beast/core.hpp>
7#include <boost/asio/connect.hpp>
8#include <boost/asio/ip/tcp.hpp>
9#include <boost/beast/websocket/stream.hpp>
10#include <boost/beast/websocket/error.hpp>
13 #include <boost/beast/ssl.hpp>
14 #include <boost/asio/ssl/stream.hpp>
26 using tls_stream = boost::beast::websocket::stream<
27 boost::beast::ssl_stream<malloy::tcp::stream<>>
30 using websocket_t = std::variant<
34 boost::beast::websocket::stream<malloy::tcp::stream<>>
51 using ws_t = detail::websocket_t;
55 stream(detail::websocket_t&& ws) :
56 m_underlying_conn{ std::move(ws) }
62 m_underlying_conn{ std::move(s) }
68 stream{boost::beast::websocket::stream<malloy::tcp::stream<>>{std::move(from)}}
74 stream(detail::tls_stream&& ws) :
75 m_underlying_conn{std::move(ws)}
81 stream{malloy::websocket::detail::tls_stream{
82 boost::beast::websocket::stream<
83 boost::beast::ssl_stream<malloy::tcp::stream<>>
89 template<concepts::const_buffer_sequence Buff, detail::rw_completion_token Callback>
91 async_write(
const Buff& buffers, Callback&& done)
94 [&buffers, done = std::forward<Callback>(done)](
auto&
stream)
mutable {
95 return stream.async_write(buffers, std::forward<Callback>(done));
101 template<concepts::const_buffer_sequence Buff>
103 write(
const Buff& buffers) -> std::size_t
106 [&buffers](
auto&
stream)
mutable {
107 return stream.write(buffers);
113 template<concepts::dynamic_buffer Buff, detail::rw_completion_token Callback>
115 async_read(Buff& buff, Callback&& done)
118 [&buff, done = std::forward<Callback>(done)](
auto& s)
mutable {
119 return s.async_read(buff, std::forward<Callback>(done));
125 template<concepts::dynamic_buffer Buff>
127 read(Buff& buff, boost::beast::error_code& ec) -> std::size_t
130 [&buff, &ec](
auto& s)
mutable {
131 return s.read(buff, ec);
137 template<boost::asio::completion_token_for<
void(malloy::error_code)> CompletionToken>
139 async_close(boost::beast::websocket::close_reason why, CompletionToken&& done)
142 [why, done = std::forward<CompletionToken>(done)](
auto& s)
mutable {
143 return s.async_close(why, std::forward<CompletionToken>(done));
150 set_option(
auto&& opt)
153 [opt = std::forward<
decltype(opt)>(opt)](
auto& s)
mutable {
154 s.set_option(std::forward<
decltype(opt)>(opt));
160 template<
typename Body,
typename Fields, boost::asio::completion_token_for<
void(malloy::error_code)> CompletionHandler>
162 async_accept(
const boost::beast::http::request<Body, Fields>& req, CompletionHandler&& done)
165 [req, done = std::forward<
decltype(done)>(done)](
auto& s)
mutable {
166 return s.async_accept(req, std::forward<
decltype(done)>(done));
172 template<
typename Body,
typename Fields>
174 accept(
const boost::beast::http::request<Body, Fields>& req) -> boost::beast::error_code
178 return s.accept(req);
184 template<boost::asio::completion_token_for<
void(malloy::error_code)> Callback>
186 async_handshake(std::string host, std::string target, Callback&& done)
189 [host = std::move(host), target = std::move(target), done = std::forward<Callback>(done)](
auto& s)
mutable {
190 return s.async_handshake(host, target, std::forward<Callback>(done));
207 [enabled](
auto& s)
mutable {
242 template<
typename Func>
247 [visitor = std::forward<Func>(visitor)](
auto& s)
mutable {
248 visitor(boost::beast::get_lowest_layer(s));
264 return s.get_executor();
295#if MALLOY_FEATURE_TLS
296 return std::holds_alternative<detail::tls_stream>(m_underlying_conn);
302#if MALLOY_FEATURE_TLS
303 template<concepts::accept_handler Callback>
305 async_handshake_tls(boost::asio::ssl::stream_base::handshake_type type, Callback&& done)
308 throw std::logic_error{
"async_handshake_tls called on non-tls stream"};
311 [done = std::forward<Callback>(done), type](
auto& s)
mutable {
312 if constexpr (std::same_as<std::decay_t<
decltype(s)>, detail::tls_stream>)
313 s.next_layer().async_handshake(type, std::forward<Callback>(done));
321 ws_t m_underlying_conn;
Websocket stream. May use TLS.
Definition: stream.hpp:50
bool binary() const
Checks whether outgoing messages will be indicated as text or binary.
Definition: stream.hpp:222
void get_lowest_layer(Func &&visitor)
Access get_lowest_layer of wrapped stream type.
Definition: stream.hpp:244
void set_binary(const bool enabled)
Controls whether outgoing message will be indicated text or binary.
Definition: stream.hpp:204
bool is_open() const
Returns true if the stream is open.
Definition: stream.hpp:277
auto get_executor()
Get executor of the underlying stream.
Definition: stream.hpp:260
constexpr bool is_tls() const
Whether the underlying stream is TLS or not.
Definition: stream.hpp:293
Definition: stream.hpp:37
boost::beast::basic_stream< boost::asio::ip::tcp, boost::asio::any_io_executor, RatePolicy > stream
Definition: stream.hpp:22
Definition: connection.hpp:22
boost::beast::error_code error_code
Error code used to signify errors without throwing. Truthy means it holds an error.
Definition: error.hpp:9