Clio develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
PlainWsSession.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/asio/ip/tcp.hpp>
28#include <boost/beast/core/flat_buffer.hpp>
29#include <boost/beast/core/stream_traits.hpp>
30#include <boost/beast/core/tcp_stream.hpp>
31#include <boost/beast/http/message.hpp>
32#include <boost/beast/http/parser.hpp>
33#include <boost/beast/http/string_body.hpp>
34#include <boost/beast/websocket/stream.hpp>
35#include <boost/optional/optional.hpp>
36
37#include <chrono>
38#include <functional>
39#include <memory>
40#include <string>
41#include <utility>
42
43namespace web {
44
50template <SomeServerHandler HandlerType>
51class PlainWsSession : public impl::WsBase<PlainWsSession, HandlerType> {
52 using StreamType = boost::beast::websocket::stream<boost::beast::tcp_stream>;
53 StreamType ws_;
54
55public:
69 boost::asio::ip::tcp::socket&& socket,
70 std::string ip,
71 std::reference_wrapper<util::TagDecoratorFactory const> tagFactory,
72 std::reference_wrapper<dosguard::DOSGuardInterface> dosGuard,
73 std::shared_ptr<HandlerType> const& handler,
74 boost::beast::flat_buffer&& buffer,
75 bool isAdmin,
76 std::uint32_t maxSendingQueueSize
77 )
78 : impl::WsBase<PlainWsSession, HandlerType>(
79 ip,
80 tagFactory,
81 dosGuard,
82 handler,
83 std::move(buffer),
84 maxSendingQueueSize
85 )
86 , ws_(std::move(socket))
87 {
88 ConnectionBase::isAdmin_ = isAdmin; // NOLINT(cppcoreguidelines-prefer-member-initializer)
89 }
90
91 ~PlainWsSession() override = default;
92
94 StreamType&
96 {
97 return ws_;
98 }
99};
100
106template <SomeServerHandler HandlerType>
107class WsUpgrader : public std::enable_shared_from_this<WsUpgrader<HandlerType>> {
108 using std::enable_shared_from_this<WsUpgrader<HandlerType>>::shared_from_this;
109
110 boost::beast::tcp_stream http_;
111 boost::optional<http::request_parser<http::string_body>> parser_;
112 boost::beast::flat_buffer buffer_;
113 std::reference_wrapper<util::TagDecoratorFactory const> tagFactory_;
114 std::reference_wrapper<dosguard::DOSGuardInterface> dosGuard_;
115 http::request<http::string_body> req_;
116 std::string ip_;
117 std::shared_ptr<HandlerType> const handler_;
118 bool isAdmin_;
119 std::uint32_t maxWsSendingQueueSize_;
120
121public:
136 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> const& handler,
141 boost::beast::flat_buffer&& buffer,
142 http::request<http::string_body> request,
143 bool isAdmin,
144 std::uint32_t maxWsSendingQueueSize
145 )
146 : http_(std::move(stream))
147 , buffer_(std::move(buffer))
148 , tagFactory_(tagFactory)
149 , dosGuard_(dosGuard)
150 , req_(std::move(request))
151 , ip_(std::move(ip))
152 , handler_(handler)
153 , isAdmin_(isAdmin)
154 , maxWsSendingQueueSize_(maxWsSendingQueueSize)
155 {
156 }
157
159 void
161 {
162 boost::asio::dispatch(
163 http_.get_executor(),
164 boost::beast::bind_front_handler(&WsUpgrader<HandlerType>::doUpgrade, shared_from_this())
165 );
166 }
167
168private:
169 void
170 doUpgrade()
171 {
172 parser_.emplace();
173
174 static constexpr auto kMAX_BODY_SIZE = 10000;
175 parser_->body_limit(kMAX_BODY_SIZE);
176
177 boost::beast::get_lowest_layer(http_).expires_after(std::chrono::seconds(30));
178 onUpgrade();
179 }
180
181 void
182 onUpgrade()
183 {
184 if (!boost::beast::websocket::is_upgrade(req_))
185 return;
186
187 // Disable the timeout. The websocket::stream uses its own timeout settings.
188 boost::beast::get_lowest_layer(http_).expires_never();
189
190 std::make_shared<PlainWsSession<HandlerType>>(
191 http_.release_socket(),
192 ip_,
193 tagFactory_,
194 dosGuard_,
195 handler_,
196 std::move(buffer_),
197 isAdmin_,
198 maxWsSendingQueueSize_
199 )
200 ->run(std::move(req_));
201 }
202};
203
204} // namespace web
Represents a non-secure websocket session.
Definition PlainWsSession.hpp:51
PlainWsSession(boost::asio::ip::tcp::socket &&socket, 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 maxSendingQueueSize)
Create a new non-secure websocket session.
Definition PlainWsSession.hpp:68
StreamType & ws()
Definition PlainWsSession.hpp:95
The websocket upgrader class, upgrade from an HTTP session to a non-secure websocket session.
Definition PlainWsSession.hpp:107
WsUpgrader(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, http::request< http::string_body > request, bool isAdmin, std::uint32_t maxWsSendingQueueSize)
Create a new upgrader to non-secure websocket.
Definition PlainWsSession.hpp:135
void run()
Initiate the upgrade.
Definition PlainWsSession.hpp:160
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