mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Rename boost_asio files
This commit is contained in:
141
modules/beast_asio/protocol/HandshakeDetectLogic.h
Normal file
141
modules/beast_asio/protocol/HandshakeDetectLogic.h
Normal file
@@ -0,0 +1,141 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HANDSHAKE_HANDSHAKEDETECTLOGIC_H_INCLUDED
|
||||
#define BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTLOGIC_H_INCLUDED
|
||||
|
||||
class HandshakeDetectLogic
|
||||
{
|
||||
public:
|
||||
HandshakeDetectLogic ()
|
||||
: m_finished (false)
|
||||
, m_success (false)
|
||||
{
|
||||
}
|
||||
|
||||
/** How many bytes maximum we might need.
|
||||
|
||||
This is the largest number of bytes that the detector
|
||||
might need in order to come to a conclusion about
|
||||
whether or not the handshake is a match. Depending
|
||||
on the data, it could come to that conclusion sooner
|
||||
though.
|
||||
|
||||
Use read_some instead of read so that the detect logic
|
||||
can reject the handshake sooner if possible.
|
||||
*/
|
||||
virtual std::size_t max_needed () = 0;
|
||||
|
||||
/** How many bytes the handshake consumes.
|
||||
If the detector processes the entire handshake this will
|
||||
be non zero. The SSL detector would return 0, since we
|
||||
want all the existing bytes to be passed on.
|
||||
*/
|
||||
virtual std::size_t bytes_consumed () = 0;
|
||||
|
||||
/** Return true if we have enough data to form a conclusion.
|
||||
*/
|
||||
bool finished () const noexcept
|
||||
{
|
||||
return m_finished;
|
||||
}
|
||||
|
||||
/** Return true if we came to a conclusion and the data matched.
|
||||
*/
|
||||
bool success () const noexcept
|
||||
{
|
||||
return m_finished && m_success;
|
||||
}
|
||||
|
||||
protected:
|
||||
void conclude (bool success = true)
|
||||
{
|
||||
m_finished = true;
|
||||
m_success = success;
|
||||
}
|
||||
|
||||
void fail ()
|
||||
{
|
||||
conclude (false);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_finished;
|
||||
bool m_success;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Wraps the logic and exports it as an abstract interface.
|
||||
*/
|
||||
template <typename Logic>
|
||||
class HandshakeDetectLogicType
|
||||
{
|
||||
public:
|
||||
typedef Logic LogicType;
|
||||
typedef typename Logic::arg_type arg_type;
|
||||
|
||||
explicit HandshakeDetectLogicType (arg_type const& arg = arg_type ())
|
||||
: m_logic (arg)
|
||||
{
|
||||
}
|
||||
|
||||
LogicType& get ()
|
||||
{
|
||||
return m_logic;
|
||||
}
|
||||
|
||||
std::size_t max_needed ()
|
||||
{
|
||||
return m_logic.max_needed ();
|
||||
}
|
||||
|
||||
std::size_t bytes_consumed ()
|
||||
{
|
||||
return m_logic.bytes_consumed ();
|
||||
}
|
||||
|
||||
bool finished ()
|
||||
{
|
||||
return m_logic.finished ();
|
||||
}
|
||||
|
||||
/** If finished is true, this tells us if the handshake was detected.
|
||||
*/
|
||||
bool success ()
|
||||
{
|
||||
return m_logic.success ();
|
||||
}
|
||||
|
||||
/** Analyze the buffer to match the Handshake.
|
||||
Returns `true` if the analysis is complete.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
bool analyze (ConstBufferSequence const& buffer)
|
||||
{
|
||||
bassert (! m_logic.finished ());
|
||||
m_logic.analyze (buffer);
|
||||
return m_logic.finished ();
|
||||
}
|
||||
|
||||
private:
|
||||
Logic m_logic;
|
||||
};
|
||||
|
||||
#endif
|
||||
20
modules/beast_asio/protocol/HandshakeDetectLogicPROXY.cpp
Normal file
20
modules/beast_asio/protocol/HandshakeDetectLogicPROXY.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
|
||||
159
modules/beast_asio/protocol/HandshakeDetectLogicPROXY.h
Normal file
159
modules/beast_asio/protocol/HandshakeDetectLogicPROXY.h
Normal file
@@ -0,0 +1,159 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HANDSHAKE_HANDSHAKEDETECTLOGICPROXY_H_INCLUDED
|
||||
#define BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTLOGICPROXY_H_INCLUDED
|
||||
|
||||
/** Handshake detector for the PROXY protcol
|
||||
|
||||
http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
|
||||
*/
|
||||
class HandshakeDetectLogicPROXY : public HandshakeDetectLogic
|
||||
{
|
||||
public:
|
||||
typedef int arg_type;
|
||||
|
||||
enum
|
||||
{
|
||||
// This is for version 1. The largest number of bytes
|
||||
// that we could possibly need to parse a valid handshake.
|
||||
// We will reject it much sooner if there's an illegal value.
|
||||
//
|
||||
maxBytesNeeded = 107 // including CRLF, no null term
|
||||
};
|
||||
|
||||
struct ProxyInfo
|
||||
{
|
||||
typedef InputParser::IPv4Address IPv4Address;
|
||||
|
||||
String protocol; // "TCP4", "TCP6", "UNKNOWN"
|
||||
|
||||
IPv4Address sourceAddress;
|
||||
IPv4Address destAddress;
|
||||
|
||||
uint16 sourcePort;
|
||||
uint16 destPort;
|
||||
};
|
||||
|
||||
explicit HandshakeDetectLogicPROXY (arg_type const&)
|
||||
: m_consumed (0)
|
||||
{
|
||||
}
|
||||
|
||||
ProxyInfo const& getInfo () const noexcept
|
||||
{
|
||||
return m_info;
|
||||
}
|
||||
|
||||
std::size_t max_needed ()
|
||||
{
|
||||
return maxBytesNeeded;
|
||||
}
|
||||
|
||||
std::size_t bytes_consumed ()
|
||||
{
|
||||
return m_consumed;
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
void analyze (ConstBufferSequence const& buffer)
|
||||
{
|
||||
FixedInputBufferSize <maxBytesNeeded> in (buffer);
|
||||
|
||||
InputParser::State state;
|
||||
|
||||
analyze_input (in, state);
|
||||
|
||||
if (state.passed ())
|
||||
{
|
||||
m_consumed = in.used ();
|
||||
conclude (true);
|
||||
}
|
||||
else if (state.failed ())
|
||||
{
|
||||
conclude (false);
|
||||
}
|
||||
}
|
||||
|
||||
void analyze_input (FixedInputBuffer& in, InputParser::State& state)
|
||||
{
|
||||
using namespace InputParser;
|
||||
|
||||
if (! match (in, "PROXY ", state))
|
||||
return;
|
||||
|
||||
if (match (in, "TCP4 "))
|
||||
{
|
||||
m_info.protocol = "TCP4";
|
||||
|
||||
if (! read (in, m_info.sourceAddress, state))
|
||||
return;
|
||||
|
||||
if (! match (in, " ", state))
|
||||
return;
|
||||
|
||||
if (! read (in, m_info.destAddress, state))
|
||||
return;
|
||||
|
||||
if (! match (in, " ", state))
|
||||
return;
|
||||
|
||||
UInt16Str sourcePort;
|
||||
if (! read (in, sourcePort, state))
|
||||
return;
|
||||
m_info.sourcePort = sourcePort.value;
|
||||
|
||||
if (! match (in, " ", state))
|
||||
return;
|
||||
|
||||
UInt16Str destPort;
|
||||
if (! read (in, destPort, state))
|
||||
return;
|
||||
m_info.destPort = destPort.value;
|
||||
|
||||
if (! match (in, "\r\n", state))
|
||||
return;
|
||||
|
||||
state = State::pass;
|
||||
return;
|
||||
}
|
||||
else if (match (in, "TCP6 "))
|
||||
{
|
||||
m_info.protocol = "TCP6";
|
||||
|
||||
state = State::fail;
|
||||
return;
|
||||
}
|
||||
else if (match (in, "UNKNOWN "))
|
||||
{
|
||||
m_info.protocol = "UNKNOWN";
|
||||
|
||||
state = State::fail;
|
||||
return;
|
||||
}
|
||||
|
||||
state = State::fail;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t m_consumed;
|
||||
ProxyInfo m_info;
|
||||
};
|
||||
|
||||
#endif
|
||||
108
modules/beast_asio/protocol/HandshakeDetectLogicSSL2.h
Normal file
108
modules/beast_asio/protocol/HandshakeDetectLogicSSL2.h
Normal file
@@ -0,0 +1,108 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HANDSHAKE_HANDSHAKEDETECTLOGICSSL2_H_INCLUDED
|
||||
#define BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTLOGICSSL2_H_INCLUDED
|
||||
|
||||
// Handshake for SSL 2
|
||||
//
|
||||
// http://tools.ietf.org/html/rfc5246#appendix-E.2
|
||||
//
|
||||
// uint8 V2CipherSpec[3];
|
||||
// struct {
|
||||
// uint16 msg_length;
|
||||
// uint8 msg_type;
|
||||
// Version version; Should be 'ProtocolVersion'?
|
||||
// uint16 cipher_spec_length;
|
||||
// uint16 session_id_length;
|
||||
// uint16 challenge_length;
|
||||
// ...
|
||||
//
|
||||
class HandshakeDetectLogicSSL2 : public HandshakeDetectLogic
|
||||
{
|
||||
public:
|
||||
typedef int arg_type;
|
||||
|
||||
explicit HandshakeDetectLogicSSL2 (arg_type const&)
|
||||
{
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
bytesNeeded = 3
|
||||
};
|
||||
|
||||
std::size_t max_needed ()
|
||||
{
|
||||
return bytesNeeded;
|
||||
}
|
||||
|
||||
std::size_t bytes_consumed ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
void analyze (ConstBufferSequence const& buffer)
|
||||
{
|
||||
FixedInputBufferSize <bytesNeeded> in (buffer);
|
||||
|
||||
{
|
||||
uint8 byte;
|
||||
if (! in.peek (&byte))
|
||||
return;
|
||||
|
||||
// First byte must have the high bit set
|
||||
//
|
||||
if((byte & 0x80) != 0x80)
|
||||
return fail ();
|
||||
}
|
||||
|
||||
// The remaining bits contain the
|
||||
// length of the following data in bytes.
|
||||
//
|
||||
uint16 msg_length;
|
||||
if (! in.readNetworkInteger(&msg_length))
|
||||
return;
|
||||
|
||||
// sizeof (msg_type +
|
||||
// Version (ProtcolVersion?) +
|
||||
// cipher_spec_length +
|
||||
// session_id_length +
|
||||
// challenge_length)
|
||||
//
|
||||
// Should be 9 or greater.
|
||||
//
|
||||
if (msg_length < 9)
|
||||
return fail ();
|
||||
|
||||
uint8 msg_type;
|
||||
if (! in.read (&msg_type))
|
||||
return;
|
||||
|
||||
// The msg_type must be 0x01 for a version 2 ClientHello
|
||||
//
|
||||
if (msg_type != 0x01)
|
||||
return fail ();
|
||||
|
||||
conclude ();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
82
modules/beast_asio/protocol/HandshakeDetectLogicSSL3.h
Normal file
82
modules/beast_asio/protocol/HandshakeDetectLogicSSL3.h
Normal file
@@ -0,0 +1,82 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HANDSHAKE_HANDSHAKEDETECTLOGICSSL3_H_INCLUDED
|
||||
#define BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTLOGICSSL3_H_INCLUDED
|
||||
|
||||
// Handshake for SSL 3 (Also TLS 1.0 and 1.1)
|
||||
//
|
||||
// http://www.ietf.org/rfc/rfc2246.txt
|
||||
//
|
||||
// Section 7.4. Handshake protocol
|
||||
//
|
||||
class HandshakeDetectLogicSSL3 : public HandshakeDetectLogic
|
||||
{
|
||||
public:
|
||||
typedef int arg_type; // dummy
|
||||
|
||||
explicit HandshakeDetectLogicSSL3 (arg_type const&)
|
||||
{
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
bytesNeeded = 6
|
||||
};
|
||||
|
||||
std::size_t max_needed ()
|
||||
{
|
||||
return bytesNeeded;
|
||||
}
|
||||
|
||||
std::size_t bytes_consumed ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
void analyze (ConstBufferSequence const& buffer)
|
||||
{
|
||||
uint16 version;
|
||||
FixedInputBufferSize <bytesNeeded> in (buffer);
|
||||
|
||||
uint8 msg_type;
|
||||
if (! in.read (&msg_type))
|
||||
return;
|
||||
|
||||
// msg_type must be 0x16 = "SSL Handshake"
|
||||
//
|
||||
if (msg_type != 0x16)
|
||||
return fail ();
|
||||
|
||||
if (! in.read (&version))
|
||||
return;
|
||||
version = fromNetworkByteOrder (version);
|
||||
|
||||
uint16 length;
|
||||
if (! in.read (&length))
|
||||
return;
|
||||
|
||||
length = fromNetworkByteOrder (length);
|
||||
|
||||
conclude ();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
206
modules/beast_asio/protocol/HandshakeDetector.h
Normal file
206
modules/beast_asio/protocol/HandshakeDetector.h
Normal file
@@ -0,0 +1,206 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HANDSHAKE_HANDSHAKEDETECTOR_H_INCLUDED
|
||||
#define BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTOR_H_INCLUDED
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** A wrapper to decode the handshake data on a Stream.
|
||||
|
||||
Stream must meet these requirements
|
||||
|
||||
For detect:
|
||||
SyncReadStream
|
||||
|
||||
For async_detect:
|
||||
AsyncReadStream
|
||||
|
||||
Logic must meet this requirement:
|
||||
HandshakeDetectLogic
|
||||
*/
|
||||
template <typename Stream, typename Logic>
|
||||
class HandshakeDetectorType
|
||||
{
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
public:
|
||||
Logic& getLogic ()
|
||||
{
|
||||
return m_logic.get ();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Synchronous handshake detect.
|
||||
The bytes from the input sequence in the specified buffer
|
||||
are used first.
|
||||
*/
|
||||
template <typename Allocator>
|
||||
error_code detect (Stream& stream,
|
||||
boost::asio::basic_streambuf <Allocator>& buffer)
|
||||
{
|
||||
typedef boost::asio::basic_streambuf <Allocator> BufferType;
|
||||
|
||||
error_code ec;
|
||||
|
||||
do
|
||||
{
|
||||
m_logic.analyze (buffer.data ());
|
||||
|
||||
if (m_logic.finished ())
|
||||
{
|
||||
// consume what we used (for SSL its 0)
|
||||
std::size_t const consumed = m_logic.bytes_consumed ();
|
||||
bassert (consumed <= buffer.size ());
|
||||
buffer.consume (consumed);
|
||||
break;
|
||||
}
|
||||
|
||||
std::size_t const available = buffer.size ();
|
||||
std::size_t const needed = m_logic.max_needed ();
|
||||
|
||||
// If postcondition fails, loop will never end
|
||||
if (meets_postcondition (available < needed))
|
||||
{
|
||||
typename BufferType::mutable_buffers_type buffers (
|
||||
buffer.prepare (needed - available));
|
||||
buffer.commit (stream.read_some (buffers, ec));
|
||||
}
|
||||
}
|
||||
while (! ec);
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Asynchronous handshake detect.
|
||||
The bytes from the input sequence in the specified buffer
|
||||
are used first.
|
||||
|
||||
DetectHandler must have this signature:
|
||||
void(error_code)
|
||||
*/
|
||||
template <typename DetectHandler, typename Allocator>
|
||||
void async_detect (Stream& stream,
|
||||
boost::asio::basic_streambuf <Allocator>& buffer,
|
||||
BOOST_ASIO_MOVE_ARG(DetectHandler) handler)
|
||||
{
|
||||
async_detect <Allocator> (stream, buffer, SharedHandlerPtr (
|
||||
new ErrorSharedHandlerType <DetectHandler> (
|
||||
BOOST_ASIO_MOVE_CAST(DetectHandler)(handler))));
|
||||
}
|
||||
|
||||
template <typename Allocator>
|
||||
void async_detect (Stream& stream,
|
||||
boost::asio::basic_streambuf <Allocator>& buffer,
|
||||
SharedHandlerPtr handler)
|
||||
{
|
||||
typedef AsyncOp <Allocator> OpType;
|
||||
OpType* const op = new AsyncOp <Allocator> (
|
||||
m_logic, stream, buffer, handler);
|
||||
stream.get_io_service ().wrap (SharedHandlerPtr (op))
|
||||
(error_code (), 0);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Allocator>
|
||||
struct AsyncOp : ComposedAsyncOperation
|
||||
{
|
||||
typedef boost::asio::basic_streambuf <Allocator> BufferType;
|
||||
|
||||
AsyncOp (HandshakeDetectLogicType <Logic>& logic, Stream& stream,
|
||||
BufferType& buffer, SharedHandlerPtr const& handler)
|
||||
: ComposedAsyncOperation (sizeof (*this), handler)
|
||||
, m_logic (logic)
|
||||
, m_stream (stream)
|
||||
, m_buffer (buffer)
|
||||
, m_handler (handler)
|
||||
, m_running (false)
|
||||
{
|
||||
}
|
||||
|
||||
// Set breakpoint to prove it gets destroyed
|
||||
~AsyncOp ()
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (error_code const& ec_, size_t bytes_transferred)
|
||||
{
|
||||
m_running = true;
|
||||
|
||||
error_code ec (ec_);
|
||||
|
||||
if (! ec)
|
||||
{
|
||||
m_buffer.commit (bytes_transferred);
|
||||
|
||||
m_logic.analyze (m_buffer.data ());
|
||||
|
||||
if (!m_logic.finished ())
|
||||
{
|
||||
std::size_t const available = m_buffer.size ();
|
||||
std::size_t const needed = m_logic.max_needed ();
|
||||
|
||||
// If postcondition fails, loop will never end
|
||||
if (meets_postcondition (available < needed))
|
||||
{
|
||||
typename BufferType::mutable_buffers_type buffers (
|
||||
m_buffer.prepare (needed - available));
|
||||
|
||||
m_stream.async_read_some (buffers, SharedHandlerPtr (this));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t const consumed = m_logic.bytes_consumed ();
|
||||
m_buffer.consume (consumed);
|
||||
}
|
||||
|
||||
// Finalize with a call to the original handler.
|
||||
m_stream.get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST (SharedHandlerPtr)(m_handler))
|
||||
(ec);
|
||||
}
|
||||
|
||||
bool is_continuation ()
|
||||
{
|
||||
return m_running
|
||||
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
|
||||
|| boost_asio_handler_cont_helpers::is_continuation (m_handler);
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
private:
|
||||
HandshakeDetectLogicType <Logic>& m_logic;
|
||||
Stream& m_stream;
|
||||
BufferType& m_buffer;
|
||||
SharedHandlerPtr m_handler;
|
||||
bool m_running;
|
||||
};
|
||||
|
||||
private:
|
||||
HandshakeDetectLogicType <Logic> m_logic;
|
||||
};
|
||||
|
||||
#endif
|
||||
23
modules/beast_asio/protocol/HttpClient.h
Normal file
23
modules/beast_asio/protocol/HttpClient.h
Normal file
@@ -0,0 +1,23 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_PROTOCOL_HTTPCLIENT_H_INCLUDED
|
||||
#define BEAST_ASIO_PROTOCOL_HTTPCLIENT_H_INCLUDED
|
||||
|
||||
#endif
|
||||
387
modules/beast_asio/protocol/InputParser.h
Normal file
387
modules/beast_asio/protocol/InputParser.h
Normal file
@@ -0,0 +1,387 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HANDSHAKE_INPUTPARSER_H_INCLUDED
|
||||
#define BEAST_ASIO_HANDSHAKE_INPUTPARSER_H_INCLUDED
|
||||
|
||||
namespace InputParser
|
||||
{
|
||||
|
||||
/** Tri-valued parsing state.
|
||||
This is convertible to bool which means continue.
|
||||
Or you can use stop() to decide if you should return.
|
||||
After a stop you can use failed () to determine if parsing failed.
|
||||
*/
|
||||
struct State : SafeBool <State>
|
||||
{
|
||||
enum State_t
|
||||
{
|
||||
pass, // passed the parse
|
||||
fail, // failed the parse
|
||||
more // didn't fail but need more bytes
|
||||
};
|
||||
|
||||
State () : m_state (more) { }
|
||||
|
||||
State (State_t state) : m_state (state) { }
|
||||
|
||||
/** Implicit construction from bool.
|
||||
If condition is true then the parse passes, else need more.
|
||||
*/
|
||||
State (bool condition) : m_state (condition ? pass : more) { }
|
||||
|
||||
State& operator= (State_t state) { m_state = state; return *this; }
|
||||
|
||||
bool eof () const noexcept { return m_state == more; }
|
||||
bool stop () const noexcept { return m_state != pass; }
|
||||
bool passed () const noexcept { return m_state == pass; }
|
||||
bool failed () const noexcept { return m_state == fail; }
|
||||
bool asBoolean () const noexcept { return m_state == pass; } // for SafeBool<>
|
||||
|
||||
private:
|
||||
State_t m_state;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Shortcut to save typing.
|
||||
typedef FixedInputBuffer& Input;
|
||||
|
||||
/** Specializations implement the get() function. */
|
||||
template <class T>
|
||||
struct Get;
|
||||
|
||||
/** Specializations implement the match() function.
|
||||
Default implementation of match tries to read it into a local.
|
||||
*/
|
||||
template <class T>
|
||||
struct Match
|
||||
{
|
||||
static State func (Input in, T other)
|
||||
{
|
||||
T t;
|
||||
State state = Get <T>::func (in, t);
|
||||
if (state.passed ())
|
||||
{
|
||||
if (t == other)
|
||||
return State::pass;
|
||||
return State::fail;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
/** Specializations implement the peek() function.
|
||||
Default implementation of peek reads and rewinds.
|
||||
*/
|
||||
template <class T>
|
||||
struct Peek
|
||||
{
|
||||
static State func (Input in, T& t)
|
||||
{
|
||||
Input dup (in);
|
||||
return Get <T>::func (dup, t);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Free Functions
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// match a block of data in memory
|
||||
//
|
||||
static State match_buffer (Input in, void const* buffer, std::size_t bytes)
|
||||
{
|
||||
bassert (bytes > 0);
|
||||
if (in.size () <= 0)
|
||||
return State::more;
|
||||
|
||||
std::size_t const have = std::min (in.size (), bytes);
|
||||
void const* data = in.peek (have);
|
||||
bassert (data != nullptr);
|
||||
|
||||
int const compare = memcmp (data, buffer, have);
|
||||
if (compare != 0)
|
||||
return State::fail;
|
||||
in.consume (have);
|
||||
|
||||
return have == bytes;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// match
|
||||
//
|
||||
|
||||
// Returns the state
|
||||
template <class T>
|
||||
State match (Input in, T t)
|
||||
{
|
||||
return Match <T>::func (in, t);
|
||||
}
|
||||
|
||||
// Stores the state in the argument and returns true if its a pass
|
||||
template <class T>
|
||||
bool match (Input in, T t, State& state)
|
||||
{
|
||||
return (state = match (in, t)).passed ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// peek
|
||||
//
|
||||
|
||||
// Returns the state
|
||||
template <class T>
|
||||
State peek (Input in, T& t)
|
||||
{
|
||||
return Peek <T>::func (in, t);
|
||||
}
|
||||
|
||||
// Stores the state in the argument and returns true if its a pass
|
||||
template <class T>
|
||||
bool peek (Input in, T& t, State& state)
|
||||
{
|
||||
return (state = peek (in, t)).passed ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// read
|
||||
//
|
||||
|
||||
// Returns the state
|
||||
template <class T>
|
||||
State read (Input in, T& t)
|
||||
{
|
||||
return Get <T>::func (in, t);
|
||||
}
|
||||
|
||||
// Stores the state in the argument and returns true if its a pass
|
||||
template <class T>
|
||||
bool read (Input in, T& t, State& state)
|
||||
{
|
||||
return (state = read (in, t)).passed ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Specializations for basic types
|
||||
//
|
||||
|
||||
template <>
|
||||
struct Match <char const*>
|
||||
{
|
||||
static State func (Input in, char const* text)
|
||||
{
|
||||
return InputParser::match_buffer (in, text, strlen (text));
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Special types and their specializations
|
||||
//
|
||||
|
||||
struct Digit
|
||||
{
|
||||
int value;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Get <Digit>
|
||||
{
|
||||
static State func (Input in, Digit& t)
|
||||
{
|
||||
char c;
|
||||
if (! in.peek (&c))
|
||||
return State::more;
|
||||
if (! std::isdigit (c))
|
||||
return State::fail;
|
||||
in.consume (1);
|
||||
t.value = c - '0';
|
||||
return State::pass;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// An unsigned 32 bit number expressed as a string
|
||||
struct UInt32Str
|
||||
{
|
||||
uint32 value;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Get <UInt32Str>
|
||||
{
|
||||
static State func (Input in, UInt32Str& t)
|
||||
{
|
||||
State state;
|
||||
uint32 value (0);
|
||||
|
||||
Digit digit;
|
||||
// have to have at least one digit
|
||||
if (! read (in, digit, state))
|
||||
return state;
|
||||
value = digit.value;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
state = peek (in, digit);
|
||||
|
||||
if (state.failed ())
|
||||
{
|
||||
t.value = value;
|
||||
return State::pass;
|
||||
}
|
||||
else if (state.eof ())
|
||||
{
|
||||
t.value = value;
|
||||
return state;
|
||||
}
|
||||
|
||||
// can't have a digit following a zero
|
||||
if (value == 0)
|
||||
return State::fail;
|
||||
|
||||
uint32 newValue = (value * 10) + digit.value;
|
||||
|
||||
// overflow
|
||||
if (newValue < value)
|
||||
return State::fail;
|
||||
|
||||
value = newValue;
|
||||
}
|
||||
|
||||
return State::fail;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// An unsigned 16 bit number expressed as a string
|
||||
struct UInt16Str
|
||||
{
|
||||
uint16 value;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Get <UInt16Str>
|
||||
{
|
||||
static State func (Input in, UInt16Str& t)
|
||||
{
|
||||
UInt32Str v;
|
||||
State state = read (in, v);
|
||||
if (state.passed ())
|
||||
{
|
||||
if (v.value <= 65535)
|
||||
{
|
||||
t.value = uint16(v.value);
|
||||
return State::pass;
|
||||
}
|
||||
return State::fail;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// An unsigned 8 bit number expressed as a string
|
||||
struct UInt8Str
|
||||
{
|
||||
uint8 value;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Get <UInt8Str>
|
||||
{
|
||||
static State func (Input in, UInt8Str& t)
|
||||
{
|
||||
UInt32Str v;
|
||||
State state = read (in, v);
|
||||
if (state.passed ())
|
||||
{
|
||||
if (v.value <= 255)
|
||||
{
|
||||
t.value = uint8(v.value);
|
||||
return State::pass;
|
||||
}
|
||||
return State::fail;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// An dotted IPv4 address
|
||||
struct IPv4Address
|
||||
{
|
||||
uint8 value [4];
|
||||
|
||||
String toString () const
|
||||
{
|
||||
return String::fromNumber <int> (value [0]) + "." +
|
||||
String::fromNumber <int> (value [1]) + "." +
|
||||
String::fromNumber <int> (value [2]) + "." +
|
||||
String::fromNumber <int> (value [3]);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Get <IPv4Address>
|
||||
{
|
||||
static State func (Input in, IPv4Address& t)
|
||||
{
|
||||
State state;
|
||||
UInt8Str digit [4];
|
||||
if (! read (in, digit [0], state))
|
||||
return state;
|
||||
if (! match (in, ".", state))
|
||||
return state;
|
||||
if (! read (in, digit [1], state))
|
||||
return state;
|
||||
if (! match (in, ".", state))
|
||||
return state;
|
||||
if (! read (in, digit [2], state))
|
||||
return state;
|
||||
if (! match (in, ".", state))
|
||||
return state;
|
||||
if (! read (in, digit [3], state))
|
||||
return state;
|
||||
|
||||
t.value [0] = digit [0].value;
|
||||
t.value [1] = digit [1].value;
|
||||
t.value [2] = digit [2].value;
|
||||
t.value [3] = digit [3].value;
|
||||
|
||||
return State::pass;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
197
modules/beast_asio/protocol/PrefilledReadStream.h
Normal file
197
modules/beast_asio/protocol/PrefilledReadStream.h
Normal file
@@ -0,0 +1,197 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HANDSHAKE_PREFILLEDREADSTREAM_H_INCLUDED
|
||||
#define BEAST_ASIO_HANDSHAKE_PREFILLEDREADSTREAM_H_INCLUDED
|
||||
|
||||
/** Front-ends a stream with a provided block of data.
|
||||
|
||||
When read operations are performed on this object, bytes will first be
|
||||
returned from the buffer provided on construction. When those bytes
|
||||
are exhausted, read operations will then pass through to the underlying
|
||||
stream.
|
||||
|
||||
Write operations are all simply passed through.
|
||||
*/
|
||||
template <typename Stream>
|
||||
class PrefilledReadStream : public Uncopyable
|
||||
{
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
void throw_error (error_code const& ec, char const* fileName, int lineNumber)
|
||||
{
|
||||
Throw (boost::system::system_error (ec), fileName, lineNumber);
|
||||
}
|
||||
|
||||
public:
|
||||
typedef typename boost::remove_reference <Stream>::type next_layer_type;
|
||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
/** Single argument constructor for when we are wrapped in something.
|
||||
arg is passed through to the next layer's constructor.
|
||||
*/
|
||||
template <typename Arg>
|
||||
explicit PrefilledReadStream (Arg& arg)
|
||||
: m_next_layer (arg)
|
||||
{
|
||||
}
|
||||
|
||||
/** Construct with the buffer, and argument passed through.
|
||||
This creates a copy of the data. The argument is passed through
|
||||
to the constructor of Stream.
|
||||
*/
|
||||
template <typename Arg, typename ConstBufferSequence>
|
||||
PrefilledReadStream (Arg& arg, ConstBufferSequence const& buffers)
|
||||
: m_next_layer (arg)
|
||||
{
|
||||
fill (buffers);
|
||||
}
|
||||
|
||||
/** Place some input into the prefilled buffer.
|
||||
Note that this is in no way thread safe. The only reason this function
|
||||
is here is for the case when you can't pass the buffer through the
|
||||
constructor because there is another object wrapping this stream.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
void fill (ConstBufferSequence const& buffers)
|
||||
{
|
||||
// We don't assume the caller's buffers will
|
||||
// remain valid for the lifetime of this object.
|
||||
//
|
||||
using namespace boost;
|
||||
m_buffer.commit (asio::buffer_copy (
|
||||
m_buffer.prepare (asio::buffer_size (buffers)),
|
||||
buffers));
|
||||
}
|
||||
|
||||
next_layer_type& next_layer()
|
||||
{
|
||||
return m_next_layer;
|
||||
}
|
||||
|
||||
next_layer_type const& next_layer() const
|
||||
{
|
||||
return m_next_layer;
|
||||
}
|
||||
|
||||
lowest_layer_type& lowest_layer()
|
||||
{
|
||||
return m_next_layer.lowest_layer();
|
||||
}
|
||||
|
||||
const lowest_layer_type& lowest_layer() const
|
||||
{
|
||||
return m_next_layer.lowest_layer();
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service()
|
||||
{
|
||||
return m_next_layer.get_io_service();
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
error_code ec;
|
||||
if (close(ec))
|
||||
throw_error (ec, __FILE__, __LINE__);
|
||||
return ec;
|
||||
}
|
||||
|
||||
error_code close (error_code& ec)
|
||||
{
|
||||
// VFALCO NOTE This is questionable. We can't
|
||||
// call m_next_layer.close() because Stream might not
|
||||
// support that function. For example, ssl::stream has no close()
|
||||
//
|
||||
return lowest_layer ().close(ec);
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some (MutableBufferSequence const& buffers)
|
||||
{
|
||||
error_code ec;
|
||||
std::size_t const amount = read_some (buffers, ec);
|
||||
if (ec)
|
||||
throw_error (ec, __FILE__, __LINE__);
|
||||
return amount;
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some (MutableBufferSequence const& buffers, error_code& ec)
|
||||
{
|
||||
if (m_buffer.size () > 0)
|
||||
{
|
||||
ec = error_code ();
|
||||
std::size_t const bytes_transferred = boost::asio::buffer_copy (
|
||||
buffers, m_buffer.data ());
|
||||
m_buffer.consume (bytes_transferred);
|
||||
return bytes_transferred;
|
||||
}
|
||||
return m_next_layer.read_some (buffers, ec);
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers)
|
||||
{
|
||||
error_code ec;
|
||||
std::size_t const amount = write_some (buffers, ec);
|
||||
if (ec)
|
||||
throw_error (ec, __FILE__, __LINE__);
|
||||
return amount;
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers, error_code& ec)
|
||||
{
|
||||
return m_next_layer.write_some (buffers, ec);
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_read_some (MutableBufferSequence const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
if (m_buffer.size () > 0)
|
||||
{
|
||||
std::size_t const bytes_transferred = boost::asio::buffer_copy (
|
||||
buffers, m_buffer.data ());
|
||||
m_buffer.consume (bytes_transferred);
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) (
|
||||
error_code (), bytes_transferred);
|
||||
return;
|
||||
}
|
||||
m_next_layer.async_read_some (buffers,
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_write_some (ConstBufferSequence const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
m_next_layer.async_write_some (buffers,
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
}
|
||||
|
||||
private:
|
||||
Stream m_next_layer;
|
||||
boost::asio::streambuf m_buffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user