Add module ripple_basio and ripple_net

This commit is contained in:
Vinnie Falco
2013-07-08 09:29:16 -07:00
parent 87f3c1e597
commit 394328e202
21 changed files with 412 additions and 78 deletions

View File

@@ -1,114 +0,0 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
SETUP_LOG (HTTPRequest)
// Logic to handle incoming HTTP reqests
void HTTPRequest::reset ()
{
mHeaders.clear ();
sRequestBody.clear ();
sAuthorization.clear ();
iDataSize = 0;
bShouldClose = true;
eState = await_request;
}
HTTPRequestAction HTTPRequest::requestDone (bool forceClose)
{
if (forceClose || bShouldClose)
return haCLOSE_CONN;
reset ();
return haREAD_LINE;
}
std::string HTTPRequest::getReplyHeaders (bool forceClose)
{
if (forceClose || bShouldClose)
return "Connection: close\r\n";
else
return "Connection: Keep-Alive\r\n";
}
HTTPRequestAction HTTPRequest::consume (boost::asio::streambuf& buf)
{
std::string line;
std::istream is (&buf);
std::getline (is, line);
boost::trim (line);
// WriteLog (lsTRACE, HTTPRequest) << "HTTPRequest line: " << line;
if (eState == await_request)
{
// VERB URL PROTO
if (line.empty ())
return haREAD_LINE;
sRequest = line;
bShouldClose = sRequest.find ("HTTP/1.1") == std::string::npos;
eState = await_header;
return haREAD_LINE;
}
if (eState == await_header)
{
// HEADER_NAME: HEADER_BODY
if (line.empty ()) // empty line or bare \r
{
if (iDataSize == 0)
{
// no body
eState = do_request;
return haDO_REQUEST;
}
eState = getting_body;
return haREAD_RAW;
}
size_t colon = line.find (':');
if (colon != std::string::npos)
{
std::string headerName = line.substr (0, colon);
boost::trim (headerName);
boost::to_lower (headerName);
std::string headerValue = line.substr (colon + 1);
boost::trim (headerValue);
mHeaders[headerName] += headerValue;
if (headerName == "connection")
{
boost::to_lower (headerValue);
if ((headerValue == "keep-alive") || (headerValue == "keepalive"))
bShouldClose = false;
if (headerValue == "close")
bShouldClose = true;
}
if (headerName == "content-length")
iDataSize = boost::lexical_cast<int> (headerValue);
if (headerName == "authorization")
sAuthorization = headerValue;
}
return haREAD_LINE;
}
assert (false);
return haERROR;
}
// vim:ts=4

View File

@@ -1,90 +0,0 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
#ifndef HTTPREQUEST__HPP
#define HTTPREQUEST__HPP
enum HTTPRequestAction
{
// What the application code needs to do
haERROR = 0,
haREAD_LINE = 1,
haREAD_RAW = 2,
haDO_REQUEST = 3,
haCLOSE_CONN = 4
};
class HTTPRequest
{
// an HTTP request we are handling from a client
public:
HTTPRequest () : eState (await_request), iDataSize (0), bShouldClose (true)
{
;
}
void reset ();
std::string& peekBody ()
{
return sRequestBody;
}
std::string getBody ()
{
return sRequestBody;
}
std::string& peekRequest ()
{
return sRequest;
}
std::string getRequest ()
{
return sRequest;
}
std::string& peekAuth ()
{
return sAuthorization;
}
std::string getAuth ()
{
return sAuthorization;
}
std::map<std::string, std::string>& peekHeaders ()
{
return mHeaders;
}
std::string getReplyHeaders (bool forceClose);
HTTPRequestAction consume (boost::asio::streambuf&);
HTTPRequestAction requestDone (bool forceClose); // call after reply is sent
int getDataSize ()
{
return iDataSize;
}
private:
enum state
{
await_request, // We are waiting for the request line
await_header, // We are waiting for request headers
getting_body, // We are waiting for the body
do_request, // We are waiting for the request to complete
};
state eState;
std::string sRequest; // VERB URL PROTO
std::string sRequestBody;
std::string sAuthorization;
std::map<std::string, std::string> mHeaders;
int iDataSize;
bool bShouldClose;
};
#endif

View File

