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:
19     explicit WebSocketRule(const std::string& ruleIn) : BaseRule(ruleIn) {}
20 
21     void validate() override {}
22 
23     void handle(const Request& /*req*/,
24                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
25                 const std::vector<std::string>& /*params*/) override
26     {
27         asyncResp->res.result(boost::beast::http::status::not_found);
28     }
29 
30     void handleUpgrade(const Request& req,
31                        const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/,
32                        boost::asio::ip::tcp::socket&& adaptor) override
33     {
34         BMCWEB_LOG_DEBUG("Websocket handles upgrade");
35         std::shared_ptr<
36             crow::websocket::ConnectionImpl<boost::asio::ip::tcp::socket>>
37             myConnection = std::make_shared<
38                 crow::websocket::ConnectionImpl<boost::asio::ip::tcp::socket>>(
39                 req.url(), req.session, std::move(adaptor), openHandler,
40                 messageHandler, messageExHandler, closeHandler, errorHandler);
41         myConnection->start(req);
42     }
43 
44     void handleUpgrade(const Request& req,
45                        const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/,
46                        boost::asio::ssl::stream<boost::asio::ip::tcp::socket>&&
47                            adaptor) override
48     {
49         BMCWEB_LOG_DEBUG("Websocket handles upgrade");
50         std::shared_ptr<crow::websocket::ConnectionImpl<
51             boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>>
52             myConnection = std::make_shared<crow::websocket::ConnectionImpl<
53                 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>>(
54                 req.url(), req.session, std::move(adaptor), openHandler,
55                 messageHandler, messageExHandler, closeHandler, errorHandler);
56         myConnection->start(req);
57     }
58 
59     template <typename Func>
60     self_t& onopen(Func f)
61     {
62         openHandler = f;
63         return *this;
64     }
65 
66     template <typename Func>
67     self_t& onmessage(Func f)
68     {
69         messageHandler = f;
70         return *this;
71     }
72 
73     template <typename Func>
74     self_t& onmessageex(Func f)
75     {
76         messageExHandler = f;
77         return *this;
78     }
79 
80     template <typename Func>
81     self_t& onclose(Func f)
82     {
83         closeHandler = f;
84         return *this;
85     }
86 
87     template <typename Func>
88     self_t& onerror(Func f)
89     {
90         errorHandler = f;
91         return *this;
92     }
93 
94   protected:
95     std::function<void(crow::websocket::Connection&)> openHandler;
96     std::function<void(crow::websocket::Connection&, const std::string&, bool)>
97         messageHandler;
98     std::function<void(crow::websocket::Connection&, std::string_view,
99                        crow::websocket::MessageType type,
100                        std::function<void()>&& whenComplete)>
101         messageExHandler;
102     std::function<void(crow::websocket::Connection&, const std::string&)>
103         closeHandler;
104     std::function<void(crow::websocket::Connection&)> errorHandler;
105 };
106 } // namespace crow
107