1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3 #pragma once 4 5 #include "async_resp.hpp" 6 #include "baserule.hpp" 7 #include "http_request.hpp" 8 #include "http_response.hpp" 9 #include "logging.hpp" 10 #include "server_sent_event.hpp" 11 12 #include <boost/asio/ip/tcp.hpp> 13 #include <boost/asio/ssl/stream.hpp> 14 #include <boost/beast/http/status.hpp> 15 16 #include <functional> 17 #include <memory> 18 #include <string> 19 #include <utility> 20 #include <vector> 21 22 namespace crow 23 { 24 25 class SseSocketRule : public BaseRule 26 { 27 using self_t = SseSocketRule; 28 29 public: SseSocketRule(const std::string & ruleIn)30 explicit SseSocketRule(const std::string& ruleIn) : BaseRule(ruleIn) 31 { 32 isUpgrade = true; 33 // Clear GET handler 34 methodsBitfield = 0; 35 } 36 validate()37 void validate() override {} 38 handle(const Request &,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::vector<std::string> &)39 void handle(const Request& /*req*/, 40 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 41 const std::vector<std::string>& /*params*/) override 42 { 43 BMCWEB_LOG_ERROR( 44 "Handle called on websocket rule. This should never happen"); 45 asyncResp->res.result( 46 boost::beast::http::status::internal_server_error); 47 } 48 handleUpgrade(const Request & req,const std::shared_ptr<bmcweb::AsyncResp> &,boost::asio::ip::tcp::socket && adaptor)49 void handleUpgrade(const Request& req, 50 const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/, 51 boost::asio::ip::tcp::socket&& adaptor) override 52 { 53 std::shared_ptr< 54 crow::sse_socket::ConnectionImpl<boost::asio::ip::tcp::socket>> 55 myConnection = std::make_shared< 56 crow::sse_socket::ConnectionImpl<boost::asio::ip::tcp::socket>>( 57 std::move(adaptor), openHandler, closeHandler); 58 myConnection->start(req); 59 } handleUpgrade(const Request & req,const std::shared_ptr<bmcweb::AsyncResp> &,boost::asio::ssl::stream<boost::asio::ip::tcp::socket> && adaptor)60 void handleUpgrade(const Request& req, 61 const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/, 62 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>&& 63 adaptor) override 64 { 65 std::shared_ptr<crow::sse_socket::ConnectionImpl< 66 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>> 67 myConnection = std::make_shared<crow::sse_socket::ConnectionImpl< 68 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>>( 69 std::move(adaptor), openHandler, closeHandler); 70 myConnection->start(req); 71 } 72 73 template <typename Func> onopen(Func f)74 self_t& onopen(Func f) 75 { 76 openHandler = f; 77 return *this; 78 } 79 80 template <typename Func> onclose(Func f)81 self_t& onclose(Func f) 82 { 83 closeHandler = f; 84 return *this; 85 } 86 87 private: 88 std::function<void(crow::sse_socket::Connection&, const crow::Request&)> 89 openHandler; 90 std::function<void(crow::sse_socket::Connection&)> closeHandler; 91 }; 92 93 } // namespace crow 94