Refactor Server:

* Remove HTTP namespace
* Rename connection classes
* Mark Server test automatic
* Build server sources in classic
This commit is contained in:
Vinnie Falco
2016-02-02 09:08:50 -05:00
parent ba38bfad9d
commit 137dd351b8
31 changed files with 286 additions and 241 deletions

View File

@@ -3305,37 +3305,43 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\Handoff.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\impl\BaseHTTPPeer.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\server\impl\Door.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\server\impl\Door.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\server\impl\JSONRPCUtil.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\server\impl\JSONRPCUtil.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\impl\Peer.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\impl\PlainPeer.h">
<ClInclude Include="..\..\src\ripple\server\impl\PlainHTTPPeer.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\server\impl\Port.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\server\impl\Role.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\server\impl\ServerHandlerImp.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\server\impl\ServerHandlerImp.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\server\impl\ServerImpl.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\server\impl\ServerImpl.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\impl\SSLPeer.h">
<ClInclude Include="..\..\src\ripple\server\impl\SSLHTTPPeer.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\JsonWriter.h">
</ClInclude>
@@ -3355,8 +3361,9 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\Session.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\server\tests\Server.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
<ClCompile Include="..\..\src\ripple\server\tests\Server_test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\server\Writer.h">
</ClInclude>
@@ -3721,6 +3728,8 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='release|x64'">..\..\src\secp256k1;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<ClCompile Include="..\..\src\ripple\unity\server.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\unity\shamap.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>

View File

@@ -3792,6 +3792,9 @@
<ClInclude Include="..\..\src\ripple\server\Handoff.h">
<Filter>ripple\server</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\impl\BaseHTTPPeer.h">
<Filter>ripple\server\impl</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\server\impl\Door.cpp">
<Filter>ripple\server\impl</Filter>
</ClCompile>
@@ -3804,10 +3807,7 @@
<ClInclude Include="..\..\src\ripple\server\impl\JSONRPCUtil.h">
<Filter>ripple\server\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\impl\Peer.h">
<Filter>ripple\server\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\impl\PlainPeer.h">
<ClInclude Include="..\..\src\ripple\server\impl\PlainHTTPPeer.h">
<Filter>ripple\server\impl</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\server\impl\Port.cpp">
@@ -3828,7 +3828,7 @@
<ClInclude Include="..\..\src\ripple\server\impl\ServerImpl.h">
<Filter>ripple\server\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\impl\SSLPeer.h">
<ClInclude Include="..\..\src\ripple\server\impl\SSLHTTPPeer.h">
<Filter>ripple\server\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\JsonWriter.h">
@@ -3858,7 +3858,7 @@
<ClInclude Include="..\..\src\ripple\server\Session.h">
<Filter>ripple\server</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\server\tests\Server.test.cpp">
<ClCompile Include="..\..\src\ripple\server\tests\Server_test.cpp">
<Filter>ripple\server\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\server\Writer.h">

View File

@@ -905,6 +905,7 @@ def get_classic_sources(toolchain):
append_sources(result, *list_sources('src/ripple/protocol', '.cpp'))
append_sources(result, *list_sources('src/ripple/rpc', '.cpp'))
append_sources(result, *list_sources('src/ripple/shamap', '.cpp'))
append_sources(result, *list_sources('src/ripple/server', '.cpp'))
append_sources(result, *list_sources('src/ripple/test', '.cpp'))
if use_shp(toolchain):
@@ -948,6 +949,7 @@ def get_unity_sources(toolchain):
'src/ripple/unity/protocol.cpp',
'src/ripple/unity/rpcx.cpp',
'src/ripple/unity/shamap.cpp',
'src/ripple/unity/server.cpp',
'src/ripple/unity/test.cpp',
)
@@ -1093,7 +1095,6 @@ for tu_style in ['classic', 'unity']:
'src/ripple/unity/protobuf.cpp',
'src/ripple/unity/ripple.proto.cpp',
'src/ripple/unity/resource.cpp',
'src/ripple/unity/server.cpp',
'src/ripple/unity/websocket02.cpp',
**cc_flags
)

View File

@@ -304,7 +304,7 @@ OverlayImpl::makePrefix (std::uint32_t id)
return ss.str();
}
std::shared_ptr<HTTP::Writer>
std::shared_ptr<Writer>
OverlayImpl::makeRedirectResponse (PeerFinder::Slot::ptr const& slot,
beast::http::message const& request, address_type remote_address)
{
@@ -326,7 +326,7 @@ OverlayImpl::makeRedirectResponse (PeerFinder::Slot::ptr const& slot,
{
//?
}
auto const response = HTTP::make_JsonWriter (m, json);
auto const response = make_JsonWriter (m, json);
return response;
}
@@ -851,7 +851,7 @@ OverlayImpl::processRequest (beast::http::message const& req,
resp.reason("OK");
Json::Value v;
v["overlay"] = crawl();
handoff.response = HTTP::make_JsonWriter(resp, v);
handoff.response = make_JsonWriter(resp, v);
return true;
}

View File

@@ -276,7 +276,7 @@ public:
int bytes);
private:
std::shared_ptr<HTTP::Writer>
std::shared_ptr<Writer>
makeRedirectResponse (PeerFinder::Slot::ptr const& slot,
beast::http::message const& request, address_type remote_address);

View File

