rippled
Loading...
Searching...
No Matches
SSLHTTPPeer.h
1#ifndef XRPL_SERVER_SSLHTTPPEER_H_INCLUDED
2#define XRPL_SERVER_SSLHTTPPEER_H_INCLUDED
3
4#include <xrpl/server/detail/BaseHTTPPeer.h>
5#include <xrpl/server/detail/SSLWSPeer.h>
6
7#include <boost/asio/ip/tcp.hpp>
8#include <boost/asio/ssl/context.hpp>
9#include <boost/asio/ssl/stream.hpp>
10#include <boost/beast/core/tcp_stream.hpp>
11#include <boost/beast/ssl/ssl_stream.hpp>
12
13#include <memory>
14
15namespace ripple {
16
17template <class Handler>
18class SSLHTTPPeer : public BaseHTTPPeer<Handler, SSLHTTPPeer<Handler>>,
19 public std::enable_shared_from_this<SSLHTTPPeer<Handler>>
20{
21private:
22 friend class BaseHTTPPeer<Handler, SSLHTTPPeer>;
23 using socket_type = boost::asio::ip::tcp::socket;
24 using middle_type = boost::beast::tcp_stream;
25 using stream_type = boost::beast::ssl_stream<middle_type>;
26 using endpoint_type = boost::asio::ip::tcp::endpoint;
27 using yield_context = boost::asio::yield_context;
28 using error_code = boost::system::error_code;
29
33
34public:
35 template <class ConstBufferSequence>
37 Port const& port,
38 Handler& handler,
39 boost::asio::io_context& ioc,
41 endpoint_type remote_address,
42 ConstBufferSequence const& buffers,
43 middle_type&& stream);
44
45 void
46 run();
47
49 websocketUpgrade() override;
50
51private:
52 void
54
55 void
56 do_request() override;
57
58 void
59 do_close() override;
60
61 void
63};
64
65//------------------------------------------------------------------------------
66
67template <class Handler>
68template <class ConstBufferSequence>
70 Port const& port,
71 Handler& handler,
72 boost::asio::io_context& ioc,
73 beast::Journal journal,
74 endpoint_type remote_address,
75 ConstBufferSequence const& buffers,
76 middle_type&& stream)
77 : BaseHTTPPeer<Handler, SSLHTTPPeer>(
78 port,
79 handler,
80 ioc.get_executor(),
81 journal,
82 remote_address,
83 buffers)
84 , stream_ptr_(std::make_unique<stream_type>(
85 middle_type(std::move(stream)),
86 *port.context))
87 , stream_(*stream_ptr_)
88 , socket_(stream_.next_layer().socket())
89{
90}
91
92// Called when the acceptor accepts our socket.
93template <class Handler>
94void
96{
97 if (!this->handler_.onAccept(this->session(), this->remote_address_))
98 {
100 this->strand_,
101 std::bind(&SSLHTTPPeer::do_close, this->shared_from_this()));
102 return;
103 }
104 if (!socket_.is_open())
105 return;
107 this->strand_,
108 std::bind(
110 this->shared_from_this(),
111 std::placeholders::_1));
112}
113
114template <class Handler>
117{
118 auto ws = this->ios().template emplace<SSLWSPeer<Handler>>(
119 this->port_,
120 this->handler_,
121 this->remote_address_,
122 std::move(this->message_),
123 std::move(this->stream_ptr_),
124 this->journal_);
125 return ws;
126}
127
128template <class Handler>
129void
131{
132 boost::system::error_code ec;
133 stream_.set_verify_mode(boost::asio::ssl::verify_none);
134 this->start_timer();
135 this->read_buf_.consume(stream_.async_handshake(
136 stream_type::server, this->read_buf_.data(), do_yield[ec]));
137 this->cancel_timer();
138 if (ec == boost::beast::error::timeout)
139 return this->on_timer();
140 if (ec)
141 return this->fail(ec, "handshake");
142 bool const http = this->port().protocol.count("peer") > 0 ||
143 this->port().protocol.count("wss") > 0 ||
144 this->port().protocol.count("wss2") > 0 ||
145 this->port().protocol.count("https") > 0;
146 if (http)
147 {
149 this->strand_,
150 std::bind(
152 this->shared_from_this(),
153 std::placeholders::_1));
154 return;
155 }
156 // `this` will be destroyed
157}
158
159template <class Handler>
160void
162{
163 ++this->request_count_;
164 auto const what = this->handler_.onHandoff(
165 this->session(),
166 std::move(stream_ptr_),
167 std::move(this->message_),
168 this->remote_address_);
169 if (what.moved)
170 return;
171 if (what.response)
172 return this->write(what.response, what.keep_alive);
173 // legacy
174 this->handler_.onRequest(this->session());
175}
176
177template <class Handler>
178void
180{
181 this->start_timer();
182 stream_.async_shutdown(bind_executor(
183 this->strand_,
184 std::bind(
186 this->shared_from_this(),
187 std::placeholders::_1)));
188}
189
190template <class Handler>
191void
193{
194 this->cancel_timer();
195
196 if (ec == boost::asio::error::operation_aborted)
197 return;
198 if (ec)
199 {
200 JLOG(this->journal_.debug()) << "on_shutdown: " << ec.message();
201 }
202
203 // Close socket now in case this->destructor is delayed
204 stream_.next_layer().close();
205}
206
207} // namespace ripple
208
209#endif
T bind(T... args)
A generic endpoint for log messages.
Definition Journal.h:41
Represents an active connection.
boost::asio::ip::tcp::socket socket_type
Definition SSLHTTPPeer.h:23
stream_type & stream_
Definition SSLHTTPPeer.h:31
void do_request() override
std::unique_ptr< stream_type > stream_ptr_
Definition SSLHTTPPeer.h:30
std::shared_ptr< WSSession > websocketUpgrade() override
Convert the connection to WebSocket.
void on_shutdown(error_code ec)
boost::system::error_code error_code
Definition SSLHTTPPeer.h:28
void do_close() override
SSLHTTPPeer(Port const &port, Handler &handler, boost::asio::io_context &ioc, beast::Journal journal, endpoint_type remote_address, ConstBufferSequence const &buffers, middle_type &&stream)
Definition SSLHTTPPeer.h:69
boost::asio::ip::tcp::endpoint endpoint_type
Definition SSLHTTPPeer.h:26
boost::asio::yield_context yield_context
Definition SSLHTTPPeer.h:27
void do_handshake(yield_context do_yield)
socket_type & socket_
Definition SSLHTTPPeer.h:32
boost::beast::ssl_stream< middle_type > stream_type
Definition SSLHTTPPeer.h:25
boost::beast::tcp_stream middle_type
Definition SSLHTTPPeer.h:24
void spawn(Ctx &&ctx, F &&func)
Spawns a coroutine using boost::asio::spawn
Definition Spawn.h:68
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
STL namespace.
Configuration information for a Server listening port.
Definition Port.h:31