blob: 03410221fb3ac0c6fcb65b825c1242b8d5be1df5 [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
Ed Tanous08bbe112023-04-06 13:10:02 -07003#pragma once
4
Ed Tanousd7857202025-01-28 15:32:26 -08005#include "async_resp.hpp"
Ed Tanous08bbe112023-04-06 13:10:02 -07006#include "baserule.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -08007#include "http_request.hpp"
8#include "logging.hpp"
Ed Tanous08bbe112023-04-06 13:10:02 -07009#include "websocket.hpp"
10
Ed Tanousd7857202025-01-28 15:32:26 -080011#include <boost/asio/ip/tcp.hpp>
12#include <boost/asio/ssl/stream.hpp>
13#include <boost/beast/http/status.hpp>
Ed Tanous08bbe112023-04-06 13:10:02 -070014
Ed Tanousd7857202025-01-28 15:32:26 -080015#include <functional>
Ed Tanous08bbe112023-04-06 13:10:02 -070016#include <memory>
17#include <string>
Ed Tanousd7857202025-01-28 15:32:26 -080018#include <string_view>
19#include <utility>
Ed Tanous08bbe112023-04-06 13:10:02 -070020#include <vector>
21
22namespace crow
23{
24class WebSocketRule : public BaseRule
25{
26 using self_t = WebSocketRule;
27
28 public:
Ed Tanousa3b9eb92024-06-03 08:39:37 -070029 explicit WebSocketRule(const std::string& ruleIn) : BaseRule(ruleIn)
30 {
31 isUpgrade = true;
32 // Clear GET handler
33 methodsBitfield = 0;
34 }
Ed Tanous08bbe112023-04-06 13:10:02 -070035
36 void validate() override {}
37
38 void handle(const Request& /*req*/,
39 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
40 const std::vector<std::string>& /*params*/) override
41 {
Ed Tanousa3b9eb92024-06-03 08:39:37 -070042 BMCWEB_LOG_ERROR(
43 "Handle called on websocket rule. This should never happen");
44 asyncResp->res.result(
45 boost::beast::http::status::internal_server_error);
Ed Tanous08bbe112023-04-06 13:10:02 -070046 }
47
Ed Tanous08bbe112023-04-06 13:10:02 -070048 void handleUpgrade(const Request& req,
49 const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/,
50 boost::asio::ip::tcp::socket&& adaptor) override
51 {
Ed Tanous62598e32023-07-17 17:06:25 -070052 BMCWEB_LOG_DEBUG("Websocket handles upgrade");
Ed Tanous08bbe112023-04-06 13:10:02 -070053 std::shared_ptr<
54 crow::websocket::ConnectionImpl<boost::asio::ip::tcp::socket>>
55 myConnection = std::make_shared<
56 crow::websocket::ConnectionImpl<boost::asio::ip::tcp::socket>>(
Ed Tanous5ebb9d32023-02-27 18:20:47 -080057 req.url(), req.session, std::move(adaptor), openHandler,
58 messageHandler, messageExHandler, closeHandler, errorHandler);
59 myConnection->start(req);
Ed Tanous08bbe112023-04-06 13:10:02 -070060 }
Ed Tanous8db83742024-04-13 09:11:15 -070061
Ed Tanous08bbe112023-04-06 13:10:02 -070062 void handleUpgrade(const Request& req,
63 const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/,
Ed Tanous003301a2024-04-16 09:59:19 -070064 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>&&
Ed Tanous08bbe112023-04-06 13:10:02 -070065 adaptor) override
66 {
Ed Tanous62598e32023-07-17 17:06:25 -070067 BMCWEB_LOG_DEBUG("Websocket handles upgrade");
Ed Tanous08bbe112023-04-06 13:10:02 -070068 std::shared_ptr<crow::websocket::ConnectionImpl<
Ed Tanous003301a2024-04-16 09:59:19 -070069 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>>
Ed Tanous08bbe112023-04-06 13:10:02 -070070 myConnection = std::make_shared<crow::websocket::ConnectionImpl<
Ed Tanous003301a2024-04-16 09:59:19 -070071 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>>(
Ed Tanous5ebb9d32023-02-27 18:20:47 -080072 req.url(), req.session, std::move(adaptor), openHandler,
73 messageHandler, messageExHandler, closeHandler, errorHandler);
74 myConnection->start(req);
Ed Tanous08bbe112023-04-06 13:10:02 -070075 }
Ed Tanous08bbe112023-04-06 13:10:02 -070076
77 template <typename Func>
78 self_t& onopen(Func f)
79 {
80 openHandler = f;
81 return *this;
82 }
83
84 template <typename Func>
85 self_t& onmessage(Func f)
86 {
87 messageHandler = f;
88 return *this;
89 }
90
91 template <typename Func>
92 self_t& onmessageex(Func f)
93 {
94 messageExHandler = f;
95 return *this;
96 }
97
98 template <typename Func>
99 self_t& onclose(Func f)
100 {
101 closeHandler = f;
102 return *this;
103 }
104
105 template <typename Func>
106 self_t& onerror(Func f)
107 {
108 errorHandler = f;
109 return *this;
110 }
111
112 protected:
113 std::function<void(crow::websocket::Connection&)> openHandler;
114 std::function<void(crow::websocket::Connection&, const std::string&, bool)>
115 messageHandler;
116 std::function<void(crow::websocket::Connection&, std::string_view,
117 crow::websocket::MessageType type,
118 std::function<void()>&& whenComplete)>
119 messageExHandler;
120 std::function<void(crow::websocket::Connection&, const std::string&)>
121 closeHandler;
122 std::function<void(crow::websocket::Connection&)> errorHandler;
123};
124} // namespace crow