mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-04 11:15:56 +00:00
Switch to Boost.Beast for SSL detection (#3166)
This commit is contained in:
@@ -1,71 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_SSL_BUNDLE_H_INCLUDED
|
||||
#define BEAST_ASIO_SSL_BUNDLE_H_INCLUDED
|
||||
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#include <boost/asio/ssl/stream.hpp>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Work-around for non-movable boost::ssl::stream.
|
||||
This allows ssl::stream to be movable and allows the stream to
|
||||
construct from an already-existing socket.
|
||||
*/
|
||||
struct ssl_bundle
|
||||
{
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
using stream_type = boost::asio::ssl::stream <socket_type&>;
|
||||
using shared_context = std::shared_ptr<boost::asio::ssl::context>;
|
||||
|
||||
template <class... Args>
|
||||
ssl_bundle (shared_context const& context_, Args&&... args);
|
||||
|
||||
// DEPRECATED
|
||||
template <class... Args>
|
||||
ssl_bundle (boost::asio::ssl::context& context_, Args&&... args);
|
||||
|
||||
shared_context context;
|
||||
socket_type socket;
|
||||
stream_type stream;
|
||||
};
|
||||
|
||||
template <class... Args>
|
||||
ssl_bundle::ssl_bundle (shared_context const& context_, Args&&... args)
|
||||
: socket(std::forward<Args>(args)...)
|
||||
, stream (socket, *context_)
|
||||
{
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
ssl_bundle::ssl_bundle (boost::asio::ssl::context& context_, Args&&... args)
|
||||
: socket(std::forward<Args>(args)...)
|
||||
, stream (socket, context_)
|
||||
{
|
||||
}
|
||||
|
||||
} // asio
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -24,8 +24,12 @@
|
||||
#include <ripple/overlay/Peer.h>
|
||||
#include <ripple/overlay/PeerSet.h>
|
||||
#include <ripple/server/Handoff.h>
|
||||
#include <ripple/beast/asio/ssl_bundle.h>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#include <boost/asio/ssl/stream.hpp>
|
||||
#include <boost/beast/http/message.hpp>
|
||||
#include <boost/beast/core/tcp_stream.hpp>
|
||||
#include <boost/beast/ssl/ssl_stream.hpp>
|
||||
#include <ripple/core/Stoppable.h>
|
||||
#include <ripple/beast/utility/PropertyStream.h>
|
||||
#include <memory>
|
||||
@@ -45,6 +49,9 @@ class Overlay
|
||||
, public beast::PropertyStream::Source
|
||||
{
|
||||
protected:
|
||||
using socket_type = boost::beast::tcp_stream;
|
||||
using stream_type = boost::beast::ssl_stream <socket_type>;
|
||||
|
||||
// VFALCO NOTE The requirement of this constructor is an
|
||||
// unfortunate problem with the API for
|
||||
// Stoppable and PropertyStream
|
||||
@@ -82,7 +89,7 @@ public:
|
||||
/** Conditionally accept an incoming HTTP request. */
|
||||
virtual
|
||||
Handoff
|
||||
onHandoff (std::unique_ptr <beast::asio::ssl_bundle>&& bundle,
|
||||
onHandoff (std::unique_ptr <stream_type>&& bundle,
|
||||
http_request_type&& request,
|
||||
boost::asio::ip::tcp::endpoint remote_address) = 0;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace ripple {
|
||||
|
||||
ConnectAttempt::ConnectAttempt (Application& app, boost::asio::io_service& io_service,
|
||||
endpoint_type const& remote_endpoint, Resource::Consumer usage,
|
||||
beast::asio::ssl_bundle::shared_context const& context,
|
||||
shared_context const& context,
|
||||
std::uint32_t id, std::shared_ptr<PeerFinder::Slot> const& slot,
|
||||
beast::Journal journal, OverlayImpl& overlay)
|
||||
: Child (overlay)
|
||||
@@ -39,10 +39,10 @@ ConnectAttempt::ConnectAttempt (Application& app, boost::asio::io_service& io_se
|
||||
, usage_ (usage)
|
||||
, strand_ (io_service)
|
||||
, timer_ (io_service)
|
||||
, ssl_bundle_ (std::make_unique<beast::asio::ssl_bundle>(
|
||||
context, io_service))
|
||||
, socket_ (ssl_bundle_->socket)
|
||||
, stream_ (ssl_bundle_->stream)
|
||||
, stream_ptr_ (std::make_unique<stream_type>(
|
||||
socket_type(std::forward<boost::asio::io_service&>(io_service)), *context))
|
||||
, socket_ (stream_ptr_->next_layer().socket())
|
||||
, stream_ (*stream_ptr_)
|
||||
, slot_ (slot)
|
||||
{
|
||||
JLOG(journal_.debug()) <<
|
||||
@@ -63,7 +63,7 @@ ConnectAttempt::stop()
|
||||
if (! strand_.running_in_this_thread())
|
||||
return strand_.post(std::bind(
|
||||
&ConnectAttempt::stop, shared_from_this()));
|
||||
if (stream_.next_layer().is_open())
|
||||
if (socket_.is_open())
|
||||
{
|
||||
JLOG(journal_.debug()) <<
|
||||
"Stop";
|
||||
@@ -85,7 +85,7 @@ void
|
||||
ConnectAttempt::close()
|
||||
{
|
||||
assert(strand_.running_in_this_thread());
|
||||
if (stream_.next_layer().is_open())
|
||||
if (socket_.is_open())
|
||||
{
|
||||
error_code ec;
|
||||
timer_.cancel(ec);
|
||||
@@ -135,7 +135,7 @@ ConnectAttempt::cancelTimer()
|
||||
void
|
||||
ConnectAttempt::onTimer (error_code ec)
|
||||
{
|
||||
if (! stream_.next_layer().is_open())
|
||||
if (! socket_.is_open())
|
||||
return;
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
@@ -158,10 +158,10 @@ ConnectAttempt::onConnect (error_code ec)
|
||||
return;
|
||||
endpoint_type local_endpoint;
|
||||
if(! ec)
|
||||
local_endpoint = stream_.next_layer().local_endpoint(ec);
|
||||
local_endpoint = socket_.local_endpoint(ec);
|
||||
if(ec)
|
||||
return fail("onConnect", ec);
|
||||
if(! stream_.next_layer().is_open())
|
||||
if(! socket_.is_open())
|
||||
return;
|
||||
JLOG(journal_.trace()) <<
|
||||
"onConnect";
|
||||
@@ -177,13 +177,13 @@ void
|
||||
ConnectAttempt::onHandshake (error_code ec)
|
||||
{
|
||||
cancelTimer();
|
||||
if(! stream_.next_layer().is_open())
|
||||
if(! socket_.is_open())
|
||||
return;
|
||||
if(ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
endpoint_type local_endpoint;
|
||||
if (! ec)
|
||||
local_endpoint = stream_.next_layer().local_endpoint(ec);
|
||||
local_endpoint = socket_.local_endpoint(ec);
|
||||
if(ec)
|
||||
return fail("onHandshake", ec);
|
||||
JLOG(journal_.trace()) <<
|
||||
@@ -193,7 +193,7 @@ ConnectAttempt::onHandshake (error_code ec)
|
||||
beast::IPAddressConversion::from_asio (local_endpoint)))
|
||||
return fail("Duplicate connection");
|
||||
|
||||
auto const sharedValue = makeSharedValue(*ssl_bundle_, journal_);
|
||||
auto const sharedValue = makeSharedValue(*stream_ptr_, journal_);
|
||||
if (! sharedValue)
|
||||
return close(); // makeSharedValue logs
|
||||
|
||||
@@ -212,7 +212,7 @@ void
|
||||
ConnectAttempt::onWrite (error_code ec)
|
||||
{
|
||||
cancelTimer();
|
||||
if(! stream_.next_layer().is_open())
|
||||
if(! socket_.is_open())
|
||||
return;
|
||||
if(ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
@@ -228,7 +228,7 @@ ConnectAttempt::onRead (error_code ec)
|
||||
{
|
||||
cancelTimer();
|
||||
|
||||
if(! stream_.next_layer().is_open())
|
||||
if(! socket_.is_open())
|
||||
return;
|
||||
if(ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
@@ -338,7 +338,7 @@ ConnectAttempt::processResponse()
|
||||
return fail("processResponse: Unable to negotiate protocol version");
|
||||
}
|
||||
|
||||
auto const sharedValue = makeSharedValue(*ssl_bundle_, journal_);
|
||||
auto const sharedValue = makeSharedValue(*stream_ptr_, journal_);
|
||||
if(! sharedValue)
|
||||
return close(); // makeSharedValue logs
|
||||
|
||||
@@ -365,7 +365,7 @@ ConnectAttempt::processResponse()
|
||||
if (result != PeerFinder::Result::success)
|
||||
return fail("Outbound slots full");
|
||||
|
||||
auto const peer = std::make_shared<PeerImp>(app_, std::move(ssl_bundle_),
|
||||
auto const peer = std::make_shared<PeerImp>(app_, std::move(stream_ptr_),
|
||||
read_buf_.data(), std::move(slot_), std::move(response_), usage_,
|
||||
publicKey, *negotiatedProtocol, id_, overlay_);
|
||||
|
||||
|
||||
@@ -41,6 +41,11 @@ private:
|
||||
using response_type =
|
||||
boost::beast::http::response<boost::beast::http::dynamic_body>;
|
||||
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
using middle_type = boost::beast::tcp_stream;
|
||||
using stream_type = boost::beast::ssl_stream <middle_type>;
|
||||
using shared_context = std::shared_ptr<boost::asio::ssl::context>;
|
||||
|
||||
Application& app_;
|
||||
std::uint32_t const id_;
|
||||
beast::WrappedSink sink_;
|
||||
@@ -49,9 +54,9 @@ private:
|
||||
Resource::Consumer usage_;
|
||||
boost::asio::io_service::strand strand_;
|
||||
boost::asio::basic_waitable_timer<std::chrono::steady_clock> timer_;
|
||||
std::unique_ptr<beast::asio::ssl_bundle> ssl_bundle_;
|
||||
beast::asio::ssl_bundle::socket_type& socket_;
|
||||
beast::asio::ssl_bundle::stream_type& stream_;
|
||||
std::unique_ptr<stream_type> stream_ptr_;
|
||||
socket_type& socket_;
|
||||
stream_type& stream_;
|
||||
boost::beast::multi_buffer read_buf_;
|
||||
response_type response_;
|
||||
std::shared_ptr<PeerFinder::Slot> slot_;
|
||||
@@ -60,7 +65,7 @@ private:
|
||||
public:
|
||||
ConnectAttempt (Application& app, boost::asio::io_service& io_service,
|
||||
endpoint_type const& remote_endpoint, Resource::Consumer usage,
|
||||
beast::asio::ssl_bundle::shared_context const& context,
|
||||
shared_context const& context,
|
||||
std::uint32_t id, std::shared_ptr<PeerFinder::Slot> const& slot,
|
||||
beast::Journal journal, OverlayImpl& overlay);
|
||||
|
||||
|
||||
@@ -70,10 +70,10 @@ hashLastMessage (SSL const* ssl,
|
||||
}
|
||||
|
||||
boost::optional<uint256>
|
||||
makeSharedValue (beast::asio::ssl_bundle& ssl, beast::Journal journal)
|
||||
makeSharedValue (stream_type& ssl, beast::Journal journal)
|
||||
{
|
||||
auto const cookie1 = hashLastMessage(
|
||||
ssl.stream.native_handle(), SSL_get_finished);
|
||||
ssl.native_handle(), SSL_get_finished);
|
||||
if (!cookie1)
|
||||
{
|
||||
JLOG (journal.error()) << "Cookie generation: local setup not complete";
|
||||
@@ -81,7 +81,7 @@ makeSharedValue (beast::asio::ssl_bundle& ssl, beast::Journal journal)
|
||||
}
|
||||
|
||||
auto const cookie2 = hashLastMessage(
|
||||
ssl.stream.native_handle(), SSL_get_peer_finished);
|
||||
ssl.native_handle(), SSL_get_peer_finished);
|
||||
if (!cookie2)
|
||||
{
|
||||
JLOG (journal.error()) << "Cookie generation: peer setup not complete";
|
||||
|
||||
@@ -21,7 +21,11 @@
|
||||
#define RIPPLE_OVERLAY_HANDSHAKE_H_INCLUDED
|
||||
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/beast/asio/ssl_bundle.h>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#include <boost/asio/ssl/stream.hpp>
|
||||
#include <boost/beast/core/tcp_stream.hpp>
|
||||
#include <boost/beast/ssl/ssl_stream.hpp>
|
||||
#include <ripple/beast/utility/Journal.h>
|
||||
#include <ripple/protocol/BuildInfo.h>
|
||||
|
||||
@@ -32,6 +36,9 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
using socket_type = boost::beast::tcp_stream;
|
||||
using stream_type = boost::beast::ssl_stream <socket_type>;
|
||||
|
||||
/** Computes a shared value based on the SSL connection state.
|
||||
|
||||
When there is no man in the middle, both sides will compute the same
|
||||
@@ -42,7 +49,7 @@ namespace ripple {
|
||||
@return A 256-bit value on success; an unseated optional otherwise.
|
||||
*/
|
||||
boost::optional<uint256>
|
||||
makeSharedValue (beast::asio::ssl_bundle& ssl, beast::Journal journal);
|
||||
makeSharedValue (stream_type& ssl, beast::Journal journal);
|
||||
|
||||
/** Insert fields headers necessary for upgrading the link to the peer protocol. */
|
||||
void
|
||||
|
||||
@@ -177,7 +177,7 @@ OverlayImpl::~OverlayImpl ()
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Handoff
|
||||
OverlayImpl::onHandoff (std::unique_ptr <beast::asio::ssl_bundle>&& ssl_bundle,
|
||||
OverlayImpl::onHandoff (std::unique_ptr <stream_type>&& stream_ptr,
|
||||
http_request_type&& request,
|
||||
endpoint_type remote_endpoint)
|
||||
{
|
||||
@@ -196,7 +196,7 @@ OverlayImpl::onHandoff (std::unique_ptr <beast::asio::ssl_bundle>&& ssl_bundle,
|
||||
JLOG(journal.debug()) << "Peer connection upgrade from " << remote_endpoint;
|
||||
|
||||
error_code ec;
|
||||
auto const local_endpoint (ssl_bundle->socket.local_endpoint(ec));
|
||||
auto const local_endpoint (stream_ptr->next_layer().socket().local_endpoint(ec));
|
||||
if (ec)
|
||||
{
|
||||
JLOG(journal.debug()) << remote_endpoint << " failed: " << ec.message();
|
||||
@@ -249,7 +249,7 @@ OverlayImpl::onHandoff (std::unique_ptr <beast::asio::ssl_bundle>&& ssl_bundle,
|
||||
return handoff;
|
||||
}
|
||||
|
||||
auto const sharedValue = makeSharedValue(*ssl_bundle, journal);
|
||||
auto const sharedValue = makeSharedValue(*stream_ptr, journal);
|
||||
if(! sharedValue)
|
||||
{
|
||||
m_peerFinder->on_closed(slot);
|
||||
@@ -286,7 +286,7 @@ OverlayImpl::onHandoff (std::unique_ptr <beast::asio::ssl_bundle>&& ssl_bundle,
|
||||
|
||||
auto const peer = std::make_shared<PeerImp>(app_, id, slot,
|
||||
std::move(request), publicKey, *negotiatedVersion, consumer,
|
||||
std::move(ssl_bundle), *this);
|
||||
std::move(stream_ptr), *this);
|
||||
{
|
||||
// As we are not on the strand, run() must be called
|
||||
// while holding the lock, otherwise new I/O can be
|
||||
|
||||
@@ -169,7 +169,7 @@ public:
|
||||
}
|
||||
|
||||
Handoff
|
||||
onHandoff (std::unique_ptr <beast::asio::ssl_bundle>&& bundle,
|
||||
onHandoff (std::unique_ptr <stream_type>&& bundle,
|
||||
http_request_type&& request,
|
||||
endpoint_type remote_endpoint) override;
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ PeerImp::PeerImp (Application& app, id_t id,
|
||||
std::shared_ptr<PeerFinder::Slot> const& slot, http_request_type&& request,
|
||||
PublicKey const& publicKey,
|
||||
ProtocolVersion protocol, Resource::Consumer consumer,
|
||||
std::unique_ptr<beast::asio::ssl_bundle>&& ssl_bundle,
|
||||
std::unique_ptr<stream_type>&& stream_ptr,
|
||||
OverlayImpl& overlay)
|
||||
: Child (overlay)
|
||||
, app_ (app)
|
||||
@@ -67,9 +67,9 @@ PeerImp::PeerImp (Application& app, id_t id,
|
||||
, p_sink_(app_.journal("Protocol"), makePrefix(id))
|
||||
, journal_ (sink_)
|
||||
, p_journal_(p_sink_)
|
||||
, ssl_bundle_(std::move(ssl_bundle))
|
||||
, socket_ (ssl_bundle_->socket)
|
||||
, stream_ (ssl_bundle_->stream)
|
||||
, stream_ptr_(std::move(stream_ptr))
|
||||
, socket_ (stream_ptr_->next_layer().socket())
|
||||
, stream_ (*stream_ptr_)
|
||||
, strand_ (socket_.get_executor())
|
||||
, timer_ (waitable_timer{socket_.get_executor()})
|
||||
, remote_address_ (slot->remote_endpoint())
|
||||
@@ -697,7 +697,7 @@ void PeerImp::doAccept()
|
||||
|
||||
JLOG(journal_.debug()) << "doAccept: " << remote_address_;
|
||||
|
||||
auto const sharedValue = makeSharedValue(*ssl_bundle_, journal_);
|
||||
auto const sharedValue = makeSharedValue(*stream_ptr_, journal_);
|
||||
|
||||
// This shouldn't fail since we already computed
|
||||
// the shared value successfully in OverlayImpl
|
||||
@@ -857,7 +857,7 @@ PeerImp::onReadMessage (error_code ec, std::size_t bytes_transferred)
|
||||
read_buffer_.data(), *this);
|
||||
if (ec)
|
||||
return fail("onReadMessage", ec);
|
||||
if (! stream_.next_layer().is_open())
|
||||
if (! socket_.is_open())
|
||||
return;
|
||||
if(gracefulClose_)
|
||||
return;
|
||||
|
||||
@@ -94,7 +94,8 @@ private:
|
||||
using clock_type = std::chrono::steady_clock;
|
||||
using error_code = boost::system::error_code;
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
using stream_type = boost::asio::ssl::stream <socket_type&>;
|
||||
using middle_type = boost::beast::tcp_stream;
|
||||
using stream_type = boost::beast::ssl_stream <middle_type>;
|
||||
using address_type = boost::asio::ip::address;
|
||||
using endpoint_type = boost::asio::ip::tcp::endpoint;
|
||||
using waitable_timer = boost::asio::basic_waitable_timer<std::chrono::steady_clock>;
|
||||
@@ -105,7 +106,7 @@ private:
|
||||
beast::WrappedSink p_sink_;
|
||||
beast::Journal const journal_;
|
||||
beast::Journal const p_journal_;
|
||||
std::unique_ptr<beast::asio::ssl_bundle> ssl_bundle_;
|
||||
std::unique_ptr<stream_type> stream_ptr_;
|
||||
socket_type& socket_;
|
||||
stream_type& stream_;
|
||||
boost::asio::strand<boost::asio::executor> strand_;
|
||||
@@ -234,13 +235,13 @@ public:
|
||||
std::shared_ptr<PeerFinder::Slot> const& slot, http_request_type&& request,
|
||||
PublicKey const& publicKey,
|
||||
ProtocolVersion protocol, Resource::Consumer consumer,
|
||||
std::unique_ptr<beast::asio::ssl_bundle>&& ssl_bundle,
|
||||
std::unique_ptr<stream_type>&& stream_ptr,
|
||||
OverlayImpl& overlay);
|
||||
|
||||
/** Create outgoing, handshaked peer. */
|
||||
// VFALCO legacyPublicKey should be implied by the Slot
|
||||
template <class Buffers>
|
||||
PeerImp (Application& app, std::unique_ptr<beast::asio::ssl_bundle>&& ssl_bundle,
|
||||
PeerImp (Application& app, std::unique_ptr<stream_type>&& stream_ptr,
|
||||
Buffers const& buffers, std::shared_ptr<PeerFinder::Slot>&& slot,
|
||||
http_response_type&& response, Resource::Consumer usage,
|
||||
PublicKey const& publicKey,
|
||||
@@ -541,7 +542,7 @@ private:
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Buffers>
|
||||
PeerImp::PeerImp (Application& app, std::unique_ptr<beast::asio::ssl_bundle>&& ssl_bundle,
|
||||
PeerImp::PeerImp (Application& app, std::unique_ptr<stream_type>&& stream_ptr,
|
||||
Buffers const& buffers, std::shared_ptr<PeerFinder::Slot>&& slot,
|
||||
http_response_type&& response, Resource::Consumer usage,
|
||||
PublicKey const& publicKey,
|
||||
@@ -553,9 +554,9 @@ PeerImp::PeerImp (Application& app, std::unique_ptr<beast::asio::ssl_bundle>&& s
|
||||
, p_sink_ (app_.journal("Protocol"), makePrefix(id))
|
||||
, journal_ (sink_)
|
||||
, p_journal_ (p_sink_)
|
||||
, ssl_bundle_(std::move(ssl_bundle))
|
||||
, socket_ (ssl_bundle_->socket)
|
||||
, stream_ (ssl_bundle_->stream)
|
||||
, stream_ptr_(std::move(stream_ptr))
|
||||
, socket_ (stream_ptr_->next_layer().socket())
|
||||
, stream_ (*stream_ptr_)
|
||||
, strand_ (socket_.get_executor())
|
||||
, timer_ (waitable_timer{socket_.get_executor()})
|
||||
, remote_address_ (slot->remote_endpoint())
|
||||
|
||||
@@ -172,7 +172,7 @@ ServerHandlerImp::onAccept (Session& session,
|
||||
Handoff
|
||||
ServerHandlerImp::onHandoff(
|
||||
Session& session,
|
||||
std::unique_ptr<beast::asio::ssl_bundle>&& bundle,
|
||||
std::unique_ptr<stream_type>&& bundle,
|
||||
http_request_type&& request,
|
||||
boost::asio::ip::tcp::endpoint const& remote_address)
|
||||
{
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <ripple/rpc/RPCHandler.h>
|
||||
#include <ripple/app/main/CollectorManager.h>
|
||||
#include <ripple/json/Output.h>
|
||||
#include <boost/beast/core/tcp_stream.hpp>
|
||||
#include <boost/beast/ssl/ssl_stream.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
@@ -84,6 +86,8 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
using socket_type = boost::beast::tcp_stream;
|
||||
using stream_type = boost::beast::ssl_stream <socket_type>;
|
||||
|
||||
Application& app_;
|
||||
Resource::Manager& m_resourceManager;
|
||||
@@ -135,7 +139,7 @@ public:
|
||||
Handoff
|
||||
onHandoff(
|
||||
Session& session,
|
||||
std::unique_ptr<beast::asio::ssl_bundle>&& bundle,
|
||||
std::unique_ptr<stream_type>&& bundle,
|
||||
http_request_type&& request,
|
||||
boost::asio::ip::tcp::endpoint const& remote_address);
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <ripple/server/impl/io_list.h>
|
||||
#include <ripple/beast/net/IPAddressConversion.h>
|
||||
#include <ripple/beast/asio/ssl_error.h> // for is_short_read?
|
||||
#include <boost/beast/core/stream_traits.hpp>
|
||||
#include <boost/beast/http/read.hpp>
|
||||
#include <boost/beast/http/message.hpp>
|
||||
#include <boost/beast/http/parser.hpp>
|
||||
@@ -54,7 +55,6 @@ protected:
|
||||
using clock_type = std::chrono::system_clock;
|
||||
using error_code = boost::system::error_code;
|
||||
using endpoint_type = boost::asio::ip::tcp::endpoint;
|
||||
using waitable_timer = boost::asio::basic_waitable_timer <clock_type>;
|
||||
using yield_context = boost::asio::yield_context;
|
||||
|
||||
enum
|
||||
@@ -86,7 +86,6 @@ protected:
|
||||
Handler& handler_;
|
||||
boost::asio::executor_work_guard<boost::asio::executor> work_;
|
||||
boost::asio::strand<boost::asio::executor> strand_;
|
||||
waitable_timer timer_;
|
||||
endpoint_type remote_address_;
|
||||
beast::Journal const journal_;
|
||||
|
||||
@@ -114,7 +113,6 @@ public:
|
||||
Port const& port,
|
||||
Handler& handler,
|
||||
boost::asio::executor const& executor,
|
||||
waitable_timer timer,
|
||||
beast::Journal journal,
|
||||
endpoint_type remote_address,
|
||||
ConstBufferSequence const& buffers);
|
||||
@@ -147,7 +145,7 @@ protected:
|
||||
cancel_timer();
|
||||
|
||||
void
|
||||
on_timer(error_code ec);
|
||||
on_timer();
|
||||
|
||||
void
|
||||
do_read(yield_context do_yield);
|
||||
@@ -219,7 +217,6 @@ BaseHTTPPeer<Handler, Impl>::BaseHTTPPeer(
|
||||
Port const& port,
|
||||
Handler& handler,
|
||||
boost::asio::executor const& executor,
|
||||
waitable_timer timer,
|
||||
beast::Journal journal,
|
||||
endpoint_type remote_address,
|
||||
ConstBufferSequence const& buffers)
|
||||
@@ -227,7 +224,6 @@ BaseHTTPPeer<Handler, Impl>::BaseHTTPPeer(
|
||||
, handler_(handler)
|
||||
, work_(executor)
|
||||
, strand_(executor)
|
||||
, timer_(std::move(timer))
|
||||
, remote_address_(remote_address)
|
||||
, journal_(journal)
|
||||
{
|
||||
@@ -261,8 +257,7 @@ close()
|
||||
std::bind(
|
||||
(void (BaseHTTPPeer::*)(void)) & BaseHTTPPeer::close,
|
||||
impl().shared_from_this()));
|
||||
error_code ec;
|
||||
impl().stream_.lowest_layer().close(ec);
|
||||
boost::beast::get_lowest_layer(impl().stream_).close();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -277,7 +272,7 @@ fail(error_code ec, char const* what)
|
||||
ec_ = ec;
|
||||
JLOG(journal_.trace()) << id_ <<
|
||||
std::string(what) << ": " << ec.message();
|
||||
impl().stream_.lowest_layer().close(ec);
|
||||
boost::beast::get_lowest_layer(impl().stream_).close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,21 +281,12 @@ void
|
||||
BaseHTTPPeer<Handler, Impl>::
|
||||
start_timer()
|
||||
{
|
||||
error_code ec;
|
||||
timer_.expires_from_now(
|
||||
boost::beast::get_lowest_layer(impl().stream_).expires_after(
|
||||
std::chrono::seconds(
|
||||
remote_address_.address().is_loopback() ?
|
||||
timeoutSecondsLocal :
|
||||
timeoutSeconds),
|
||||
ec);
|
||||
if(ec)
|
||||
return fail(ec, "start_timer");
|
||||
timer_.async_wait(bind_executor(
|
||||
strand_,
|
||||
std::bind(
|
||||
&BaseHTTPPeer<Handler, Impl>::on_timer,
|
||||
impl().shared_from_this(),
|
||||
std::placeholders::_1)));
|
||||
timeoutSeconds)
|
||||
);
|
||||
}
|
||||
|
||||
// Convenience for discarding the error code
|
||||
@@ -309,20 +295,16 @@ void
|
||||
BaseHTTPPeer<Handler, Impl>::
|
||||
cancel_timer()
|
||||
{
|
||||
error_code ec;
|
||||
timer_.cancel(ec);
|
||||
boost::beast::get_lowest_layer(impl().stream_).expires_never();
|
||||
}
|
||||
|
||||
// Called when session times out
|
||||
template<class Handler, class Impl>
|
||||
void
|
||||
BaseHTTPPeer<Handler, Impl>::
|
||||
on_timer(error_code ec)
|
||||
on_timer()
|
||||
{
|
||||
if(ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
if(! ec)
|
||||
ec = boost::system::errc::make_error_code(
|
||||
auto ec = boost::system::errc::make_error_code(
|
||||
boost::system::errc::timed_out);
|
||||
fail(ec, "timer");
|
||||
}
|
||||
@@ -342,6 +324,8 @@ do_read(yield_context do_yield)
|
||||
cancel_timer();
|
||||
if(ec == boost::beast::http::error::end_of_stream)
|
||||
return do_close();
|
||||
if(ec == boost::beast::error::timeout)
|
||||
return on_timer();
|
||||
if(ec)
|
||||
return fail(ec, "http::read");
|
||||
do_request();
|
||||
@@ -356,6 +340,8 @@ on_write(error_code const& ec,
|
||||
std::size_t bytes_transferred)
|
||||
{
|
||||
cancel_timer();
|
||||
if(ec == boost::beast::error::timeout)
|
||||
return on_timer();
|
||||
if(ec)
|
||||
return fail(ec, "write");
|
||||
bytes_out_ += bytes_transferred;
|
||||
@@ -549,8 +535,7 @@ close(bool graceful)
|
||||
return do_close();
|
||||
}
|
||||
|
||||
error_code ec;
|
||||
impl().stream_.lowest_layer().close(ec);
|
||||
boost::beast::get_lowest_layer(impl().stream_).close();
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -103,7 +103,7 @@ close()
|
||||
return post(
|
||||
strand_, std::bind(&BasePeer::close, impl().shared_from_this()));
|
||||
error_code ec;
|
||||
ripple::get_lowest_layer(impl().ws_).close(ec);
|
||||
ripple::get_lowest_layer(impl().ws_).socket().close(ec);
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -529,7 +529,7 @@ fail(error_code ec, String const& what)
|
||||
ec_ = ec;
|
||||
JLOG(this->j_.trace()) <<
|
||||
what << ": " << ec.message();
|
||||
ripple::get_lowest_layer(impl().ws_).close(ec);
|
||||
ripple::get_lowest_layer(impl().ws_).socket().close(ec);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,9 @@
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/server/impl/PlainHTTPPeer.h>
|
||||
#include <ripple/server/impl/SSLHTTPPeer.h>
|
||||
#include <ripple/beast/asio/ssl_bundle.h>
|
||||
#include <boost/beast/core/detect_ssl.hpp>
|
||||
#include <boost/beast/core/multi_buffer.hpp>
|
||||
#include <boost/beast/core/tcp_stream.hpp>
|
||||
#include <boost/asio/basic_waitable_timer.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
@@ -55,7 +56,8 @@ private:
|
||||
using protocol_type = boost::asio::ip::tcp;
|
||||
using acceptor_type = protocol_type::acceptor;
|
||||
using endpoint_type = protocol_type::endpoint;
|
||||
using socket_type = protocol_type::socket;
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
using stream_type = boost::beast::tcp_stream;
|
||||
|
||||
// Detects SSL on a socket
|
||||
class Detector
|
||||
@@ -66,8 +68,8 @@ private:
|
||||
Port const& port_;
|
||||
Handler& handler_;
|
||||
boost::asio::io_context& ioc_;
|
||||
socket_type socket_;
|
||||
timer_type timer_;
|
||||
stream_type stream_;
|
||||
socket_type &socket_;
|
||||
endpoint_type remote_address_;
|
||||
boost::asio::io_context::strand strand_;
|
||||
beast::Journal const j_;
|
||||
@@ -77,14 +79,13 @@ private:
|
||||
Port const& port,
|
||||
Handler& handler,
|
||||
boost::asio::io_context& ioc,
|
||||
socket_type&& socket,
|
||||
stream_type&& stream,
|
||||
endpoint_type remote_address,
|
||||
beast::Journal j);
|
||||
void run();
|
||||
void close() override;
|
||||
|
||||
private:
|
||||
void do_timer (yield_context yield);
|
||||
void do_detect (yield_context yield);
|
||||
};
|
||||
|
||||
@@ -120,74 +121,24 @@ public:
|
||||
private:
|
||||
template <class ConstBufferSequence>
|
||||
void create (bool ssl, ConstBufferSequence const& buffers,
|
||||
socket_type&& socket, endpoint_type remote_address);
|
||||
stream_type&& stream, endpoint_type remote_address);
|
||||
|
||||
void do_accept (yield_context yield);
|
||||
};
|
||||
|
||||
/** Detect SSL client handshakes.
|
||||
Analyzes the bytes in the provided buffer to detect the SSL client
|
||||
handshake. If the buffer contains insufficient data, more data will be
|
||||
read from the stream until there is enough to determine a result.
|
||||
No bytes are discarded from buf. Any additional bytes read are retained.
|
||||
buf must provide an interface compatible with boost::asio::streambuf
|
||||
http://boost.org/doc/libs/1_56_0/doc/html/boost_asio/reference/streambuf.html
|
||||
See
|
||||
http://www.ietf.org/rfc/rfc2246.txt
|
||||
Section 7.4. Handshake protocol
|
||||
@param socket The stream to read from
|
||||
@param buf A buffer to hold the received data
|
||||
@param do_yield A do_yield context
|
||||
@return The error code if an error occurs, otherwise `true` if
|
||||
the data read indicates the SSL client handshake.
|
||||
*/
|
||||
template <class Socket, class StreamBuf, class Yield>
|
||||
std::pair <boost::system::error_code, bool>
|
||||
detect_ssl (Socket& socket, StreamBuf& buf, Yield do_yield)
|
||||
{
|
||||
std::pair <boost::system::error_code, bool> result;
|
||||
result.second = false;
|
||||
for(;;)
|
||||
{
|
||||
std::size_t const max = 4; // the most bytes we could need
|
||||
unsigned char data[max];
|
||||
auto const bytes = boost::asio::buffer_copy (
|
||||
boost::asio::buffer(data), buf.data());
|
||||
|
||||
if (bytes > 0)
|
||||
{
|
||||
if (data[0] != 0x16) // message type 0x16 = "SSL Handshake"
|
||||
break;
|
||||
}
|
||||
|
||||
if (bytes >= max)
|
||||
{
|
||||
result.second = true;
|
||||
break;
|
||||
}
|
||||
|
||||
buf.commit(boost::asio::async_read (socket,
|
||||
buf.prepare(max - bytes), boost::asio::transfer_at_least(1),
|
||||
do_yield[result.first]));
|
||||
if (result.first)
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Handler>
|
||||
Door<Handler>::Detector::Detector(
|
||||
Port const& port,
|
||||
Handler& handler,
|
||||
boost::asio::io_context& ioc,
|
||||
socket_type&& socket,
|
||||
stream_type&& stream,
|
||||
endpoint_type remote_address,
|
||||
beast::Journal j)
|
||||
: port_(port)
|
||||
, handler_(handler)
|
||||
, ioc_(ioc)
|
||||
, socket_(std::move(socket))
|
||||
, timer_(ioc_)
|
||||
, stream_(std::move(stream))
|
||||
, socket_(stream_.socket())
|
||||
, remote_address_(remote_address)
|
||||
, strand_(ioc_)
|
||||
, j_(j)
|
||||
@@ -199,13 +150,8 @@ void
|
||||
Door<Handler>::Detector::
|
||||
run()
|
||||
{
|
||||
// do_detect must be called before do_timer or else
|
||||
// the timer can be canceled before it gets set.
|
||||
boost::asio::spawn(strand_, std::bind (&Detector::do_detect,
|
||||
this->shared_from_this(), std::placeholders::_1));
|
||||
|
||||
boost::asio::spawn(strand_, std::bind (&Detector::do_timer,
|
||||
this->shared_from_this(), std::placeholders::_1));
|
||||
}
|
||||
|
||||
template<class Handler>
|
||||
@@ -213,23 +159,7 @@ void
|
||||
Door<Handler>::Detector::
|
||||
close()
|
||||
{
|
||||
error_code ec;
|
||||
socket_.close(ec);
|
||||
timer_.cancel(ec);
|
||||
}
|
||||
|
||||
template<class Handler>
|
||||
void
|
||||
Door<Handler>::Detector::
|
||||
do_timer(yield_context do_yield)
|
||||
{
|
||||
error_code ec; // ignored
|
||||
while (socket_.is_open())
|
||||
{
|
||||
timer_.async_wait (do_yield[ec]);
|
||||
if (timer_.expires_from_now() <= std::chrono::seconds(0))
|
||||
socket_.close(ec);
|
||||
}
|
||||
stream_.close();
|
||||
}
|
||||
|
||||
template<class Handler>
|
||||
@@ -238,23 +168,23 @@ Door<Handler>::Detector::
|
||||
do_detect(boost::asio::yield_context do_yield)
|
||||
{
|
||||
boost::beast::multi_buffer buf(16);
|
||||
timer_.expires_from_now(std::chrono::seconds(15));
|
||||
auto const [ec, ssl] = detect_ssl(socket_, buf, do_yield);
|
||||
error_code unused;
|
||||
timer_.cancel(unused);
|
||||
stream_.expires_after(std::chrono::seconds(15));
|
||||
boost::system::error_code ec;
|
||||
bool const ssl = async_detect_ssl(stream_, buf, do_yield[ec]);
|
||||
stream_.expires_never();
|
||||
if (! ec)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
if (auto sp = ios().template emplace<SSLHTTPPeer<Handler>>(
|
||||
port_, handler_, ioc_, j_, remote_address_,
|
||||
buf.data(), std::move(socket_)))
|
||||
buf.data(), std::move(stream_)))
|
||||
sp->run();
|
||||
return;
|
||||
}
|
||||
if (auto sp = ios().template emplace<PlainHTTPPeer<Handler>>(
|
||||
port_, handler_, ioc_, j_, remote_address_,
|
||||
buf.data(), std::move(socket_)))
|
||||
buf.data(), std::move(stream_)))
|
||||
sp->run();
|
||||
return;
|
||||
}
|
||||
@@ -357,19 +287,19 @@ template<class ConstBufferSequence>
|
||||
void
|
||||
Door<Handler>::
|
||||
create(bool ssl, ConstBufferSequence const& buffers,
|
||||
socket_type&& socket, endpoint_type remote_address)
|
||||
stream_type&& stream, endpoint_type remote_address)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
if (auto sp = ios().template emplace<SSLHTTPPeer<Handler>>(
|
||||
port_, handler_, ioc_, j_, remote_address,
|
||||
buffers, std::move(socket)))
|
||||
buffers, std::move(stream)))
|
||||
sp->run();
|
||||
return;
|
||||
}
|
||||
if (auto sp = ios().template emplace<PlainHTTPPeer<Handler>>(
|
||||
port_, handler_, ioc_, j_, remote_address,
|
||||
buffers, std::move(socket)))
|
||||
buffers, std::move(stream)))
|
||||
sp->run();
|
||||
}
|
||||
|
||||
@@ -382,7 +312,8 @@ do_accept(boost::asio::yield_context do_yield)
|
||||
{
|
||||
error_code ec;
|
||||
endpoint_type remote_address;
|
||||
socket_type socket (ioc_);
|
||||
stream_type stream (ioc_);
|
||||
socket_type &socket = stream.socket();
|
||||
acceptor_.async_accept (socket, remote_address, do_yield[ec]);
|
||||
if (ec && ec != boost::asio::error::operation_aborted)
|
||||
{
|
||||
@@ -397,14 +328,14 @@ do_accept(boost::asio::yield_context do_yield)
|
||||
if (ssl_ && plain_)
|
||||
{
|
||||
if (auto sp = ios().template emplace<Detector>(
|
||||
port_, handler_, ioc_, std::move(socket),
|
||||
port_, handler_, ioc_, std::move(stream),
|
||||
remote_address, j_))
|
||||
sp->run();
|
||||
}
|
||||
else if (ssl_ || plain_)
|
||||
{
|
||||
create(ssl_, boost::asio::null_buffers{},
|
||||
std::move(socket), remote_address);
|
||||
std::move(stream), remote_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <ripple/beast/rfc2616.h>
|
||||
#include <ripple/server/impl/BaseHTTPPeer.h>
|
||||
#include <ripple/server/impl/PlainWSPeer.h>
|
||||
#include <boost/beast/core/tcp_stream.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace ripple {
|
||||
@@ -34,11 +35,12 @@ class PlainHTTPPeer
|
||||
{
|
||||
private:
|
||||
friend class BaseHTTPPeer<Handler, PlainHTTPPeer>;
|
||||
using waitable_timer = typename BaseHTTPPeer<Handler, PlainHTTPPeer>::waitable_timer;
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
using stream_type = boost::beast::tcp_stream;
|
||||
using endpoint_type = boost::asio::ip::tcp::endpoint;
|
||||
|
||||
socket_type stream_;
|
||||
stream_type stream_;
|
||||
socket_type& socket_;
|
||||
|
||||
public:
|
||||
template <class ConstBufferSequence>
|
||||
@@ -49,7 +51,7 @@ public:
|
||||
beast::Journal journal,
|
||||
endpoint_type remote_address,
|
||||
ConstBufferSequence const& buffers,
|
||||
socket_type&& socket);
|
||||
stream_type&& stream);
|
||||
|
||||
void run();
|
||||
|
||||
@@ -75,23 +77,23 @@ PlainHTTPPeer<Handler>::PlainHTTPPeer(
|
||||
beast::Journal journal,
|
||||
endpoint_type remote_endpoint,
|
||||
ConstBufferSequence const& buffers,
|
||||
socket_type&& socket)
|
||||
stream_type&& stream)
|
||||
: BaseHTTPPeer<Handler, PlainHTTPPeer>(
|
||||
port,
|
||||
handler,
|
||||
ioc.get_executor(),
|
||||
waitable_timer{ioc},
|
||||
journal,
|
||||
remote_endpoint,
|
||||
buffers)
|
||||
, stream_(std::move(socket))
|
||||
, stream_(std::move(stream))
|
||||
, socket_(stream_.socket())
|
||||
{
|
||||
// Set TCP_NODELAY on loopback interfaces,
|
||||
// otherwise Nagle's algorithm makes Env
|
||||
// tests run slower on Linux systems.
|
||||
//
|
||||
if(remote_endpoint.address().is_loopback())
|
||||
stream_.set_option(boost::asio::ip::tcp::no_delay{true});
|
||||
socket_.set_option(boost::asio::ip::tcp::no_delay{true});
|
||||
}
|
||||
|
||||
template<class Handler>
|
||||
@@ -107,7 +109,7 @@ run()
|
||||
return;
|
||||
}
|
||||
|
||||
if (! stream_.is_open())
|
||||
if (! socket_.is_open())
|
||||
return;
|
||||
|
||||
boost::asio::spawn(this->strand_, std::bind(&PlainHTTPPeer::do_read,
|
||||
@@ -141,7 +143,7 @@ do_request()
|
||||
{
|
||||
// half-close on Connection: close
|
||||
if (! what.keep_alive)
|
||||
stream_.shutdown(socket_type::shutdown_receive, ec);
|
||||
socket_.shutdown(socket_type::shutdown_receive, ec);
|
||||
if (ec)
|
||||
return this->fail(ec, "request");
|
||||
return this->write(what.response, what.keep_alive);
|
||||
@@ -149,7 +151,7 @@ do_request()
|
||||
|
||||
// Perform half-close when Connection: close and not SSL
|
||||
if (! beast::rfc2616::is_keep_alive(this->message_))
|
||||
stream_.shutdown(socket_type::shutdown_receive, ec);
|
||||
socket_.shutdown(socket_type::shutdown_receive, ec);
|
||||
if (ec)
|
||||
return this->fail(ec, "request");
|
||||
// legacy
|
||||
@@ -162,7 +164,7 @@ PlainHTTPPeer<Handler>::
|
||||
do_close()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
stream_.shutdown(socket_type::shutdown_send, ec);
|
||||
socket_.shutdown(socket_type::shutdown_send, ec);
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define RIPPLE_SERVER_PLAINWSPEER_H_INCLUDED
|
||||
|
||||
#include <ripple/server/impl/BaseWSPeer.h>
|
||||
#include <boost/beast/core/tcp_stream.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace ripple {
|
||||
@@ -37,7 +38,7 @@ class PlainWSPeer
|
||||
using error_code = boost::system::error_code;
|
||||
using endpoint_type = boost::asio::ip::tcp::endpoint;
|
||||
using waitable_timer = boost::asio::basic_waitable_timer <clock_type>;
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
using socket_type = boost::beast::tcp_stream;
|
||||
|
||||
boost::beast::websocket::stream<socket_type> ws_;
|
||||
|
||||
|
||||
@@ -22,7 +22,11 @@
|
||||
|
||||
#include <ripple/server/impl/BaseHTTPPeer.h>
|
||||
#include <ripple/server/impl/SSLWSPeer.h>
|
||||
#include <ripple/beast/asio/ssl_bundle.h>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#include <boost/asio/ssl/stream.hpp>
|
||||
#include <boost/beast/core/tcp_stream.hpp>
|
||||
#include <boost/beast/ssl/ssl_stream.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace ripple {
|
||||
@@ -34,15 +38,16 @@ class SSLHTTPPeer
|
||||
{
|
||||
private:
|
||||
friend class BaseHTTPPeer<Handler, SSLHTTPPeer>;
|
||||
using waitable_timer = typename BaseHTTPPeer<Handler, SSLHTTPPeer>::waitable_timer;
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
using stream_type = boost::asio::ssl::stream <socket_type&>;
|
||||
using middle_type = boost::beast::tcp_stream;
|
||||
using stream_type = boost::beast::ssl_stream <middle_type>;
|
||||
using endpoint_type = boost::asio::ip::tcp::endpoint;
|
||||
using yield_context = boost::asio::yield_context;
|
||||
using error_code = boost::system::error_code;
|
||||
|
||||
std::unique_ptr<beast::asio::ssl_bundle> ssl_bundle_;
|
||||
std::unique_ptr<stream_type> stream_ptr_;
|
||||
stream_type& stream_;
|
||||
socket_type& socket_;
|
||||
|
||||
public:
|
||||
template <class ConstBufferSequence>
|
||||
@@ -53,7 +58,7 @@ public:
|
||||
beast::Journal journal,
|
||||
endpoint_type remote_address,
|
||||
ConstBufferSequence const& buffers,
|
||||
socket_type&& socket);
|
||||
middle_type&& stream);
|
||||
|
||||
void
|
||||
run();
|
||||
@@ -86,18 +91,18 @@ SSLHTTPPeer<Handler>::SSLHTTPPeer(
|
||||
beast::Journal journal,
|
||||
endpoint_type remote_address,
|
||||
ConstBufferSequence const& buffers,
|
||||
socket_type&& socket)
|
||||
middle_type&& stream)
|
||||
: BaseHTTPPeer<Handler, SSLHTTPPeer>(
|
||||
port,
|
||||
handler,
|
||||
ioc.get_executor(),
|
||||
waitable_timer{ioc},
|
||||
journal,
|
||||
remote_address,
|
||||
buffers)
|
||||
, ssl_bundle_(std::make_unique<beast::asio::ssl_bundle>(
|
||||
port.context, std::move(socket)))
|
||||
, stream_(ssl_bundle_->stream)
|
||||
, stream_ptr_(std::make_unique<stream_type>(
|
||||
middle_type(std::move(stream)), *port.context))
|
||||
, stream_(*stream_ptr_)
|
||||
, socket_(stream_.next_layer().socket())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -114,7 +119,7 @@ run()
|
||||
this->shared_from_this()));
|
||||
return;
|
||||
}
|
||||
if (! stream_.lowest_layer().is_open())
|
||||
if (! socket_.is_open())
|
||||
return;
|
||||
boost::asio::spawn(this->strand_, std::bind(
|
||||
&SSLHTTPPeer::do_handshake, this->shared_from_this(),
|
||||
@@ -128,7 +133,7 @@ websocketUpgrade()
|
||||
{
|
||||
auto ws = this->ios().template emplace<SSLWSPeer<Handler>>(
|
||||
this->port_, this->handler_, this->remote_address_,
|
||||
std::move(this->message_), std::move(this->ssl_bundle_),
|
||||
std::move(this->message_), std::move(this->stream_ptr_),
|
||||
this->journal_);
|
||||
return ws;
|
||||
}
|
||||
@@ -144,6 +149,8 @@ do_handshake(yield_context do_yield)
|
||||
this->read_buf_.consume(stream_.async_handshake(
|
||||
stream_type::server, this->read_buf_.data(), do_yield[ec]));
|
||||
this->cancel_timer();
|
||||
if(ec == boost::beast::error::timeout)
|
||||
return this->on_timer();
|
||||
if (ec)
|
||||
return this->fail(ec, "handshake");
|
||||
bool const http =
|
||||
@@ -168,7 +175,7 @@ do_request()
|
||||
{
|
||||
++this->request_count_;
|
||||
auto const what = this->handler_.onHandoff(this->session(),
|
||||
std::move(ssl_bundle_), std::move(this->message_),
|
||||
std::move(stream_ptr_), std::move(this->message_),
|
||||
this->remote_address_);
|
||||
if(what.moved)
|
||||
return;
|
||||
@@ -208,7 +215,7 @@ on_shutdown(error_code ec)
|
||||
}
|
||||
|
||||
// Close socket now in case this->destructor is delayed
|
||||
stream_.lowest_layer().close(ec);
|
||||
stream_.next_layer().close();
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -22,7 +22,11 @@
|
||||
|
||||
#include <ripple/server/impl/BaseHTTPPeer.h>
|
||||
#include <ripple/server/WSSession.h>
|
||||
#include <ripple/beast/asio/ssl_bundle.h>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#include <boost/asio/ssl/stream.hpp>
|
||||
#include <boost/beast/core/tcp_stream.hpp>
|
||||
#include <boost/beast/ssl/ssl_stream.hpp>
|
||||
#include <boost/beast/websocket/ssl.hpp>
|
||||
#include <memory>
|
||||
|
||||
@@ -39,12 +43,13 @@ class SSLWSPeer
|
||||
using clock_type = std::chrono::system_clock;
|
||||
using error_code = boost::system::error_code;
|
||||
using endpoint_type = boost::asio::ip::tcp::endpoint;
|
||||
using socket_type = boost::beast::tcp_stream;
|
||||
using stream_type = boost::beast::ssl_stream <socket_type>;
|
||||
using waitable_timer =
|
||||
boost::asio::basic_waitable_timer <clock_type>;
|
||||
|
||||
std::unique_ptr<beast::asio::ssl_bundle> ssl_bundle_;
|
||||
boost::beast::websocket::stream<
|
||||
beast::asio::ssl_bundle::stream_type&> ws_;
|
||||
std::unique_ptr<stream_type> stream_ptr_;
|
||||
boost::beast::websocket::stream<stream_type&> ws_;
|
||||
|
||||
public:
|
||||
template<class Body, class Headers>
|
||||
@@ -53,8 +58,7 @@ public:
|
||||
Handler& handler,
|
||||
endpoint_type remote_endpoint,
|
||||
boost::beast::http::request<Body, Headers>&& request,
|
||||
std::unique_ptr<
|
||||
beast::asio::ssl_bundle>&& ssl_bundle,
|
||||
std::unique_ptr<stream_type>&& stream_ptr,
|
||||
beast::Journal journal);
|
||||
};
|
||||
|
||||
@@ -67,18 +71,18 @@ SSLWSPeer<Handler>::SSLWSPeer(
|
||||
Handler& handler,
|
||||
endpoint_type remote_endpoint,
|
||||
boost::beast::http::request<Body, Headers>&& request,
|
||||
std::unique_ptr<beast::asio::ssl_bundle>&& ssl_bundle,
|
||||
std::unique_ptr<stream_type>&& stream_ptr,
|
||||
beast::Journal journal)
|
||||
: BaseWSPeer<Handler, SSLWSPeer>(
|
||||
port,
|
||||
handler,
|
||||
ssl_bundle->socket.get_executor(),
|
||||
waitable_timer{ssl_bundle->socket.get_executor()},
|
||||
stream_ptr->get_executor(),
|
||||
waitable_timer{stream_ptr->get_executor()},
|
||||
remote_endpoint,
|
||||
std::move(request),
|
||||
journal)
|
||||
, ssl_bundle_(std::move(ssl_bundle))
|
||||
, ws_(ssl_bundle_->stream)
|
||||
, stream_ptr_(std::move(stream_ptr))
|
||||
, ws_(*stream_ptr_)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/utility/in_place_factory.hpp>
|
||||
#include <boost/beast/core/tcp_stream.hpp>
|
||||
#include <boost/beast/ssl/ssl_stream.hpp>
|
||||
#include <chrono>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
@@ -36,6 +38,9 @@
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
using socket_type = boost::beast::tcp_stream;
|
||||
using stream_type = boost::beast::ssl_stream <socket_type>;
|
||||
|
||||
class Server_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
@@ -104,7 +109,7 @@ public:
|
||||
|
||||
Handoff
|
||||
onHandoff (Session& session,
|
||||
std::unique_ptr <beast::asio::ssl_bundle>&& bundle,
|
||||
std::unique_ptr <stream_type>&& bundle,
|
||||
http_request_type&& request,
|
||||
boost::asio::ip::tcp::endpoint remote_address)
|
||||
{
|
||||
@@ -309,7 +314,7 @@ public:
|
||||
|
||||
Handoff
|
||||
onHandoff (Session& session,
|
||||
std::unique_ptr <beast::asio::ssl_bundle>&& bundle,
|
||||
std::unique_ptr <stream_type>&& bundle,
|
||||
http_request_type&& request,
|
||||
boost::asio::ip::tcp::endpoint remote_address)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user