@@ -29,10 +29,9 @@
#include <memory>
namespace ripple {
namespace HTTP {
class Server;
class Session;
class Server;
/** Processes all sessions.
Thread safety:
@@ -91,7 +90,6 @@ struct Handler
virtual void onStopped (Server& server) = 0;
};
} // HTTP
} // ripple
#endif

View File

@@ -36,7 +36,7 @@ struct Handoff
bool keep_alive = false;
// When set, this will be sent back
std::shared_ptr<HTTP::Writer> response;
std::shared_ptr<Writer> response;
bool handled() const
{

View File

@@ -29,7 +29,6 @@
#include <sstream>
namespace ripple {
namespace HTTP {
namespace detail {
@@ -160,7 +159,6 @@ make_JsonWriter (beast::http::message& m, Json::Value const& json)
std::move(prebody), std::move(body));
}
}
}
} // ripple
#endif

View File

@@ -32,7 +32,6 @@
namespace boost { namespace asio { namespace ssl { class context; } } }
namespace ripple {
namespace HTTP {
/** Configuration information for a Server listening port. */
struct Port
@@ -53,54 +52,18 @@ struct Port
std::shared_ptr<boost::asio::ssl::context> context;
// Returns `true` if any websocket protocols are specified
template <class = void>
bool
websockets() const;
bool websockets() const;
// Returns `true` if any secure protocols are specified
template <class = void>
bool
secure() const;
bool secure() const;
// Returns a string containing the list of protocols
template <class = void>
std::string
protocols() const;
std::string protocols() const;
};
//------------------------------------------------------------------------------
template <class>
bool
Port::websockets() const
{
return protocol.count("ws") > 0 || protocol.count("wss") > 0;
}
template <class>
bool
Port::secure() const
{
return protocol.count("peer") > 0 ||
protocol.count("https") > 0 || protocol.count("wss") > 0;
}
template <class>
std::string
Port::protocols() const
{
std::string s;
for (auto iter = protocol.cbegin();
iter != protocol.cend(); ++iter)
s += (iter != protocol.cbegin() ? "," : "") + *iter;
return s;
}
std::ostream&
operator<< (std::ostream& os, Port const& p);
} // HTTP
//------------------------------------------------------------------------------
struct ParsedPort

View File

@@ -51,14 +51,14 @@ enum class Role
validate the credentials.
*/
Role
requestRole (Role const& required, HTTP::Port const& port,
requestRole (Role const& required, Port const& port,
Json::Value const& jsonRPC, beast::IP::Endpoint const& remoteIp,
std::string const& user);
Resource::Consumer
requestInboundEndpoint (Resource::Manager& manager,
beast::IP::Endpoint const& remoteAddress,
HTTP::Port const& port, std::string const& user);
Port const& port, std::string const& user);
/**
* Check if the role entitles the user to unlimited resources.
@@ -71,7 +71,7 @@ isUnlimited (Role const& role);
* configured as secure_gateway, then the user can be positively identified.
*/
bool
isIdentified (HTTP::Port const& port, beast::IP::Address const& remoteIp,
isIdentified (Port const& port, beast::IP::Address const& remoteIp,
std::string const& user);
} // ripple

View File

@@ -25,7 +25,6 @@
#include <beast/utility/PropertyStream.h>
namespace ripple {
namespace HTTP {
/** Multi-threaded, asynchronous HTTP server. */
class Server
@@ -67,7 +66,6 @@ public:
close() = 0;
};
} // HTTP
} // ripple
#endif

View File

