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