Clio  develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
SslWsSession.hpp
1#pragma once
2
3#include "util/Taggable.hpp"
4#include "web/dosguard/DOSGuardInterface.hpp"
5#include "web/impl/WsBase.hpp"
6#include "web/interface/ConnectionBase.hpp"
7
8#include <boost/beast/core/flat_buffer.hpp>
9#include <boost/beast/core/stream_traits.hpp>
10#include <boost/beast/core/tcp_stream.hpp>
11#include <boost/beast/http/message.hpp>
12#include <boost/beast/http/parser.hpp>
13#include <boost/beast/http/string_body.hpp>
14#include <boost/beast/ssl.hpp>
15#include <boost/beast/ssl/ssl_stream.hpp>
16#include <boost/beast/websocket/stream.hpp>
17#include <boost/optional/optional.hpp>
18
19#include <chrono>
20#include <cstdint>
21#include <functional>
22#include <memory>
23#include <string>
24#include <utility>
25
26namespace web {
27
33template <SomeServerHandler HandlerType>
34class SslWsSession : public impl::WsBase<SslWsSession, HandlerType> {
35 using StreamType =
36 boost::beast::websocket::stream<boost::asio::ssl::stream<boost::beast::tcp_stream>>;
37 StreamType ws_;
38
39public:
52 explicit SslWsSession(
53 boost::asio::ssl::stream<boost::beast::tcp_stream>&& stream,
54 std::string ip,
55 std::reference_wrapper<util::TagDecoratorFactory const> tagFactory,
56 std::reference_wrapper<dosguard::DOSGuardInterface> dosGuard,
57 std::shared_ptr<HandlerType> const& handler,
58 boost::beast::flat_buffer&& buffer,
59 bool isAdmin,
60 std::uint32_t maxWsSendingQueueSize
61 )
62 : impl::WsBase<SslWsSession, HandlerType>(
63 ip,
64 tagFactory,
65 dosGuard,
66 handler,
67 std::move(buffer),
68 maxWsSendingQueueSize
69 )
70 , ws_(std::move(stream))
71 {
72 ConnectionBase::isAdmin_ = isAdmin; // NOLINT(cppcoreguidelines-prefer-member-initializer)
73 }
74
78 StreamType&
80 {
81 return ws_;
82 }
83};
84
90template <SomeServerHandler HandlerType>
91class SslWsUpgrader : public std::enable_shared_from_this<SslWsUpgrader<HandlerType>> {
92 using std::enable_shared_from_this<SslWsUpgrader<HandlerType>>::shared_from_this;
93
94 boost::asio::ssl::stream<boost::beast::tcp_stream> https_;
95 boost::optional<http::request_parser<http::string_body>> parser_;
96 boost::beast::flat_buffer buffer_;
97 std::string ip_;
98 std::reference_wrapper<util::TagDecoratorFactory const> tagFactory_;
99 std::reference_wrapper<dosguard::DOSGuardInterface> dosGuard_;
100 std::shared_ptr<HandlerType> const handler_;
101 http::request<http::string_body> req_;
102 bool isAdmin_;
103 std::uint32_t maxWsSendingQueueSize_;
104
105public:
120 boost::asio::ssl::stream<boost::beast::tcp_stream> stream,
121 std::string ip,
122 std::reference_wrapper<util::TagDecoratorFactory const> tagFactory,
123 std::reference_wrapper<dosguard::DOSGuardInterface> dosGuard,
124 std::shared_ptr<HandlerType> handler,
125 boost::beast::flat_buffer&& buffer,
126 http::request<http::string_body> request,
127 bool isAdmin,
128 std::uint32_t maxWsSendingQueueSize
129 )
130 : https_(std::move(stream))
131 , buffer_(std::move(buffer))
132 , ip_(std::move(ip))
133 , tagFactory_(tagFactory)
134 , dosGuard_(dosGuard)
135 , handler_(std::move(handler))
136 , req_(std::move(request))
137 , isAdmin_(isAdmin)
138 , maxWsSendingQueueSize_(maxWsSendingQueueSize)
139 {
140 }
141
142 ~SslWsUpgrader() = default;
143
147 void
149 {
150 boost::beast::get_lowest_layer(https_).expires_after(std::chrono::seconds(30));
151
152 boost::asio::dispatch(
153 https_.get_executor(),
154 boost::beast::bind_front_handler(
155 &SslWsUpgrader<HandlerType>::doUpgrade, shared_from_this()
156 )
157 );
158 }
159
160private:
161 void
162 doUpgrade()
163 {
164 parser_.emplace();
165
166 // Apply a reasonable limit to the allowed size of the body in bytes to prevent abuse.
167 static constexpr auto kMaxBodySize = 10000;
168 parser_->body_limit(kMaxBodySize);
169
170 boost::beast::get_lowest_layer(https_).expires_after(std::chrono::seconds(30));
171 onUpgrade();
172 }
173
174 void
175 onUpgrade()
176 {
177 if (!boost::beast::websocket::is_upgrade(req_))
178 return;
179
180 // Disable the timeout. The websocket::stream uses its own timeout settings.
181 boost::beast::get_lowest_layer(https_).expires_never();
182
183 std::make_shared<SslWsSession<HandlerType>>(
184 std::move(https_),
185 ip_,
186 tagFactory_,
187 dosGuard_,
188 handler_,
189 std::move(buffer_),
190 isAdmin_,
191 maxWsSendingQueueSize_
192 )
193 ->run(std::move(req_));
194 }
195};
196} // namespace web
SslWsSession(boost::asio::ssl::stream< boost::beast::tcp_stream > &&stream, std::string ip, std::reference_wrapper< util::TagDecoratorFactory const > tagFactory, std::reference_wrapper< dosguard::DOSGuardInterface > dosGuard, std::shared_ptr< HandlerType > const &handler, boost::beast::flat_buffer &&buffer, bool isAdmin, std::uint32_t maxWsSendingQueueSize)
Create a new non-secure websocket session.
Definition SslWsSession.hpp:52
StreamType & ws()
Definition SslWsSession.hpp:79
The HTTPS upgrader class, upgrade from an HTTPS session to a secure websocket session.
Definition SslWsSession.hpp:91
void run()
Initiate the upgrade.
Definition SslWsSession.hpp:148
SslWsUpgrader(boost::asio::ssl::stream< boost::beast::tcp_stream > stream, std::string ip, std::reference_wrapper< util::TagDecoratorFactory const > tagFactory, std::reference_wrapper< dosguard::DOSGuardInterface > dosGuard, std::shared_ptr< HandlerType > handler, boost::beast::flat_buffer &&buffer, http::request< http::string_body > request, bool isAdmin, std::uint32_t maxWsSendingQueueSize)
Create a new upgrader to secure websocket.
Definition SslWsSession.hpp:119
Web socket implementation. This class is the base class of the web socket session,...
Definition WsBase.hpp:57
This namespace implements the web server and related components.
Definition Types.hpp:24
bool isAdmin() const
Indicates whether the connection has admin privileges.
Definition ConnectionBase.hpp:99