From 478e9f340fe303f3171f4184f494947bf39e3dbf Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Tue, 10 Jan 2023 20:14:48 +0100 Subject: Forwarding subprotocol and target to target websocket --- websocket.h | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'websocket.h') 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 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&& 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())); } -- cgit v1.2.3