rippled
Loading...
Searching...
No Matches
SSLHTTPPeer.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or 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#ifndef RIPPLE_SERVER_SSLHTTPPEER_H_INCLUDED
21#define RIPPLE_SERVER_SSLHTTPPEER_H_INCLUDED
22
23#include <xrpl/server/detail/BaseHTTPPeer.h>
24#include <xrpl/server/detail/SSLWSPeer.h>
25
26#include <boost/asio/ip/tcp.hpp>
27#include <boost/asio/ssl/context.hpp>
28#include <boost/asio/ssl/stream.hpp>
29#include <boost/beast/core/tcp_stream.hpp>
30#include <boost/beast/ssl/ssl_stream.hpp>
31
32#include <memory>
33
34namespace ripple {
35
36template <class Handler>
37class SSLHTTPPeer : public BaseHTTPPeer<Handler, SSLHTTPPeer<Handler>>,
38 public std::enable_shared_from_this<SSLHTTPPeer<Handler>>
39{
40private:
41 friend class BaseHTTPPeer<Handler, SSLHTTPPeer>;
42 using socket_type = boost::asio::ip::tcp::socket;
43 using middle_type = boost::beast::tcp_stream;
44 using stream_type = boost::beast::ssl_stream<middle_type>;
45 using endpoint_type = boost::asio::ip::tcp::endpoint;
46 using yield_context = boost::asio::yield_context;
47 using error_code = boost::system::error_code;
48
52
53public:
54 template <class ConstBufferSequence>
56 Port const& port,
57 Handler& handler,
58 boost::asio::io_context& ioc,
60 endpoint_type remote_address,
61 ConstBufferSequence const& buffers,
62 middle_type&& stream);
63
64 void
65 run();
66
68 websocketUpgrade() override;
69
70private:
71 void
73
74 void
75 do_request() override;
76
77 void
78 do_close() override;
79
80 void
82};
83
84//------------------------------------------------------------------------------
85
86template <class Handler>
87template <class ConstBufferSequence>
89 Port const& port,
90 Handler& handler,
91 boost::asio::io_context& ioc,
92 beast::Journal journal,
93 endpoint_type remote_address,
94 ConstBufferSequence const& buffers,
95 middle_type&& stream)
96 : BaseHTTPPeer<Handler, SSLHTTPPeer>(
97 port,
98 handler,
99 ioc.get_executor(),
100 journal,
101 remote_address,
102 buffers)
103 , stream_ptr_(std::make_unique<stream_type>(
104 middle_type(std::move(stream)),
105 *port.context))
106 , stream_(*stream_ptr_)
107 , socket_(stream_.next_layer().socket())
108{
109}
110
111// Called when the acceptor accepts our socket.
112template <class Handler>
113void
115{
116 if (!this->handler_.onAccept(this->session(), this->remote_address_))
117 {
119 this->strand_,
120 std::bind(&SSLHTTPPeer::do_close, this->shared_from_this()));
121 return;
122 }
123 if (!socket_.is_open())
124 return;
126 this->strand_,
127 std::bind(
129 this->shared_from_this(),
130 std::placeholders::_1));
131}
132
133template <class Handler>
136{
137 auto ws = this->ios().template emplace<SSLWSPeer<Handler>>(
138 this->port_,
139 this->handler_,
140 this->remote_address_,
141 std::move(this->message_),
142 std::move(this->stream_ptr_),
143 this->journal_);
144 return ws;
145}
146
147template <class Handler>
148void
150{
151 boost::system::error_code ec;
152 stream_.set_verify_mode(boost::asio::ssl::verify_none);
153 this->start_timer();
154 this->read_buf_.consume(stream_.async_handshake(
155 stream_type::server, this->read_buf_.data(), do_yield[ec]));
156 this->cancel_timer();
157 if (ec == boost::beast::error::timeout)
158 return this->on_timer();
159 if (ec)
160 return this->fail(ec, "handshake");
161 bool const http = this->port().protocol.count("peer") > 0 ||
162 this->port().protocol.count("wss") > 0 ||
163 this->port().protocol.count("wss2") > 0 ||
164 this->port().protocol.count("https") > 0;
165 if (http)
166 {
168 this->strand_,
169 std::bind(
171 this->shared_from_this(),
172 std::placeholders::_1));
173 return;
174 }
175 // `this` will be destroyed
176}
177
178template <class Handler>
179void
181{
182 ++this->request_count_;
183 auto const what = this->handler_.onHandoff(
184 this->session(),
185 std::move(stream_ptr_),
186 std::move(this->message_),
187 this->remote_address_);
188 if (what.moved)
189 return;
190 if (what.response)
191 return this->write(what.response, what.keep_alive);
192 // legacy
193 this->handler_.onRequest(this->session());
194}
195
196template <class Handler>
197void
199{
200 this->start_timer();
201 stream_.async_shutdown(bind_executor(
202 this->strand_,
203 std::bind(
205 this->shared_from_this(),
206 std::placeholders::_1)));
207}
208
209template <class Handler>
210void
212{
213 this->cancel_timer();
214
215 if (ec == boost::asio::error::operation_aborted)
216 return;
217 if (ec)
218 {
219 JLOG(this->journal_.debug()) << "on_shutdown: " << ec.message();
220 }
221
222 // Close socket now in case this->destructor is delayed
223 stream_.next_layer().close();
224}
225
226} // namespace ripple
227
228#endif
T bind(T... args)
A generic endpoint for log messages.
Definition Journal.h:60
Represents an active connection.
boost::asio::ip::tcp::socket socket_type
Definition SSLHTTPPeer.h:42
stream_type & stream_
Definition SSLHTTPPeer.h:50
void do_request() override
std::unique_ptr< stream_type > stream_ptr_
Definition SSLHTTPPeer.h:49
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:47
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:88
boost::asio::ip::tcp::endpoint endpoint_type
Definition SSLHTTPPeer.h:45
boost::asio::yield_context yield_context
Definition SSLHTTPPeer.h:46
void do_handshake(yield_context do_yield)
socket_type & socket_
Definition SSLHTTPPeer.h:51
boost::beast::ssl_stream< middle_type > stream_type
Definition SSLHTTPPeer.h:44
boost::beast::tcp_stream middle_type
Definition SSLHTTPPeer.h:43
void spawn(Ctx &&ctx, F &&func)
Spawns a coroutine using boost::asio::spawn
Definition Spawn.h:87
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
STL namespace.
Configuration information for a Server listening port.
Definition Port.h:50