Clio develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
SslHttpSession.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/AdminVerificationStrategy.hpp"
24#include "web/ProxyIpResolver.hpp"
25#include "web/SslWsSession.hpp"
26#include "web/dosguard/DOSGuardInterface.hpp"
27#include "web/impl/HttpBase.hpp"
28#include "web/interface/Concepts.hpp"
29#include "web/interface/ConnectionBase.hpp"
30
31#include <boost/asio/ip/tcp.hpp>
32#include <boost/asio/ssl/context.hpp>
33#include <boost/asio/ssl/stream_base.hpp>
34#include <boost/beast/core/error.hpp>
35#include <boost/beast/core/flat_buffer.hpp>
36#include <boost/beast/core/stream_traits.hpp>
37#include <boost/beast/core/tcp_stream.hpp>
38#include <boost/beast/ssl/ssl_stream.hpp>
39
40#include <chrono>
41#include <cstddef>
42#include <cstdint>
43#include <functional>
44#include <memory>
45#include <string>
46#include <utility>
47
48namespace web {
49
50using tcp = boost::asio::ip::tcp;
51
60template <SomeServerHandler HandlerType>
61class SslHttpSession : public impl::HttpBase<SslHttpSession, HandlerType>,
62 public std::enable_shared_from_this<SslHttpSession<HandlerType>> {
63 boost::beast::ssl_stream<boost::beast::tcp_stream> stream_;
64 std::reference_wrapper<util::TagDecoratorFactory const> tagFactory_;
65 std::uint32_t maxWsSendingQueueSize_;
66
67public:
83 tcp::socket&& socket,
84 std::string const& ip,
85 std::shared_ptr<AdminVerificationStrategy> const& adminVerification,
86 std::shared_ptr<ProxyIpResolver> proxyIpResolver,
87 boost::asio::ssl::context& ctx,
88 std::reference_wrapper<util::TagDecoratorFactory const> tagFactory,
89 std::reference_wrapper<dosguard::DOSGuardInterface> dosGuard,
90 std::shared_ptr<HandlerType> const& handler,
91 boost::beast::flat_buffer buffer,
92 std::uint32_t maxWsSendingQueueSize
93 )
94 : impl::HttpBase<SslHttpSession, HandlerType>(
95 ip,
96 tagFactory,
97 adminVerification,
98 std::move(proxyIpResolver),
99 dosGuard,
100 handler,
101 std::move(buffer)
102 )
103 , stream_(std::move(socket), ctx)
104 , tagFactory_(tagFactory)
105 , maxWsSendingQueueSize_(maxWsSendingQueueSize)
106 {
107 }
108
109 ~SslHttpSession() override = default;
110
112 boost::beast::ssl_stream<boost::beast::tcp_stream>&
114 {
115 return stream_;
116 }
117
119 void
121 {
122 auto self = this->shared_from_this();
123 boost::asio::dispatch(stream_.get_executor(), [self]() {
124 // Set the timeout.
125 boost::beast::get_lowest_layer(self->stream()).expires_after(std::chrono::seconds(30));
126
127 // Perform the SSL handshake
128 // Note, this is the buffered version of the handshake.
129 self->stream_.async_handshake(
130 boost::asio::ssl::stream_base::server,
131 self->buffer_.data(),
132 boost::beast::bind_front_handler(&SslHttpSession<HandlerType>::onHandshake, self)
133 );
134 });
135 }
136
143 void
144 onHandshake(boost::beast::error_code ec, std::size_t bytesUsed)
145 {
146 if (ec)
147 return this->httpFail(ec, "handshake");
148
149 this->buffer_.consume(bytesUsed);
150 this->doRead();
151 }
152
154 void
156 {
157 boost::beast::get_lowest_layer(stream_).expires_after(std::chrono::seconds(30));
158 stream_.async_shutdown(boost::beast::bind_front_handler(&SslHttpSession::onShutdown, this->shared_from_this()));
159 }
160
166 void
167 onShutdown(boost::beast::error_code ec)
168 {
169 if (ec)
170 return this->httpFail(ec, "shutdown");
171 // At this point the connection is closed gracefully
172 }
173
175 void
177 {
178 std::make_shared<SslWsUpgrader<HandlerType>>(
179 std::move(stream_),
180 this->clientIp_,
181 tagFactory_,
182 this->dosGuard_,
183 this->handler_,
184 std::move(this->buffer_),
185 std::move(this->req_),
187 maxWsSendingQueueSize_
188 )
189 ->run();
190 }
191};
192} // namespace web
Represents a HTTPS connection established by a client.
Definition SslHttpSession.hpp:62
void upgrade()
Upgrades connection to secure websocket.
Definition SslHttpSession.hpp:176
void run()
Initiates the handshake.
Definition SslHttpSession.hpp:120
void onShutdown(boost::beast::error_code ec)
Handles a connection shutdown.
Definition SslHttpSession.hpp:167
void doClose()
Closes the underlying connection.
Definition SslHttpSession.hpp:155
SslHttpSession(tcp::socket &&socket, std::string const &ip, std::shared_ptr< AdminVerificationStrategy > const &adminVerification, std::shared_ptr< ProxyIpResolver > proxyIpResolver, boost::asio::ssl::context &ctx, std::reference_wrapper< util::TagDecoratorFactory const > tagFactory, std::reference_wrapper< dosguard::DOSGuardInterface > dosGuard, std::shared_ptr< HandlerType > const &handler, boost::beast::flat_buffer buffer, std::uint32_t maxWsSendingQueueSize)
Create a new SSL session.
Definition SslHttpSession.hpp:82
boost::beast::ssl_stream< boost::beast::tcp_stream > & stream()
Definition SslHttpSession.hpp:113
void onHandshake(boost::beast::error_code ec, std::size_t bytesUsed)
Handles the handshake.
Definition SslHttpSession.hpp:144
This is the implementation class for http sessions.
Definition HttpBase.hpp:83
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