summaryrefslogtreecommitdiffhomepage
path: root/websocket.h
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2023-01-10 20:14:48 +0100
committerRoland Reichwein <mail@reichwein.it>2023-01-10 20:14:48 +0100
commit478e9f340fe303f3171f4184f494947bf39e3dbf (patch)
tree79d80ef1b0ebc3fe0d667db7c2d80c246fddaa5c /websocket.h
parentd02a29f0ff33279268e675aae0856f3f8cf9d939 (diff)
Forwarding subprotocol and target to target websocket
Diffstat (limited to 'websocket.h')
-rw-r--r--websocket.h38
1 files changed, 32 insertions, 6 deletions
diff --git a/websocket.h b/websocket.h
index 85492f2..951155e 100644
--- a/websocket.h
+++ b/websocket.h
@@ -47,6 +47,8 @@ class websocket_session: public std::enable_shared_from_this<websocket_session>
boost::beast::flat_buffer buffer_out_;
std::string host_;
std::string port_;
+ std::string subprotocol_;
+ std::string relative_target_;
public:
explicit websocket_session(boost::asio::io_context& ioc, beast::ssl_stream<beast::tcp_stream>&& stream, const std::string& websocket_address):
@@ -55,17 +57,32 @@ public:
ws_in_(std::move(stream)),
ws_app_(boost::asio::make_strand(ioc_)),
host_{},
- port_{}
+ port_{},
+ subprotocol_{},
+ relative_target_{}
{
// Parse websocket address host:port :
- auto pos{websocket_address.find_last_of(':')};
+ auto colon_pos{websocket_address.find_last_of(':')};
- if (pos == std::string::npos)
+ if (colon_pos == std::string::npos) {
+ std::cerr << "Warning: Bad websocket address (colon missing): " << websocket_address << std::endl;
return;
+ }
+
+ auto slash_pos{websocket_address.find('/')};
+ if (slash_pos == std::string::npos) {
+ std::cerr << "Warning: Bad websocket address (slash missing): " << websocket_address << std::endl;
+ return;
+ }
+ if (slash_pos <= colon_pos) {
+ std::cerr << "Warning: Bad websocket address: " << websocket_address << std::endl;
+ return;
+ }
- host_ = websocket_address.substr(0, pos);
- port_ = websocket_address.substr(pos + 1);
+ host_ = websocket_address.substr(0, colon_pos);
+ port_ = websocket_address.substr(colon_pos + 1, slash_pos - (colon_pos + 1));
+ relative_target_ = websocket_address.substr(slash_pos);
}
//
@@ -89,6 +106,9 @@ public:
std::string{"Reichwein.IT Webserver"});
}));
+ // Forward subprotocol from request to target websocket
+ subprotocol_ = std::string{req[http::field::sec_websocket_protocol]};
+
// Accept the websocket handshake
ws_in_.async_accept(
req,
@@ -135,8 +155,14 @@ private:
{
req.set(boost::beast::http::field::user_agent, "Reichwein.IT Webserver Websocket client");
}));
+
+ ws_app_.set_option(boost::beast::websocket::stream_base::decorator(
+ [this](boost::beast::websocket::request_type& req)
+ {
+ req.set(boost::beast::http::field::sec_websocket_protocol, subprotocol_);
+ }));
- ws_app_.async_handshake(host_, "/",
+ ws_app_.async_handshake(host_, relative_target_,
beast::bind_front_handler(&websocket_session::on_handshake_app, shared_from_this()));
}