Clio develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
SslWsSession.hpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of clio: https://github.com/XRPLF/clio
4 Copyright (c) 2023, the clio developers.
5
6 Permission to use, copy, modify, and distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#pragma once
21
22#include "util/Taggable.hpp"
23#include "web/dosguard/DOSGuardInterface.hpp"
24#include "web/impl/WsBase.hpp"
25#include "web/interface/ConnectionBase.hpp"
26
27#include <boost/beast/core/flat_buffer.hpp>
28#include <boost/beast/core/stream_traits.hpp>
29#include <boost/beast/core/tcp_stream.hpp>
30#include <boost/beast/http/message.hpp>
31#include <boost/beast/http/parser.hpp>
32#include <boost/beast/http/string_body.hpp>
33#include <boost/beast/ssl.hpp>
34#include <boost/beast/ssl/ssl_stream.hpp>
35#include <boost/beast/websocket/stream.hpp>
36#include <boost/optional/optional.hpp>
37
38#include <chrono>
39#include <cstdint>
40#include <functional>
41#include <memory>
42#include <string>
43#include <utility>
44
45namespace web {
46
52template <SomeServerHandler HandlerType>
53class SslWsSession : public impl::WsBase<SslWsSession, HandlerType> {
54 using StreamType = boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::tcp_stream>>;
55 StreamType ws_;
56
57public:
70 explicit SslWsSession(
71 boost::beast::ssl_stream<boost::beast::tcp_stream>&& stream,
72 std::string ip,
73 std::reference_wrapper<util::TagDecoratorFactory const> tagFactory,
74 std::reference_wrapper<dosguard::DOSGuardInterface> dosGuard,
75 std::shared_ptr<HandlerType> const& handler,
76 boost::beast::flat_buffer&& buffer,
77 bool isAdmin,
78 std::uint32_t maxWsSendingQueueSize
79 )
80 : impl::WsBase<SslWsSession, HandlerType>(
81 ip,
82 tagFactory,
83 dosGuard,
84 handler,
85 std::move(buffer),
86 maxWsSendingQueueSize
87 )
88 , ws_(std::move(stream))
89 {
90 ConnectionBase::isAdmin_ = isAdmin; // NOLINT(cppcoreguidelines-prefer-member-initializer)
91 }
92
94 StreamType&
96 {
97 return ws_;
98 }
99};
100
106template <SomeServerHandler HandlerType>
107class SslWsUpgrader : public std::enable_shared_from_this<SslWsUpgrader<HandlerType>> {
108 using std::enable_shared_from_this<SslWsUpgrader<HandlerType>>::shared_from_this;
109
110 boost::beast::ssl_stream<boost::beast::tcp_stream> https_;
111 boost::optional<http::request_parser<http::string_body>> parser_;
112 boost::beast::flat_buffer buffer_;
113 std::string ip_;
114 std::reference_wrapper<util::TagDecoratorFactory const> tagFactory_;
115 std::reference_wrapper<dosguard::DOSGuardInterface> dosGuard_;
116 std::shared_ptr<HandlerType> const handler_;
117 http::request<http::string_body> req_;
118 bool isAdmin_;
119 std::uint32_t maxWsSendingQueueSize_;
120
121public:
136 boost::beast::ssl_stream<boost::beast::tcp_stream> stream,
137 std::string ip,
138 std::reference_wrapper<util::TagDecoratorFactory const> tagFactory,
139 std::reference_wrapper<dosguard::DOSGuardInterface> dosGuard,
140 std::shared_ptr<HandlerType> handler,
141 boost::beast::flat_buffer&& buffer,
142 http::request<http::string_body> request,
143 bool isAdmin,
144 std::uint32_t maxWsSendingQueueSize
145 )
146 : https_(std::move(stream))
147 , buffer_(std::move(buffer))
148 , ip_(std::move(ip))
149 , tagFactory_(tagFactory)
150 , dosGuard_(dosGuard)
151 , handler_(std::move(handler))
152 , req_(std::move(request))
153 , isAdmin_(isAdmin)
154 , maxWsSendingQueueSize_(maxWsSendingQueueSize)
155 {
156 }
157
158 ~SslWsUpgrader() = default;
159
161 void
163 {
164 boost::beast::get_lowest_layer(https_).expires_after(std::chrono::seconds(30));
165
166 boost::asio::dispatch(
167 https_.get_executor(),
168 boost::beast::bind_front_handler(&SslWsUpgrader<HandlerType>::doUpgrade, shared_from_this())
169 );
170 }
171
172private:
173 void
174 doUpgrade()
175 {
176 parser_.emplace();
177
178 // Apply a reasonable limit to the allowed size of the body in bytes to prevent abuse.
179 static constexpr auto kMAX_BODY_SIZE = 10000;
180 parser_->body_limit(kMAX_BODY_SIZE);
181
182 boost::beast::get_lowest_layer(https_).expires_after(std::chrono::seconds(30));
183 onUpgrade();
184 }
185
186 void
187 onUpgrade()
188 {
189 if (!boost::beast::websocket::is_upgrade(req_))
190 return;
191
192 // Disable the timeout. The websocket::stream uses its own timeout settings.
193 boost::beast::get_lowest_layer(https_).expires_never();
194
195 std::make_shared<SslWsSession<HandlerType>>(
196 std::move(https_),
197 ip_,
198 tagFactory_,
199 dosGuard_,
200 handler_,
201 std::move(buffer_),
202 isAdmin_,
203 maxWsSendingQueueSize_
204 )
205 ->run(std::move(req_));
206 }
207};
208} // namespace web
Represents a secure websocket session.
Definition SslWsSession.hpp:53
SslWsSession(boost::beast::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:70
StreamType & ws()
Definition SslWsSession.hpp:95
The HTTPS upgrader class, upgrade from an HTTPS session to a secure websocket session.
Definition SslWsSession.hpp:107
void run()
Initiate the upgrade.
Definition SslWsSession.hpp:162
SslWsUpgrader(boost::beast::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:135
Web socket implementation. This class is the base class of the web socket session,...
Definition WsBase.hpp:75
This namespace implements the web server and related components.
Definition Types.hpp:43
bool isAdmin() const
Indicates whether the connection has admin privileges.
Definition ConnectionBase.hpp:111