diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj
index f50b5e5564..0e1234873b 100644
--- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj
+++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj
@@ -75,6 +75,8 @@
+
+
@@ -306,6 +308,12 @@
true
+
+ true
+ true
+ true
+ true
+
true
true
diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters
index be813db54c..6ae621f34a 100644
--- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters
+++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters
@@ -842,6 +842,12 @@
beast_core\memory
+
+ beast_asio\protocol
+
+
+ beast_asio\protocol
+
@@ -1303,6 +1309,9 @@
beast_asio\basics
+
+ beast_asio\protocol
+
diff --git a/Subtrees/beast/modules/beast_asio/basics/beast_BufferType.h b/Subtrees/beast/modules/beast_asio/basics/beast_BufferType.h
index 24e71d7564..006d624137 100644
--- a/Subtrees/beast/modules/beast_asio/basics/beast_BufferType.h
+++ b/Subtrees/beast/modules/beast_asio/basics/beast_BufferType.h
@@ -91,10 +91,13 @@ private:
std::vector m_buffers;
};
+typedef boost::asio::const_buffer ConstBuffer;
+typedef boost::asio::mutable_buffer MutableBuffer;
+
/** Meets the requirements of ConstBufferSequence */
-typedef BufferType ConstBuffers;
+typedef BufferType ConstBuffers;
/** Meets the requirements of MutableBufferSequence */
-typedef BufferType MutableBuffers;
+typedef BufferType MutableBuffers;
#endif
diff --git a/Subtrees/beast/modules/beast_asio/beast_asio.cpp b/Subtrees/beast/modules/beast_asio/beast_asio.cpp
index f8b0817cd5..71a155aafb 100644
--- a/Subtrees/beast/modules/beast_asio/beast_asio.cpp
+++ b/Subtrees/beast/modules/beast_asio/beast_asio.cpp
@@ -31,6 +31,7 @@ namespace beast
#include "sockets/beast_SslContext.cpp"
#include "protocol/beast_ProxyHandshake.cpp"
+#include "protocol/beast_StreamHandshakeDetectorType.cpp"
#include "tests/beast_TestPeerBasics.cpp"
#include "tests/beast_TestPeerLogic.cpp"
diff --git a/Subtrees/beast/modules/beast_asio/beast_asio.h b/Subtrees/beast/modules/beast_asio/beast_asio.h
index be9b236de9..e797f6567f 100644
--- a/Subtrees/beast/modules/beast_asio/beast_asio.h
+++ b/Subtrees/beast/modules/beast_asio/beast_asio.h
@@ -63,6 +63,8 @@ namespace beast
#include "sockets/beast_SslContext.h"
#include "protocol/beast_ProxyHandshake.h"
+#include "protocol/beast_HandshakeDetectorType.h"
+#include "protocol/beast_StreamHandshakeDetectorType.h"
#include "tests/beast_TestPeerBasics.h"
#include "tests/beast_TestPeer.h"
diff --git a/Subtrees/beast/modules/beast_asio/protocol/beast_HandshakeDetectorType.h b/Subtrees/beast/modules/beast_asio/protocol/beast_HandshakeDetectorType.h
new file mode 100644
index 0000000000..037a720a74
--- /dev/null
+++ b/Subtrees/beast/modules/beast_asio/protocol/beast_HandshakeDetectorType.h
@@ -0,0 +1,344 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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_HANDSHAKEDETECTORTYPE_H_INCLUDED
+#define BEAST_HANDSHAKEDETECTORTYPE_H_INCLUDED
+
+class DetectPolicy
+{
+public:
+ DetectPolicy ()
+ : m_finished (false)
+ , m_success (false)
+ {
+ }
+
+ /** Returns the minimum number of bytes we need to succeed.
+ */
+ virtual std::size_t needed () = 0;
+
+ /** Returns true if the return value of success() is valid.
+ */
+ bool finished () const noexcept
+ {
+ return m_finished;
+ }
+
+ /** Returns true if the buffers matched the Handshake
+ */
+ bool success () const noexcept
+ {
+ bassert (m_finished);
+ return m_success;
+ }
+
+protected:
+ void conclude (bool success = true)
+ {
+ m_finished = true;
+ m_success = success;
+ }
+
+ void fail ()
+ {
+ conclude (false);
+ }
+
+ //--------------------------------------------------------------------------
+
+ /** Represents a small, fixed size buffer.
+ This provides a convenient interface for doing a bytewise
+ verification/reject test on a handshake protocol.
+ */
+ template
+ struct Input
+ {
+ template
+ explicit Input (ConstBufferSequence const& buffer)
+ : m_buffer (boost::asio::buffer (m_storage))
+ , m_size (boost::asio::buffer_copy (m_buffer, buffer))
+ , m_data (boost::asio::buffer_cast (m_buffer))
+ {
+ }
+#if 0
+ uint8 const* data () const noexcept
+ {
+ return m_data;
+ }
+#endif
+
+ uint8 operator[] (std::size_t index) const noexcept
+ {
+ bassert (index >= 0 && index < m_size);
+ return m_data [index];
+ }
+
+ bool peek (std::size_t bytes) const noexcept
+ {
+ if (m_size >= bytes)
+ return true;
+ return false;
+ }
+
+ template
+ bool peek (T* t) noexcept
+ {
+ std::size_t const bytes = sizeof (T);
+ if (m_size >= bytes)
+ {
+ std::copy (m_data, m_data + bytes, t);
+ return true;
+ }
+ return false;
+ }
+
+ bool consume (std::size_t bytes) noexcept
+ {
+ if (m_size >= bytes)
+ {
+ m_data += bytes;
+ m_size -= bytes;
+ return true;
+ }
+ return false;
+ }
+
+ template
+ bool read (T* t) noexcept
+ {
+ std::size_t const bytes = sizeof (T);
+ if (m_size >= bytes)
+ {
+ //this causes a stack corruption.
+ //std::copy (m_data, m_data + bytes, t);
+
+ memcpy (t, m_data, bytes);
+ m_data += bytes;
+ m_size -= bytes;
+ return true;
+ }
+ return false;
+ }
+
+ // Reads an integraltype in network byte order
+ template
+ bool readNetworkInteger (IntegerType* value)
+ {
+ // Must be an integral type!
+ // not available in all versions of std:: unfortunately
+ //static_bassert (std::is_integral ::value);
+ IntegerType networkValue;
+ if (! read (&networkValue))
+ return;
+ *value = fromNetworkByteOrder (networkValue);
+ return true;
+ }
+
+ private:
+ boost::array m_storage;
+ MutableBuffer m_buffer;
+ std::size_t m_size;
+ uint8 const* m_data;
+ };
+
+private:
+ bool m_finished;
+ bool m_success;
+};
+
+// 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 SSL2 : public DetectPolicy
+{
+public:
+ typedef int arg_type;
+
+ explicit SSL2 (arg_type const&)
+ {
+ }
+
+ enum
+ {
+ bytesNeeded = 3
+ };
+
+ std::size_t needed ()
+ {
+ return bytesNeeded;
+ }
+
+ template
+ void analyze (ConstBufferSequence const& buffer)
+ {
+ Input 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 ();
+ }
+};
+
+// Handshake for SSL 3 (Also TLS 1.0 and 1.1)
+//
+// http://www.ietf.org/rfc/rfc2246.txt
+//
+// Section 7.4. Handshake protocol
+//
+class SSL3 : public DetectPolicy
+{
+public:
+ typedef int arg_type; // dummy
+
+ explicit SSL3 (arg_type const&)
+ {
+ }
+
+ enum
+ {
+ bytesNeeded = 6
+ };
+
+ std::size_t needed ()
+ {
+ return bytesNeeded;
+ }
+
+ template
+ void analyze (ConstBufferSequence const& buffer)
+ {
+ uint16 version;
+ Input 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 ();
+ }
+};
+
+//--------------------------------------------------------------------------
+
+template
+class HandshakeDetectorType
+{
+public:
+ typedef typename Logic::arg_type arg_type;
+
+ explicit HandshakeDetectorType (arg_type const& arg = arg_type ())
+ : m_logic (arg)
+ {
+ }
+
+ std::size_t needed () noexcept
+ {
+ return m_logic.needed ();
+ }
+
+ bool finished () noexcept
+ {
+ return m_logic.finished ();
+ }
+
+ /** If finished is true, this tells us if the handshake was detected.
+ */
+ bool success () noexcept
+ {
+ return m_logic.success ();
+ }
+
+ /** Analyze the buffer to match the Handshake.
+ Returns `true` if the analysis is complete.
+ */
+ template
+ bool analyze (ConstBufferSequence const& buffer)
+ {
+ bassert (! m_logic.finished ());
+ m_logic.analyze (buffer);
+ return m_logic.finished ();
+ }
+
+private:
+ Logic m_logic;
+};
+
+#endif
diff --git a/Subtrees/beast/modules/beast_asio/protocol/beast_StreamHandshakeDetectorType.cpp b/Subtrees/beast/modules/beast_asio/protocol/beast_StreamHandshakeDetectorType.cpp
new file mode 100644
index 0000000000..31d57f5deb
--- /dev/null
+++ b/Subtrees/beast/modules/beast_asio/protocol/beast_StreamHandshakeDetectorType.cpp
@@ -0,0 +1,19 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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.
+*/
+//==============================================================================
+
diff --git a/Subtrees/beast/modules/beast_asio/protocol/beast_StreamHandshakeDetectorType.h b/Subtrees/beast/modules/beast_asio/protocol/beast_StreamHandshakeDetectorType.h
new file mode 100644
index 0000000000..7550e77655
--- /dev/null
+++ b/Subtrees/beast/modules/beast_asio/protocol/beast_StreamHandshakeDetectorType.h
@@ -0,0 +1,78 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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_STREAMHANDSHAKEDETECTORTYPE_H_INCLUDED
+#define BEAST_STREAMHANDSHAKEDETECTORTYPE_H_INCLUDED
+
+/** Wraps a HandshakeDetector and does the work on the Socket for you.
+*/
+template
+class StreamHandshakeDetectorType
+{
+protected:
+ typedef boost::system::error_code error_code;
+ typedef StreamHandshakeDetectorType This;
+
+public:
+ typedef typename Detector::arg_type arg_type;
+
+ explicit StreamHandshakeDetectorType (arg_type const& arg = arg_type ())
+ {
+ }
+
+ template
+ void async_handshake (Socket& socket, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
+ {
+#if 0
+ std::size_t const bytes = m_detector.needed ();
+#if 1
+ boost::asio::async_read (socket, m_buffer.prepare (bytes), boost::bind (
+ &This::on_read , this, &socket,
+ handler,
+ boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+#else
+ boost::asio::async_read (socket, m_buffer.prepare (bytes), boost::bind (
+ &This::on_read2, this,
+ boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+#endif
+#endif
+ }
+
+protected:
+ template
+ void on_read (Socket* socket, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler,
+ error_code const& ec, std::size_t bytes_transferred)
+ {
+ m_buffer.commit (bytes_transferred);
+
+ if (m_detector.analyze (m_buffer.data ()))
+ {
+ if (m_detector.success ())
+ {
+ //socket->async_handshake (Socket::server, m_buffer.data (), handler);
+ }
+ }
+ }
+
+private:
+ Detector m_detector;
+ boost::asio::streambuf m_buffer;
+};
+
+#endif
diff --git a/Subtrees/beast/modules/beast_asio/system/beast_BoostIncludes.h b/Subtrees/beast/modules/beast_asio/system/beast_BoostIncludes.h
index 588fd45c26..917139a7d3 100644
--- a/Subtrees/beast/modules/beast_asio/system/beast_BoostIncludes.h
+++ b/Subtrees/beast/modules/beast_asio/system/beast_BoostIncludes.h
@@ -51,10 +51,14 @@
#include
#if (BOOST_VERSION / 100) >= 1054
# define BEAST_ASIO_HAS_BUFFEREDHANDSHAKE 1
-# define BEAST_ASIO_HAS_FUTURE_RETURNS 1
+# ifndef BEAST_ASIO_HAS_FUTURE_RETURNS
+# define BEAST_ASIO_HAS_FUTURE_RETURNS 1
+# endif
#else
# define BEAST_ASIO_HAS_BUFFEREDHANDSHAKE 0
-# define BEAST_ASIO_HAS_FUTURE_RETURNS 0
+# ifndef BEAST_ASIO_HAS_FUTURE_RETURNS
+# define BEAST_ASIO_HAS_FUTURE_RETURNS 0
+# endif
#endif
#if ! BEAST_ASIO_HAS_FUTURE_RETURNS
diff --git a/Subtrees/beast/modules/beast_asio/tests/beast_TestPeerLogicProxyClient.cpp b/Subtrees/beast/modules/beast_asio/tests/beast_TestPeerLogicProxyClient.cpp
index fb57deaf55..36a37659ba 100644
--- a/Subtrees/beast/modules/beast_asio/tests/beast_TestPeerLogicProxyClient.cpp
+++ b/Subtrees/beast/modules/beast_asio/tests/beast_TestPeerLogicProxyClient.cpp
@@ -34,4 +34,3 @@ void TestPeerLogicProxyClient::on_pre_handshake ()
std::size_t const amount = boost::asio::write (
socket (), boost::asio::buffer (line), error ());
}
-