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