xrpld
Loading...
Searching...
No Matches
PlainHTTPPeer.h
1#pragma once
2
3#include <xrpl/beast/rfc2616.h>
4#include <xrpl/beast/utility/Journal.h>
5#include <xrpl/server/Port.h>
6#include <xrpl/server/WSSession.h>
7#include <xrpl/server/detail/BaseHTTPPeer.h>
8#include <xrpl/server/detail/PlainWSPeer.h>
9
10#include <boost/beast/core/tcp_stream.hpp>
11
12#include <memory>
13#include <utility>
14
15namespace xrpl {
16
17template <class Handler>
18class PlainHTTPPeer : public BaseHTTPPeer<Handler, PlainHTTPPeer<Handler>>,
19 public std::enable_shared_from_this<PlainHTTPPeer<Handler>>
20{
21private:
22 friend class BaseHTTPPeer<Handler, PlainHTTPPeer>;
23 using socket_type = boost::asio::ip::tcp::socket;
24 using stream_type = boost::beast::tcp_stream;
25 using endpoint_type = boost::asio::ip::tcp::endpoint;
26
29
30public:
31 template <class ConstBufferSequence>
33 Port const& port,
34 Handler& handler,
35 boost::asio::io_context& ioc,
38 ConstBufferSequence const& buffers,
39 stream_type&& stream);
40
41 void
42 run();
43
45 websocketUpgrade() override;
46
47private:
48 void
49 doRequest() override;
50
51 void
52 doClose() override;
53};
54
55//------------------------------------------------------------------------------
56
57template <class Handler>
58template <class ConstBufferSequence>
60 Port const& port,
61 Handler& handler,
62 boost::asio::io_context& ioc,
64 endpoint_type remoteEndpoint,
65 ConstBufferSequence const& buffers,
66 stream_type&& stream)
67 : BaseHTTPPeer<Handler, PlainHTTPPeer>(
68 port,
69 handler,
70 ioc.get_executor(),
71 journal,
72 remoteEndpoint,
73 buffers)
74 , stream_(std::move(stream))
75 , socket_(stream_.socket())
76{
77 // Set TCP_NODELAY on loopback interfaces,
78 // otherwise Nagle's algorithm makes Env
79 // tests run slower on Linux systems.
80 //
81 if (remoteEndpoint.address().is_loopback())
82 socket_.set_option(boost::asio::ip::tcp::no_delay{true});
83}
84
85template <class Handler>
86void
88{
89 if (!this->handler_.onAccept(this->session(), this->remoteAddress_))
90 {
91 util::spawn(this->strand_, [self = this->shared_from_this()](boost::asio::yield_context) {
92 self->doClose();
93 });
94 return;
95 }
96
97 if (!socket_.is_open())
98 return;
99
101 this->strand_, [self = this->shared_from_this()](boost::asio::yield_context doYield) {
102 self->doRead(doYield);
103 });
104}
105
106template <class Handler>
109{
110 auto ws = this->ios().template emplace<PlainWSPeer<Handler>>(
111 this->port_,
112 this->handler_,
113 this->remoteAddress_,
114 std::move(this->message_),
115 std::move(stream_),
116 this->journal_);
117 return ws;
118}
119
120template <class Handler>
121void
123{
124 ++this->requestCount_;
125 auto const what =
126 this->handler_.onHandoff(this->session(), std::move(this->message_), this->remoteAddress_);
127 if (what.moved)
128 return;
129 boost::system::error_code ec;
130 if (what.response)
131 {
132 // half-close on Connection: close
133 if (!what.keepAlive)
134 socket_.shutdown(socket_type::shutdown_receive, ec);
135 if (ec)
136 return this->fail(ec, "request");
137 return this->write(what.response, what.keepAlive);
138 }
139
140 // Perform half-close when Connection: close and not SSL
142 socket_.shutdown(socket_type::shutdown_receive, ec);
143 if (ec)
144 return this->fail(ec, "request");
145 // legacy
146 this->handler_.onRequest(this->session());
147}
148
149template <class Handler>
150void
152{
153 boost::system::error_code ec;
154 socket_.shutdown(socket_type::shutdown_send, ec);
155}
156
157} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:44
BaseHTTPPeer(Port const &port, Handler &handler, boost::asio::executor const &executor, beast::Journal journal, endpoint_type remoteAddress, ConstBufferSequence const &buffers)
void write(void const *buffer, std::size_t bytes) override
void fail(error_code ec, char const *what)
boost::asio::strand< boost::asio::executor > strand_
void doRequest() override
std::shared_ptr< WSSession > websocketUpgrade() override
Convert the connection to WebSocket.
void doClose() override
PlainHTTPPeer(Port const &port, Handler &handler, boost::asio::io_context &ioc, beast::Journal journal, endpoint_type remoteAddress, ConstBufferSequence const &buffers, stream_type &&stream)
boost::asio::ip::tcp::socket socket_type
boost::asio::ip::tcp::endpoint endpoint_type
boost::beast::tcp_stream stream_type
socket_type & socket_
bool isKeepAlive(boost::beast::http::message< IsRequest, Body, Fields > const &m)
Definition rfc2616.h:366
STL namespace.
void spawn(Ctx &&ctx, F &&func)
Spawns a coroutine using boost::asio::spawn.
Definition Spawn.h:67
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
Configuration information for a Server listening port.
Definition Port.h:29