mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
SETUP_LOG();
|
||||
|
||||
LogPartition TaggedCachePartition("TaggedCache");
|
||||
LogPartition AutoSocketPartition("AutoSocket");
|
||||
Application* theApp = NULL;
|
||||
|
||||
DatabaseCon::DatabaseCon(const std::string& strName, const char *initStrings[], int initCount)
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
|
||||
#include "AutoSocket.h"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
void AutoSocket::handle_autodetect(const error_code& ec)
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
if (mCallback)
|
||||
mCallback(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((mBuffer[0] < 127) && (mBuffer[0] > 31) &&
|
||||
(mBuffer[1] < 127) && (mBuffer[1] > 31) &&
|
||||
(mBuffer[2] < 127) && (mBuffer[2] > 31) &&
|
||||
(mBuffer[3] < 127) && (mBuffer[3] > 31))
|
||||
{ // non-SSL
|
||||
mSecure = false;
|
||||
if (mCallback)
|
||||
mCallback(ec);
|
||||
}
|
||||
else
|
||||
{ // ssl
|
||||
mSecure = true;
|
||||
SSLSocket().async_handshake(ssl_socket::server, mCallback);
|
||||
mCallback = callback();
|
||||
}
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
@@ -5,9 +5,14 @@
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/smart_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
|
||||
#include "Log.h"
|
||||
extern LogPartition AutoSocketPartition;
|
||||
|
||||
// Socket wrapper that supports both SSL and non-SSL connections.
|
||||
// Generally, handle it as you would an SSL connection.
|
||||
// To force a non-SSL connection, just don't call async_handshake.
|
||||
@@ -20,78 +25,140 @@ class AutoSocket
|
||||
{
|
||||
public:
|
||||
typedef bassl::stream<basio::ip::tcp::socket> ssl_socket;
|
||||
typedef boost::shared_ptr<ssl_socket> socket_ptr;
|
||||
typedef ssl_socket::next_layer_type plain_socket;
|
||||
typedef ssl_socket::lowest_layer_type lowest_layer_type;
|
||||
typedef ssl_socket::handshake_type handshake_type;
|
||||
typedef boost::system::error_code error_code;
|
||||
typedef boost::function<void(error_code)> callback;
|
||||
typedef boost::function<void(error_code)> callback;
|
||||
|
||||
protected:
|
||||
ssl_socket mSocket;
|
||||
socket_ptr mSocket;
|
||||
bool mSecure;
|
||||
callback mCallback;
|
||||
|
||||
std::vector<char> mBuffer;
|
||||
|
||||
public:
|
||||
AutoSocket(basio::io_service& s, bassl::context& c) : mSocket(s, c), mSecure(false), mBuffer(4) { ; }
|
||||
AutoSocket(basio::io_service& s, bassl::context& c) : mSecure(false), mBuffer(4)
|
||||
{
|
||||
mSocket = boost::make_shared<ssl_socket>(boost::ref(s), boost::ref(c));
|
||||
}
|
||||
|
||||
AutoSocket(basio::io_service& s, bassl::context& c, bool secureOnly, bool plainOnly)
|
||||
: mSecure(secureOnly), mBuffer((plainOnly || secureOnly) ? 0 : 4)
|
||||
{
|
||||
mSocket = boost::make_shared<ssl_socket>(boost::ref(s), boost::ref(c));
|
||||
}
|
||||
|
||||
bool isSecure() { return mSecure; }
|
||||
ssl_socket& SSLSocket() { return mSocket; }
|
||||
plain_socket& PlainSocket() { return mSocket.next_layer(); }
|
||||
ssl_socket& SSLSocket() { return *mSocket; }
|
||||
plain_socket& PlainSocket() { return mSocket->next_layer(); }
|
||||
void setSSLOnly() { mSecure = true;}
|
||||
void setPlainOnly() { mBuffer.clear(); }
|
||||
|
||||
void setSSLOnly() { mBuffer.clear(); }
|
||||
lowest_layer_type& lowest_layer() { return mSocket->lowest_layer(); }
|
||||
|
||||
void async_handshake(ssl_socket::handshake_type type, callback cbFunc)
|
||||
void swap(AutoSocket& s)
|
||||
{
|
||||
mSecure = true;
|
||||
if ((type == ssl_socket::client) || (mBuffer.empty()))
|
||||
SSLSocket().async_handshake(type, cbFunc);
|
||||
mBuffer.swap(s.mBuffer);
|
||||
mSocket.swap(s.mSocket);
|
||||
std::swap(mSecure, s.mSecure);
|
||||
}
|
||||
|
||||
void async_handshake(handshake_type type, callback cbFunc)
|
||||
{
|
||||
if ((type == ssl_socket::client) || (mSecure))
|
||||
{ // must be ssl
|
||||
mSecure = true;
|
||||
mSocket->async_handshake(type, cbFunc);
|
||||
}
|
||||
else if (mBuffer.empty())
|
||||
{ // must be plain
|
||||
mSecure = false;
|
||||
mSocket->get_io_service().post(boost::bind(cbFunc, error_code()));
|
||||
}
|
||||
else
|
||||
{
|
||||
mCallback = cbFunc;
|
||||
PlainSocket().async_receive(basio::buffer(mBuffer), basio::socket_base::message_peek,
|
||||
boost::bind(&AutoSocket::handle_autodetect, this, basio::placeholders::error));
|
||||
|
||||
{ // autodetect
|
||||
mSocket->next_layer().async_receive(basio::buffer(mBuffer), basio::socket_base::message_peek,
|
||||
boost::bind(&AutoSocket::handle_autodetect, this, cbFunc, basio::placeholders::error));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename StreamType> StreamType& getSocket()
|
||||
{
|
||||
if (isSecure())
|
||||
return SSLSocket();
|
||||
if (!isSecure())
|
||||
return PlainSocket();
|
||||
}
|
||||
|
||||
template <typename ShutdownHandler> void async_shutdown(ShutdownHandler handler)
|
||||
{
|
||||
if (isSecure())
|
||||
SSLSocket().async_shutdown(handler);
|
||||
mSocket->async_shutdown(handler);
|
||||
else
|
||||
{
|
||||
PlainSocket().shutdown(plain_socket::shutdown_both);
|
||||
if (handler)
|
||||
mSocket.get_io_service().post(handler);
|
||||
lowest_layer().shutdown(plain_socket::shutdown_both);
|
||||
mSocket->get_io_service().post(boost::bind(handler, error_code()));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Seq, typename Handler> void async_read_some(const Seq& buffers, Handler handler)
|
||||
{
|
||||
if (isSecure())
|
||||
SSLSocket().async_read_some(buffers, handler);
|
||||
mSocket->async_read_some(buffers, handler);
|
||||
else
|
||||
PlainSocket().async_read_some(buffers, handler);
|
||||
}
|
||||
|
||||
template <typename Buf, typename Handler> void async_write(const Buf& buffers, Handler handler)
|
||||
{
|
||||
if (isSecure())
|
||||
boost::asio::async_write(*mSocket, buffers, handler);
|
||||
else
|
||||
boost::asio::async_write(PlainSocket(), buffers, handler);
|
||||
}
|
||||
|
||||
|
||||
template <typename Buf, typename Condition, typename Handler>
|
||||
void async_read(const Buf& buffers, Condition cond, Handler handler)
|
||||
{
|
||||
if (isSecure())
|
||||
boost::asio::async_read(*mSocket, buffers, cond, handler);
|
||||
else
|
||||
boost::asio::async_read(PlainSocket(), buffers, cond, handler);
|
||||
}
|
||||
|
||||
template <typename Buf, typename Handler> void async_read(const Buf& buffers, Handler handler)
|
||||
{
|
||||
if (isSecure())
|
||||
boost::asio::async_read(*mSocket, buffers, handler);
|
||||
else
|
||||
boost::asio::async_read(PlainSocket(), buffers, handler);
|
||||
}
|
||||
|
||||
template <typename Seq, typename Handler> void async_write_some(const Seq& buffers, Handler handler)
|
||||
{
|
||||
if (isSecure())
|
||||
SSLSocket().async_write_some(buffers, handler);
|
||||
mSocket->async_write_some(buffers, handler);
|
||||
else
|
||||
PlainSocket().async_write_some(buffers, handler);
|
||||
}
|
||||
|
||||
protected:
|
||||
void handle_autodetect(const error_code&);
|
||||
void handle_autodetect(callback cbFunc, const error_code& ec)
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
Log(lsWARNING, AutoSocketPartition) << "Handle autodetect error: " << ec;
|
||||
cbFunc(ec);
|
||||
}
|
||||
else if ((mBuffer[0] < 127) && (mBuffer[0] > 31) &&
|
||||
(mBuffer[1] < 127) && (mBuffer[1] > 31) &&
|
||||
(mBuffer[2] < 127) && (mBuffer[2] > 31) &&
|
||||
(mBuffer[3] < 127) && (mBuffer[3] > 31))
|
||||
{ // not ssl
|
||||
mSecure = false;
|
||||
cbFunc(ec);
|
||||
}
|
||||
else
|
||||
{ // ssl
|
||||
mSecure = true;
|
||||
mSocket->async_handshake(ssl_socket::server, cbFunc);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -178,8 +178,8 @@ Config::Config()
|
||||
RPC_PORT = 5001;
|
||||
WEBSOCKET_PORT = SYSTEM_WEBSOCKET_PORT;
|
||||
WEBSOCKET_PUBLIC_PORT = SYSTEM_WEBSOCKET_PUBLIC_PORT;
|
||||
WEBSOCKET_PUBLIC_SECURE = true;
|
||||
WEBSOCKET_SECURE = false;
|
||||
WEBSOCKET_PUBLIC_SECURE = 1;
|
||||
WEBSOCKET_SECURE = 0;
|
||||
NUMBER_CONNECTIONS = 30;
|
||||
|
||||
// a new ledger every minute
|
||||
@@ -340,10 +340,10 @@ void Config::load()
|
||||
WEBSOCKET_PUBLIC_PORT = boost::lexical_cast<int>(strTemp);
|
||||
|
||||
if (sectionSingleB(secConfig, SECTION_WEBSOCKET_SECURE, strTemp))
|
||||
WEBSOCKET_SECURE = boost::lexical_cast<bool>(strTemp);
|
||||
WEBSOCKET_SECURE = boost::lexical_cast<int>(strTemp);
|
||||
|
||||
if (sectionSingleB(secConfig, SECTION_WEBSOCKET_PUBLIC_SECURE, strTemp))
|
||||
WEBSOCKET_PUBLIC_SECURE = boost::lexical_cast<bool>(strTemp);
|
||||
WEBSOCKET_PUBLIC_SECURE = boost::lexical_cast<int>(strTemp);
|
||||
|
||||
sectionSingleB(secConfig, SECTION_WEBSOCKET_SSL_CERT, WEBSOCKET_SSL_CERT);
|
||||
sectionSingleB(secConfig, SECTION_WEBSOCKET_SSL_CHAIN, WEBSOCKET_SSL_CHAIN);
|
||||
|
||||
@@ -101,11 +101,12 @@ public:
|
||||
// Websocket networking parameters
|
||||
std::string WEBSOCKET_PUBLIC_IP; // XXX Going away. Merge with the inbound peer connction.
|
||||
int WEBSOCKET_PUBLIC_PORT;
|
||||
bool WEBSOCKET_PUBLIC_SECURE;
|
||||
int WEBSOCKET_PUBLIC_SECURE;
|
||||
|
||||
std::string WEBSOCKET_IP;
|
||||
int WEBSOCKET_PORT;
|
||||
bool WEBSOCKET_SECURE;
|
||||
int WEBSOCKET_SECURE;
|
||||
|
||||
std::string WEBSOCKET_SSL_CERT;
|
||||
std::string WEBSOCKET_SSL_CHAIN;
|
||||
std::string WEBSOCKET_SSL_KEY;
|
||||
|
||||
@@ -100,9 +100,10 @@ std::vector<RippleAddress> SerializedTransaction::getMentionedAccounts() const
|
||||
if (!found)
|
||||
accounts.push_back(na);
|
||||
}
|
||||
if (it.getFName() == sfLimitAmount)
|
||||
const STAmount* sam = dynamic_cast<const STAmount*>(&it);
|
||||
if (sam)
|
||||
{
|
||||
uint160 issuer = dynamic_cast<const STAmount*>(&it)->getIssuer();
|
||||
uint160 issuer = sam->getIssuer();
|
||||
if (issuer.isNonZero())
|
||||
{
|
||||
RippleAddress na;
|
||||
|
||||
@@ -127,28 +127,23 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
|
||||
uint32 t_seq = txn.getSequence();
|
||||
uint32 a_seq = txnAcct->getFieldU32(sfSequence);
|
||||
|
||||
if (t_seq != a_seq)
|
||||
{
|
||||
if (a_seq < t_seq)
|
||||
terResult = terPRE_SEQ;
|
||||
else
|
||||
terResult = tefPAST_SEQ;
|
||||
}
|
||||
if (a_seq < t_seq)
|
||||
terResult = terPRE_SEQ;
|
||||
else if (a_seq > t_seq)
|
||||
terResult = tefPAST_SEQ;
|
||||
else
|
||||
{
|
||||
STAmount fee = txn.getTransactionFee();
|
||||
STAmount balance = txnAcct->getFieldAmount(sfBalance);
|
||||
|
||||
if (balance < fee)
|
||||
{
|
||||
terResult = terINSUF_FEE_B;
|
||||
}
|
||||
else
|
||||
{
|
||||
txnAcct->setFieldAmount(sfBalance, balance - fee);
|
||||
txnAcct->setFieldU32(sfSequence, t_seq + 1);
|
||||
didApply = true;
|
||||
entryModify(txnAcct);
|
||||
didApply = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,8 @@ std::vector<RippleAddress> TransactionMetaSet::getAffectedAccounts()
|
||||
const STAccount* sa = dynamic_cast<const STAccount*>(&field);
|
||||
if (sa)
|
||||
addIfUnique(accounts, sa->getValueNCA());
|
||||
else if ((field.getFName() == sfLowLimit) || (field.getFName() == sfHighLimit))
|
||||
else if ((field.getFName() == sfLowLimit) || (field.getFName() == sfHighLimit) ||
|
||||
(field.getFName() == sfTakerPays) || (field.getFName() == sfTakerGets))
|
||||
{
|
||||
const STAmount* lim = dynamic_cast<const STAmount*>(&field);
|
||||
if (lim != NULL)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#include "../websocketpp/src/sockets/tls.hpp"
|
||||
#include "../websocketpp/src/sockets/autotls.hpp"
|
||||
#include "../websocketpp/src/websocketpp.hpp"
|
||||
|
||||
#include "../json/value.h"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "Log.h"
|
||||
|
||||
#define WSDOOR_CPP
|
||||
#include "../websocketpp/src/sockets/tls.hpp"
|
||||
#include "../websocketpp/src/sockets/autotls.hpp"
|
||||
#include "../websocketpp/src/websocketpp.hpp"
|
||||
|
||||
SETUP_LOG();
|
||||
@@ -59,80 +59,40 @@ void WSDoor::startListening()
|
||||
|
||||
SSL_CTX_set_tmp_dh_callback(mCtx->native_handle(), handleTmpDh);
|
||||
|
||||
if (mPublic ? theConfig.WEBSOCKET_PUBLIC_SECURE : theConfig.WEBSOCKET_SECURE)
|
||||
// Construct a single handler for all requests.
|
||||
websocketpp::server_autotls::handler::ptr handler(new WSServerHandler<websocketpp::server_autotls>(mCtx, mPublic));
|
||||
|
||||
// Construct a websocket server.
|
||||
mSEndpoint = new websocketpp::server_autotls(handler);
|
||||
|
||||
// mEndpoint->alog().unset_level(websocketpp::log::alevel::ALL);
|
||||
// mEndpoint->elog().unset_level(websocketpp::log::elevel::ALL);
|
||||
|
||||
// Call the main-event-loop of the websocket server.
|
||||
try
|
||||
{
|
||||
// Construct a single handler for all requests.
|
||||
websocketpp::server_tls::handler::ptr handler(new WSServerHandler<websocketpp::server_tls>(mCtx, mPublic));
|
||||
|
||||
// Construct a websocket server.
|
||||
mSEndpoint = new websocketpp::server_tls(handler);
|
||||
|
||||
// mEndpoint->alog().unset_level(websocketpp::log::alevel::ALL);
|
||||
// mEndpoint->elog().unset_level(websocketpp::log::elevel::ALL);
|
||||
|
||||
// Call the main-event-loop of the websocket server.
|
||||
try
|
||||
{
|
||||
mSEndpoint->listen(
|
||||
boost::asio::ip::tcp::endpoint(
|
||||
boost::asio::ip::address().from_string(mIp), mPort));
|
||||
}
|
||||
catch (websocketpp::exception& e)
|
||||
{
|
||||
cLog(lsWARNING) << "websocketpp exception: " << e.what();
|
||||
while (1) // temporary workaround for websocketpp throwing exceptions on access/close races
|
||||
{ // https://github.com/zaphoyd/websocketpp/issues/98
|
||||
try
|
||||
{
|
||||
mSEndpoint->get_io_service().run();
|
||||
break;
|
||||
}
|
||||
catch (websocketpp::exception& e)
|
||||
{
|
||||
cLog(lsWARNING) << "websocketpp exception: " << e.what();
|
||||
}
|
||||
mSEndpoint->listen(
|
||||
boost::asio::ip::tcp::endpoint(
|
||||
boost::asio::ip::address().from_string(mIp), mPort));
|
||||
}
|
||||
catch (websocketpp::exception& e)
|
||||
{
|
||||
cLog(lsWARNING) << "websocketpp exception: " << e.what();
|
||||
while (1) // temporary workaround for websocketpp throwing exceptions on access/close races
|
||||
{ // https://github.com/zaphoyd/websocketpp/issues/98
|
||||
try
|
||||
{
|
||||
mSEndpoint->get_io_service().run();
|
||||
break;
|
||||
}
|
||||
catch (websocketpp::exception& e)
|
||||
{
|
||||
cLog(lsWARNING) << "websocketpp exception: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
delete mSEndpoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Construct a single handler for all requests.
|
||||
websocketpp::server::handler::ptr handler(new WSServerHandler<websocketpp::server>(mCtx, mPublic));
|
||||
|
||||
// Construct a websocket server.
|
||||
mEndpoint = new websocketpp::server(handler);
|
||||
|
||||
// mEndpoint->alog().unset_level(websocketpp::log::alevel::ALL);
|
||||
// mEndpoint->elog().unset_level(websocketpp::log::elevel::ALL);
|
||||
|
||||
// Call the main-event-loop of the websocket server.
|
||||
try
|
||||
{
|
||||
mEndpoint->listen(
|
||||
boost::asio::ip::tcp::endpoint(
|
||||
boost::asio::ip::address().from_string(mIp), mPort));
|
||||
}
|
||||
catch (websocketpp::exception& e)
|
||||
{
|
||||
cLog(lsWARNING) << "websocketpp exception: " << e.what();
|
||||
while (1) // temporary workaround for websocketpp throwing exceptions on access/close races
|
||||
{ // https://github.com/zaphoyd/websocketpp/issues/98
|
||||
try
|
||||
{
|
||||
mEndpoint->get_io_service().run();
|
||||
break;
|
||||
}
|
||||
catch (websocketpp::exception& e)
|
||||
{
|
||||
cLog(lsWARNING) << "websocketpp exception: " << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete mEndpoint;
|
||||
}
|
||||
delete mSEndpoint;
|
||||
}
|
||||
|
||||
WSDoor* WSDoor::createWSDoor(const std::string& strIp, const int iPort, bool bPublic)
|
||||
@@ -154,8 +114,6 @@ void WSDoor::stop()
|
||||
{
|
||||
if (mThread)
|
||||
{
|
||||
if (mEndpoint)
|
||||
mEndpoint->stop();
|
||||
if (mSEndpoint)
|
||||
mSEndpoint->stop();
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace websocketpp
|
||||
{
|
||||
class server;
|
||||
class server_tls;
|
||||
class server_autotls;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -20,19 +20,18 @@ namespace websocketpp
|
||||
class WSDoor
|
||||
{
|
||||
private:
|
||||
websocketpp::server* mEndpoint;
|
||||
websocketpp::server_tls* mSEndpoint;
|
||||
websocketpp::server_autotls* mSEndpoint;
|
||||
|
||||
boost::thread* mThread;
|
||||
bool mPublic;
|
||||
std::string mIp;
|
||||
int mPort;
|
||||
boost::thread* mThread;
|
||||
bool mPublic;
|
||||
std::string mIp;
|
||||
int mPort;
|
||||
|
||||
void startListening();
|
||||
|
||||
public:
|
||||
|
||||
WSDoor(const std::string& strIp, int iPort, bool bPublic) : mEndpoint(0), mSEndpoint(0), mThread(0), mPublic(bPublic), mIp(strIp), mPort(iPort) { ; }
|
||||
WSDoor(const std::string& strIp, int iPort, bool bPublic) : mSEndpoint(0), mThread(0), mPublic(bPublic), mIp(strIp), mPort(iPort) { ; }
|
||||
|
||||
void stop();
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ protected:
|
||||
public:
|
||||
WSServerHandler(boost::shared_ptr<boost::asio::ssl::context> spCtx, bool bPublic) : mCtx(spCtx), mPublic(bPublic)
|
||||
{
|
||||
if (theConfig.WEBSOCKET_SECURE)
|
||||
if (theConfig.WEBSOCKET_SECURE != 0)
|
||||
{
|
||||
initSSLContext(*mCtx, theConfig.WEBSOCKET_SSL_KEY,
|
||||
theConfig.WEBSOCKET_SSL_CERT, theConfig.WEBSOCKET_SSL_CHAIN);
|
||||
|
||||
@@ -898,20 +898,39 @@ public:
|
||||
!m_protocol_error)
|
||||
{
|
||||
// TODO: read timeout timer?
|
||||
|
||||
boost::asio::async_read(
|
||||
socket_type::get_socket(),
|
||||
m_buf,
|
||||
boost::asio::transfer_at_least(std::min(
|
||||
m_read_threshold,
|
||||
static_cast<size_t>(m_processor->get_bytes_needed())
|
||||
)),
|
||||
m_strand.wrap(boost::bind(
|
||||
&type::handle_read_frame,
|
||||
type::shared_from_this(),
|
||||
boost::asio::placeholders::error
|
||||
))
|
||||
);
|
||||
|
||||
if (socket_type::get_socket().isSecure())
|
||||
{
|
||||
boost::asio::async_read(
|
||||
socket_type::get_socket().SSLSocket(),
|
||||
m_buf,
|
||||
boost::asio::transfer_at_least(std::min(
|
||||
m_read_threshold,
|
||||
static_cast<size_t>(m_processor->get_bytes_needed())
|
||||
)),
|
||||
m_strand.wrap(boost::bind(
|
||||
&type::handle_read_frame,
|
||||
type::shared_from_this(),
|
||||
boost::asio::placeholders::error
|
||||
))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::asio::async_read(
|
||||
socket_type::get_socket().PlainSocket(),
|
||||
m_buf,
|
||||
boost::asio::transfer_at_least(std::min(
|
||||
m_read_threshold,
|
||||
static_cast<size_t>(m_processor->get_bytes_needed())
|
||||
)),
|
||||
m_strand.wrap(boost::bind(
|
||||
&type::handle_read_frame,
|
||||
type::shared_from_this(),
|
||||
boost::asio::placeholders::error
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
@@ -1209,15 +1228,31 @@ public:
|
||||
|
||||
//m_endpoint.alog().at(log::alevel::DEVEL) << "write header: " << zsutil::to_hex(m_write_queue.front()->get_header()) << log::endl;
|
||||
|
||||
boost::asio::async_write(
|
||||
socket_type::get_socket(),
|
||||
m_write_buf,
|
||||
m_strand.wrap(boost::bind(
|
||||
&type::handle_write,
|
||||
type::shared_from_this(),
|
||||
boost::asio::placeholders::error
|
||||
))
|
||||
);
|
||||
if (socket_type::get_socket().isSecure())
|
||||
{
|
||||
boost::asio::async_write(
|
||||
socket_type::get_socket().SSLSocket(),
|
||||
m_write_buf,
|
||||
m_strand.wrap(boost::bind(
|
||||
&type::handle_write,
|
||||
type::shared_from_this(),
|
||||
boost::asio::placeholders::error
|
||||
))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::asio::async_write(
|
||||
socket_type::get_socket().PlainSocket(),
|
||||
m_write_buf,
|
||||
m_strand.wrap(boost::bind(
|
||||
&type::handle_write,
|
||||
type::shared_from_this(),
|
||||
boost::asio::placeholders::error
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
} else {
|
||||
// if we are in an inturrupted state and had nothing else to write
|
||||
// it is safe to terminate the connection.
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#define WEBSOCKETPP_ENDPOINT_HPP
|
||||
|
||||
#include "connection.hpp"
|
||||
#include "sockets/plain.hpp" // should this be here?
|
||||
#include "sockets/autotls.hpp" // should this be here?
|
||||
#include "logger/logger.hpp"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
@@ -74,7 +74,7 @@ protected:
|
||||
*/
|
||||
template <
|
||||
template <class> class role,
|
||||
template <class> class socket = socket::plain,
|
||||
template <class> class socket = socket::autotls,
|
||||
template <class> class logger = log::logger>
|
||||
class endpoint
|
||||
: public endpoint_base,
|
||||
|
||||
@@ -57,26 +57,30 @@ typedef boost::asio::buffers_iterator<boost::asio::streambuf::const_buffers_type
|
||||
|
||||
static std::pair<bufIterator, bool> match_header(bufIterator begin, bufIterator end)
|
||||
{
|
||||
static const std::string eol_match = "\n";
|
||||
static const std::string header_match = "\n\r\n";
|
||||
static const std::string alt_header_match = "\n\n";
|
||||
static const std::string flash_match = "<policy-file-request/>";
|
||||
|
||||
// Do we have a complete HTTP request
|
||||
const std::string header_match = "\r\n\r\n";
|
||||
bufIterator it = std::search(begin, end, header_match.begin(), header_match.end());
|
||||
if (it != end)
|
||||
return std::make_pair(it, true);
|
||||
return std::make_pair(it + header_match.size(), true);
|
||||
it = std::search(begin, end, alt_header_match.begin(), alt_header_match.end());
|
||||
return std::make_pair(it + alt_header_match.size(), true);
|
||||
|
||||
// If we don't have a flash policy request, we're done
|
||||
const std::string flash_match = "<policy-file-request/>";
|
||||
it = std::search(begin, end, flash_match.begin(), flash_match.end());
|
||||
if (it == end)
|
||||
if (it == end) // No match
|
||||
return std::make_pair(end, false);
|
||||
|
||||
// If we have a line ending before the flash policy request, treat as http
|
||||
const std::string eol_match = "\r\n";
|
||||
bufIterator it2 = std::search(begin, end, eol_match.begin(), eol_match.end());
|
||||
if ((it2 != end) || (it < it2))
|
||||
return std::make_pair(end, false);
|
||||
|
||||
// Treat as flash policy request
|
||||
return std::make_pair(it, true);
|
||||
return std::make_pair(it + flash_match.size(), true);
|
||||
}
|
||||
|
||||
// Forward declarations
|
||||
@@ -539,18 +543,37 @@ void server<endpoint>::connection<connection_type>::async_init() {
|
||||
// TODO: make this value configurable
|
||||
m_connection.register_timeout(5000,fail::status::TIMEOUT_WS,
|
||||
"Timeout on WebSocket handshake");
|
||||
|
||||
boost::asio::async_read_until(
|
||||
m_connection.get_socket(),
|
||||
m_connection.buffer(),
|
||||
match_header,
|
||||
m_connection.get_strand().wrap(boost::bind(
|
||||
&type::handle_read_request,
|
||||
m_connection.shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred
|
||||
))
|
||||
);
|
||||
|
||||
if (m_connection.get_socket().isSecure())
|
||||
{
|
||||
boost::asio::async_read_until(
|
||||
m_connection.get_socket().SSLSocket(),
|
||||
m_connection.buffer(),
|
||||
// match_header,
|
||||
"\r\n\r\n",
|
||||
m_connection.get_strand().wrap(boost::bind(
|
||||
&type::handle_read_request,
|
||||
m_connection.shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred
|
||||
))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::asio::async_read_until(
|
||||
m_connection.get_socket().PlainSocket(),
|
||||
m_connection.buffer(),
|
||||
// match_header,
|
||||
"\r\n\r\n",
|
||||
m_connection.get_strand().wrap(boost::bind(
|
||||
&type::handle_read_request,
|
||||
m_connection.shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// processes the response from an async read for an HTTP header
|
||||
@@ -699,9 +722,9 @@ void server<endpoint>::connection<connection_type>::handle_read_request(
|
||||
{
|
||||
// TODO: this makes the assumption that WS and HTTP
|
||||
// default ports are the same.
|
||||
m_uri.reset(new uri(m_endpoint.is_secure(),h,m_request.uri()));
|
||||
m_uri.reset(new uri(m_connection.is_secure(),h,m_request.uri()));
|
||||
} else {
|
||||
m_uri.reset(new uri(m_endpoint.is_secure(),
|
||||
m_uri.reset(new uri(m_connection.is_secure(),
|
||||
h.substr(0,last_colon),
|
||||
h.substr(last_colon+1),
|
||||
m_request.uri()));
|
||||
@@ -821,17 +844,16 @@ void server<endpoint>::connection<connection_type>::write_response() {
|
||||
shared_const_buffer buffer(raw);
|
||||
|
||||
m_endpoint.m_alog->at(log::alevel::DEBUG_HANDSHAKE) << raw << log::endl;
|
||||
|
||||
boost::asio::async_write(
|
||||
m_connection.get_socket(),
|
||||
//boost::asio::buffer(raw),
|
||||
buffer,
|
||||
boost::bind(
|
||||
&type::handle_write_response,
|
||||
m_connection.shared_from_this(),
|
||||
boost::asio::placeholders::error
|
||||
)
|
||||
);
|
||||
|
||||
m_connection.get_socket().async_write(
|
||||
//boost::asio::buffer(raw),
|
||||
buffer,
|
||||
boost::bind(
|
||||
&type::handle_write_response,
|
||||
m_connection.shared_from_this(),
|
||||
boost::asio::placeholders::error
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template <class endpoint>
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#error Use Auto TLS only
|
||||
|
||||
#ifndef WEBSOCKETPP_SOCKET_PLAIN_HPP
|
||||
#define WEBSOCKETPP_SOCKET_PLAIN_HPP
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#error Use auto TLS only
|
||||
|
||||
#ifndef WEBSOCKETPP_SOCKET_TLS_HPP
|
||||
#define WEBSOCKETPP_SOCKET_TLS_HPP
|
||||
|
||||
|
||||
@@ -41,6 +41,10 @@ namespace websocketpp {
|
||||
typedef websocketpp::endpoint<websocketpp::role::server,
|
||||
websocketpp::socket::tls> server_tls;
|
||||
#endif
|
||||
#ifdef WEBSOCKETPP_SOCKET_AUTOTLS_HPP
|
||||
typedef websocketpp::endpoint<websocketpp::role::server,
|
||||
websocketpp::socket::autotls> server_autotls;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user