rippled
Loading...
Searching...
No Matches
PlainHTTPPeer.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_PLAINHTTPPEER_H_INCLUDED
21#define RIPPLE_SERVER_PLAINHTTPPEER_H_INCLUDED
22
23#include <xrpl/beast/rfc2616.h>
24#include <xrpl/server/detail/BaseHTTPPeer.h>
25#include <xrpl/server/detail/PlainWSPeer.h>
26
27#include <boost/beast/core/tcp_stream.hpp>
28
29#include <memory>
30
31namespace ripple {
32
33template <class Handler>
35 : public BaseHTTPPeer<Handler, PlainHTTPPeer<Handler>>,
36 public std::enable_shared_from_this<PlainHTTPPeer<Handler>>
37{
38private:
39 friend class BaseHTTPPeer<Handler, PlainHTTPPeer>;
40 using socket_type = boost::asio::ip::tcp::socket;
41 using stream_type = boost::beast::tcp_stream;
42 using endpoint_type = boost::asio::ip::tcp::endpoint;
43
46
47public:
48 template <class ConstBufferSequence>
50 Port const& port,
51 Handler& handler,
52 boost::asio::io_context& ioc,
54 endpoint_type remote_address,
55 ConstBufferSequence const& buffers,
56 stream_type&& stream);
57
58 void
59 run();
60
62 websocketUpgrade() override;
63
64private:
65 void
66 do_request() override;
67
68 void
69 do_close() override;
70};
71
72//------------------------------------------------------------------------------
73
74template <class Handler>
75template <class ConstBufferSequence>
77 Port const& port,
78 Handler& handler,
79 boost::asio::io_context& ioc,
80 beast::Journal journal,
81 endpoint_type remote_endpoint,
82 ConstBufferSequence const& buffers,
83 stream_type&& stream)
84 : BaseHTTPPeer<Handler, PlainHTTPPeer>(
85 port,
86 handler,
87 ioc.get_executor(),
88 journal,
89 remote_endpoint,
90 buffers)
91 , stream_(std::move(stream))
92 , socket_(stream_.socket())
93{
94 // Set TCP_NODELAY on loopback interfaces,
95 // otherwise Nagle's algorithm makes Env
96 // tests run slower on Linux systems.
97 //
98 if (remote_endpoint.address().is_loopback())
99 socket_.set_option(boost::asio::ip::tcp::no_delay{true});
100}
101
102template <class Handler>
103void
105{
106 if (!this->handler_.onAccept(this->session(), this->remote_address_))
107 {
109 this->strand_,
110 std::bind(&PlainHTTPPeer::do_close, this->shared_from_this()));
111 return;
112 }
113
114 if (!socket_.is_open())
115 return;
116
118 this->strand_,
119 std::bind(
121 this->shared_from_this(),
122 std::placeholders::_1));
123}
124
125template <class Handler>
128{
129 auto ws = this->ios().template emplace<PlainWSPeer<Handler>>(
130 this->port_,
131 this->handler_,
132 this->remote_address_,
133 std::move(this->message_),
134 std::move(stream_),
135 this->journal_);
136 return ws;
137}
138
139template <class Handler>
140void
142{
143 ++this->request_count_;
144 auto const what = this->handler_.onHandoff(
145 this->session(), std::move(this->message_), this->remote_address_);
146 if (what.moved)
147 return;
148 boost::system::error_code ec;
149 if (what.response)
150 {
151 // half-close on Connection: close
152 if (!what.keep_alive)
153 socket_.shutdown(socket_type::shutdown_receive, ec);
154 if (ec)
155 return this->fail(ec, "request");
156 return this->write(what.response, what.keep_alive);
157 }
158
159 // Perform half-close when Connection: close and not SSL
160 if (!beast::rfc2616::is_keep_alive(this->message_))
161 socket_.shutdown(socket_type::shutdown_receive, ec);
162 if (ec)
163 return this->fail(ec, "request");
164 // legacy
165 this->handler_.onRequest(this->session());
166}
167
168template <class Handler>
169void
171{
172 boost::system::error_code ec;
173 socket_.shutdown(socket_type::shutdown_send, ec);
174}
175
176} // namespace ripple
177
178#endif
T bind(T... args)
A generic endpoint for log messages.
Definition Journal.h:60
Represents an active connection.
boost::asio::ip::tcp::endpoint endpoint_type
socket_type & socket_
void do_request() override
std::shared_ptr< WSSession > websocketUpgrade() override
Convert the connection to WebSocket.
boost::beast::tcp_stream stream_type
boost::asio::ip::tcp::socket socket_type
void do_close() override
PlainHTTPPeer(Port const &port, Handler &handler, boost::asio::io_context &ioc, beast::Journal journal, endpoint_type remote_address, ConstBufferSequence const &buffers, stream_type &&stream)
bool is_keep_alive(boost::beast::http::message< isRequest, Body, Fields > const &m)
Definition rfc2616.h:386
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