@@ -42,7 +42,7 @@ protected:
public:
struct Setup
{
std::vector<HTTP::Port> ports;
std::vector<Port> ports;
// Memberspace
struct client_t

View File

@@ -32,10 +32,6 @@
namespace ripple {
namespace HTTP {
class Session;
/** Persistent state information for a connection session.
These values are preserved between calls for efficiency.
Some fields are input parameters, some are output parameters,
@@ -141,7 +137,6 @@ public:
close (bool graceful) = 0;
};
} // namespace HTTP
} // ripple
#endif

View File

@@ -25,7 +25,6 @@
#include <vector>
namespace ripple {
namespace HTTP {
class Writer
{
@@ -58,7 +57,6 @@ public:
data() = 0;
};
}
}
} // ripple
#endif

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#ifndef RIPPLE_SERVER_PEER_H_INCLUDED
#define RIPPLE_SERVER_PEER_H_INCLUDED
#ifndef RIPPLE_SERVER_BASEHTTPPEER_H_INCLUDED
#define RIPPLE_SERVER_BASEHTTPPEER_H_INCLUDED
#include <ripple/server/impl/Door.h>
#include <ripple/server/Session.h>
@@ -42,11 +42,10 @@
#include <type_traits>
namespace ripple {
namespace HTTP {
/** Represents an active connection. */
template <class Impl>
class Peer
class BaseHTTPPeer
: public Door::Child
, public Session
{
@@ -109,12 +108,12 @@ protected:
public:
template <class ConstBufferSequence>
Peer (Door& door, boost::asio::io_service& io_service,
BaseHTTPPeer (Door& door, boost::asio::io_service& io_service,
beast::Journal journal, endpoint_type remote_address,
ConstBufferSequence const& buffers);
virtual
~Peer();
~BaseHTTPPeer();
Session&
session()
@@ -214,7 +213,7 @@ protected:
template <class Impl>
template <class ConstBufferSequence>
Peer<Impl>::Peer (Door& door, boost::asio::io_service& io_service,
BaseHTTPPeer<Impl>::BaseHTTPPeer (Door& door, boost::asio::io_service& io_service,
beast::Journal journal, endpoint_type remote_address,
ConstBufferSequence const& buffers)
: Child(door)
@@ -235,7 +234,7 @@ Peer<Impl>::Peer (Door& door, boost::asio::io_service& io_service,
}
template <class Impl>
Peer<Impl>::~Peer()
BaseHTTPPeer<Impl>::~BaseHTTPPeer()
{
Stat stat;
stat.id = nid_;
@@ -246,7 +245,8 @@ Peer<Impl>::~Peer()
stat.bytes_out = bytes_out_;
stat.ec = std::move (ec_);
door_.server().report (std::move (stat));
door_.server().handler().onClose (session(), ec_);
if(door_.server().handler())
door_.server().handler()->onClose(session(), ec_);
if (journal_.trace) journal_.trace << id_ <<
"destroyed: " << request_count_ <<
((request_count_ == 1) ? " request" : " requests");
@@ -254,11 +254,11 @@ Peer<Impl>::~Peer()
template <class Impl>
void
Peer<Impl>::close()
BaseHTTPPeer<Impl>::close()
{
if (! strand_.running_in_this_thread())
return strand_.post(std::bind(
(void(Peer::*)(void))&Peer::close,
(void(BaseHTTPPeer::*)(void))&BaseHTTPPeer::close,
impl().shared_from_this()));
error_code ec;
impl().stream_.lowest_layer().close(ec);
@@ -268,7 +268,7 @@ Peer<Impl>::close()
template <class Impl>
void
Peer<Impl>::fail (error_code ec, char const* what)
BaseHTTPPeer<Impl>::fail (error_code ec, char const* what)
{
if (! ec_ && ec != boost::asio::error::operation_aborted)
{
@@ -281,21 +281,21 @@ Peer<Impl>::fail (error_code ec, char const* what)
template <class Impl>
void
Peer<Impl>::start_timer()
BaseHTTPPeer<Impl>::start_timer()
{
error_code ec;
timer_.expires_from_now (std::chrono::seconds(timeoutSeconds), ec);
if (ec)
return fail (ec, "start_timer");
timer_.async_wait (strand_.wrap (std::bind (
&Peer<Impl>::on_timer, impl().shared_from_this(),
&BaseHTTPPeer<Impl>::on_timer, impl().shared_from_this(),
beast::asio::placeholders::error)));
}
// Convenience for discarding the error code
template <class Impl>
void
Peer<Impl>::cancel_timer()
BaseHTTPPeer<Impl>::cancel_timer()
{
error_code ec;
timer_.cancel(ec);
@@ -304,7 +304,7 @@ Peer<Impl>::cancel_timer()
// Called when session times out
template <class Impl>
void
Peer<Impl>::on_timer (error_code ec)
BaseHTTPPeer<Impl>::on_timer (error_code ec)
{
if (ec == boost::asio::error::operation_aborted)
return;
@@ -318,7 +318,7 @@ Peer<Impl>::on_timer (error_code ec)
template <class Impl>
void
Peer<Impl>::do_read (yield_context yield)
BaseHTTPPeer<Impl>::do_read (yield_context yield)
{
complete_ = false;
@@ -385,7 +385,7 @@ Peer<Impl>::do_read (yield_context yield)
// The write queue must not be empty upon entry.
template <class Impl>
void
Peer<Impl>::do_write (yield_context yield)
BaseHTTPPeer<Impl>::do_write (yield_context yield)
{
error_code ec;
std::size_t bytes = 0;
@@ -429,13 +429,13 @@ Peer<Impl>::do_write (yield_context yield)
if (graceful_)
return do_close();
boost::asio::spawn (strand_, std::bind (&Peer<Impl>::do_read,
boost::asio::spawn (strand_, std::bind (&BaseHTTPPeer<Impl>::do_read,
impl().shared_from_this(), std::placeholders::_1));
}
template <class Impl>
void
Peer<Impl>::do_writer (std::shared_ptr <Writer> const& writer,
BaseHTTPPeer<Impl>::do_writer (std::shared_ptr <Writer> const& writer,
bool keep_alive, yield_context yield)
{
std::function <void(void)> resume;
@@ -445,7 +445,7 @@ Peer<Impl>::do_writer (std::shared_ptr <Writer> const& writer,
[this, p, writer, keep_alive]()
{
boost::asio::spawn (strand_, std::bind (
&Peer<Impl>::do_writer, p, writer, keep_alive,
&BaseHTTPPeer<Impl>::do_writer, p, writer, keep_alive,
std::placeholders::_1));
});
}
@@ -468,7 +468,7 @@ Peer<Impl>::do_writer (std::shared_ptr <Writer> const& writer,
if (! keep_alive)
return do_close();
boost::asio::spawn (strand_, std::bind (&Peer<Impl>::do_read,
boost::asio::spawn (strand_, std::bind (&BaseHTTPPeer<Impl>::do_read,
impl().shared_from_this(), std::placeholders::_1));
}
@@ -477,7 +477,7 @@ Peer<Impl>::do_writer (std::shared_ptr <Writer> const& writer,
// Send a copy of the data.
template <class Impl>
void
Peer<Impl>::write (void const* buffer, std::size_t bytes)
BaseHTTPPeer<Impl>::write (void const* buffer, std::size_t bytes)
{
if (bytes == 0)
return;
@@ -490,17 +490,17 @@ Peer<Impl>::write (void const* buffer, std::size_t bytes)
}
if (empty)
boost::asio::spawn (strand_, std::bind (&Peer<Impl>::do_write,
boost::asio::spawn (strand_, std::bind (&BaseHTTPPeer<Impl>::do_write,
impl().shared_from_this(), std::placeholders::_1));
}
template <class Impl>
void
Peer<Impl>::write (std::shared_ptr <Writer> const& writer,
BaseHTTPPeer<Impl>::write (std::shared_ptr <Writer> const& writer,
bool keep_alive)
{
boost::asio::spawn (strand_, std::bind (
&Peer<Impl>::do_writer, impl().shared_from_this(),
&BaseHTTPPeer<Impl>::do_writer, impl().shared_from_this(),
writer, keep_alive, std::placeholders::_1));
}
@@ -508,7 +508,7 @@ Peer<Impl>::write (std::shared_ptr <Writer> const& writer,
// Make the Session asynchronous
template <class Impl>
std::shared_ptr<Session>
Peer<Impl>::detach()
BaseHTTPPeer<Impl>::detach()
{
return impl().shared_from_this();
}
@@ -517,10 +517,10 @@ Peer<Impl>::detach()
// Called to indicate the response has been written (but not sent)
template <class Impl>
void
Peer<Impl>::complete()
BaseHTTPPeer<Impl>::complete()
{
if (! strand_.running_in_this_thread())
return strand_.post(std::bind (&Peer<Impl>::complete,
return strand_.post(std::bind (&BaseHTTPPeer<Impl>::complete,
impl().shared_from_this()));
message_ = beast::http::message{};
@@ -533,7 +533,7 @@ Peer<Impl>::complete()
}
// keep-alive
boost::asio::spawn (strand_, std::bind (&Peer<Impl>::do_read,
boost::asio::spawn (strand_, std::bind (&BaseHTTPPeer<Impl>::do_read,
impl().shared_from_this(), std::placeholders::_1));
}
@@ -541,11 +541,11 @@ Peer<Impl>::complete()
// Called from the Handler to close the session.
template <class Impl>
void
Peer<Impl>::close (bool graceful)
BaseHTTPPeer<Impl>::close (bool graceful)
{
if (! strand_.running_in_this_thread())
return strand_.post(std::bind(
(void(Peer::*)(bool))&Peer<Impl>::close,
(void(BaseHTTPPeer::*)(bool))&BaseHTTPPeer<Impl>::close,
impl().shared_from_this(), graceful));
complete_ = true;
@@ -564,7 +564,6 @@ Peer<Impl>::close (bool graceful)
impl().stream_.lowest_layer().close (ec);
}
}
}
} // ripple
#endif

View File

@@ -20,15 +20,14 @@
#include <BeastConfig.h>
#include <ripple/basics/contract.h>
#include <ripple/server/impl/Door.h>
#include <ripple/server/impl/PlainPeer.h>
#include <ripple/server/impl/SSLPeer.h>
#include <ripple/server/impl/PlainHTTPPeer.h>
#include <ripple/server/impl/SSLHTTPPeer.h>
#include <boost/asio/buffer.hpp>
#include <beast/asio/placeholders.h>
#include <beast/asio/ssl_bundle.h>
#include <functional>
namespace ripple {
namespace HTTP {
/** Detect SSL client handshakes.
Analyzes the bytes in the provided buffer to detect the SSL client
@@ -225,7 +224,7 @@ void
Door::run()
{
boost::asio::spawn (strand_, std::bind (&Door::do_accept,
shared_from_this(), std::placeholders::_1));
this, std::placeholders::_1));
}
void
@@ -233,7 +232,7 @@ Door::close()
{
if (! strand_.running_in_this_thread())
return strand_.post(std::bind(
&Door::close, shared_from_this()));
&Door::close, this));
error_code ec;
acceptor_.close(ec);
// Close all detector, Peer objects
@@ -259,7 +258,9 @@ void
Door::remove (Child& c)
{
std::lock_guard<std::mutex> lock(mutex_);
list_.erase(&c);
auto const n = list_.erase(&c);
if(n != 1)
Throw<std::runtime_error>("missing child");
if (list_.empty())
cond_.notify_all();
}
@@ -283,14 +284,14 @@ Door::create (bool ssl, ConstBufferSequence const& buffers,
if (ssl)
{
auto const peer = std::make_shared <SSLPeer> (*this,
auto const peer = std::make_shared <SSLHTTPPeer> (*this,
server_.journal(), remote_address, buffers,
std::move(socket));
add(peer);
return peer->run();
}
auto const peer = std::make_shared <PlainPeer> (*this,
auto const peer = std::make_shared <PlainHTTPPeer> (*this,
server_.journal(), remote_address, buffers,
std::move(socket));
add(peer);
@@ -330,6 +331,4 @@ Door::do_accept (boost::asio::yield_context yield)
server_.remove();
}
}
} // ripple

View File

@@ -33,12 +33,10 @@
#include <mutex>
namespace ripple {
namespace HTTP {
/** A listening socket. */
class Door
: public ServerImpl::Child
, public std::enable_shared_from_this <Door>
{
public:
class Child
@@ -140,7 +138,6 @@ private:
void do_accept (yield_context yield);
};
}
}
} // ripple
#endif

View File

@@ -17,28 +17,27 @@
*/
//==============================================================================
#ifndef RIPPLE_SERVER_PLAINPEER_H_INCLUDED
#define RIPPLE_SERVER_PLAINPEER_H_INCLUDED
#ifndef RIPPLE_SERVER_PLAINHTTPPEER_H_INCLUDED
#define RIPPLE_SERVER_PLAINHTTPPEER_H_INCLUDED
#include <ripple/server/impl/Peer.h>
#include <ripple/server/impl/BaseHTTPPeer.h>
#include <memory>
namespace ripple {
namespace HTTP {
class PlainPeer
: public Peer <PlainPeer>
, public std::enable_shared_from_this <PlainPeer>
class PlainHTTPPeer
: public BaseHTTPPeer<PlainHTTPPeer>
, public std::enable_shared_from_this <PlainHTTPPeer>
{
private:
friend class Peer <PlainPeer>;
friend class BaseHTTPPeer<PlainHTTPPeer>;
using socket_type = boost::asio::ip::tcp::socket;
socket_type stream_;
public:
template <class ConstBufferSequence>
PlainPeer (Door& door, beast::Journal journal, endpoint_type endpoint,
PlainHTTPPeer (Door& door, beast::Journal journal, endpoint_type endpoint,
ConstBufferSequence const& buffers, socket_type&& socket);
void
@@ -55,30 +54,30 @@ private:
//------------------------------------------------------------------------------
template <class ConstBufferSequence>
PlainPeer::PlainPeer (Door& door, beast::Journal journal,
PlainHTTPPeer::PlainHTTPPeer (Door& door, beast::Journal journal,
endpoint_type remote_address, ConstBufferSequence const& buffers,
socket_type&& socket)
: Peer (door, socket.get_io_service(), journal, remote_address, buffers)
: BaseHTTPPeer (door, socket.get_io_service(), journal, remote_address, buffers)
, stream_(std::move(socket))
{
}
void
PlainPeer::run ()
PlainHTTPPeer::run ()
{
door_.server().handler().onAccept (session());
door_.server().handler()->onAccept (session());
if (! stream_.is_open())
return;
boost::asio::spawn (strand_, std::bind (&PlainPeer::do_read,
boost::asio::spawn (strand_, std::bind (&PlainHTTPPeer::do_read,
shared_from_this(), std::placeholders::_1));
}
void
PlainPeer::do_request()
PlainHTTPPeer::do_request()
{
++request_count_;
auto const what = door_.server().handler().onHandoff (session(),
auto const what = door_.server().handler()->onHandoff (session(),
std::move(stream_), std::move(message_), remote_address_);
if (what.moved)
return;
@@ -99,17 +98,16 @@ PlainPeer::do_request()
if (ec)
return fail (ec, "request");
// legacy
door_.server().handler().onRequest (session());
door_.server().handler()->onRequest (session());
}
void
PlainPeer::do_close()
PlainHTTPPeer::do_close()
{
error_code ec;
stream_.shutdown (socket_type::shutdown_send, ec);
}
}
}
} // ripple
#endif

View File

@@ -21,7 +21,29 @@
#include <beast/http/rfc2616.h>
namespace ripple {
namespace HTTP {
bool
Port::websockets() const
{
return protocol.count("ws") > 0 || protocol.count("wss") > 0;
}
bool
Port::secure() const
{
return protocol.count("peer") > 0 ||
protocol.count("https") > 0 || protocol.count("wss") > 0;
}
std::string
Port::protocols() const
{
std::string s;
for (auto iter = protocol.cbegin();
iter != protocol.cend(); ++iter)
s += (iter != protocol.cbegin() ? "," : "") + *iter;
return s;
}
std::ostream&
operator<< (std::ostream& os, Port const& p)
@@ -46,8 +68,6 @@ operator<< (std::ostream& os, Port const& p)
return os;
}
} // HTTP
//------------------------------------------------------------------------------
static

View File

@@ -23,7 +23,7 @@
namespace ripple {
bool
passwordUnrequiredOrSentCorrect (HTTP::Port const& port,
passwordUnrequiredOrSentCorrect (Port const& port,
Json::Value const& params) {
assert(! port.admin_ip.empty ());
@@ -47,7 +47,7 @@ ipAllowed (beast::IP::Address const& remoteIp,
}
bool
isAdmin (HTTP::Port const& port, Json::Value const& params,
isAdmin (Port const& port, Json::Value const& params,
beast::IP::Address const& remoteIp)
{
return ipAllowed (remoteIp, port.admin_ip) &&
@@ -55,7 +55,7 @@ isAdmin (HTTP::Port const& port, Json::Value const& params,
}
Role
requestRole (Role const& required, HTTP::Port const& port,
requestRole (Role const& required, Port const& port,
Json::Value const& params, beast::IP::Endpoint const& remoteIp,
std::string const& user)
{
@@ -75,7 +75,7 @@ requestRole (Role const& required, HTTP::Port const& port,
* ADMIN and IDENTIFIED roles shall have unlimited resources.
*/
bool
isUnlimited (Role const& required, HTTP::Port const& port,
isUnlimited (Role const& required, Port const& port,
Json::Value const&params, beast::IP::Endpoint const& remoteIp,
std::string const& user)
{
@@ -96,7 +96,7 @@ isUnlimited (Role const& role)
Resource::Consumer
requestInboundEndpoint (Resource::Manager& manager,
beast::IP::Endpoint const& remoteAddress,
HTTP::Port const& port, std::string const& user)
Port const& port, std::string const& user)
{
if (isUnlimited (Role::GUEST, port, Json::Value(), remoteAddress, user))
return manager.newUnlimitedEndpoint (to_string (remoteAddress));
@@ -105,7 +105,7 @@ requestInboundEndpoint (Resource::Manager& manager,
}
bool
isIdentified (HTTP::Port const& port, beast::IP::Address const& remoteIp,
isIdentified (Port const& port, beast::IP::Address const& remoteIp,
std::string const& user)
{
return ! user.empty() && ipAllowed (remoteIp, port.secure_gateway_ip);

View File

@@ -17,22 +17,21 @@
*/
//==============================================================================
#ifndef RIPPLE_SERVER_SSLPEER_H_INCLUDED
#define RIPPLE_SERVER_SSLPEER_H_INCLUDED
#ifndef RIPPLE_SERVER_SSLHTTPPEER_H_INCLUDED
#define RIPPLE_SERVER_SSLHTTPPEER_H_INCLUDED
#include <ripple/server/impl/Peer.h>
#include <ripple/server/impl/BaseHTTPPeer.h>
#include <beast/asio/ssl_bundle.h>
#include <memory>
namespace ripple {
namespace HTTP {
class SSLPeer
: public Peer <SSLPeer>
, public std::enable_shared_from_this <SSLPeer>
class SSLHTTPPeer
: public BaseHTTPPeer<SSLHTTPPeer>
, public std::enable_shared_from_this <SSLHTTPPeer>
{
private:
friend class Peer <SSLPeer>;
friend class BaseHTTPPeer<SSLHTTPPeer>;
using socket_type = boost::asio::ip::tcp::socket;
using stream_type = boost::asio::ssl::stream <socket_type&>;
@@ -41,7 +40,7 @@ private:
public:
template <class ConstBufferSequence>
SSLPeer (Door& door, beast::Journal journal, endpoint_type remote_address,
SSLHTTPPeer (Door& door, beast::Journal journal, endpoint_type remote_address,
ConstBufferSequence const& buffers, socket_type&& socket);
void
@@ -64,10 +63,10 @@ private:
//------------------------------------------------------------------------------
template <class ConstBufferSequence>
SSLPeer::SSLPeer (Door& door, beast::Journal journal,
SSLHTTPPeer::SSLHTTPPeer (Door& door, beast::Journal journal,
endpoint_type remote_address, ConstBufferSequence const& buffers,
socket_type&& socket)
: Peer (door, socket.get_io_service(), journal, remote_address, buffers)
: BaseHTTPPeer (door, socket.get_io_service(), journal, remote_address, buffers)
, ssl_bundle_(std::make_unique<beast::asio::ssl_bundle>(
port().context, std::move(socket)))
, stream_(ssl_bundle_->stream)
@@ -76,18 +75,18 @@ SSLPeer::SSLPeer (Door& door, beast::Journal journal,
// Called when the acceptor accepts our socket.
void
SSLPeer::run()
SSLHTTPPeer::run()
{
door_.server().handler().onAccept (session());
door_.server().handler()->onAccept (session());
if (! stream_.lowest_layer().is_open())
return;
boost::asio::spawn (strand_, std::bind (&SSLPeer::do_handshake,
boost::asio::spawn (strand_, std::bind (&SSLHTTPPeer::do_handshake,
shared_from_this(), std::placeholders::_1));
}
void
SSLPeer::do_handshake (yield_context yield)
SSLHTTPPeer::do_handshake (yield_context yield)
{
error_code ec;
stream_.set_verify_mode (boost::asio::ssl::verify_none);
@@ -103,7 +102,7 @@ SSLPeer::do_handshake (yield_context yield)
port().protocol.count("https") > 0;
if (http)
{
boost::asio::spawn (strand_, std::bind (&SSLPeer::do_read,
boost::asio::spawn (strand_, std::bind (&SSLHTTPPeer::do_read,
shared_from_this(), std::placeholders::_1));
return;
}
@@ -111,36 +110,35 @@ SSLPeer::do_handshake (yield_context yield)
}
void
SSLPeer::do_request()
SSLHTTPPeer::do_request()
{
++request_count_;
auto const what = door_.server().handler().onHandoff (session(),
auto const what = door_.server().handler()->onHandoff (session(),
std::move(ssl_bundle_), std::move(message_), remote_address_);
if (what.moved)
return;
if (what.response)
return write(what.response, what.keep_alive);
// legacy
door_.server().handler().onRequest (session());
door_.server().handler()->onRequest (session());
}
void
SSLPeer::do_close()
SSLHTTPPeer::do_close()
{
start_timer();
stream_.async_shutdown (strand_.wrap (std::bind (
&SSLPeer::on_shutdown, shared_from_this(),
&SSLHTTPPeer::on_shutdown, shared_from_this(),
std::placeholders::_1)));
}
void
SSLPeer::on_shutdown (error_code ec)
SSLHTTPPeer::on_shutdown (error_code ec)
{
cancel_timer();
stream_.lowest_layer().close(ec);
}
}
}
} // ripple
#endif

View File

@@ -28,6 +28,7 @@
#include <ripple/basics/Log.h>
#include <ripple/basics/make_SSLContext.h>
#include <ripple/core/JobQueue.h>
#include <ripple/json/to_string.h>
#include <ripple/server/make_Server.h>
#include <ripple/overlay/Overlay.h>
#include <ripple/resource/ResourceManager.h>
@@ -62,7 +63,7 @@ ServerHandlerImp::ServerHandlerImp (Application& app, Stoppable& parent,
, m_resourceManager (resourceManager)
, m_journal (app_.journal("Server"))
, m_networkOPs (networkOPs)
, m_server (HTTP::make_Server(
, m_server (make_Server(
*this, io_service, app_.journal("Server")))
, m_jobQueue (jobQueue)
{
@@ -95,19 +96,19 @@ ServerHandlerImp::onStop()
//------------------------------------------------------------------------------
void
ServerHandlerImp::onAccept (HTTP::Session& session)
ServerHandlerImp::onAccept (Session& session)
{
}
bool
ServerHandlerImp::onAccept (HTTP::Session& session,
ServerHandlerImp::onAccept (Session& session,
boost::asio::ip::tcp::endpoint endpoint)
{
return true;
}
auto
ServerHandlerImp::onHandoff (HTTP::Session& session,
ServerHandlerImp::onHandoff (Session& session,
std::unique_ptr <beast::asio::ssl_bundle>&& bundle,
beast::http::message&& request,
boost::asio::ip::tcp::endpoint remote_address) ->
@@ -129,7 +130,7 @@ ServerHandlerImp::onHandoff (HTTP::Session& session,
}
auto
ServerHandlerImp::onHandoff (HTTP::Session& session,
ServerHandlerImp::onHandoff (Session& session,
boost::asio::ip::tcp::socket&& socket,
beast::http::message&& request,
boost::asio::ip::tcp::endpoint remote_address) ->
@@ -148,7 +149,7 @@ ServerHandlerImp::onHandoff (HTTP::Session& session,
}
static inline
Json::Output makeOutput (HTTP::Session& session)
Json::Output makeOutput (Session& session)
{
return [&](boost::string_ref const& b)
{
@@ -157,7 +158,7 @@ Json::Output makeOutput (HTTP::Session& session)
}
void
ServerHandlerImp::onRequest (HTTP::Session& session)
ServerHandlerImp::onRequest (Session& session)
{
// Make sure RPC is enabled on the port
if (session.port().protocol.count("http") == 0 &&
@@ -185,13 +186,13 @@ ServerHandlerImp::onRequest (HTTP::Session& session)
}
void
ServerHandlerImp::onClose (HTTP::Session& session,
ServerHandlerImp::onClose (Session& session,
boost::system::error_code const&)
{
}
void
ServerHandlerImp::onStopped (HTTP::Server&)
ServerHandlerImp::onStopped (Server&)
{
stopped();
}
@@ -200,7 +201,7 @@ ServerHandlerImp::onStopped (HTTP::Server&)
// Run as a couroutine.
void
ServerHandlerImp::processSession (std::shared_ptr<HTTP::Session> const& session,
ServerHandlerImp::processSession (std::shared_ptr<Session> const& session,
std::shared_ptr<JobCoro> jobCoro)
{
processRequest (session->port(), to_string (session->body()),
@@ -231,7 +232,7 @@ ServerHandlerImp::processSession (std::shared_ptr<HTTP::Session> const& session,
}
void
ServerHandlerImp::processRequest (HTTP::Port const& port,
ServerHandlerImp::processRequest (Port const& port,
std::string const& request, beast::IP::Endpoint const& remoteIPAddress,
Output&& output, std::shared_ptr<JobCoro> jobCoro,
std::string forwardedFor, std::string user)
@@ -426,7 +427,7 @@ ServerHandlerImp::isWebsocketUpgrade (beast::http::message const& request)
// VFALCO TODO Rewrite to use beast::http::headers
bool
ServerHandlerImp::authorized (HTTP::Port const& port,
ServerHandlerImp::authorized (Port const& port,
std::map<std::string, std::string> const& h)
{
if (port.user.empty() || port.password.empty())
@@ -487,10 +488,10 @@ ServerHandler::Setup::makeContexts()
}
static
HTTP::Port
Port
to_Port(ParsedPort const& parsed, std::ostream& log)
{
HTTP::Port p;
Port p;
p.name = parsed.name;
if (! parsed.ip)
@@ -543,12 +544,12 @@ to_Port(ParsedPort const& parsed, std::ostream& log)
}
static
std::vector<HTTP::Port>
std::vector<Port>
parse_Ports (
Config const& config,
std::ostream& log)
{
std::vector<HTTP::Port> result;
std::vector<Port> result;
if (! config.exists("server"))
{
@@ -596,7 +597,7 @@ parse_Ports (
{
auto const count = std::count_if (
result.cbegin(), result.cend(),
[](HTTP::Port const& p)
[](Port const& p)
{
return p.protocol.count("peer") != 0;
});
@@ -647,7 +648,7 @@ setup_Overlay (ServerHandler::Setup& setup)
{
auto const iter = std::find_if(
setup.ports.cbegin(), setup.ports.cend(),
[](HTTP::Port const& port)
[](Port const& port)
{
return port.protocol.count("peer") != 0;
});

View File

@@ -23,6 +23,7 @@
#include <ripple/core/Job.h>
#include <ripple/core/JobCoro.h>
#include <ripple/json/Output.h>
#include <ripple/server/Handler.h>
#include <ripple/server/ServerHandler.h>
#include <ripple/server/Session.h>
#include <ripple/rpc/RPCHandler.h>
@@ -33,14 +34,14 @@ namespace ripple {
// Private implementation
class ServerHandlerImp
: public ServerHandler
, public HTTP::Handler
, public Handler
{
private:
Application& app_;
Resource::Manager& m_resourceManager;
beast::Journal m_journal;
NetworkOPs& m_networkOPs;
std::unique_ptr<HTTP::Server> m_server;
std::unique_ptr<Server> m_server;
Setup setup_;
JobQueue& m_jobQueue;
beast::insight::Counter rpc_requests_;
@@ -79,40 +80,40 @@ private:
//
void
onAccept (HTTP::Session& session) override;
onAccept (Session& session) override;
bool
onAccept (HTTP::Session& session,
onAccept (Session& session,
boost::asio::ip::tcp::endpoint endpoint) override;
Handoff
onHandoff (HTTP::Session& session,
onHandoff (Session& session,
std::unique_ptr <beast::asio::ssl_bundle>&& bundle,
beast::http::message&& request,
boost::asio::ip::tcp::endpoint remote_address) override;
Handoff
onHandoff (HTTP::Session& session, boost::asio::ip::tcp::socket&& socket,
onHandoff (Session& session, boost::asio::ip::tcp::socket&& socket,
beast::http::message&& request,
boost::asio::ip::tcp::endpoint remote_address) override;
void
onRequest (HTTP::Session& session) override;
onRequest (Session& session) override;
void
onClose (HTTP::Session& session,
onClose (Session& session,
boost::system::error_code const&) override;
void
onStopped (HTTP::Server&) override;
onStopped (Server&) override;
//--------------------------------------------------------------------------
void
processSession (std::shared_ptr<HTTP::Session> const&,
processSession (std::shared_ptr<Session> const&,
std::shared_ptr<JobCoro> jobCoro);
void
processRequest (HTTP::Port const& port, std::string const& request,
processRequest (Port const& port, std::string const& request,
beast::IP::Endpoint const& remoteIPAddress, Output&&,
std::shared_ptr<JobCoro> jobCoro,
std::string forwardedFor, std::string user);
@@ -129,7 +130,7 @@ private:
isWebsocketUpgrade (beast::http::message const& request);
bool
authorized (HTTP::Port const& port,
authorized (Port const& port,
std::map<std::string, std::string> const& h);
};

View File

@@ -20,7 +20,7 @@
#include <BeastConfig.h>
#include <ripple/basics/contract.h>
#include <ripple/server/impl/ServerImpl.h>
#include <ripple/server/impl/Peer.h>
#include <ripple/server/impl/BaseHTTPPeer.h>
#include <beast/chrono/chrono_io.h>
#include <boost/chrono/chrono_io.hpp>
#include <boost/utility/in_place_factory.hpp>
@@ -33,7 +33,6 @@
#include <time.h>
namespace ripple {
namespace HTTP {
ServerImpl::ServerImpl (Handler& handler,
boost::asio::io_service& io_service, beast::Journal journal)
@@ -63,13 +62,13 @@ void
ServerImpl::ports (std::vector<Port> const& ports)
{
if (closed())
Throw<std::logic_error> ("ports() on closed HTTP::Server");
Throw<std::logic_error> ("ports() on closed Server");
for(auto const& port : ports)
{
if (! port.websockets())
{
++accepting_;
list_.emplace_back(std::make_shared<Door>(
list_.emplace_back(std::make_unique<Door>(
io_service_, *this, port));
}
}
@@ -214,5 +213,5 @@ make_Server (Handler& handler,
return std::make_unique<ServerImpl>(handler, io_service, journal);
}
}
}
} // ripple

View File

@@ -36,7 +36,6 @@
#include <thread>
namespace ripple {
namespace HTTP {
class BasicPeer;
class Door;
@@ -78,7 +77,7 @@ private:
std::mutex mutable mutex_;
std::condition_variable cond_;
std::vector<std::shared_ptr<Door>> list_;
std::vector<std::unique_ptr<Door>> list_;
std::size_t accepting_ = 0;
std::deque <Stat> stats_;
int high_ = 0;
@@ -107,10 +106,10 @@ public:
close() override;
public:
Handler&
Handler*
handler()
{
return *handler_;
return handler_;
}
boost::asio::io_service&
@@ -135,7 +134,6 @@ private:
};
}
}
} // ripple
#endif

View File

@@ -26,14 +26,12 @@
#include <boost/asio/io_service.hpp>
namespace ripple {
namespace HTTP {
/** Create the HTTP server using the specified handler. */
std::unique_ptr<Server>
make_Server (Handler& handler,
boost::asio::io_service& io_service, beast::Journal journal);
} // HTTP
} // ripple
#endif

View File

@@ -19,10 +19,12 @@
#include <BeastConfig.h>
#include <ripple/basics/make_SSLContext.h>
#include <ripple/server/Handler.h>
#include <ripple/server/make_Server.h>
#include <ripple/server/Server.h>
#include <ripple/server/Session.h>
#include <beast/unit_test/suite.h>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio.hpp>
#include <boost/optional.hpp>
#include <boost/utility/in_place_factory.hpp>
#include <chrono>
@@ -30,14 +32,14 @@
#include <thread>
namespace ripple {
namespace HTTP {
namespace test {
class Server_test : public beast::unit_test::suite
{
public:
enum
{
testPort = 1001
testPort = 40000
};
class TestThread
@@ -283,8 +285,7 @@ public:
}
}
void
run()
void basicTests()
{
TestSink sink {*this};
TestThread thread;
@@ -308,9 +309,83 @@ public:
pass();
}
void stressTest()
{
struct NullHandler : Handler
{
void
onAccept (Session& session) override
{
}
bool
onAccept (Session& session,
boost::asio::ip::tcp::endpoint endpoint) override
{
return true;
}
Handoff
onHandoff (Session& session,
std::unique_ptr <beast::asio::ssl_bundle>&& bundle,
beast::http::message&& request,
boost::asio::ip::tcp::endpoint remote_address) override
{
return Handoff{};
}
Handoff
onHandoff (Session& session, boost::asio::ip::tcp::socket&& socket,
beast::http::message&& request,
boost::asio::ip::tcp::endpoint remote_address) override
{
return Handoff{};
}
void
onRequest (Session& session) override
{
}
void
onClose (Session& session,
boost::system::error_code const&) override
{
}
void
onStopped (Server& server) override
{
}
};
NullHandler h;
for(int i = 0; i < 10000; ++i)
{
TestThread thread;
auto s = make_Server(h,
thread.get_io_service(), {});
std::vector<Port> list;
list.resize(1);
list.back().port = testPort;
list.back().ip = boost::asio::ip::address::from_string (
"127.0.0.1");
list.back().protocol.insert("http");
s->ports (list);
}
}
void
run()
{
basicTests();
stressTest();
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(Server,http,ripple);
BEAST_DEFINE_TESTSUITE(Server,http,ripple);
} // test
} // ripple
}
}

View File

@@ -16,6 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#if DOXYGEN
#include <ripple/server/README.md>
#endif
@@ -28,4 +29,5 @@
#include <ripple/server/impl/Role.cpp>
#include <ripple/server/impl/ServerImpl.cpp>
#include <ripple/server/impl/ServerHandlerImp.cpp>
#include <ripple/server/tests/Server.test.cpp>
#include <ripple/server/tests/Server_test.cpp>

View File

@@ -104,7 +104,7 @@ public:
private:
Application& app_;
HTTP::Port const& m_port;
Port const& m_port;
Resource::Manager& m_resourceManager;
Resource::Consumer m_usage;
beast::IP::Endpoint const m_remoteAddress;

View File

@@ -101,7 +101,7 @@ public:
HandlerImpl(HandlerImpl const&) = delete;
HandlerImpl& operator= (HandlerImpl const&) = delete;
HTTP::Port const&
Port const&
port() const
{
return desc_.port;

View File

@@ -38,7 +38,7 @@ namespace websocket {
struct ServerDescription
{
Application& app;
HTTP::Port port;
Port port;
Resource::Manager& resourceManager;
InfoSub::Source& source;
beast::Journal& journal;