xref: /openbmc/bmcweb/http/routing/websocketrule.hpp (revision 40e9b92ec19acffb46f83a6e55b18974da5d708e)
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