1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3 #pragma once 4 5 #include "baserule.hpp" 6 #include "websocket.hpp" 7 8 #include <boost/beast/http/verb.hpp> 9 10 #include <memory> 11 #include <string> 12 #include <vector> 13 14 namespace crow 15 { 16 class WebSocketRule : public BaseRule 17 { 18 using self_t = WebSocketRule; 19 20 public: 21 explicit WebSocketRule(const std::string& ruleIn) : BaseRule(ruleIn) 22 { 23 isUpgrade = true; 24 // Clear GET handler 25 methodsBitfield = 0; 26 } 27 28 void validate() override {} 29 30 void handle(const Request& /*req*/, 31 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 32 const std::vector<std::string>& /*params*/) override 33 { 34 BMCWEB_LOG_ERROR( 35 "Handle called on websocket rule. This should never happen"); 36 asyncResp->res.result( 37 boost::beast::http::status::internal_server_error); 38 } 39 40 void handleUpgrade(const Request& req, 41 const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/, 42 boost::asio::ip::tcp::socket&& adaptor) override 43 { 44 BMCWEB_LOG_DEBUG("Websocket handles upgrade"); 45 std::shared_ptr< 46 crow::websocket::ConnectionImpl<boost::asio::ip::tcp::socket>> 47 myConnection = std::make_shared< 48 crow::websocket::ConnectionImpl<boost::asio::ip::tcp::socket>>( 49 req.url(), req.session, std::move(adaptor), openHandler, 50 messageHandler, messageExHandler, closeHandler, errorHandler); 51 myConnection->start(req); 52 } 53 54 void handleUpgrade(const Request& req, 55 const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/, 56 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>&& 57 adaptor) override 58 { 59 BMCWEB_LOG_DEBUG("Websocket handles upgrade"); 60 std::shared_ptr<crow::websocket::ConnectionImpl< 61 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>> 62 myConnection = std::make_shared<crow::websocket::ConnectionImpl< 63 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>>( 64 req.url(), req.session, std::move(adaptor), openHandler, 65 messageHandler, messageExHandler, closeHandler, errorHandler); 66 myConnection->start(req); 67 } 68 69 template <typename Func> 70 self_t& onopen(Func f) 71 { 72 openHandler = f; 73 return *this; 74 } 75 76 template <typename Func> 77 self_t& onmessage(Func f) 78 { 79 messageHandler = f; 80 return *this; 81 } 82 83 template <typename Func> 84 self_t& onmessageex(Func f) 85 { 86 messageExHandler = f; 87 return *this; 88 } 89 90 template <typename Func> 91 self_t& onclose(Func f) 92 { 93 closeHandler = f; 94 return *this; 95 } 96 97 template <typename Func> 98 self_t& onerror(Func f) 99 { 100 errorHandler = f; 101 return *this; 102 } 103 104 protected: 105 std::function<void(crow::websocket::Connection&)> openHandler; 106 std::function<void(crow::websocket::Connection&, const std::string&, bool)> 107 messageHandler; 108 std::function<void(crow::websocket::Connection&, std::string_view, 109 crow::websocket::MessageType type, 110 std::function<void()>&& whenComplete)> 111 messageExHandler; 112 std::function<void(crow::websocket::Connection&, const std::string&)> 113 closeHandler; 114 std::function<void(crow::websocket::Connection&)> errorHandler; 115 }; 116 } // namespace crow 117