@@ -18,13 +18,25 @@ SETUP_LOG (NetworkOPs)
// code assumes this node is synched (and will continue to do so until
// there's a functional network.
NetworkOPs::NetworkOPs (boost::asio::io_service& io_service, LedgerMaster* pLedgerMaster) :
mMode (omDISCONNECTED), mNeedNetworkLedger (false), mProposing (false), mValidating (false),
mFeatureBlocked (false),
mNetTimer (io_service), mLedgerMaster (pLedgerMaster), mCloseTimeOffset (0), mLastCloseProposers (0),
mLastCloseConvergeTime (1000 * LEDGER_IDLE_INTERVAL), mLastCloseTime (0), mLastValidationTime (0),
mFetchPack ("FetchPack", 2048, 20), mLastFetchPack (0), mFetchSeq (static_cast<uint32> (-1)),
mLastLoadBase (256), mLastLoadFactor (256)
NetworkOPs::NetworkOPs (boost::asio::io_service& io_service, LedgerMaster* pLedgerMaster)
: mMode (omDISCONNECTED)
, mNeedNetworkLedger (false)
, mProposing (false)
, mValidating (false)
, mFeatureBlocked (false)
, mNetTimer (io_service)
, mLedgerMaster (pLedgerMaster)
, mCloseTimeOffset (0)
, mLastCloseProposers (0)
, mLastCloseConvergeTime (1000 * LEDGER_IDLE_INTERVAL)
, mLastCloseTime (0)
, mLastValidationTime (0)
, mFetchPack ("FetchPack", 2048, 20)
, mLastFetchPack (0)
// VFALCO TODO Give this magic number a name
, mFetchSeq (static_cast <uint32> (-1))
, mLastLoadBase (256)
, mLastLoadFactor (256)
{
}
@@ -2278,11 +2290,18 @@ bool NetworkOPs::shouldFetchPack (uint32 seq)
int size = mFetchPack.getCacheSize ();
if (size == 0)
{
// VFALCO TODO Give this magic number a name
//
mFetchSeq = static_cast<uint32> (-1);
}
else if (mFetchPack.getCacheSize () > 64)
{
return false;
}
mLastFetchPack = now;
return true;
}

View File

@@ -397,6 +397,11 @@ private:
TaggedCache< uint256, Blob , UptimeTimerAdapter > mFetchPack;
uint32 mLastFetchPack;
// VFALCO TODO Document the special value uint32(-1) for this member
// and replace uint32(-1) with a constant. It is initialized
// in the ctor-initializer list to this constant.
//
uint32 mFetchSeq;
uint32 mLastLoadBase;

View File

@@ -49,22 +49,22 @@ void RPCServer::handle_read_line (const boost::system::error_code& e)
if (e)
return;
HTTPRequestAction action = mHTTPRequest.consume (mLineBuffer);
HTTPRequest::Action action = mHTTPRequest.consume (mLineBuffer);
if (action == haDO_REQUEST)
if (action == HTTPRequest::haDO_REQUEST)
{
// request with no body
WriteLog (lsWARNING, RPCServer) << "RPC HTTP request with no body";
mSocket.async_shutdown (mStrand.wrap (boost::bind (&RPCServer::handle_shutdown, shared_from_this(), boost::asio::placeholders::error)));
return;
}
else if (action == haREAD_LINE)
else if (action == HTTPRequest::haREAD_LINE)
{
boost::asio::async_read_until (mSocket, mLineBuffer, "\r\n",
mStrand.wrap (boost::bind (&RPCServer::handle_read_line, shared_from_this (),
boost::asio::placeholders::error)));
}
else if (action == haREAD_RAW)
else if (action == HTTPRequest::haREAD_RAW)
{
int rLen = mHTTPRequest.getDataSize ();
@@ -182,9 +182,9 @@ void RPCServer::handle_write (const boost::system::error_code& e)
if (!e)
{
HTTPRequestAction action = mHTTPRequest.requestDone (false);
HTTPRequest::Action action = mHTTPRequest.requestDone (false);
if (action == haCLOSE_CONN)
if (action == HTTPRequest::haCLOSE_CONN)
mSocket.async_shutdown (mStrand.wrap (boost::bind (&RPCServer::handle_shutdown, shared_from_this(), boost::asio::placeholders::error)));
else
{

View File

@@ -208,6 +208,10 @@ private:
private:
boost::asio::io_service mIOService;
boost::asio::io_service mAuxService;
// The lifetime of the io_service::work object informs the io_service
// of when the work starts and finishes. io_service::run() will not exit
// while the work object exists.
//
boost::asio::io_service::work mIOWork;
boost::recursive_mutex mMasterLock;