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
107template <SomeServerHandler HandlerType>
108class WsUpgrader : public std::enable_shared_from_this<WsUpgrader<HandlerType>> {
109 using std::enable_shared_from_this<WsUpgrader<HandlerType>>::shared_from_this;
110
111 boost::beast::tcp_stream http_;
112 boost::optional<http::request_parser<http::string_body>> parser_;
113 boost::beast::flat_buffer buffer_;
114 std::reference_wrapper<util::TagDecoratorFactory const> tagFactory_;
115 std::reference_wrapper<dosguard::DOSGuardInterface> dosGuard_;
116 http::request<http::string_body> req_;
117 std::string ip_;
118 std::shared_ptr<HandlerType> const handler_;
119 bool isAdmin_;
120 std::uint32_t maxWsSendingQueueSize_;
121
122public:
137 boost::beast::tcp_stream&& stream,
138 std::string ip,
139 std::reference_wrapper<util::TagDecoratorFactory const> tagFactory,
140 std::reference_wrapper<dosguard::DOSGuardInterface> dosGuard,
141 std::shared_ptr<HandlerType> const& handler,
142 boost::beast::flat_buffer&& buffer,
143 http::request<http::string_body> request,
144 bool isAdmin,
145 std::uint32_t maxWsSendingQueueSize
146 )
147 : http_(std::move(stream))
148 , buffer_(std::move(buffer))
149 , tagFactory_(tagFactory)
150 , dosGuard_(dosGuard)
151 , req_(std::move(request))
152 , ip_(std::move(ip))
153 , handler_(handler)
154 , isAdmin_(isAdmin)
155 , maxWsSendingQueueSize_(maxWsSendingQueueSize)
156 {
157 }
158
160 void
162 {
163 boost::asio::dispatch(
164 http_.get_executor(),
165 boost::beast::bind_front_handler(
166 &WsUpgrader<HandlerType>::doUpgrade, shared_from_this()
167 )
168 );
169 }
170
171private:
172 void
173 doUpgrade()
174 {
175 parser_.emplace();
176
177 static constexpr auto kMAX_BODY_SIZE = 10000;
178 parser_->body_limit(kMAX_BODY_SIZE);
179
180 boost::beast::get_lowest_layer(http_).expires_after(std::chrono::seconds(30));
181 onUpgrade();
182 }
183
184 void
185 onUpgrade()
186 {
187 if (!boost::beast::websocket::is_upgrade(req_))
188 return;
189
190 // Disable the timeout. The websocket::stream uses its own timeout settings.
191 boost::beast::get_lowest_layer(http_).expires_never();
192
193 std::make_shared<PlainWsSession<HandlerType>>(
194 http_.release_socket(),
195 ip_,
196 tagFactory_,
197 dosGuard_,
198 handler_,
199 std::move(buffer_),
200 isAdmin_,
201 maxWsSendingQueueSize_
202 )
203 ->run(std::move(req_));
204 }
205};
206
207} // 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
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:136
void run()
Initiate the upgrade.
Definition PlainWsSession.hpp:161
Web socket implementation. This class is the base class of the web socket session,...
Definition WsBase.hpp:76
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:118