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