mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
Remove unused and obsolete classes and tidy up:
Many classes required to support type-erasure of handlers and boost::asio types are now obsolete, so these classes and files are removed: HTTPClientType, FixedInputBuffer, PeerRole, socket_wrapper, client_session, basic_url, abstract_socket, buffer_sequence, memory_buffer, enable_wait_for_async, shared_handler, wrap_handler, streambuf, ContentBodyBuffer, SSLContext, completion-handler based handshake detectors. These structural changes are made: * Some missing includes added to headers * asio module directory flattened
This commit is contained in:
@@ -130,20 +130,11 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\Arithmetic.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\abstract_socket.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\abstract_socket.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\Asio.unity.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\bind_handler.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\buffer_sequence.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\enable_wait_for_async.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\impl\IPAddressConversion.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -151,14 +142,8 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\IPAddressConversion.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\memory_buffer.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\placeholders.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\shared_handler.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\socket_wrapper.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\ssl.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\ssl_bundle.h">
|
||||
@@ -166,17 +151,6 @@
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\tests\bind_handler.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\tests\enable_wait_for_async.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\tests\shared_handler.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\tests\wrap_handler.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\wrap_handler.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\Atomic.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\boost\Boost.unity.cpp">
|
||||
@@ -184,8 +158,6 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\boost\ErrorCode.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\boost\get_pointer.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\ByteOrder.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\chrono\abstract_clock.h">
|
||||
@@ -362,14 +334,8 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\http\basic_parser.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\http\basic_url.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\http\body.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\http\client_session.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\http\detail\header_traits.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\http\headers.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\http\HTTP.unity.cpp">
|
||||
@@ -378,9 +344,6 @@
|
||||
<ClCompile Include="..\..\src\beast\beast\http\impl\basic_parser.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\http\impl\basic_url.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\http\impl\http-parser\http_parser.c">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -410,12 +373,6 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\http\rfc2616.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\http\tests\basic_url.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\http\tests\client_session.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\http\tests\parser.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -500,149 +457,58 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\Memory.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\asio.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\asio.unity.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\async\AsyncObject.h">
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\AsyncObject.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\basics\FixedInputBuffer.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\basics\PeerRole.cpp">
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPField.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\basics\PeerRole.h">
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPField.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\basics\SSLContext.cpp">
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPHeaders.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\basics\SSLContext.h">
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPHeaders.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPClientType.cpp">
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPMessage.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPClientType.h">
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPMessage.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPField.cpp">
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPParser.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPField.h">
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPParser.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPHeaders.cpp">
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPParserImpl.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPRequest.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPHeaders.h">
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPRequest.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPMessage.cpp">
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPRequestParser.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPMessage.h">
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPRequestParser.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPParser.cpp">
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPResponse.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPParser.h">
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPResponse.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPParserImpl.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPRequest.cpp">
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPResponseParser.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPRequest.h">
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPResponseParser.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPRequestParser.cpp">
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPVersion.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPRequestParser.h">
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPVersion.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPResponse.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPResponse.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPResponseParser.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPResponseParser.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPVersion.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPVersion.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\HandshakeDetectLogic.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\protocol\HandshakeDetectLogicPROXY.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\HandshakeDetectLogicPROXY.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\HandshakeDetectLogicSSL2.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\HandshakeDetectLogicSSL3.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\HandshakeDetector.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\InputParser.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\PrefilledReadStream.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\system\BoostIncludes.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\system\OpenSSLIncludes.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\PeerTest.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\PeerTest.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeer.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerBasics.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerBasics.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerDetails.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerDetailsTcp.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogic.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogic.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicAsyncClient.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicAsyncClient.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicAsyncServer.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicAsyncServer.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicProxyClient.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicProxyClient.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicSyncClient.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicSyncClient.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicSyncServer.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicSyncServer.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerType.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerUnitTests.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\containers\Array.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\containers\ArrayAllocationBase.h">
|
||||
@@ -1141,8 +1007,6 @@
|
||||
<ClCompile Include="..\..\src\beast\beast\utility\impl\StaticObject.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\utility\is_call_possible.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\utility\Journal.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\utility\LeakChecked.h">
|
||||
|
||||
@@ -64,9 +64,6 @@
|
||||
<Filter Include="beast\http">
|
||||
<UniqueIdentifier>{7138D215-DA65-98D5-EF7D-C9896685201E}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\http\detail">
|
||||
<UniqueIdentifier>{3E84AA4C-CB48-99F0-EB35-5603FF633A51}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\http\impl">
|
||||
<UniqueIdentifier>{932F732F-F09E-5C50-C8A1-D62342CCAA1F}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -91,24 +88,6 @@
|
||||
<Filter Include="beast\module\asio">
|
||||
<UniqueIdentifier>{98F41E1A-9413-1CD5-5EA7-DE837BC9FF66}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\asio\async">
|
||||
<UniqueIdentifier>{6C88FB42-ECB6-831B-CC7F-D59177337235}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\asio\basics">
|
||||
<UniqueIdentifier>{FCA1A8DC-54B3-FE11-FF2C-35D8E498B74E}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\asio\http">
|
||||
<UniqueIdentifier>{AE9C05DA-9DF4-1D28-FDD4-58703FCC2FC9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\asio\protocol">
|
||||
<UniqueIdentifier>{C4CBDF7F-B92F-7BAF-285C-188AE9555AC1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\asio\system">
|
||||
<UniqueIdentifier>{E5B5D1BC-6B68-AE77-2A0F-46A50C948338}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\asio\tests">
|
||||
<UniqueIdentifier>{DDA959BD-205A-AA5F-A80E-7CE11C748552}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\core">
|
||||
<UniqueIdentifier>{7451A33F-2734-1B7A-974D-34C35487A770}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -618,24 +597,12 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\Arithmetic.h">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\abstract_socket.cpp">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\abstract_socket.h">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\Asio.unity.cpp">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\bind_handler.h">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\buffer_sequence.h">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\enable_wait_for_async.h">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\impl\IPAddressConversion.cpp">
|
||||
<Filter>beast\asio\impl</Filter>
|
||||
</ClCompile>
|
||||
@@ -645,18 +612,9 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\IPAddressConversion.h">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\memory_buffer.h">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\placeholders.h">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\shared_handler.h">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\socket_wrapper.h">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\ssl.h">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClInclude>
|
||||
@@ -666,18 +624,6 @@
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\tests\bind_handler.test.cpp">
|
||||
<Filter>beast\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\tests\enable_wait_for_async.test.cpp">
|
||||
<Filter>beast\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\tests\shared_handler.test.cpp">
|
||||
<Filter>beast\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\tests\wrap_handler.test.cpp">
|
||||
<Filter>beast\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\asio\wrap_handler.h">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\Atomic.h">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
@@ -687,9 +633,6 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\boost\ErrorCode.h">
|
||||
<Filter>beast\boost</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\boost\get_pointer.h">
|
||||
<Filter>beast\boost</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\ByteOrder.h">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
@@ -921,18 +864,9 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\http\basic_parser.h">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\http\basic_url.h">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\http\body.h">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\http\client_session.h">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\http\detail\header_traits.h">
|
||||
<Filter>beast\http\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\http\headers.h">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
@@ -942,9 +876,6 @@
|
||||
<ClCompile Include="..\..\src\beast\beast\http\impl\basic_parser.cpp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\http\impl\basic_url.cpp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\http\impl\http-parser\http_parser.c">
|
||||
<Filter>beast\http\impl\http-parser</Filter>
|
||||
</ClCompile>
|
||||
@@ -981,12 +912,6 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\http\rfc2616.h">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\http\tests\basic_url.test.cpp">
|
||||
<Filter>beast\http\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\http\tests\client_session.test.cpp">
|
||||
<Filter>beast\http\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\http\tests\parser.test.cpp">
|
||||
<Filter>beast\http\tests</Filter>
|
||||
</ClCompile>
|
||||
@@ -1095,186 +1020,69 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\Memory.h">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\asio.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\asio.unity.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\async\AsyncObject.h">
|
||||
<Filter>beast\module\asio\async</Filter>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\AsyncObject.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\basics\FixedInputBuffer.h">
|
||||
<Filter>beast\module\asio\basics</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\basics\PeerRole.cpp">
|
||||
<Filter>beast\module\asio\basics</Filter>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPField.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\basics\PeerRole.h">
|
||||
<Filter>beast\module\asio\basics</Filter>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPField.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\basics\SSLContext.cpp">
|
||||
<Filter>beast\module\asio\basics</Filter>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPHeaders.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\basics\SSLContext.h">
|
||||
<Filter>beast\module\asio\basics</Filter>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPHeaders.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPClientType.cpp">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPMessage.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPClientType.h">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPMessage.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPField.cpp">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPParser.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPField.h">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPParser.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPHeaders.cpp">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPParserImpl.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPRequest.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPHeaders.h">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPRequest.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPMessage.cpp">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPRequestParser.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPMessage.h">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPRequestParser.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPParser.cpp">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPResponse.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPParser.h">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPResponse.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPParserImpl.h">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPRequest.cpp">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPResponseParser.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPRequest.h">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPResponseParser.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPRequestParser.cpp">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPVersion.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPRequestParser.h">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPVersion.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPResponse.cpp">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPResponse.h">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPResponseParser.cpp">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPResponseParser.h">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\http\HTTPVersion.cpp">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\http\HTTPVersion.h">
|
||||
<Filter>beast\module\asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\HandshakeDetectLogic.h">
|
||||
<Filter>beast\module\asio\protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\protocol\HandshakeDetectLogicPROXY.cpp">
|
||||
<Filter>beast\module\asio\protocol</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\HandshakeDetectLogicPROXY.h">
|
||||
<Filter>beast\module\asio\protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\HandshakeDetectLogicSSL2.h">
|
||||
<Filter>beast\module\asio\protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\HandshakeDetectLogicSSL3.h">
|
||||
<Filter>beast\module\asio\protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\HandshakeDetector.h">
|
||||
<Filter>beast\module\asio\protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\InputParser.h">
|
||||
<Filter>beast\module\asio\protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\protocol\PrefilledReadStream.h">
|
||||
<Filter>beast\module\asio\protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\system\BoostIncludes.h">
|
||||
<Filter>beast\module\asio\system</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\system\OpenSSLIncludes.h">
|
||||
<Filter>beast\module\asio\system</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\PeerTest.cpp">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\PeerTest.h">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeer.h">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerBasics.cpp">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerBasics.h">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerDetails.h">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerDetailsTcp.h">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogic.cpp">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogic.h">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicAsyncClient.cpp">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicAsyncClient.h">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicAsyncServer.cpp">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicAsyncServer.h">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicProxyClient.cpp">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicProxyClient.h">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicSyncClient.cpp">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicSyncClient.h">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicSyncServer.cpp">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerLogicSyncServer.h">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\tests\TestPeerType.h">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\tests\TestPeerUnitTests.cpp">
|
||||
<Filter>beast\module\asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\containers\Array.h">
|
||||
<Filter>beast\module\core\containers</Filter>
|
||||
</ClInclude>
|
||||
@@ -1905,9 +1713,6 @@
|
||||
<ClCompile Include="..\..\src\beast\beast\utility\impl\StaticObject.cpp">
|
||||
<Filter>beast\utility\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\utility\is_call_possible.h">
|
||||
<Filter>beast\utility</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\utility\Journal.h">
|
||||
<Filter>beast\utility</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -22,11 +22,5 @@
|
||||
#endif
|
||||
|
||||
#include <beast/asio/impl/IPAddressConversion.cpp>
|
||||
|
||||
#include <beast/asio/tests/wrap_handler.test.cpp>
|
||||
#include <beast/asio/tests/bind_handler.test.cpp>
|
||||
#include <beast/asio/tests/enable_wait_for_async.test.cpp>
|
||||
#include <beast/asio/tests/shared_handler.test.cpp>
|
||||
|
||||
#include <beast/asio/abstract_socket.cpp> // TEMPORARY!
|
||||
|
||||
|
||||
@@ -1,217 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/asio/abstract_socket.h>
|
||||
#include <beast/asio/bind_handler.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
#if ! BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Socket
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void* abstract_socket::this_layer_ptr (char const*) const
|
||||
{
|
||||
pure_virtual_called ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// native_handle
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool abstract_socket::native_handle (char const*, void*)
|
||||
{
|
||||
pure_virtual_called ();
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// basic_io_object
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
boost::asio::io_service& abstract_socket::get_io_service ()
|
||||
{
|
||||
pure_virtual_called ();
|
||||
return *static_cast <boost::asio::io_service*>(nullptr);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void*
|
||||
abstract_socket::lowest_layer_ptr (char const*) const
|
||||
{
|
||||
pure_virtual_called ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto
|
||||
abstract_socket::cancel (boost::system::error_code& ec) -> error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
auto
|
||||
abstract_socket::shutdown (shutdown_type, boost::system::error_code& ec) -> error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
auto
|
||||
abstract_socket::close (boost::system::error_code& ec) -> error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket_acceptor
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
auto
|
||||
abstract_socket::accept (abstract_socket&, error_code& ec) -> error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::async_accept (abstract_socket&, error_handler handler)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error()));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// basic_stream_socket
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::size_t
|
||||
abstract_socket::read_some (mutable_buffers, error_code& ec)
|
||||
{
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
abstract_socket::write_some (const_buffers, error_code& ec)
|
||||
{
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::async_read_some (mutable_buffers, transfer_handler handler)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error(), 0));
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::async_write_some (const_buffers, transfer_handler handler)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error(), 0));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// ssl::stream
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void*
|
||||
abstract_socket::next_layer_ptr (char const*) const
|
||||
{
|
||||
pure_virtual_called ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
abstract_socket::needs_handshake ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::set_verify_mode (int)
|
||||
{
|
||||
pure_virtual_called ();
|
||||
}
|
||||
|
||||
auto
|
||||
abstract_socket::handshake (handshake_type, error_code& ec) -> error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::async_handshake (handshake_type, error_handler handler)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error()));
|
||||
}
|
||||
|
||||
auto
|
||||
abstract_socket::handshake (handshake_type, const_buffers, error_code& ec) ->
|
||||
error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::async_handshake (handshake_type, const_buffers,
|
||||
transfer_handler handler)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error(), 0));
|
||||
}
|
||||
|
||||
auto
|
||||
abstract_socket::shutdown (error_code& ec) -> error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::async_shutdown (error_handler handler)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error()));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,404 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_ABSTRACT_SOCKET_H_INCLUDED
|
||||
#define BEAST_ASIO_ABSTRACT_SOCKET_H_INCLUDED
|
||||
|
||||
#include <beast/asio/buffer_sequence.h>
|
||||
#include <beast/asio/shared_handler.h>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/socket_base.hpp>
|
||||
#include <boost/asio/ssl/stream_base.hpp>
|
||||
|
||||
// Checking overrides replaces unimplemented stubs with pure virtuals
|
||||
#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
|
||||
# define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 1
|
||||
#endif
|
||||
|
||||
#if BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
|
||||
# define BEAST_SOCKET_VIRTUAL = 0
|
||||
#else
|
||||
# define BEAST_SOCKET_VIRTUAL
|
||||
#endif
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** A high level socket abstraction.
|
||||
|
||||
This combines the capabilities of multiple socket interfaces such
|
||||
as listening, connecting, streaming, and handshaking. It brings
|
||||
everything together into a single abstract interface.
|
||||
|
||||
When member functions are called and the underlying implementation does
|
||||
not support the operation, a fatal error is generated.
|
||||
*/
|
||||
class abstract_socket
|
||||
: public boost::asio::ssl::stream_base
|
||||
, public boost::asio::socket_base
|
||||
{
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
typedef asio::shared_handler <void (void)> post_handler;
|
||||
|
||||
typedef asio::shared_handler <void (error_code)> error_handler;
|
||||
|
||||
typedef asio::shared_handler <
|
||||
void (error_code, std::size_t)> transfer_handler;
|
||||
|
||||
static
|
||||
void
|
||||
pure_virtual_called()
|
||||
{
|
||||
throw std::runtime_error ("pure virtual called");
|
||||
}
|
||||
|
||||
static
|
||||
error_code
|
||||
pure_virtual_error ()
|
||||
{
|
||||
pure_virtual_called();
|
||||
return boost::system::errc::make_error_code (
|
||||
boost::system::errc::function_not_supported);
|
||||
}
|
||||
|
||||
static
|
||||
error_code
|
||||
pure_virtual_error (error_code& ec)
|
||||
{
|
||||
return ec = pure_virtual_error();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
throw_if (error_code const& ec)
|
||||
{
|
||||
if (ec)
|
||||
throw boost::system::system_error (ec);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~abstract_socket ()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// abstract_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Retrieve the underlying object.
|
||||
|
||||
@note If the type doesn't match, nullptr is returned or an
|
||||
exception is thrown if trying to acquire a reference.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Object>
|
||||
Object& this_layer ()
|
||||
{
|
||||
Object* object (this->this_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
throw std::bad_cast ();
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const& this_layer () const
|
||||
{
|
||||
Object const* object (this->this_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
throw std::bad_cast ();
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object* this_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this->this_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const* this_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
this->this_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* this_layer_ptr (char const* type_name) const
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// native_handle
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Retrieve the native representation of the object.
|
||||
|
||||
Since we dont know the return type, and because almost every
|
||||
asio implementation passes the result by value, you need to provide
|
||||
a pointer to a default-constructed object of the matching type.
|
||||
|
||||
@note If the type doesn't match, an exception is thrown.
|
||||
*/
|
||||
template <typename Handle>
|
||||
void native_handle (Handle* dest)
|
||||
{
|
||||
if (! native_handle (typeid (Handle).name (), dest))
|
||||
throw std::bad_cast ();
|
||||
}
|
||||
|
||||
virtual bool native_handle (char const* type_name, void* dest)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_io_object
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
virtual boost::asio::io_service& get_io_service ()
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Retrieve the lowest layer object.
|
||||
|
||||
@note If the type doesn't match, nullptr is returned or an
|
||||
exception is thrown if trying to acquire a reference.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Object>
|
||||
Object& lowest_layer ()
|
||||
{
|
||||
Object* object (this->lowest_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
throw std::bad_cast ();
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const& lowest_layer () const
|
||||
{
|
||||
Object const* object (this->lowest_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
throw std::bad_cast ();
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object* lowest_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this->lowest_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const* lowest_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
this->lowest_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* lowest_layer_ptr (char const* type_name) const
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void cancel ()
|
||||
{
|
||||
error_code ec;
|
||||
cancel (ec);
|
||||
throw_if (ec);
|
||||
}
|
||||
|
||||
virtual error_code cancel (error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
void shutdown (shutdown_type what)
|
||||
{
|
||||
error_code ec;
|
||||
shutdown (what, ec);
|
||||
throw_if (ec);
|
||||
}
|
||||
|
||||
virtual error_code shutdown (shutdown_type what,
|
||||
error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
void close ()
|
||||
{
|
||||
error_code ec;
|
||||
close (ec);
|
||||
throw_if (ec);
|
||||
}
|
||||
|
||||
virtual error_code close (error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket_acceptor
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
virtual error_code accept (abstract_socket& peer, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void async_accept (abstract_socket& peer, error_handler handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_stream_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
virtual std::size_t read_some (mutable_buffers buffers, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual std::size_t write_some (const_buffers buffers, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void async_read_some (mutable_buffers buffers,
|
||||
transfer_handler handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void async_write_some (const_buffers buffers,
|
||||
transfer_handler handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// ssl::stream
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Retrieve the next layer object.
|
||||
|
||||
@note If the type doesn't match, nullptr is returned or an
|
||||
exception is thrown if trying to acquire a reference.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Object>
|
||||
Object& next_layer ()
|
||||
{
|
||||
Object* object (this->next_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
throw std::bad_cast ();
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const& next_layer () const
|
||||
{
|
||||
Object const* object (this->next_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
throw std::bad_cast ();
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object* next_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this->next_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const* next_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
this->next_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* next_layer_ptr (char const* type_name) const
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
/** Determines if the underlying stream requires a handshake.
|
||||
|
||||
If needs_handshake is true, it will be necessary to call handshake or
|
||||
async_handshake after the connection is established. Furthermore it
|
||||
will be necessary to call the shutdown member from the
|
||||
HandshakeInterface to close the connection. Do not close the underlying
|
||||
socket or else the closure will not be graceful. Only one side should
|
||||
initiate the handshaking shutdon. The other side should observe it.
|
||||
Which side does what is up to the user.
|
||||
|
||||
The default version returns false.
|
||||
*/
|
||||
virtual bool needs_handshake ()
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void set_verify_mode (int verify_mode)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
void handshake (handshake_type type)
|
||||
{
|
||||
error_code ec;
|
||||
handshake (type, ec);
|
||||
throw_if (ec);
|
||||
}
|
||||
|
||||
virtual error_code handshake (handshake_type type, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void async_handshake (handshake_type type, error_handler handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
virtual error_code handshake (handshake_type type,
|
||||
const_buffers buffers, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void async_handshake (handshake_type type,
|
||||
const_buffers buffers, transfer_handler handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void shutdown ()
|
||||
{
|
||||
error_code ec;
|
||||
shutdown (ec);
|
||||
throw_if (ec);
|
||||
}
|
||||
|
||||
virtual error_code shutdown (error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void async_shutdown (error_handler handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,126 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_BUFFER_SEQUENCE_H_INCLUDED
|
||||
#define BEAST_ASIO_BUFFER_SEQUENCE_H_INCLUDED
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <beast/utility/noexcept.h>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
template <class Buffer>
|
||||
class buffer_sequence
|
||||
{
|
||||
private:
|
||||
typedef std::vector <Buffer> sequence_type;
|
||||
|
||||
public:
|
||||
typedef Buffer value_type;
|
||||
typedef typename sequence_type::const_iterator const_iterator;
|
||||
|
||||
private:
|
||||
sequence_type m_buffers;
|
||||
|
||||
template <class FwdIter>
|
||||
void assign (FwdIter first, FwdIter last)
|
||||
{
|
||||
m_buffers.clear();
|
||||
m_buffers.reserve (std::distance (first, last));
|
||||
for (;first != last; ++first)
|
||||
m_buffers.push_back (*first);
|
||||
}
|
||||
|
||||
public:
|
||||
buffer_sequence ()
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
class BufferSequence,
|
||||
class = std::enable_if_t <std::is_constructible <
|
||||
Buffer, typename BufferSequence::value_type>::value>
|
||||
>
|
||||
buffer_sequence (BufferSequence const& s)
|
||||
{
|
||||
assign (std::begin (s), std::end (s));
|
||||
}
|
||||
|
||||
template <
|
||||
class FwdIter,
|
||||
class = std::enable_if_t <std::is_constructible <
|
||||
Buffer, typename std::iterator_traits <
|
||||
FwdIter>::value_type>::value>
|
||||
>
|
||||
buffer_sequence (FwdIter first, FwdIter last)
|
||||
{
|
||||
assign (first, last);
|
||||
}
|
||||
|
||||
template <class BufferSequence>
|
||||
std::enable_if_t <std::is_constructible <
|
||||
Buffer, typename BufferSequence::value_type>::value,
|
||||
buffer_sequence&
|
||||
>
|
||||
operator= (BufferSequence const& s)
|
||||
{
|
||||
return assign (s);
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin () const noexcept
|
||||
{
|
||||
return m_buffers.begin ();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end () const noexcept
|
||||
{
|
||||
return m_buffers.end ();
|
||||
}
|
||||
|
||||
#if 0
|
||||
template <class ConstBufferSequence>
|
||||
void
|
||||
assign (ConstBufferSequence const& buffers)
|
||||
{
|
||||
auto const n (std::distance (
|
||||
std::begin (buffers), std::end (buffers)));
|
||||
|
||||
for (int i = 0, auto iter (std::begin (buffers));
|
||||
iter != std::end (buffers); ++iter, ++i)
|
||||
m_buffers[i] = Buffer (boost::asio::buffer_cast <void*> (
|
||||
*iter), boost::asio::buffer_size (*iter));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef buffer_sequence <boost::asio::const_buffer> const_buffers;
|
||||
typedef buffer_sequence <boost::asio::mutable_buffer> mutable_buffers;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,369 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_ENABLE_WAIT_FOR_ASYNC_H_INCLUDED
|
||||
#define BEAST_ASIO_ENABLE_WAIT_FOR_ASYNC_H_INCLUDED
|
||||
|
||||
#include <beast/asio/wrap_handler.h>
|
||||
#include <beast/utility/is_call_possible.h>
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Owner, class Handler>
|
||||
class ref_counted_wrapped_handler
|
||||
{
|
||||
private:
|
||||
static_assert (std::is_same <std::decay_t <Owner>, Owner>::value,
|
||||
"Owner cannot be a const or reference type");
|
||||
|
||||
Handler m_handler;
|
||||
std::reference_wrapper <Owner> m_owner;
|
||||
bool m_continuation;
|
||||
|
||||
public:
|
||||
~ref_counted_wrapped_handler();
|
||||
|
||||
ref_counted_wrapped_handler (Owner& owner,
|
||||
Handler&& handler, bool continuation);
|
||||
|
||||
ref_counted_wrapped_handler (Owner& owner,
|
||||
Handler const& handler, bool continuation);
|
||||
|
||||
ref_counted_wrapped_handler (
|
||||
ref_counted_wrapped_handler const& other);
|
||||
|
||||
ref_counted_wrapped_handler (
|
||||
ref_counted_wrapped_handler&& other);
|
||||
|
||||
ref_counted_wrapped_handler& operator= (
|
||||
ref_counted_wrapped_handler const&) = delete;
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
operator() (Args&&... args)
|
||||
{
|
||||
m_handler (std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
operator() (Args&&... args) const
|
||||
{
|
||||
m_handler (std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function& f,
|
||||
ref_counted_wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (f, h->m_handler);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function const& f,
|
||||
ref_counted_wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (f, h->m_handler);
|
||||
}
|
||||
|
||||
friend
|
||||
void*
|
||||
asio_handler_allocate (std::size_t size,
|
||||
ref_counted_wrapped_handler* h)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate (size, h->m_handler);
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
asio_handler_deallocate (void* p, std::size_t size,
|
||||
ref_counted_wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate (p, size, h->m_handler);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
asio_handler_is_continuation (ref_counted_wrapped_handler* h)
|
||||
{
|
||||
return h->m_continuation;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Owner, class Handler>
|
||||
ref_counted_wrapped_handler<Owner, Handler>::~ref_counted_wrapped_handler()
|
||||
{
|
||||
m_owner.get().decrement();
|
||||
}
|
||||
|
||||
template <class Owner, class Handler>
|
||||
ref_counted_wrapped_handler<Owner, Handler>::ref_counted_wrapped_handler (
|
||||
Owner& owner, Handler&& handler, bool continuation)
|
||||
: m_handler (std::move (handler))
|
||||
, m_owner (owner)
|
||||
, m_continuation (continuation ? true :
|
||||
boost_asio_handler_cont_helpers::is_continuation (m_handler))
|
||||
{
|
||||
m_owner.get().increment();
|
||||
}
|
||||
|
||||
template <class Owner, class Handler>
|
||||
ref_counted_wrapped_handler<Owner, Handler>::ref_counted_wrapped_handler (
|
||||
Owner& owner, Handler const& handler, bool continuation)
|
||||
: m_handler (handler)
|
||||
, m_owner (owner)
|
||||
, m_continuation (continuation ? true :
|
||||
boost_asio_handler_cont_helpers::is_continuation (m_handler))
|
||||
{
|
||||
m_owner.get().increment();
|
||||
}
|
||||
|
||||
template <class Owner, class Handler>
|
||||
ref_counted_wrapped_handler<Owner, Handler>::ref_counted_wrapped_handler (
|
||||
ref_counted_wrapped_handler const& other)
|
||||
: m_handler (other.m_handler)
|
||||
, m_owner (other.m_owner)
|
||||
, m_continuation (other.m_continuation)
|
||||
{
|
||||
m_owner.get().increment();
|
||||
}
|
||||
|
||||
template <class Owner, class Handler>
|
||||
ref_counted_wrapped_handler<Owner, Handler>::ref_counted_wrapped_handler (
|
||||
ref_counted_wrapped_handler&& other)
|
||||
: m_handler (std::move (other.m_handler))
|
||||
, m_owner (other.m_owner)
|
||||
, m_continuation (other.m_continuation)
|
||||
{
|
||||
m_owner.get().increment();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Facilitates blocking until no completion handlers are remaining.
|
||||
If Derived has this member function:
|
||||
|
||||
@code
|
||||
void on_wait_for_async (void)
|
||||
@endcode
|
||||
|
||||
Then it will be called every time the number of pending completion
|
||||
handlers transitions to zero from a non-zero value. The call is made
|
||||
while holding the internal mutex.
|
||||
*/
|
||||
template <class Derived>
|
||||
class enable_wait_for_async
|
||||
{
|
||||
private:
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(
|
||||
has_on_wait_for_async,on_wait_for_async);
|
||||
|
||||
void increment()
|
||||
{
|
||||
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||
++m_count;
|
||||
}
|
||||
|
||||
void notify (std::true_type)
|
||||
{
|
||||
static_cast <Derived*> (this)->on_wait_for_async();
|
||||
}
|
||||
|
||||
void notify (std::false_type)
|
||||
{
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||
--m_count;
|
||||
if (m_count == 0)
|
||||
{
|
||||
m_cond.notify_all();
|
||||
notify (std::integral_constant <bool,
|
||||
has_on_wait_for_async<Derived, void(void)>::value>());
|
||||
}
|
||||
}
|
||||
|
||||
template <class Owner, class Handler>
|
||||
friend class detail::ref_counted_wrapped_handler;
|
||||
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_cond;
|
||||
std::size_t m_count;
|
||||
|
||||
public:
|
||||
/** Blocks if there are any pending completion handlers. */
|
||||
void
|
||||
wait_for_async()
|
||||
{
|
||||
std::unique_lock <decltype (m_mutex)> lock (m_mutex);
|
||||
while (m_count != 0)
|
||||
m_cond.wait (lock);
|
||||
}
|
||||
|
||||
protected:
|
||||
enable_wait_for_async()
|
||||
: m_count (0)
|
||||
{
|
||||
}
|
||||
|
||||
~enable_wait_for_async()
|
||||
{
|
||||
assert (m_count == 0);
|
||||
}
|
||||
|
||||
/** Wraps the specified handler so it can be counted. */
|
||||
/** @{ */
|
||||
template <class Handler>
|
||||
detail::ref_counted_wrapped_handler <
|
||||
enable_wait_for_async,
|
||||
std::remove_reference_t <Handler>
|
||||
>
|
||||
wrap_with_counter (Handler&& handler, bool continuation = false)
|
||||
{
|
||||
return detail::ref_counted_wrapped_handler <enable_wait_for_async,
|
||||
std::remove_reference_t <Handler>> (*this,
|
||||
std::forward <Handler> (handler), continuation);
|
||||
}
|
||||
|
||||
template <class Handler>
|
||||
detail::ref_counted_wrapped_handler <
|
||||
enable_wait_for_async,
|
||||
std::remove_reference_t <Handler>
|
||||
>
|
||||
wrap_with_counter (continuation_t, Handler&& handler)
|
||||
{
|
||||
return detail::ref_counted_wrapped_handler <enable_wait_for_async,
|
||||
std::remove_reference_t <Handler>> (*this,
|
||||
std::forward <Handler> (handler), true);
|
||||
}
|
||||
/** @} */
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** A waitable event object that blocks when handlers are pending. */
|
||||
class pending_handlers
|
||||
{
|
||||
private:
|
||||
std::size_t count_ = 0;
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cond_;
|
||||
|
||||
template <class Owner, class Handler>
|
||||
friend class detail::ref_counted_wrapped_handler;
|
||||
|
||||
template <class = void>
|
||||
void
|
||||
increment();
|
||||
|
||||
template <class = void>
|
||||
void
|
||||
decrement();
|
||||
|
||||
public:
|
||||
~pending_handlers()
|
||||
{
|
||||
assert (count_ == 0);
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
void
|
||||
wait();
|
||||
|
||||
/** Returns a handler that causes wait to block until completed.
|
||||
The returned handler provides the same execution
|
||||
guarantees as the passed handler.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Handler>
|
||||
detail::ref_counted_wrapped_handler <pending_handlers,
|
||||
std::remove_reference_t<Handler>>
|
||||
wrap (Handler&& handler,
|
||||
bool continuation = false)
|
||||
{
|
||||
return detail::ref_counted_wrapped_handler <pending_handlers,
|
||||
std::remove_reference_t<Handler>> (*this,
|
||||
std::forward<Handler>(handler), continuation);
|
||||
}
|
||||
|
||||
template <class Handler>
|
||||
detail::ref_counted_wrapped_handler <pending_handlers,
|
||||
std::remove_reference_t<Handler>>
|
||||
wrap (continuation_t, Handler&& handler)
|
||||
{
|
||||
return detail::ref_counted_wrapped_handler <pending_handlers,
|
||||
std::remove_reference_t<Handler>> (*this,
|
||||
std::forward<Handler>(handler), true);
|
||||
}
|
||||
/** @} */
|
||||
};
|
||||
|
||||
template <class>
|
||||
void
|
||||
pending_handlers::increment()
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (mutex_);
|
||||
++count_;
|
||||
}
|
||||
|
||||
template <class>
|
||||
void
|
||||
pending_handlers::decrement()
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (mutex_);
|
||||
if (--count_ == 0)
|
||||
cond_.notify_all();
|
||||
}
|
||||
|
||||
template <class>
|
||||
void
|
||||
pending_handlers::wait()
|
||||
{
|
||||
std::unique_lock <std::mutex> lock (mutex_);
|
||||
while (count_ != 0)
|
||||
cond_.wait (lock);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,426 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_MEMORY_BUFFER_H_INCLUDED
|
||||
#define BEAST_ASIO_MEMORY_BUFFER_H_INCLUDED
|
||||
|
||||
#include <beast/utility/empty_base_optimization.h>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <beast/utility/noexcept.h>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
template <
|
||||
class T,
|
||||
class Alloc = std::allocator <T>
|
||||
>
|
||||
class memory_buffer
|
||||
: private empty_base_optimization <Alloc>
|
||||
{
|
||||
private:
|
||||
static_assert (std::is_same <char, T>::value ||
|
||||
std::is_same <unsigned char, T>::value,
|
||||
"memory_buffer only works with char and unsigned char");
|
||||
|
||||
typedef empty_base_optimization <Alloc> Base;
|
||||
|
||||
using AllocTraits = std::allocator_traits <Alloc>;
|
||||
|
||||
T* m_base;
|
||||
std::size_t m_size;
|
||||
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef Alloc allocator_type;
|
||||
typedef T* iterator;
|
||||
typedef T const* const_iterator;
|
||||
typedef std::reverse_iterator <iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator <const_iterator> const_reverse_iterator;
|
||||
|
||||
memory_buffer ()
|
||||
: m_base (nullptr)
|
||||
, m_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
memory_buffer (memory_buffer&& other)
|
||||
: Base (std::move (other))
|
||||
, m_base (other.m_base)
|
||||
, m_size (other.m_size)
|
||||
{
|
||||
other.m_base = nullptr;
|
||||
other.m_size = 0;
|
||||
}
|
||||
|
||||
explicit memory_buffer (size_type n)
|
||||
: m_base (AllocTraits::allocate (Base::member(), n))
|
||||
, m_size (n)
|
||||
{
|
||||
}
|
||||
|
||||
explicit memory_buffer (Alloc const& alloc)
|
||||
: Base (alloc)
|
||||
, m_base (nullptr)
|
||||
, m_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
memory_buffer (size_type n, Alloc const& alloc)
|
||||
: Base (alloc)
|
||||
, m_base (AllocTraits::allocate (Base::member(), n))
|
||||
, m_size (n)
|
||||
{
|
||||
}
|
||||
|
||||
~memory_buffer()
|
||||
{
|
||||
if (m_base != nullptr)
|
||||
AllocTraits::deallocate (Base::member(), m_base, m_size);
|
||||
}
|
||||
|
||||
memory_buffer& operator= (memory_buffer const&) = delete;
|
||||
|
||||
allocator_type
|
||||
get_allocator() const
|
||||
{
|
||||
return Base::member;
|
||||
}
|
||||
|
||||
//
|
||||
// asio support
|
||||
//
|
||||
|
||||
boost::asio::mutable_buffer
|
||||
buffer()
|
||||
{
|
||||
return boost::asio::mutable_buffer (
|
||||
data(), bytes());
|
||||
}
|
||||
|
||||
boost::asio::const_buffer
|
||||
buffer() const
|
||||
{
|
||||
return boost::asio::const_buffer (
|
||||
data(), bytes());
|
||||
}
|
||||
|
||||
boost::asio::mutable_buffers_1
|
||||
buffers()
|
||||
{
|
||||
return boost::asio::mutable_buffers_1 (
|
||||
data(), bytes());
|
||||
}
|
||||
|
||||
boost::asio::const_buffers_1
|
||||
buffers() const
|
||||
{
|
||||
return boost::asio::const_buffers_1 (
|
||||
data(), bytes());
|
||||
}
|
||||
|
||||
operator boost::asio::mutable_buffer()
|
||||
{
|
||||
return buffer();
|
||||
}
|
||||
|
||||
operator boost::asio::const_buffer() const
|
||||
{
|
||||
return buffer();
|
||||
}
|
||||
|
||||
operator boost::asio::mutable_buffers_1()
|
||||
{
|
||||
return buffers();
|
||||
}
|
||||
|
||||
operator boost::asio::const_buffers_1() const
|
||||
{
|
||||
return buffers();
|
||||
}
|
||||
|
||||
//
|
||||
// Element access
|
||||
//
|
||||
|
||||
reference
|
||||
at (size_type pos)
|
||||
{
|
||||
if (! (pos < size()))
|
||||
throw std::out_of_range ("bad array index");
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
const_reference
|
||||
at (size_type pos) const
|
||||
{
|
||||
if (! (pos < size()))
|
||||
throw std::out_of_range ("bad array index");
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
reference
|
||||
operator[] (size_type pos) noexcept
|
||||
{
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
const_reference
|
||||
operator[] (size_type pos) const noexcept
|
||||
{
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
reference
|
||||
back() noexcept
|
||||
{
|
||||
return m_base [m_size - 1];
|
||||
}
|
||||
|
||||
const_reference
|
||||
back() const noexcept
|
||||
{
|
||||
return m_base [m_size - 1];
|
||||
}
|
||||
|
||||
reference
|
||||
front() noexcept
|
||||
{
|
||||
return *m_base;
|
||||
}
|
||||
|
||||
const_reference
|
||||
front() const noexcept
|
||||
{
|
||||
return *m_base;
|
||||
}
|
||||
|
||||
pointer
|
||||
data() noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
const_pointer
|
||||
data() const noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
//
|
||||
// Iterators
|
||||
//
|
||||
|
||||
iterator
|
||||
begin() noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
iterator
|
||||
end() noexcept
|
||||
{
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
reverse_iterator
|
||||
rbegin() noexcept
|
||||
{
|
||||
return reverse_iterator (end());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
rbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cend());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cend());
|
||||
}
|
||||
|
||||
reverse_iterator
|
||||
rend() noexcept
|
||||
{
|
||||
return reverse_iterator (begin());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
rend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cbegin());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cbegin());
|
||||
}
|
||||
|
||||
//
|
||||
// Capacity
|
||||
//
|
||||
|
||||
bool
|
||||
empty() const noexcept
|
||||
{
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
size_type
|
||||
size() const noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
size_type
|
||||
max_size() const noexcept
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
size_type
|
||||
capacity() const noexcept
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
size_type bytes() const
|
||||
{
|
||||
return m_size * sizeof(T);
|
||||
}
|
||||
|
||||
//
|
||||
// Modifiers
|
||||
//
|
||||
|
||||
template <class U, class A>
|
||||
friend
|
||||
void
|
||||
swap (memory_buffer <U, A>& lhs,
|
||||
memory_buffer <U, A>& rhs) noexcept;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T, class Alloc>
|
||||
void
|
||||
swap (memory_buffer <T, Alloc>& lhs,
|
||||
memory_buffer <T, Alloc>& rhs) noexcept
|
||||
{
|
||||
std::swap (lhs.m_base, rhs.m_base);
|
||||
std::swap (lhs.m_size, rhs.m_size);
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator== (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return std::equal (lhs.cbegin(), lhs.cend(),
|
||||
rhs.cbegin(), rhs.cend());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator!= (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator< (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return std::lexicographical_compare (
|
||||
lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator>= (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return ! (lhs < rhs);
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator> (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator<= (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return ! (rhs < lhs);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,475 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_SHARED_HANDLER_H_INCLUDED
|
||||
#define BEAST_ASIO_SHARED_HANDLER_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
|
||||
#include <beast/utility/is_call_possible.h>
|
||||
|
||||
#include <boost/utility/base_from_member.hpp>
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
|
||||
#include <beast/utility/noexcept.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
|
||||
#ifndef BEAST_ASIO_NO_ALLOCATE_SHARED
|
||||
#define BEAST_ASIO_NO_ALLOCATE_SHARED 0
|
||||
#endif
|
||||
|
||||
#ifndef BEAST_ASIO_NO_HANDLER_RESULT_OF
|
||||
#define BEAST_ASIO_NO_HANDLER_RESULT_OF 1
|
||||
#endif
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
class shared_handler_wrapper_base
|
||||
{
|
||||
public:
|
||||
virtual ~shared_handler_wrapper_base()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void invoke (std::function <void (void)> f) = 0;
|
||||
virtual void* allocate (std::size_t size) = 0;
|
||||
virtual void deallocate (void* p, std::size_t size) = 0;
|
||||
virtual bool is_continuation () = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Signature>
|
||||
class shared_handler_wrapper_func
|
||||
: public shared_handler_wrapper_base
|
||||
{
|
||||
private:
|
||||
std::function <Signature> m_func;
|
||||
|
||||
public:
|
||||
template <class Handler>
|
||||
explicit shared_handler_wrapper_func (Handler&& handler)
|
||||
: m_func (std::ref (std::forward <Handler> (handler)))
|
||||
{
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
#if BEAST_ASIO_NO_HANDLER_RESULT_OF
|
||||
void
|
||||
#else
|
||||
std::result_of_t <std::function <Signature> (Args...)>
|
||||
#endif
|
||||
operator() (Args&&... args) const
|
||||
{
|
||||
return m_func (std::forward <Args> (args)...);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4512) // assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
template <class Signature, class Handler>
|
||||
class shared_handler_wrapper
|
||||
: private boost::base_from_member <Handler>
|
||||
, public shared_handler_wrapper_func <Signature>
|
||||
{
|
||||
private:
|
||||
typedef boost::base_from_member <Handler> Base;
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_is_continuation, is_continuation);
|
||||
|
||||
public:
|
||||
shared_handler_wrapper (Handler&& handler)
|
||||
: boost::base_from_member <Handler> (std::move (handler))
|
||||
, shared_handler_wrapper_func <Signature> (Base::member)
|
||||
{
|
||||
}
|
||||
|
||||
shared_handler_wrapper (Handler const& handler)
|
||||
: boost::base_from_member <Handler> (handler)
|
||||
, shared_handler_wrapper_func <Signature> (Base::member)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
invoke (std::function <void (void)> f) override
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke (f, Base::member);
|
||||
}
|
||||
|
||||
void*
|
||||
allocate (std::size_t size) override
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate (size, Base::member);
|
||||
}
|
||||
|
||||
void
|
||||
deallocate (void* p, std::size_t size) override
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate (p, size, Base::member);
|
||||
}
|
||||
|
||||
bool
|
||||
is_continuation () override
|
||||
{
|
||||
return is_continuation (std::integral_constant <bool,
|
||||
has_is_continuation <Handler, bool(void)>::value>());
|
||||
}
|
||||
|
||||
bool
|
||||
is_continuation (std::true_type)
|
||||
{
|
||||
return Base::member.is_continuation();
|
||||
}
|
||||
|
||||
bool
|
||||
is_continuation (std::false_type)
|
||||
{
|
||||
return boost_asio_handler_cont_helpers::
|
||||
is_continuation (Base::member);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct is_shared_handler : public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T, class Handler>
|
||||
class handler_allocator
|
||||
{
|
||||
private:
|
||||
// We want a partial template specialization as a friend
|
||||
// but that isn't allowed so we friend all versions. This
|
||||
// should produce a compile error if Handler is not constructible
|
||||
// from H.
|
||||
//
|
||||
template <class U, class H>
|
||||
friend class handler_allocator;
|
||||
|
||||
Handler m_handler;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
|
||||
template <class U>
|
||||
struct rebind
|
||||
{
|
||||
public:
|
||||
typedef handler_allocator <U, Handler> other;
|
||||
};
|
||||
|
||||
handler_allocator() = delete;
|
||||
|
||||
handler_allocator (Handler const& handler)
|
||||
: m_handler (handler)
|
||||
{
|
||||
}
|
||||
|
||||
template <class U>
|
||||
handler_allocator (
|
||||
handler_allocator <U, Handler> const& other)
|
||||
: m_handler (other.m_handler)
|
||||
{
|
||||
}
|
||||
|
||||
handler_allocator&
|
||||
operator= (handler_allocator const&) = delete;
|
||||
|
||||
pointer
|
||||
allocate (std::ptrdiff_t n)
|
||||
{
|
||||
auto const size (n * sizeof (T));
|
||||
return static_cast <pointer> (
|
||||
boost_asio_handler_alloc_helpers::allocate (
|
||||
size, m_handler));
|
||||
}
|
||||
|
||||
void
|
||||
deallocate (pointer p, std::ptrdiff_t n)
|
||||
{
|
||||
auto const size (n * sizeof (T));
|
||||
boost_asio_handler_alloc_helpers::deallocate (
|
||||
p, size, m_handler);
|
||||
}
|
||||
|
||||
// Work-around for MSVC not using allocator_traits
|
||||
// in the implementation of shared_ptr
|
||||
//
|
||||
#ifdef _MSC_VER
|
||||
void
|
||||
destroy (T* t)
|
||||
{
|
||||
t->~T();
|
||||
}
|
||||
#endif
|
||||
|
||||
friend
|
||||
bool
|
||||
operator== (handler_allocator const& lhs, handler_allocator const& rhs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
operator!= (handler_allocator const& lhs, handler_allocator const& rhs)
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Handler shared reference that provides io_service execution guarantees. */
|
||||
template <class Signature>
|
||||
class shared_handler
|
||||
{
|
||||
private:
|
||||
template <class T>
|
||||
friend class shared_handler_allocator;
|
||||
|
||||
typedef shared_handler_wrapper_func <
|
||||
Signature> wrapper_type;
|
||||
|
||||
typedef std::shared_ptr <wrapper_type> ptr_type;
|
||||
|
||||
ptr_type m_ptr;
|
||||
|
||||
public:
|
||||
shared_handler()
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
class DeducedHandler,
|
||||
class = std::enable_if_t <
|
||||
! detail::is_shared_handler <
|
||||
std::decay_t <DeducedHandler>>::value &&
|
||||
std::is_constructible <std::function <Signature>,
|
||||
std::decay_t <DeducedHandler>>::value
|
||||
>
|
||||
>
|
||||
shared_handler (DeducedHandler&& handler)
|
||||
{
|
||||
typedef std::remove_reference_t <DeducedHandler> Handler;
|
||||
|
||||
#if BEAST_ASIO_NO_ALLOCATE_SHARED
|
||||
m_ptr = std::make_shared <detail::shared_handler_wrapper <
|
||||
Signature, Handler>> (std::forward <DeducedHandler> (handler));
|
||||
#else
|
||||
m_ptr = std::allocate_shared <detail::shared_handler_wrapper <
|
||||
Signature, Handler>> (detail::handler_allocator <char, Handler> (
|
||||
handler), std::forward <DeducedHandler> (handler));
|
||||
#endif
|
||||
}
|
||||
|
||||
shared_handler (shared_handler&& other)
|
||||
: m_ptr (std::move (other.m_ptr))
|
||||
{
|
||||
}
|
||||
|
||||
shared_handler (shared_handler const& other)
|
||||
: m_ptr (other.m_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
shared_handler&
|
||||
operator= (std::nullptr_t)
|
||||
{
|
||||
m_ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
shared_handler&
|
||||
operator= (shared_handler const& rhs)
|
||||
{
|
||||
m_ptr = rhs.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
shared_handler&
|
||||
operator= (shared_handler&& rhs)
|
||||
{
|
||||
m_ptr = std::move (rhs.m_ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit
|
||||
operator bool() const noexcept
|
||||
{
|
||||
return m_ptr.operator bool();
|
||||
}
|
||||
|
||||
void
|
||||
reset()
|
||||
{
|
||||
m_ptr.reset();
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
#if BEAST_ASIO_NO_HANDLER_RESULT_OF
|
||||
void
|
||||
#else
|
||||
std::result_of_t <std::function <Signature> (Args...)>
|
||||
#endif
|
||||
operator() (Args&&... args) const
|
||||
{
|
||||
return (*m_ptr)(std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function&& f, shared_handler* h)
|
||||
{
|
||||
return h->m_ptr->invoke (f);
|
||||
}
|
||||
|
||||
friend
|
||||
void*
|
||||
asio_handler_allocate (
|
||||
std::size_t size, shared_handler* h)
|
||||
{
|
||||
return h->m_ptr->allocate (size);
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
asio_handler_deallocate (
|
||||
void* p, std::size_t size, shared_handler* h)
|
||||
{
|
||||
return h->m_ptr->deallocate (p, size);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
asio_handler_is_continuation (
|
||||
shared_handler* h)
|
||||
{
|
||||
return h->m_ptr->is_continuation ();
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <
|
||||
class Signature
|
||||
>
|
||||
struct is_shared_handler <
|
||||
shared_handler <Signature>
|
||||
> : public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
class shared_handler_allocator
|
||||
{
|
||||
private:
|
||||
template <class U>
|
||||
friend class shared_handler_allocator;
|
||||
|
||||
std::shared_ptr <shared_handler_wrapper_base> m_ptr;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
|
||||
shared_handler_allocator() = delete;
|
||||
|
||||
template <class Signature>
|
||||
shared_handler_allocator (
|
||||
shared_handler <Signature> const& handler)
|
||||
: m_ptr (handler.m_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
template <class U>
|
||||
shared_handler_allocator (
|
||||
shared_handler_allocator <U> const& other)
|
||||
: m_ptr (other.m_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
pointer
|
||||
allocate (std::ptrdiff_t n)
|
||||
{
|
||||
auto const size (n * sizeof (T));
|
||||
return static_cast <pointer> (
|
||||
m_ptr->allocate (size));
|
||||
}
|
||||
|
||||
void
|
||||
deallocate (pointer p, std::ptrdiff_t n)
|
||||
{
|
||||
auto const size (n * sizeof (T));
|
||||
m_ptr->deallocate (p, size);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
operator== (shared_handler_allocator const& lhs,
|
||||
shared_handler_allocator const& rhs)
|
||||
{
|
||||
return lhs.m_ptr == rhs.m_ptr;
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
operator!= (shared_handler_allocator const& lhs,
|
||||
shared_handler_allocator const& rhs)
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,826 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_SOCKET_WRAPPER_H_INCLUDED
|
||||
#define BEAST_ASIO_SOCKET_WRAPPER_H_INCLUDED
|
||||
|
||||
#include <beast/asio/abstract_socket.h>
|
||||
#include <beast/asio/bind_handler.h>
|
||||
|
||||
#include <beast/utility/noexcept.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Wraps a reference to any object and exports all availble interfaces.
|
||||
|
||||
If the object does not support an interface, calling those
|
||||
member functions will behave as if a pure virtual was called.
|
||||
|
||||
Note that only a reference to the underlying is stored. Management
|
||||
of the lifetime of the object is controlled by the caller.
|
||||
|
||||
Examples of the type of Object:
|
||||
|
||||
asio::ip::tcp::socket
|
||||
asio::ip::tcp::socket&
|
||||
asio::ssl::stream <asio::ip::tcp::socket>
|
||||
asio::ssl::stream <asio::ip::tcp::socket&>
|
||||
explain arg must be an io_context
|
||||
explain socket_wrapper will create and take ownership of the tcp::socket
|
||||
explain this_layer_type will be tcp::socket
|
||||
explain next_layer () returns a asio::ip::tcp::socket&
|
||||
explain lowest_layer () returns a asio::ip::tcp::socket&
|
||||
|
||||
asio::ssl::stream <asio::buffered_stream <asio::ip::tcp::socket> > >
|
||||
This makes my head explode
|
||||
*/
|
||||
template <typename Object>
|
||||
class socket_wrapper : public abstract_socket
|
||||
{
|
||||
private:
|
||||
Object m_object;
|
||||
|
||||
public:
|
||||
template <class... Args>
|
||||
explicit socket_wrapper (Args&&... args)
|
||||
: m_object (std::forward <Args> (args)...)
|
||||
{
|
||||
}
|
||||
|
||||
socket_wrapper (socket_wrapper const&) = delete;
|
||||
socket_wrapper& operator= (socket_wrapper const&) = delete;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// socket_wrapper
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** The type of the object being wrapped. */
|
||||
typedef typename boost::remove_reference <Object>::type this_layer_type;
|
||||
|
||||
/** Get a reference to this layer. */
|
||||
this_layer_type& this_layer () noexcept
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
/** Get a const reference to this layer. */
|
||||
this_layer_type const& this_layer () const noexcept
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// abstract_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void* this_layer_ptr (char const* type_name) const override
|
||||
{
|
||||
char const* const name (typeid (this_layer_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*> (&m_object));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_get_io_service, get_io_service);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_lowest_layer, lowest_layer);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_cancel, cancel);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_shutdown, shutdown);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_close, close);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_accept, accept);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_accept, async_accept);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_read_some, read_some);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_write_some, write_some);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_read_some, async_read_some);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_write_some, async_write_some);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_set_verify_mode, set_verify_mode);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_handshake, handshake);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_handshake, async_handshake);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_shutdown, async_shutdown);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
template <class Cond>
|
||||
struct Enabled : public std::integral_constant <bool, Cond::value>
|
||||
{
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// native_handle
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
// This is a potential work-around for the problem with
|
||||
// the has_type_native_handle_type template, but requires
|
||||
// Boost 1.54 or later.
|
||||
//
|
||||
// This include will be needed:
|
||||
//
|
||||
// boost/tti/has_type.hpp
|
||||
//
|
||||
//
|
||||
BOOST_TTI_HAS_TYPE(native_handle_type)
|
||||
|
||||
#else
|
||||
template <class T>
|
||||
struct has_type_native_handle_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef struct {char dummy[2];} no;
|
||||
template <class C> static yes f(typename C::native_handle_type*);
|
||||
template <class C> static no f(...);
|
||||
#ifdef _MSC_VER
|
||||
static bool const value = sizeof(f<T>(0)) == 1;
|
||||
#else
|
||||
// This line fails to compile under Visual Studio 2012
|
||||
static bool const value = sizeof(
|
||||
has_type_native_handle_type<T>::f<T>(0)) == 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <typename T,
|
||||
bool Exists = has_type_native_handle_type <T>::value
|
||||
>
|
||||
struct extract_native_handle_type
|
||||
{
|
||||
typedef typename T::native_handle_type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_native_handle_type <T, false>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
// This will be void if native_handle_type doesn't exist in Object
|
||||
typedef typename extract_native_handle_type <
|
||||
this_layer_type>::type native_handle_type;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
bool native_handle (char const* type_name, void* dest) override
|
||||
{
|
||||
return native_handle (type_name, dest,
|
||||
Enabled <has_type_native_handle_type <this_layer_type> > ());
|
||||
}
|
||||
|
||||
bool native_handle (char const* type_name, void* dest,
|
||||
std::true_type)
|
||||
{
|
||||
char const* const name (typeid (
|
||||
typename this_layer_type::native_handle_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
{
|
||||
native_handle_type* const p (reinterpret_cast <
|
||||
native_handle_type*> (dest));
|
||||
*p = m_object.native_handle ();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool native_handle (char const*, void*,
|
||||
std::false_type)
|
||||
{
|
||||
pure_virtual_called();
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_io_object
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boost::asio::io_service& get_io_service () override
|
||||
{
|
||||
return get_io_service (
|
||||
Enabled <has_get_io_service <this_layer_type,
|
||||
boost::asio::io_service&()> > ());
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service (
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.get_io_service ();
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service (
|
||||
std::false_type)
|
||||
{
|
||||
pure_virtual_called();
|
||||
return *static_cast <boost::asio::io_service*>(nullptr);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
To forward the lowest_layer_type type, we need to make sure it
|
||||
exists in Object. This is a little more tricky than just figuring
|
||||
out if Object has a particular member function.
|
||||
|
||||
The problem is boost::asio::basic_socket_acceptor, which doesn't
|
||||
have lowest_layer () or lowest_layer_type ().
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
struct has_type_lowest_layer_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef struct {char dummy[2];} no;
|
||||
template <class C> static yes f(typename C::lowest_layer_type*);
|
||||
template <class C> static no f(...);
|
||||
#ifdef _MSC_VER
|
||||
static bool const value = sizeof(f<T>(0)) == 1;
|
||||
#else
|
||||
// This line fails to compile under Visual Studio 2012
|
||||
static bool const value = sizeof(has_type_lowest_layer_type<T>::f<T>(0)) == 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T, bool Exists = has_type_lowest_layer_type <T>::value >
|
||||
struct extract_lowest_layer_type
|
||||
{
|
||||
typedef typename T::lowest_layer_type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_lowest_layer_type <T, false>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
// This will be void if lowest_layer_type doesn't exist in Object
|
||||
typedef typename extract_lowest_layer_type <this_layer_type>::type lowest_layer_type;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void* lowest_layer_ptr (char const* type_name) const override
|
||||
{
|
||||
return lowest_layer_ptr (type_name,
|
||||
Enabled <has_type_lowest_layer_type <this_layer_type> > ());
|
||||
}
|
||||
|
||||
void* lowest_layer_ptr (char const* type_name,
|
||||
std::true_type) const
|
||||
{
|
||||
char const* const name (typeid (typename this_layer_type::lowest_layer_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*> (&m_object.lowest_layer ()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* lowest_layer_ptr (char const*,
|
||||
std::false_type) const
|
||||
{
|
||||
pure_virtual_called();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code cancel (error_code& ec) override
|
||||
{
|
||||
return cancel (ec,
|
||||
Enabled <has_cancel <this_layer_type,
|
||||
error_code (error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code cancel (error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.cancel (ec);
|
||||
}
|
||||
|
||||
error_code cancel (error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code shutdown (shutdown_type what, error_code& ec) override
|
||||
{
|
||||
return shutdown (what, ec,
|
||||
Enabled <has_shutdown <this_layer_type,
|
||||
error_code (shutdown_type, error_code&)> > ());
|
||||
}
|
||||
|
||||
|
||||
error_code shutdown (shutdown_type what, error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.shutdown (what, ec);
|
||||
}
|
||||
|
||||
error_code shutdown (shutdown_type, error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code close (error_code& ec) override
|
||||
{
|
||||
return close (ec,
|
||||
Enabled <has_close <this_layer_type,
|
||||
error_code (error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code close (error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.close (ec);
|
||||
}
|
||||
|
||||
error_code close (error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket_acceptor
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Extracts the underlying socket type from the protocol of another asio object
|
||||
template <typename T, typename Enable = void>
|
||||
struct native_socket
|
||||
{
|
||||
typedef void* socket_type;
|
||||
inline native_socket (abstract_socket&)
|
||||
: m_socket (nullptr)
|
||||
{
|
||||
abstract_socket::pure_virtual_called();
|
||||
}
|
||||
inline socket_type& get ()
|
||||
{
|
||||
abstract_socket::pure_virtual_called();
|
||||
return m_socket;
|
||||
}
|
||||
inline socket_type& operator-> ()
|
||||
{
|
||||
return get ();
|
||||
}
|
||||
private:
|
||||
socket_type m_socket;
|
||||
};
|
||||
|
||||
// Enabled if T::protocol_type::socket exists as a type
|
||||
template <typename T>
|
||||
struct native_socket <T, typename boost::enable_if <boost::is_class <
|
||||
typename T::protocol_type::socket> >::type>
|
||||
{
|
||||
typedef typename T::protocol_type::socket socket_type;
|
||||
inline native_socket (abstract_socket& peer)
|
||||
: m_socket_ptr (&peer.this_layer <socket_type> ())
|
||||
{
|
||||
}
|
||||
inline socket_type& get () noexcept
|
||||
{
|
||||
return *m_socket_ptr;
|
||||
}
|
||||
inline socket_type& operator-> () noexcept
|
||||
{
|
||||
return get ();
|
||||
}
|
||||
private:
|
||||
socket_type* m_socket_ptr;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code accept (abstract_socket& peer, error_code& ec) override
|
||||
{
|
||||
typedef typename native_socket <this_layer_type>::socket_type socket_type;
|
||||
return accept (peer, ec,
|
||||
Enabled <has_accept <this_layer_type,
|
||||
error_code (socket_type&, error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code accept (abstract_socket& peer, error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.accept (
|
||||
native_socket <this_layer_type> (peer).get (), ec);
|
||||
}
|
||||
|
||||
error_code accept (abstract_socket&, error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_accept (abstract_socket& peer, error_handler handler) override
|
||||
{
|
||||
typedef typename native_socket <this_layer_type>::socket_type socket_type;
|
||||
async_accept (peer, handler,
|
||||
Enabled <has_async_accept <this_layer_type,
|
||||
void (socket_type&, error_handler)> > ());
|
||||
}
|
||||
|
||||
void async_accept (abstract_socket& peer, error_handler const& handler,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.async_accept (
|
||||
native_socket <this_layer_type> (peer).get (), handler);
|
||||
}
|
||||
|
||||
void async_accept (abstract_socket&, error_handler const& handler,
|
||||
std::false_type)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error()));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_stream_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
std::size_t
|
||||
read_some (mutable_buffers buffers, error_code& ec) override
|
||||
{
|
||||
return read_some (buffers, ec,
|
||||
Enabled <has_read_some <this_layer_type,
|
||||
std::size_t (mutable_buffers const&, error_code&)> > ());
|
||||
}
|
||||
|
||||
std::size_t
|
||||
read_some (mutable_buffers const& buffers, error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.read_some (buffers, ec);
|
||||
}
|
||||
|
||||
std::size_t read_some (mutable_buffers const&, error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
std::size_t
|
||||
write_some (const_buffers buffers, error_code& ec) override
|
||||
{
|
||||
return write_some (buffers, ec,
|
||||
Enabled <has_write_some <this_layer_type,
|
||||
std::size_t (const_buffers const&, error_code&)> > ());
|
||||
}
|
||||
|
||||
std::size_t
|
||||
write_some (const_buffers const& buffers, error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.write_some (buffers, ec);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
write_some (const_buffers const&, error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_read_some (mutable_buffers buffers,
|
||||
transfer_handler handler) override
|
||||
{
|
||||
async_read_some (buffers, handler,
|
||||
Enabled <has_async_read_some <this_layer_type,
|
||||
void (mutable_buffers const&, transfer_handler const&)> > ());
|
||||
}
|
||||
|
||||
void
|
||||
async_read_some (mutable_buffers const& buffers,
|
||||
transfer_handler const& handler,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.async_read_some (buffers, handler);
|
||||
}
|
||||
|
||||
void
|
||||
async_read_some (mutable_buffers const&,
|
||||
transfer_handler const& handler,
|
||||
std::false_type)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error(), 0));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
async_write_some (const_buffers buffers,
|
||||
transfer_handler handler) override
|
||||
{
|
||||
async_write_some (buffers, handler,
|
||||
Enabled <has_async_write_some <this_layer_type,
|
||||
void (const_buffers const&, transfer_handler const&)> > ());
|
||||
}
|
||||
|
||||
void
|
||||
async_write_some (const_buffers const& buffers,
|
||||
transfer_handler const& handler,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.async_write_some (buffers, handler);
|
||||
}
|
||||
|
||||
void
|
||||
async_write_some (const_buffers const&,
|
||||
transfer_handler const& handler,
|
||||
std::false_type)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error(), 0));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// ssl::stream
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
struct has_type_next_layer_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef struct {char dummy[2];} no;
|
||||
template <class C> static yes f(typename C::next_layer_type*);
|
||||
template <class C> static no f(...);
|
||||
#ifdef _MSC_VER
|
||||
static bool const value = sizeof(f<T>(0)) == 1;
|
||||
#else
|
||||
// This line fails to compile under Visual Studio 2012
|
||||
static bool const value = sizeof(has_type_next_layer_type<T>::f<T>(0)) == 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T, bool Exists = has_type_next_layer_type <T>::value >
|
||||
struct extract_next_layer_type
|
||||
{
|
||||
typedef typename T::next_layer_type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_next_layer_type <T, false>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
// This will be void if next_layer_type doesn't exist in Object
|
||||
typedef typename extract_next_layer_type <this_layer_type>::type next_layer_type;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void* next_layer_ptr (char const* type_name) const override
|
||||
{
|
||||
return next_layer_ptr (type_name,
|
||||
Enabled <has_type_next_layer_type <this_layer_type> > ());
|
||||
}
|
||||
|
||||
void* next_layer_ptr (char const* type_name,
|
||||
std::true_type) const
|
||||
{
|
||||
char const* const name (typeid (typename this_layer_type::next_layer_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*> (&m_object.next_layer ()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* next_layer_ptr (char const*,
|
||||
std::false_type) const
|
||||
{
|
||||
pure_virtual_called();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
bool needs_handshake () override
|
||||
{
|
||||
return
|
||||
has_handshake <this_layer_type,
|
||||
error_code (handshake_type, error_code&)>::value ||
|
||||
has_async_handshake <this_layer_type,
|
||||
void (handshake_type, error_handler)>::value;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void set_verify_mode (int verify_mode) override
|
||||
{
|
||||
set_verify_mode (verify_mode,
|
||||
Enabled <has_set_verify_mode <this_layer_type,
|
||||
void (int)> > ());
|
||||
|
||||
}
|
||||
|
||||
void set_verify_mode (int verify_mode,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.set_verify_mode (verify_mode);
|
||||
}
|
||||
|
||||
void set_verify_mode (int,
|
||||
std::false_type)
|
||||
{
|
||||
pure_virtual_called();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code
|
||||
handshake (handshake_type type, error_code& ec) override
|
||||
{
|
||||
return handshake (type, ec,
|
||||
Enabled <has_handshake <this_layer_type,
|
||||
error_code (handshake_type, error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code
|
||||
handshake (handshake_type type, error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.handshake (type, ec);
|
||||
}
|
||||
|
||||
error_code
|
||||
handshake (handshake_type, error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_handshake (handshake_type type, error_handler handler) override
|
||||
{
|
||||
async_handshake (type, handler,
|
||||
Enabled <has_async_handshake <this_layer_type,
|
||||
void (handshake_type, error_handler)> > ());
|
||||
}
|
||||
|
||||
void async_handshake (handshake_type type, error_handler const& handler,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.async_handshake (type, handler);
|
||||
}
|
||||
|
||||
void async_handshake (handshake_type, error_handler const& handler,
|
||||
std::false_type)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error()));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code
|
||||
handshake (handshake_type type, const_buffers buffers,
|
||||
error_code& ec) override
|
||||
{
|
||||
return handshake (type, buffers, ec,
|
||||
Enabled <has_handshake <this_layer_type,
|
||||
error_code (handshake_type, const_buffers const&, error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code
|
||||
handshake (handshake_type type, const_buffers const& buffers,
|
||||
error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.handshake (type, buffers, ec);
|
||||
}
|
||||
|
||||
error_code
|
||||
handshake (handshake_type, const_buffers const&,
|
||||
error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_handshake (handshake_type type,
|
||||
const_buffers buffers, transfer_handler handler) override
|
||||
{
|
||||
async_handshake (type, buffers, handler,
|
||||
Enabled <has_async_handshake <this_layer_type,
|
||||
void (handshake_type, const_buffers const&,
|
||||
transfer_handler)> > ());
|
||||
}
|
||||
|
||||
void async_handshake (handshake_type type, const_buffers const& buffers,
|
||||
transfer_handler const& handler,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.async_handshake (type, buffers, handler);
|
||||
}
|
||||
|
||||
void async_handshake (handshake_type, const_buffers const&,
|
||||
transfer_handler const& handler,
|
||||
std::false_type)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error(), 0));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code shutdown (error_code& ec) override
|
||||
{
|
||||
return shutdown (ec,
|
||||
Enabled <has_shutdown <this_layer_type,
|
||||
error_code (error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code shutdown (error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.shutdown (ec);
|
||||
}
|
||||
|
||||
error_code shutdown (error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_shutdown (error_handler handler) override
|
||||
{
|
||||
async_shutdown (handler,
|
||||
Enabled <has_async_shutdown <this_layer_type,
|
||||
void (error_handler)> > ());
|
||||
}
|
||||
|
||||
void async_shutdown (error_handler const& handler,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.async_shutdown (handler);
|
||||
}
|
||||
|
||||
void async_shutdown (error_handler const& handler,
|
||||
std::false_type)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error()));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_BASIC_STREAMBUF_H_INCLUDED
|
||||
#define BEAST_ASIO_BASIC_STREAMBUF_H_INCLUDED
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
template <class Alloc = std::allocator <char>>
|
||||
class basic_streambuf : private Alloc
|
||||
{
|
||||
private:
|
||||
typedef std::allocator_traits <Alloc> alloc_traits;
|
||||
std::vector <boost::asio::mutable_buffer> bufs_;
|
||||
|
||||
public:
|
||||
~basic_streambuf()
|
||||
{
|
||||
for (auto const& buf : bufs_)
|
||||
alloc_traits::deallocate (
|
||||
boost::asio::buffer_cast<char const*>(buf));
|
||||
}
|
||||
}
|
||||
|
||||
} // asio
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -1,105 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
#include <beast/asio/bind_handler.h>
|
||||
#include <beast/asio/enable_wait_for_async.h>
|
||||
|
||||
#include <boost/asio/io_service.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class enable_wait_for_async_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
void test()
|
||||
{
|
||||
struct handler
|
||||
{
|
||||
void operator()(error_code)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct owner : asio::enable_wait_for_async <owner>
|
||||
{
|
||||
bool notified;
|
||||
|
||||
owner()
|
||||
: notified (false)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
ios.post (asio::bind_handler (handler(),
|
||||
error_code()));
|
||||
ios.run();
|
||||
ios.reset();
|
||||
wait_for_async();
|
||||
}
|
||||
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
ios.post (wrap_with_counter (asio::bind_handler (
|
||||
handler(), error_code())));
|
||||
ios.run();
|
||||
wait_for_async();
|
||||
}
|
||||
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
handler h;
|
||||
ios.post (wrap_with_counter (std::bind (
|
||||
&handler::operator(), &h,
|
||||
error_code())));
|
||||
ios.run();
|
||||
wait_for_async();
|
||||
}
|
||||
}
|
||||
|
||||
void on_wait_for_async()
|
||||
{
|
||||
notified = true;
|
||||
}
|
||||
};
|
||||
|
||||
owner o;
|
||||
o();
|
||||
expect (o.notified);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
test();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(enable_wait_for_async,asio,beast);
|
||||
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
#include <beast/asio/shared_handler.h>
|
||||
|
||||
// Disables is_constructible tests for std::function
|
||||
// Visual Studio std::function fails the is_constructible tests
|
||||
#ifndef BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE
|
||||
# ifdef _MSC_VER
|
||||
# define BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE 1
|
||||
# else
|
||||
# define BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace beast {
|
||||
|
||||
class shared_handler_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
struct test_results
|
||||
{
|
||||
bool call;
|
||||
bool invoke;
|
||||
bool alloc;
|
||||
bool dealloc;
|
||||
bool cont;
|
||||
|
||||
test_results ()
|
||||
: call (false)
|
||||
, invoke (false)
|
||||
, alloc (false)
|
||||
, dealloc (false)
|
||||
, cont (false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct test_handler
|
||||
{
|
||||
std::reference_wrapper <test_results> results;
|
||||
|
||||
explicit test_handler (test_results& results_)
|
||||
: results (results_)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() ()
|
||||
{
|
||||
results.get().call = true;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend void asio_handler_invoke (
|
||||
Function& f, test_handler* h)
|
||||
{
|
||||
h->results.get().invoke = true;
|
||||
f();
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend void asio_handler_invoke (
|
||||
Function const& f, test_handler* h)
|
||||
{
|
||||
h->results.get().invoke = true;
|
||||
f();
|
||||
}
|
||||
|
||||
friend void* asio_handler_allocate (
|
||||
std::size_t size, test_handler* h)
|
||||
{
|
||||
h->results.get().alloc = true;
|
||||
return boost::asio::asio_handler_allocate (size);
|
||||
}
|
||||
|
||||
friend void asio_handler_deallocate (
|
||||
void* p, std::size_t size, test_handler* h)
|
||||
{
|
||||
h->results.get().dealloc = true;
|
||||
boost::asio::asio_handler_deallocate (p, size);
|
||||
}
|
||||
|
||||
friend bool asio_handler_is_continuation (
|
||||
test_handler* h)
|
||||
{
|
||||
h->results.get().cont = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct test_invokable
|
||||
{
|
||||
bool call;
|
||||
|
||||
test_invokable ()
|
||||
: call (false)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() ()
|
||||
{
|
||||
call = true;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Handler>
|
||||
bool async_op (Handler&& handler)
|
||||
{
|
||||
void* const p (boost_asio_handler_alloc_helpers::allocate (32, handler));
|
||||
handler();
|
||||
boost_asio_handler_alloc_helpers::deallocate (p, 32, handler);
|
||||
return boost_asio_handler_cont_helpers::is_continuation (handler);
|
||||
}
|
||||
|
||||
void virtual_async_op (asio::shared_handler <void(void)> handler)
|
||||
{
|
||||
async_op (handler);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
#if ! BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE
|
||||
static_assert (! std::is_constructible <
|
||||
std::function <void(void)>, int&&>::value,
|
||||
"Cannot construct std::function from int&&");
|
||||
|
||||
static_assert (! std::is_constructible <
|
||||
std::function <void(void)>, int>::value,
|
||||
"Cannot construct std::function from int");
|
||||
|
||||
static_assert (! std::is_constructible <
|
||||
asio::shared_handler <void(void)>, int>::value,
|
||||
"Cannot construct shared_handler from int");
|
||||
#endif
|
||||
|
||||
static_assert (std::is_constructible <
|
||||
asio::shared_handler <void(int)>,
|
||||
asio::shared_handler <void(int)>>::value,
|
||||
"Should construct <void(int)> from <void(int)>");
|
||||
|
||||
static_assert (! std::is_constructible <
|
||||
asio::shared_handler <void(int)>,
|
||||
asio::shared_handler <void(void)>>::value,
|
||||
"Can't construct <void(int)> from <void(void)>");
|
||||
|
||||
// Hooks called when using the raw handler
|
||||
{
|
||||
test_results r;
|
||||
test_handler h (r);
|
||||
|
||||
async_op (h);
|
||||
expect (r.call);
|
||||
expect (r.alloc);
|
||||
expect (r.dealloc);
|
||||
expect (r.cont);
|
||||
|
||||
test_invokable f;
|
||||
boost_asio_handler_invoke_helpers::invoke (std::ref (f), h);
|
||||
expect (r.invoke);
|
||||
expect (f.call);
|
||||
}
|
||||
|
||||
// Use of std::function shows the hooks not getting called
|
||||
{
|
||||
test_results r;
|
||||
std::function <void(void)> fh ((test_handler) (r));
|
||||
|
||||
async_op (fh);
|
||||
expect (r.call);
|
||||
unexpected (r.alloc);
|
||||
unexpected (r.dealloc);
|
||||
unexpected (r.cont);
|
||||
|
||||
test_invokable f;
|
||||
boost_asio_handler_invoke_helpers::invoke (std::ref (f), fh);
|
||||
unexpected (r.invoke);
|
||||
expect (f.call);
|
||||
}
|
||||
|
||||
// Make sure shared_handler calls the hooks
|
||||
{
|
||||
test_results r;
|
||||
asio::shared_handler <void(void)> sh ((test_handler)(r));
|
||||
|
||||
async_op (sh);
|
||||
expect (r.call);
|
||||
expect (r.alloc);
|
||||
expect (r.dealloc);
|
||||
expect (r.cont);
|
||||
|
||||
test_invokable f;
|
||||
boost_asio_handler_invoke_helpers::invoke (std::ref (f), sh);
|
||||
expect (r.invoke);
|
||||
expect (f.call);
|
||||
}
|
||||
|
||||
// Make sure shared_handler via implicit conversion calls hooks
|
||||
{
|
||||
test_results r;
|
||||
test_handler h (r);
|
||||
|
||||
virtual_async_op ((test_handler) (r));
|
||||
expect (r.call);
|
||||
expect (r.alloc);
|
||||
expect (r.dealloc);
|
||||
expect (r.cont);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(shared_handler,asio,beast);
|
||||
|
||||
}
|
||||
@@ -1,280 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
#include <beast/asio/wrap_handler.h>
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Displays the order of destruction of parameters in the bind wrapper
|
||||
//
|
||||
class boost_bind_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
struct Result
|
||||
{
|
||||
std::string text;
|
||||
|
||||
void push_back (std::string const& s)
|
||||
{
|
||||
if (! text.empty())
|
||||
text += ", ";
|
||||
text += s;
|
||||
}
|
||||
};
|
||||
|
||||
struct Payload
|
||||
{
|
||||
std::reference_wrapper <Result> m_result;
|
||||
std::string m_name;
|
||||
|
||||
explicit Payload (Result& result, std::string const& name)
|
||||
: m_result (result)
|
||||
, m_name (name)
|
||||
{
|
||||
}
|
||||
|
||||
~Payload ()
|
||||
{
|
||||
m_result.get().push_back (m_name);
|
||||
}
|
||||
};
|
||||
|
||||
struct Arg
|
||||
{
|
||||
std::shared_ptr <Payload> m_payload;
|
||||
|
||||
Arg (Result& result, std::string const& name)
|
||||
: m_payload (std::make_shared <Payload> (result, name))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static void foo (Arg const&, Arg const&, Arg const&)
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
{
|
||||
Result r;
|
||||
{
|
||||
boost::bind (&foo,
|
||||
Arg (r, "one"),
|
||||
Arg (r, "two"),
|
||||
Arg (r, "three"));
|
||||
}
|
||||
log <<
|
||||
std::string ("boost::bind (") + r.text + ")";
|
||||
}
|
||||
|
||||
{
|
||||
Result r;
|
||||
{
|
||||
std::bind (&foo,
|
||||
Arg (r, "one"),
|
||||
Arg (r, "two"),
|
||||
Arg (r, "three"));
|
||||
}
|
||||
|
||||
log <<
|
||||
std::string ("std::bind (") + r.text + ")";
|
||||
}
|
||||
|
||||
pass();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(boost_bind,asio,beast);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class wrap_handler_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
struct test_results
|
||||
{
|
||||
bool call;
|
||||
bool invoke;
|
||||
bool alloc;
|
||||
bool dealloc;
|
||||
bool cont;
|
||||
|
||||
test_results ()
|
||||
: call (false)
|
||||
, invoke (false)
|
||||
, alloc (false)
|
||||
, dealloc (false)
|
||||
, cont (false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct test_handler
|
||||
{
|
||||
std::reference_wrapper <test_results> results;
|
||||
|
||||
explicit test_handler (test_results& results_)
|
||||
: results (results_)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() ()
|
||||
{
|
||||
results.get().call = true;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend void asio_handler_invoke (
|
||||
Function& f, test_handler* h)
|
||||
{
|
||||
h->results.get().invoke = true;
|
||||
f();
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend void asio_handler_invoke (
|
||||
Function const& f, test_handler* h)
|
||||
{
|
||||
h->results.get().invoke = true;
|
||||
f();
|
||||
}
|
||||
|
||||
friend void* asio_handler_allocate (
|
||||
std::size_t, test_handler* h)
|
||||
{
|
||||
h->results.get().alloc = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
friend void asio_handler_deallocate (
|
||||
void*, std::size_t, test_handler* h)
|
||||
{
|
||||
h->results.get().dealloc = true;
|
||||
}
|
||||
|
||||
friend bool asio_handler_is_continuation (
|
||||
test_handler* h)
|
||||
{
|
||||
h->results.get().cont = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct test_invokable
|
||||
{
|
||||
bool call;
|
||||
|
||||
test_invokable ()
|
||||
: call (false)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() ()
|
||||
{
|
||||
call = true;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Handler>
|
||||
bool async_op (Handler&& handler)
|
||||
{
|
||||
void* const p (boost_asio_handler_alloc_helpers::allocate (32, handler));
|
||||
(handler)();
|
||||
boost_asio_handler_alloc_helpers::deallocate (p, 32, handler);
|
||||
return boost_asio_handler_cont_helpers::is_continuation (handler);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
// Hooks called when using the raw handler
|
||||
{
|
||||
test_results r;
|
||||
test_handler h (r);
|
||||
|
||||
async_op (h);
|
||||
expect (r.call);
|
||||
expect (r.alloc);
|
||||
expect (r.dealloc);
|
||||
expect (r.cont);
|
||||
|
||||
test_invokable f;
|
||||
boost_asio_handler_invoke_helpers::invoke (std::ref (f), h);
|
||||
expect (r.invoke);
|
||||
expect (f.call);
|
||||
}
|
||||
|
||||
// Use of boost::bind shows the hooks not getting called
|
||||
{
|
||||
test_results r;
|
||||
test_handler h (r);
|
||||
auto b (std::bind (&test_handler::operator(), &h));
|
||||
|
||||
async_op (b);
|
||||
expect (r.call);
|
||||
unexpected (r.alloc);
|
||||
unexpected (r.dealloc);
|
||||
unexpected (r.cont);
|
||||
|
||||
test_invokable f;
|
||||
boost_asio_handler_invoke_helpers::invoke (std::ref (f), b);
|
||||
unexpected (r.invoke);
|
||||
expect (f.call);
|
||||
}
|
||||
|
||||
// Make sure the wrapped handler calls the hooks
|
||||
{
|
||||
test_results r;
|
||||
test_handler h (r);
|
||||
auto w (wrap_handler (
|
||||
std::bind (&test_handler::operator(), test_handler(r)), h));
|
||||
|
||||
async_op (w);
|
||||
expect (r.call);
|
||||
expect (r.alloc);
|
||||
expect (r.dealloc);
|
||||
expect (r.cont);
|
||||
|
||||
test_invokable f;
|
||||
boost_asio_handler_invoke_helpers::invoke (std::ref (f), w);
|
||||
expect (r.invoke);
|
||||
expect (f.call);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(wrap_handler,asio,beast);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_WRAP_HANDLER_H_INCLUDED
|
||||
#define BEAST_ASIO_WRAP_HANDLER_H_INCLUDED
|
||||
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4512) // assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
/** A handler which wraps another handler using a specfic context.
|
||||
The handler is invoked with the same io_service execution guarantees
|
||||
as the provided context.
|
||||
@note A copy of Context is made.
|
||||
*/
|
||||
template <class Handler, class Context>
|
||||
class wrapped_handler
|
||||
{
|
||||
private:
|
||||
Handler m_handler;
|
||||
Context m_context;
|
||||
bool m_continuation;
|
||||
|
||||
// If this goes off, consider carefully what the intent is.
|
||||
static_assert (! std::is_reference <Handler>::value,
|
||||
"Handler should not be a reference type");
|
||||
|
||||
public:
|
||||
wrapped_handler (bool continuation, Handler&& handler, Context context)
|
||||
: m_handler (std::move (handler))
|
||||
, m_context (context)
|
||||
, m_continuation (continuation ? true :
|
||||
boost_asio_handler_cont_helpers::is_continuation (context))
|
||||
{
|
||||
}
|
||||
|
||||
wrapped_handler (bool continuation, Handler const& handler, Context context)
|
||||
: m_handler (handler)
|
||||
, m_context (context)
|
||||
, m_continuation (continuation ? true :
|
||||
boost_asio_handler_cont_helpers::is_continuation (context))
|
||||
{
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
operator() (Args&&... args)
|
||||
{
|
||||
m_handler (std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
operator() (Args&&... args) const
|
||||
{
|
||||
m_handler (std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function& f, wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (f, h->m_context);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function const& f, wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (f, h->m_context);
|
||||
}
|
||||
|
||||
friend
|
||||
void*
|
||||
asio_handler_allocate (std::size_t size, wrapped_handler* h)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate (size, h->m_context);
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
asio_handler_deallocate (void* p, std::size_t size, wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate (p, size, h->m_context);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
asio_handler_is_continuation (wrapped_handler* h)
|
||||
{
|
||||
return h->m_continuation;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Tag for dispatching wrap_handler with is_continuation == true
|
||||
enum continuation_t
|
||||
{
|
||||
continuation
|
||||
};
|
||||
|
||||
/** Returns a wrapped handler so it executes within another context.
|
||||
The handler is invoked with the same io_service execution guarantees
|
||||
as the provided context. The handler will be copied if necessary.
|
||||
@note A copy of Context is made.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class DeducedHandler, class Context>
|
||||
detail::wrapped_handler <
|
||||
std::remove_reference_t <DeducedHandler>,
|
||||
Context
|
||||
>
|
||||
wrap_handler (DeducedHandler&& handler, Context const& context,
|
||||
bool continuation = false)
|
||||
{
|
||||
typedef std::remove_reference_t <DeducedHandler> Handler;
|
||||
return detail::wrapped_handler <Handler, Context> (continuation,
|
||||
std::forward <DeducedHandler> (handler), context);
|
||||
}
|
||||
|
||||
template <class DeducedHandler, class Context>
|
||||
detail::wrapped_handler <
|
||||
std::remove_reference_t <DeducedHandler>,
|
||||
Context
|
||||
>
|
||||
wrap_handler (continuation_t, DeducedHandler&& handler,
|
||||
Context const& context)
|
||||
{
|
||||
typedef std::remove_reference_t <DeducedHandler> Handler;
|
||||
return detail::wrapped_handler <Handler, Context> (true,
|
||||
std::forward <DeducedHandler> (handler), context);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -22,14 +22,11 @@
|
||||
#endif
|
||||
|
||||
#include <beast/http/impl/basic_parser.cpp>
|
||||
#include <beast/http/impl/basic_url.cpp>
|
||||
#include <beast/http/impl/joyent_parser.cpp>
|
||||
#include <beast/http/impl/method.cpp>
|
||||
#include <beast/http/impl/raw_parser.cpp>
|
||||
#include <beast/http/impl/URL.cpp>
|
||||
|
||||
#include <beast/http/tests/basic_url.test.cpp>
|
||||
#include <beast/http/tests/client_session.test.cpp>
|
||||
#include <beast/http/tests/parser.test.cpp>
|
||||
#include <beast/http/tests/rfc2616.test.cpp>
|
||||
#include <beast/http/tests/URL.test.cpp>
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HTTP_BASIC_URL_H_INCLUDED
|
||||
#define BEAST_HTTP_BASIC_URL_H_INCLUDED
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
#include <beast/utility/noexcept.h>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
namespace detail {
|
||||
|
||||
class basic_url_base
|
||||
{
|
||||
public:
|
||||
typedef char value_type;
|
||||
typedef std::char_traits <value_type> traits_type;
|
||||
|
||||
typedef boost::basic_string_ref <
|
||||
value_type, traits_type> string_ref;
|
||||
|
||||
string_ref
|
||||
scheme () const noexcept
|
||||
{
|
||||
return m_scheme;
|
||||
}
|
||||
|
||||
string_ref
|
||||
host () const noexcept
|
||||
{
|
||||
return m_host;
|
||||
}
|
||||
|
||||
std::uint16_t
|
||||
port () const noexcept
|
||||
{
|
||||
return m_port;
|
||||
}
|
||||
|
||||
string_ref
|
||||
port_string () const noexcept
|
||||
{
|
||||
return m_port_string;
|
||||
}
|
||||
|
||||
string_ref
|
||||
path () const noexcept
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
string_ref
|
||||
query () const noexcept
|
||||
{
|
||||
return m_query;
|
||||
}
|
||||
|
||||
string_ref
|
||||
fragment () const noexcept
|
||||
{
|
||||
return m_fragment;
|
||||
}
|
||||
|
||||
string_ref
|
||||
userinfo () const noexcept
|
||||
{
|
||||
return m_userinfo;
|
||||
}
|
||||
|
||||
protected:
|
||||
void
|
||||
parse_impl (string_ref s, boost::system::error_code& ec);
|
||||
|
||||
string_ref m_string_ref;
|
||||
string_ref m_scheme;
|
||||
string_ref m_host;
|
||||
std::uint16_t m_port;
|
||||
string_ref m_port_string;
|
||||
string_ref m_path;
|
||||
string_ref m_query;
|
||||
string_ref m_fragment;
|
||||
string_ref m_userinfo;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/** A URL. */
|
||||
template <
|
||||
class Alloc = std::allocator <char>
|
||||
>
|
||||
class basic_url : public detail::basic_url_base
|
||||
{
|
||||
public:
|
||||
typedef std::basic_string <
|
||||
value_type, traits_type, Alloc> string_type;
|
||||
|
||||
basic_url() = default;
|
||||
|
||||
explicit basic_url (Alloc const& alloc)
|
||||
: m_string (alloc)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
parse (string_ref s)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
parse (s, ec);
|
||||
if (ec)
|
||||
throw std::invalid_argument ("invalid url string");
|
||||
}
|
||||
|
||||
boost::system::error_code
|
||||
parse (string_ref s,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
parse_impl (s, ec);
|
||||
if (!ec)
|
||||
{
|
||||
m_string = string_type (s.begin(), s.end());
|
||||
m_string_ref = m_string;
|
||||
}
|
||||
return ec;
|
||||
}
|
||||
|
||||
bool
|
||||
empty () const noexcept
|
||||
{
|
||||
return m_string.empty();
|
||||
}
|
||||
|
||||
template <class Alloc1, class Alloc2>
|
||||
friend
|
||||
int
|
||||
compare (basic_url const& lhs,
|
||||
basic_url const& rhs) noexcept
|
||||
{
|
||||
return lhs.m_buf.compare (rhs.m_buf);
|
||||
}
|
||||
|
||||
private:
|
||||
string_type m_string;
|
||||
};
|
||||
|
||||
using url = basic_url <std::allocator <char>>;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,727 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HTTP_BASIC_SESSION_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTP_BASIC_SESSION_H_INCLUDED
|
||||
|
||||
#include <beast/http/basic_url.h>
|
||||
#include <beast/http/raw_parser.h>
|
||||
#include <beast/http/detail/header_traits.h>
|
||||
|
||||
#include <beast/asio/bind_handler.h>
|
||||
#include <beast/asio/enable_wait_for_async.h>
|
||||
#include <beast/asio/placeholders.h>
|
||||
#include <beast/asio/shared_handler.h>
|
||||
#include <beast/utility/is_call_possible.h>
|
||||
#include <beast/utility/ci_char_traits.h>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/deadline_timer.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/socket_base.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
#include <boost/asio/streambuf.hpp>
|
||||
//#include <boost/optional.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <boost/logic/tribool.hpp>
|
||||
|
||||
#include <beast/cxx14/memory.h> // <memory>
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
|
||||
#include <sstream> // REMOVE ASAP!
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
template <class T, class Alloc>
|
||||
boost::asio::basic_streambuf <Alloc>&
|
||||
operator<< (boost::asio::basic_streambuf <Alloc>& stream, T const& t)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << t;
|
||||
std::string const s (ss.str());
|
||||
auto const b (boost::asio::buffer (s));
|
||||
auto const len (boost::asio::buffer_size (b));
|
||||
boost::asio::buffer_copy (stream.prepare (len), b);
|
||||
stream.commit (len);
|
||||
return stream;
|
||||
}
|
||||
|
||||
template <class Alloc>
|
||||
boost::asio::basic_streambuf <Alloc>&
|
||||
operator<< (boost::asio::basic_streambuf <Alloc>& stream,
|
||||
std::string const& s)
|
||||
{
|
||||
auto const b (boost::asio::buffer (s));
|
||||
auto const len (boost::asio::buffer_size (b));
|
||||
boost::asio::buffer_copy (stream.prepare (len), b);
|
||||
stream.commit (len);
|
||||
return stream;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4100) // unreferenced formal parameter
|
||||
#endif
|
||||
|
||||
/** Provides asynchronous HTTP client service on a socket. */
|
||||
template <class Socket>
|
||||
class client_session
|
||||
: public asio::enable_wait_for_async <client_session <Socket>>
|
||||
, private raw_parser::callback
|
||||
{
|
||||
private:
|
||||
BOOST_TRIBOOL_THIRD_STATE(unspecified);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_keep_alive, keep_alive);
|
||||
|
||||
template <class Cond>
|
||||
struct Enabled : public std::integral_constant <bool, Cond::value>
|
||||
{
|
||||
};
|
||||
|
||||
static_assert (! std::is_const <Socket>::value,
|
||||
"Socket cannot be const");
|
||||
|
||||
typedef boost::system::error_code error_code;
|
||||
typedef boost::asio::streambuf write_buffers;
|
||||
typedef boost::basic_string_ref <
|
||||
char, ci_char_traits> ci_string_ref;
|
||||
|
||||
class abstract_request;
|
||||
class abstract_response;
|
||||
|
||||
Socket m_socket;
|
||||
boost::asio::io_service::strand m_strand;
|
||||
boost::asio::deadline_timer m_timer;
|
||||
|
||||
asio::shared_handler <void(error_code)> m_handler;
|
||||
std::unique_ptr <abstract_request> m_request;
|
||||
std::unique_ptr <abstract_response> m_response;
|
||||
|
||||
raw_parser m_parser;
|
||||
write_buffers m_write_buffer;
|
||||
boost::asio::mutable_buffer m_read_buffer;
|
||||
std::string m_field;
|
||||
std::string m_value;
|
||||
|
||||
bool m_complete : 1;
|
||||
bool m_keep_alive : 1;
|
||||
|
||||
public:
|
||||
typedef Socket stream_type;
|
||||
|
||||
client_session& operator= (client_session const&) = delete;
|
||||
|
||||
template <class... Args>
|
||||
explicit client_session (Args&&... args)
|
||||
: m_socket (std::forward <Args> (args)...)
|
||||
, m_strand (m_socket.get_io_service())
|
||||
, m_timer (m_socket.get_io_service())
|
||||
, m_parser (*this)
|
||||
{
|
||||
}
|
||||
|
||||
~client_session() = default;
|
||||
|
||||
/** Returns the stream associated with the session. */
|
||||
/** @{ */
|
||||
stream_type&
|
||||
stream()
|
||||
{
|
||||
return m_socket;
|
||||
}
|
||||
|
||||
stream_type const&
|
||||
stream() const
|
||||
{
|
||||
return m_socket;
|
||||
}
|
||||
/** @} */
|
||||
|
||||
void
|
||||
cancel()
|
||||
{
|
||||
error_code ec;
|
||||
m_socket.cancel(ec);
|
||||
}
|
||||
|
||||
/** Fetch a resource asynchronously. */
|
||||
template <
|
||||
class Request,
|
||||
class Response,
|
||||
class Handler
|
||||
>
|
||||
void
|
||||
async_get (Request request, Response response, Handler&& handler)
|
||||
{
|
||||
m_handler = std::forward <Handler> (handler);
|
||||
|
||||
m_request = std::make_unique <
|
||||
wrapped_request <Request>> (request);
|
||||
|
||||
m_response = std::make_unique <
|
||||
wrapped_response <Response>> (response);
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
template <
|
||||
class Handler
|
||||
>
|
||||
void
|
||||
async_get (std::string const&) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
class abstract_request
|
||||
{
|
||||
public:
|
||||
virtual
|
||||
~abstract_request()
|
||||
{
|
||||
}
|
||||
|
||||
virtual
|
||||
boost::tribool
|
||||
keep_alive () = 0;
|
||||
|
||||
virtual
|
||||
void
|
||||
headers (write_buffers& buffer) = 0;
|
||||
};
|
||||
|
||||
template <class Request>
|
||||
class wrapped_request : public abstract_request
|
||||
{
|
||||
private:
|
||||
typedef std::remove_reference_t <Request> request_type;
|
||||
|
||||
Request m_request;
|
||||
|
||||
public:
|
||||
explicit wrapped_request (Request request)
|
||||
: m_request (request)
|
||||
{
|
||||
}
|
||||
|
||||
wrapped_request (wrapped_request const&) = delete;
|
||||
|
||||
private:
|
||||
boost::tribool
|
||||
keep_alive() override
|
||||
{
|
||||
return keep_alive (Enabled <has_keep_alive <
|
||||
request_type, bool ()>>());
|
||||
}
|
||||
|
||||
boost::tribool
|
||||
keep_alive (std::true_type)
|
||||
{
|
||||
return m_request.keep_alive();
|
||||
}
|
||||
|
||||
boost::tribool
|
||||
keep_alive (std::false_type)
|
||||
{
|
||||
return unspecified;
|
||||
}
|
||||
|
||||
class submit
|
||||
{
|
||||
private:
|
||||
write_buffers& m_buffer;
|
||||
|
||||
public:
|
||||
explicit submit (write_buffers& buffer)
|
||||
: m_buffer (buffer)
|
||||
{
|
||||
}
|
||||
|
||||
// Throws if an invalid request field is specified.
|
||||
// Invalid fields are ones that the client_session inserts
|
||||
// itself, such as keep-alive.
|
||||
//
|
||||
static void check_request_field (std::string const& field)
|
||||
{
|
||||
static std::vector <std::string> reserved =
|
||||
{
|
||||
"Content-Length",
|
||||
"Connection"
|
||||
};
|
||||
|
||||
if (std::any_of (reserved.cbegin(), reserved.cend(),
|
||||
[&](typename decltype(reserved)::value_type const& s)
|
||||
{
|
||||
return detail::field_eq (field, s);
|
||||
}))
|
||||
throw std::invalid_argument (
|
||||
"Reserved HTTP header in request");
|
||||
}
|
||||
|
||||
template <class F, class V>
|
||||
void
|
||||
operator() (F const& f, V const& v)
|
||||
{
|
||||
check_request_field (f);
|
||||
|
||||
auto const fb (boost::asio::buffer (f));
|
||||
m_buffer.commit (boost::asio::buffer_copy (
|
||||
m_buffer.prepare (boost::asio::buffer_size (fb)), fb));
|
||||
m_buffer << ": ";
|
||||
auto const vb (boost::asio::buffer (v));
|
||||
m_buffer.commit (boost::asio::buffer_copy (
|
||||
m_buffer.prepare (boost::asio::buffer_size (vb)), vb));
|
||||
m_buffer << "\r\n";
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
headers (write_buffers& buffer) override
|
||||
{
|
||||
submit f (buffer);
|
||||
m_request.template headers <
|
||||
std::add_lvalue_reference_t <submit>> (f);
|
||||
}
|
||||
};
|
||||
|
||||
class abstract_response
|
||||
{
|
||||
public:
|
||||
abstract_response() = default;
|
||||
abstract_response (abstract_response const&) = default;
|
||||
abstract_response& operator= (abstract_response const&) = default;
|
||||
|
||||
virtual
|
||||
~abstract_response() = default;
|
||||
|
||||
virtual
|
||||
boost::asio::mutable_buffer
|
||||
buffer () = 0;
|
||||
|
||||
virtual
|
||||
error_code
|
||||
header (std::string const& field,
|
||||
std::string const& value) = 0;
|
||||
|
||||
virtual
|
||||
error_code
|
||||
body (boost::asio::const_buffer in) = 0;
|
||||
|
||||
};
|
||||
|
||||
template <class Response>
|
||||
class wrapped_response : public abstract_response
|
||||
{
|
||||
private:
|
||||
Response m_response;
|
||||
|
||||
public:
|
||||
explicit wrapped_response (Response response)
|
||||
: m_response (response)
|
||||
{
|
||||
}
|
||||
|
||||
wrapped_response (wrapped_response const&) = delete;
|
||||
|
||||
boost::asio::mutable_buffer
|
||||
buffer() override
|
||||
{
|
||||
return m_response.buffer();
|
||||
}
|
||||
|
||||
error_code
|
||||
header (std::string const& field,
|
||||
std::string const& value) override
|
||||
{
|
||||
return m_response.header (field, value);
|
||||
}
|
||||
|
||||
virtual
|
||||
error_code
|
||||
body (boost::asio::const_buffer in)
|
||||
{
|
||||
return m_response.body (in);
|
||||
}
|
||||
};
|
||||
|
||||
void upcall (error_code const& ec, bool continuation = true)
|
||||
{
|
||||
if (m_handler)
|
||||
{
|
||||
// TODO cancel all pending i/o here?
|
||||
|
||||
if (continuation)
|
||||
{
|
||||
m_handler (ec);
|
||||
m_handler = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_socket.get_io_service().post (
|
||||
asio::bind_handler (
|
||||
std::move (m_handler), ec));
|
||||
assert (! m_handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
// reset and setup state
|
||||
|
||||
m_parser.reset (raw_parser::response);
|
||||
|
||||
m_write_buffer.consume (m_write_buffer.size());
|
||||
m_write_buffer <<
|
||||
"GET / HTTP/1.0\r\n";
|
||||
m_request->headers (m_write_buffer);
|
||||
m_write_buffer <<
|
||||
"Content-Length: 0\r\n"
|
||||
"\r\n";
|
||||
|
||||
m_read_buffer = m_response->buffer();
|
||||
|
||||
m_field = std::string();
|
||||
m_value = std::string();
|
||||
|
||||
m_complete = false;
|
||||
m_keep_alive = false;
|
||||
|
||||
async_write_some (false);
|
||||
}
|
||||
|
||||
//
|
||||
// request
|
||||
//
|
||||
|
||||
bool
|
||||
async_write_some (bool continuation = true)
|
||||
{
|
||||
auto const& data (m_write_buffer.data());
|
||||
auto const size (boost::asio::buffer_size (
|
||||
m_write_buffer.data()));
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
m_socket.async_write_some (data, this->wrap_with_counter (
|
||||
m_strand.wrap (asio::wrap_handler (std::bind (
|
||||
&client_session::handle_write, this,
|
||||
asio::placeholders::error,
|
||||
asio::placeholders::bytes_transferred),
|
||||
continuation))));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
handle_write (error_code ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (ec)
|
||||
return upcall (ec);
|
||||
|
||||
m_write_buffer.consume (bytes_transferred);
|
||||
|
||||
if (async_write_some())
|
||||
return;
|
||||
|
||||
// write finished
|
||||
|
||||
//if (! keep_alive)
|
||||
{
|
||||
m_socket.shutdown (
|
||||
boost::asio::socket_base::shutdown_send, ec);
|
||||
// VFALCO What do we do with ec?
|
||||
}
|
||||
|
||||
// now read
|
||||
|
||||
async_read_some (true);
|
||||
}
|
||||
|
||||
//
|
||||
// response
|
||||
//
|
||||
|
||||
void
|
||||
async_read_some (bool continuation = true)
|
||||
{
|
||||
m_socket.async_read_some (boost::asio::mutable_buffers_1 (
|
||||
m_read_buffer), this->wrap_with_counter (
|
||||
m_strand.wrap (asio::wrap_handler (std::bind (
|
||||
&client_session::handle_read, this,
|
||||
asio::placeholders::error,
|
||||
asio::placeholders::bytes_transferred),
|
||||
continuation))));
|
||||
};
|
||||
|
||||
void
|
||||
handle_read (error_code ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (ec != boost::asio::error::eof)
|
||||
{
|
||||
if (ec)
|
||||
return upcall (ec);
|
||||
|
||||
std::size_t bytes_consumed;
|
||||
std::tie (ec, bytes_consumed) = m_parser.process_data (
|
||||
boost::asio::buffer_cast <void const*> (m_read_buffer),
|
||||
bytes_transferred);
|
||||
|
||||
// TODO Handle leftover bytes
|
||||
//assert (ec || bytes_consumed == bytes_transferred);
|
||||
|
||||
if (ec)
|
||||
return upcall (ec);
|
||||
|
||||
if (! m_complete)
|
||||
return async_read_some();
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is here for when we expect keep-alive but
|
||||
// the server ends up closing the connection erroneously.
|
||||
if (m_keep_alive)
|
||||
{
|
||||
m_keep_alive = false;
|
||||
// warning: Got EOF on keep-alive
|
||||
}
|
||||
|
||||
ec = m_parser.process_eof();
|
||||
}
|
||||
|
||||
if (! m_complete)
|
||||
{
|
||||
// custom error
|
||||
ec = error_code (boost::system::errc::no_message_available,
|
||||
boost::system::generic_category());
|
||||
}
|
||||
|
||||
if (ec)
|
||||
return upcall (ec);
|
||||
|
||||
// We have a complete response
|
||||
|
||||
if (! m_keep_alive)
|
||||
{
|
||||
// VFALCO NOTE This is surely wrong for ssl::stream
|
||||
{
|
||||
error_code ec_;
|
||||
m_socket.shutdown (
|
||||
boost::asio::socket_base::shutdown_receive, ec_);
|
||||
}
|
||||
|
||||
{
|
||||
error_code ec_;
|
||||
m_socket.close (ec_);
|
||||
assert (! ec_);
|
||||
}
|
||||
}
|
||||
|
||||
m_request.reset();
|
||||
m_response.reset();
|
||||
m_handler (ec);
|
||||
|
||||
// done
|
||||
}
|
||||
|
||||
//
|
||||
// parser
|
||||
//
|
||||
|
||||
error_code
|
||||
do_header()
|
||||
{
|
||||
error_code ec;
|
||||
|
||||
if (! m_value.empty())
|
||||
{
|
||||
ec = m_response->header (m_field, m_value);
|
||||
|
||||
m_field.clear();
|
||||
m_value.clear();
|
||||
}
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
error_code
|
||||
on_response () override
|
||||
{
|
||||
m_field = decltype(m_field)();
|
||||
m_value = decltype(m_value)();
|
||||
return error_code();
|
||||
}
|
||||
|
||||
error_code
|
||||
on_url (
|
||||
void const* in, std::size_t bytes) override
|
||||
{
|
||||
// Shouldn't be called for HTTP responses
|
||||
assert (false);
|
||||
return error_code();
|
||||
}
|
||||
|
||||
error_code
|
||||
on_status (int status_code,
|
||||
void const* in, std::size_t bytes) override
|
||||
{
|
||||
return error_code();
|
||||
}
|
||||
|
||||
error_code
|
||||
on_header_field (
|
||||
void const* in, std::size_t bytes) override
|
||||
{
|
||||
do_header();
|
||||
m_field.append (static_cast <char const*> (in), bytes);
|
||||
return error_code();
|
||||
}
|
||||
|
||||
error_code
|
||||
on_header_value (
|
||||
void const* in, std::size_t bytes) override
|
||||
{
|
||||
m_value.append (static_cast <char const*> (in), bytes);
|
||||
return error_code();
|
||||
}
|
||||
|
||||
error_code
|
||||
on_headers_done (
|
||||
bool keep_alive) override
|
||||
{
|
||||
do_header();
|
||||
|
||||
return error_code();
|
||||
}
|
||||
|
||||
error_code
|
||||
on_body (bool,
|
||||
void const* in, std::size_t bytes) override
|
||||
{
|
||||
m_response->body (
|
||||
boost::asio::const_buffer (in, bytes));
|
||||
return error_code();
|
||||
}
|
||||
|
||||
error_code
|
||||
on_message_complete (bool keep_alive) override
|
||||
{
|
||||
m_keep_alive = keep_alive;
|
||||
m_complete = true;
|
||||
return error_code();
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Synchronous HTTP client session. */
|
||||
template <class Socket>
|
||||
class sync_client_session
|
||||
{
|
||||
private:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
boost::asio::io_service m_ios;
|
||||
Socket m_socket;
|
||||
error_code m_ec;
|
||||
|
||||
static_assert (std::is_same <Socket, std::decay_t <Socket>>::value,
|
||||
"Socket cannot be a reference or const type");
|
||||
|
||||
struct sync_handler
|
||||
{
|
||||
std::reference_wrapper <sync_client_session> m_session;
|
||||
|
||||
sync_handler (sync_client_session& session)
|
||||
: m_session (session)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (boost::system::error_code ec)
|
||||
{
|
||||
m_session.get().m_ec = ec;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
typedef std::remove_reference_t <Socket> next_layer_type;
|
||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
sync_client_session()
|
||||
: m_socket (m_ios)
|
||||
{
|
||||
}
|
||||
|
||||
sync_client_session (sync_client_session const&) = delete;
|
||||
|
||||
// VFALCO We might be able to get away with having move ctor/assign
|
||||
|
||||
~sync_client_session() = default;
|
||||
|
||||
next_layer_type&
|
||||
next_layer() noexcept
|
||||
{
|
||||
return m_socket;
|
||||
}
|
||||
|
||||
next_layer_type const&
|
||||
next_layer() const noexcept
|
||||
{
|
||||
}
|
||||
|
||||
lowest_layer_type&
|
||||
lowest_layer() noexcept
|
||||
{
|
||||
return m_socket.lowest_layer();
|
||||
}
|
||||
|
||||
lowest_layer_type const&
|
||||
lowest_layer() const noexcept
|
||||
{
|
||||
return m_socket.lowest_layer();
|
||||
}
|
||||
|
||||
template <class Request, class Response>
|
||||
error_code
|
||||
get (Request& request, Response& response)
|
||||
{
|
||||
client_session <Socket&> session (m_socket);
|
||||
session.template async_get <
|
||||
std::add_lvalue_reference_t <Request>,
|
||||
std::add_lvalue_reference_t <Response>,
|
||||
sync_handler> (
|
||||
request, response, sync_handler (*this));
|
||||
m_ios.run();
|
||||
m_ios.reset();
|
||||
return m_ec;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,56 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/http/basic_url.h>
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class basic_url_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
void
|
||||
run ()
|
||||
{
|
||||
std::vector <char const*> const urls {
|
||||
"http://www.example.com/#%c2%a9",
|
||||
"http://127.0.0.1:443",
|
||||
"http://192.168.0.1 hello.urltest.lookout.net/",
|
||||
"http://\\uff10\\uff38\\uff43\\uff10\\uff0e\\uff10\\uff12\\uff15\\uff10\\uff0e\\uff10\\uff11.urltest.lookout.net/"
|
||||
};
|
||||
http::url url;
|
||||
for (auto const& s : urls)
|
||||
{
|
||||
try
|
||||
{
|
||||
url.parse (s);
|
||||
pass();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE_MANUAL(basic_url,http,beast);
|
||||
|
||||
}
|
||||
@@ -1,376 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// LIBS: pthread
|
||||
// MODULES: urls_large_data.cpp ../impl/raw_parser.cpp ../impl/joyent_parser.cpp
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include "../../BeastConfig.h"
|
||||
#endif
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
#include <beast/http/tests/urls_large_data.h>
|
||||
#include <beast/http/client_session.h>
|
||||
#include <beast/asio/bind_handler.h>
|
||||
#include <beast/asio/memory_buffer.h>
|
||||
#include <beast/utility/ci_char_traits.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** Allows thread-safe forward traversal of a sequence.
|
||||
|
||||
Each time the shared_iterator is dereferenced it provides an element in
|
||||
the sequence or the one-past-the-end iterator if there are no elements
|
||||
remaining in the sequence. Access to the shared iterator is thread safe:
|
||||
multiple threads of execution can request iterators from the sequence,
|
||||
and no two threads will see the same iterator.
|
||||
|
||||
Any operations on the underlying container which would invalidate
|
||||
iterators or change the sequence of elements pointed to by the range
|
||||
of iterators referenced by the shared_iterator, results in undefined
|
||||
behavior.
|
||||
*/
|
||||
template <class Iterator>
|
||||
class shared_iterator
|
||||
{
|
||||
public:
|
||||
static_assert (std::is_same <Iterator, std::decay_t <Iterator>>::value,
|
||||
"Iterator may not be a reference or const type");
|
||||
|
||||
typedef Iterator value_type;
|
||||
|
||||
private:
|
||||
std::mutex m_mutex;
|
||||
Iterator m_iter;
|
||||
Iterator m_end;
|
||||
|
||||
public:
|
||||
/** Construct the iteration from the range [first, last) */
|
||||
shared_iterator (Iterator first, Iterator last)
|
||||
: m_iter (first)
|
||||
, m_end (last)
|
||||
{
|
||||
}
|
||||
|
||||
/** Obtains the next iterator in the sequence.
|
||||
Post-condition
|
||||
Current shared position in the sequence is advanced by one.
|
||||
Thread safety:
|
||||
Can be called from any thread at any time.
|
||||
*/
|
||||
Iterator
|
||||
operator* ()
|
||||
{
|
||||
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||
if (m_iter == m_end)
|
||||
return m_iter;
|
||||
return m_iter++;
|
||||
}
|
||||
|
||||
/** Returns the one-past-the end iterator for the sequence.
|
||||
Thread safety:
|
||||
Can be called from any thread at any time.
|
||||
*/
|
||||
Iterator
|
||||
end() const
|
||||
{
|
||||
return m_end;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class client_session_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Used to submit HTTP requests. */
|
||||
class Request
|
||||
{
|
||||
private:
|
||||
typedef std::string value_type;
|
||||
typedef std::string string_type;
|
||||
|
||||
std::unordered_map <std::string, string_type> m_headers;
|
||||
|
||||
// This also works, for allowing header values to
|
||||
// span multiple discontiguous memory buffers.
|
||||
//
|
||||
std::unordered_map <std::string,
|
||||
std::vector <std::string>> m_headers_plus;
|
||||
|
||||
class vector_proxy
|
||||
{
|
||||
private:
|
||||
std::reference_wrapper <std::vector <string_type>> m_vec;
|
||||
|
||||
public:
|
||||
explicit vector_proxy (std::vector <string_type>& vec)
|
||||
: m_vec (vec)
|
||||
{
|
||||
}
|
||||
|
||||
vector_proxy& operator= (string_type const& s)
|
||||
{
|
||||
m_vec.get().emplace_back (s);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
bool keep_alive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use this to set the fields
|
||||
std::string&
|
||||
operator[] (std::string const& field)
|
||||
{
|
||||
return m_headers[field];
|
||||
}
|
||||
|
||||
/** Calls Function for each header.
|
||||
|
||||
Requirements:
|
||||
|
||||
`X` The type `Function`
|
||||
`Y` A type meeting this requirement:
|
||||
ConvertibleToConstBuffer
|
||||
`Z` A type meeting either requirement:
|
||||
ConstBufferSequence
|
||||
ConvertibleToConstBuffer
|
||||
`f` A value of type `X`
|
||||
`n` A value of type `Y`
|
||||
`v` A value of type `Z`
|
||||
|
||||
The expression
|
||||
|
||||
f (n, v);
|
||||
|
||||
must be well formed.
|
||||
*/
|
||||
template <class Function>
|
||||
void
|
||||
headers (Function f)
|
||||
{
|
||||
for (auto const& h : m_headers)
|
||||
f (h.first, h.second);
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
class Response
|
||||
{
|
||||
private:
|
||||
typedef boost::system::error_code error_code;
|
||||
asio::memory_buffer <std::uint8_t> m_buffer;
|
||||
boost::asio::streambuf m_body;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
buffer_bytes = 4192
|
||||
};
|
||||
|
||||
typedef std::vector <std::pair <
|
||||
std::string, std::string>> headers_type;
|
||||
|
||||
headers_type headers;
|
||||
|
||||
Response()
|
||||
: m_buffer (buffer_bytes)
|
||||
{
|
||||
}
|
||||
|
||||
boost::asio::mutable_buffer
|
||||
buffer()
|
||||
{
|
||||
return boost::asio::mutable_buffer (
|
||||
m_buffer.data(), m_buffer.size());
|
||||
}
|
||||
|
||||
template <class FieldString, class ValueString>
|
||||
error_code
|
||||
header (FieldString const& field, ValueString const& value)
|
||||
{
|
||||
headers.push_back (std::make_pair (field, value));
|
||||
return error_code();
|
||||
}
|
||||
|
||||
error_code
|
||||
body (boost::asio::const_buffer in)
|
||||
{
|
||||
m_body.commit (boost::asio::buffer_copy (
|
||||
m_body.prepare (boost::asio::buffer_size (in)),
|
||||
boost::asio::buffer (in)));
|
||||
return error_code();
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const
|
||||
{
|
||||
return m_body.size();
|
||||
}
|
||||
|
||||
std::string
|
||||
data() const
|
||||
{
|
||||
std::string s;
|
||||
s.resize (m_body.size());
|
||||
boost::asio::buffer_copy (boost::asio::buffer (
|
||||
&s[0], s.size()), m_body.data());
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
template <class Session>
|
||||
error_code
|
||||
visit (Session& session, std::string const& url)
|
||||
{
|
||||
error_code ec;
|
||||
typedef boost::asio::ip::tcp::resolver resolver_t;
|
||||
boost::asio::io_service ios;
|
||||
resolver_t r (ios);
|
||||
auto iter (r.resolve (resolver_t::query (
|
||||
url, "80", resolver_t::query::numeric_service), ec));
|
||||
|
||||
if (ec)
|
||||
return ec;
|
||||
|
||||
if (iter != resolver_t::iterator())
|
||||
{
|
||||
session.next_layer().connect (iter->endpoint(), ec);
|
||||
if (ec)
|
||||
return ec;
|
||||
|
||||
Request req;
|
||||
req ["User-Agent"] = "rippled-http-client/1.0";
|
||||
req ["Host"] = url + ":80";
|
||||
req ["Content-Type"] = "application/text";
|
||||
req ["Accept"] = "application/text";
|
||||
|
||||
//req ["Content-length"] = "0";
|
||||
//req.prepare ("GET / HTTP/1.0");
|
||||
|
||||
Response resp;
|
||||
ec = session.get (req, resp);
|
||||
|
||||
if (ec)
|
||||
{
|
||||
// hack
|
||||
session.next_layer().close();
|
||||
}
|
||||
|
||||
log <<
|
||||
"GET " << url << " " << ec.message();
|
||||
|
||||
for (auto const& h : resp.headers)
|
||||
log << h.first << ": " << h.second;
|
||||
|
||||
log << resp.data();
|
||||
log << " ";
|
||||
}
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
template <class Iterator>
|
||||
void
|
||||
concurrent_get (shared_iterator <Iterator>& iter)
|
||||
{
|
||||
typedef boost::asio::ip::tcp::socket socket_type;
|
||||
for (auto cur (*iter); cur != iter.end(); cur = *iter)
|
||||
{
|
||||
sync_client_session <socket_type> session;
|
||||
std::string const base (*cur);
|
||||
std::string url;
|
||||
url = "www." + base;
|
||||
visit (session, url);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform HTTP get on a sequence of URLs in parallel
|
||||
// Requirements
|
||||
// Sequence must me
|
||||
// Sequence::value_type must be convertible to std::string
|
||||
template <class Iterator>
|
||||
void test_concurrent_get (Iterator first, Iterator last)
|
||||
{
|
||||
#if 0
|
||||
last = first;
|
||||
std::advance (last, 3000);
|
||||
#endif
|
||||
|
||||
shared_iterator <Iterator> iter (first, last);
|
||||
|
||||
std::vector <std::thread> pool;
|
||||
#if 0
|
||||
std::size_t const hardware_concurrency (
|
||||
std::max (std::thread::hardware_concurrency(),
|
||||
2u
|
||||
));
|
||||
#else
|
||||
std::size_t const hardware_concurrency (1);
|
||||
#endif
|
||||
|
||||
for (std::size_t n (hardware_concurrency); n--;)
|
||||
pool.emplace_back (std::bind (
|
||||
&client_session_test::concurrent_get <Iterator>, this,
|
||||
std::ref (iter)));
|
||||
|
||||
for (auto& t : pool)
|
||||
t.join();
|
||||
|
||||
pass();
|
||||
}
|
||||
|
||||
template <class Sequence>
|
||||
void test_concurrent_get (Sequence const& sequence)
|
||||
{
|
||||
auto last (std::begin(sequence));
|
||||
std::advance (last, std::min (std::size_t(1), sequence.size()));
|
||||
test_concurrent_get (std::begin (sequence), last);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
test_concurrent_get (urls_large_data());
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE_MANUAL(client_session,http,beast);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,9 @@
|
||||
#ifndef BEAST_ASIO_ASYNCOBJECT_H_INCLUDED
|
||||
#define BEAST_ASIO_ASYNCOBJECT_H_INCLUDED
|
||||
|
||||
#include <beast/Atomic.h>
|
||||
#include <cassert>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
@@ -34,7 +37,7 @@ public:
|
||||
~AsyncObject ()
|
||||
{
|
||||
// Destroying the object with I/O pending? Not a clean exit!
|
||||
bassert (m_pending.get() == 0);
|
||||
assert (m_pending.get() == 0);
|
||||
}
|
||||
|
||||
/** RAII container that maintains the count of pending I/O.
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPField.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPField::HTTPField ()
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPHeaders.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace beast {
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef BEAST_ASIO_HTTPHEADERS_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPHEADERS_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/http/HTTPField.h>
|
||||
#include <beast/module/asio/HTTPField.h>
|
||||
#include <beast/module/core/text/StringPairArray.h>
|
||||
#include <map>
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPMessage.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPMessage::HTTPMessage (HTTPVersion const& version_,
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef BEAST_ASIO_HTTPMESSAGE_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPMESSAGE_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/http/HTTPHeaders.h>
|
||||
#include <beast/module/asio/http/HTTPVersion.h>
|
||||
#include <beast/module/asio/HTTPHeaders.h>
|
||||
#include <beast/module/asio/HTTPVersion.h>
|
||||
|
||||
#include <beast/smart_ptr/SharedObject.h>
|
||||
#include <beast/net/DynamicBuffer.h>
|
||||
@@ -17,6 +17,9 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPParser.h>
|
||||
#include <beast/module/asio/HTTPParserImpl.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPParser::HTTPParser (Type type)
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef BEAST_ASIO_HTTPPARSER_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPPARSER_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/http/HTTPRequest.h>
|
||||
#include <beast/module/asio/http/HTTPResponse.h>
|
||||
#include <beast/module/asio/HTTPRequest.h>
|
||||
#include <beast/module/asio/HTTPResponse.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#ifndef BEAST_HTTPPARSERIMPL_H_INCLUDED
|
||||
#define BEAST_HTTPPARSERIMPL_H_INCLUDED
|
||||
|
||||
#include <beast/http/impl/joyent_parser.h>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class HTTPParserImpl
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPRequest.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPRequest::HTTPRequest (
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef BEAST_ASIO_HTTPREQUEST_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPREQUEST_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/http/HTTPMessage.h>
|
||||
#include <beast/module/asio/HTTPMessage.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
//#include "HTTPRequestParser.h"
|
||||
#include <beast/module/asio/HTTPRequestParser.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef BEAST_HTTP_REQUESTPARSER_H_INCLUDED
|
||||
#define BEAST_HTTP_REQUESTPARSER_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/http/HTTPParser.h>
|
||||
#include <beast/module/asio/HTTPParser.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPResponse.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPResponse::HTTPResponse (
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef BEAST_ASIO_HTTPRESPONSE_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPRESPONSE_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/HTTPMessage.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class HTTPResponse : public HTTPMessage
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
//#include "HTTPResponseParser.h"
|
||||
#include <beast/module/asio/HTTPResponseParser.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef BEAST_HTTP_RESPONSEPARSER_H_INCLUDED
|
||||
#define BEAST_HTTP_RESPONSEPARSER_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/http/HTTPParser.h>
|
||||
#include <beast/module/asio/HTTPParser.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_MODULE_H_INCLUDED
|
||||
#define BEAST_ASIO_MODULE_H_INCLUDED
|
||||
|
||||
// Must come before boost includes to fix the bost placeholders.
|
||||
#include <beast/module/core/core.h>
|
||||
|
||||
// This module requires boost and possibly OpenSSL
|
||||
#include <beast/module/asio/system/BoostIncludes.h>
|
||||
|
||||
#include <beast/http/URL.h>
|
||||
|
||||
#include <beast/asio/IPAddressConversion.h>
|
||||
|
||||
// Order matters
|
||||
#include <beast/module/asio/async/AsyncObject.h>
|
||||
|
||||
#include <beast/module/asio/basics/FixedInputBuffer.h>
|
||||
#include <beast/module/asio/basics/PeerRole.h>
|
||||
#include <beast/module/asio/basics/SSLContext.h>
|
||||
|
||||
#include <beast/module/asio/http/HTTPVersion.h>
|
||||
#include <beast/module/asio/http/HTTPField.h>
|
||||
#include <beast/module/asio/http/HTTPHeaders.h>
|
||||
#include <beast/module/asio/http/HTTPMessage.h>
|
||||
#include <beast/module/asio/http/HTTPRequest.h>
|
||||
#include <beast/module/asio/http/HTTPResponse.h>
|
||||
|
||||
#include <beast/module/asio/http/HTTPParser.h>
|
||||
#include <beast/module/asio/http/HTTPRequestParser.h>
|
||||
#include <beast/module/asio/http/HTTPResponseParser.h>
|
||||
|
||||
#include <beast/module/asio/http/HTTPClientType.h>
|
||||
|
||||
#include <beast/module/asio/protocol/InputParser.h>
|
||||
#include <beast/module/asio/protocol/HandshakeDetectLogic.h>
|
||||
#include <beast/module/asio/protocol/HandshakeDetectLogicPROXY.h>
|
||||
#include <beast/module/asio/protocol/HandshakeDetectLogicSSL2.h>
|
||||
#include <beast/module/asio/protocol/HandshakeDetectLogicSSL3.h>
|
||||
#include <beast/module/asio/protocol/HandshakeDetector.h>
|
||||
#include <beast/module/asio/protocol/PrefilledReadStream.h>
|
||||
|
||||
#include <beast/module/asio/tests/TestPeerBasics.h>
|
||||
#include <beast/module/asio/tests/TestPeer.h>
|
||||
#include <beast/module/asio/tests/TestPeerDetails.h>
|
||||
#include <beast/module/asio/tests/TestPeerLogic.h>
|
||||
#include <beast/module/asio/tests/TestPeerLogicSyncServer.h>
|
||||
#include <beast/module/asio/tests/TestPeerLogicSyncClient.h>
|
||||
#include <beast/module/asio/tests/TestPeerLogicProxyClient.h>
|
||||
#include <beast/module/asio/tests/TestPeerLogicAsyncServer.h>
|
||||
#include <beast/module/asio/tests/TestPeerLogicAsyncClient.h>
|
||||
#include <beast/module/asio/tests/TestPeerType.h>
|
||||
#include <beast/module/asio/tests/TestPeerDetailsTcp.h>
|
||||
#include <beast/module/asio/tests/PeerTest.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,36 +21,12 @@
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/module/asio/system/OpenSSLIncludes.h>
|
||||
|
||||
#include <beast/module/asio/asio.h>
|
||||
|
||||
#include <beast/http/impl/joyent_parser.h>
|
||||
|
||||
#include <beast/module/asio/basics/PeerRole.cpp>
|
||||
#include <beast/module/asio/basics/SSLContext.cpp>
|
||||
|
||||
#include <beast/module/asio/protocol/HandshakeDetectLogicPROXY.cpp>
|
||||
|
||||
#include <beast/module/asio/http/HTTPParserImpl.h>
|
||||
#include <beast/module/asio/http/HTTPClientType.cpp>
|
||||
#include <beast/module/asio/http/HTTPField.cpp>
|
||||
#include <beast/module/asio/http/HTTPHeaders.cpp>
|
||||
#include <beast/module/asio/http/HTTPMessage.cpp>
|
||||
#include <beast/module/asio/http/HTTPRequest.cpp>
|
||||
#include <beast/module/asio/http/HTTPResponse.cpp>
|
||||
#include <beast/module/asio/http/HTTPVersion.cpp>
|
||||
|
||||
#include <beast/module/asio/tests/PeerTest.cpp>
|
||||
#include <beast/module/asio/tests/TestPeerBasics.cpp>
|
||||
#include <beast/module/asio/tests/TestPeerLogic.cpp>
|
||||
#include <beast/module/asio/tests/TestPeerLogicProxyClient.cpp>
|
||||
#include <beast/module/asio/tests/TestPeerLogicSyncServer.cpp>
|
||||
#include <beast/module/asio/tests/TestPeerLogicSyncClient.cpp>
|
||||
#include <beast/module/asio/tests/TestPeerLogicAsyncServer.cpp>
|
||||
#include <beast/module/asio/tests/TestPeerLogicAsyncClient.cpp>
|
||||
#include <beast/module/asio/tests/TestPeerUnitTests.cpp>
|
||||
|
||||
#include <beast/module/asio/http/HTTPParser.cpp>
|
||||
#include <beast/module/asio/http/HTTPRequestParser.cpp>
|
||||
#include <beast/module/asio/http/HTTPResponseParser.cpp>
|
||||
#include <beast/module/asio/HTTPField.cpp>
|
||||
#include <beast/module/asio/HTTPHeaders.cpp>
|
||||
#include <beast/module/asio/HTTPMessage.cpp>
|
||||
#include <beast/module/asio/HTTPRequest.cpp>
|
||||
#include <beast/module/asio/HTTPResponse.cpp>
|
||||
#include <beast/module/asio/HTTPVersion.cpp>
|
||||
#include <beast/module/asio/HTTPParser.cpp>
|
||||
#include <beast/module/asio/HTTPRequestParser.cpp>
|
||||
#include <beast/module/asio/HTTPResponseParser.cpp>
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
ContentBodyBuffer::ContentBodyBuffer (size_type blocksize)
|
||||
: m_blocksize (blocksize)
|
||||
, m_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
ContentBodyBuffer::~ContentBodyBuffer ()
|
||||
{
|
||||
for (Handles::iterator iter (m_handles.begin());
|
||||
iter != m_handles.end(); ++iter)
|
||||
{
|
||||
void* const buffer (*iter);
|
||||
std::free (buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void ContentBodyBuffer::swapWith (ContentBodyBuffer& other)
|
||||
{
|
||||
std::swap (m_blocksize, other.m_blocksize);
|
||||
std::swap (m_size, other.m_size);
|
||||
m_handles.swap (other.m_handles);
|
||||
}
|
||||
|
||||
void ContentBodyBuffer::commit (size_type n)
|
||||
{
|
||||
m_size += n;
|
||||
bassert (m_size <= m_handles.size () * m_blocksize);
|
||||
}
|
||||
|
||||
ConstBuffers ContentBodyBuffer::data () const
|
||||
{
|
||||
size_type n (m_size);
|
||||
std::vector <ConstBuffer> v;
|
||||
v.reserve ((m_size + m_blocksize - 1) / m_blocksize);
|
||||
for (Handles::const_iterator iter (m_handles.begin());
|
||||
iter != m_handles.end() && n > 0; ++iter)
|
||||
{
|
||||
size_type const amount (std::min (n, m_blocksize));
|
||||
v.push_back (MutableBuffer (*iter, amount));
|
||||
n -= amount;
|
||||
}
|
||||
return ConstBuffers (v);
|
||||
}
|
||||
|
||||
ContentBodyBuffer::size_type ContentBodyBuffer::size () const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
MutableBuffers ContentBodyBuffer::prepare (size_type n)
|
||||
{
|
||||
reserve (n);
|
||||
std::vector <MutableBuffer> v;
|
||||
size_type offset (m_size % m_blocksize);
|
||||
for (Handles::iterator iter = m_handles.begin () + (m_size / m_blocksize);
|
||||
iter != m_handles.end () && n > 0; ++iter)
|
||||
{
|
||||
size_type const amount (std::min (n, m_blocksize - offset));
|
||||
v.push_back (MutableBuffer (*iter, amount));
|
||||
n -= amount;
|
||||
offset = 0;
|
||||
}
|
||||
return MutableBuffers (v);
|
||||
}
|
||||
|
||||
void ContentBodyBuffer::reserve (size_type n)
|
||||
{
|
||||
size_type count ((m_size + n + m_blocksize - 1) / m_blocksize);
|
||||
if (count > m_handles.size ())
|
||||
for (count -= m_handles.size (); count-- > 0;)
|
||||
m_handles.push_back (std::malloc (m_blocksize));
|
||||
}
|
||||
|
||||
void ContentBodyBuffer::shrink_to_fit ()
|
||||
{
|
||||
size_type const count ((m_size + m_blocksize - 1) / m_blocksize);
|
||||
while (m_handles.size () > count)
|
||||
{
|
||||
std::free (m_handles.back ());
|
||||
m_handles.erase (m_handles.end () - 1);
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_BASICS_CONTENTBODYBUFFER_H_INCLUDED
|
||||
#define BEAST_ASIO_BASICS_CONTENTBODYBUFFER_H_INCLUDED
|
||||
|
||||
/** Dynamic storage optimized for a large Content-Body of unknown size.
|
||||
This comes at the expense of discontiguous storage of the segments.
|
||||
We derive from SharedObject to make transfer of ownership inexpensive.
|
||||
*/
|
||||
class ContentBodyBuffer
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
defaultBlocksize = 32 * 1024
|
||||
};
|
||||
|
||||
typedef std::size_t size_type;
|
||||
typedef ConstBuffers const_buffers_tyoe;
|
||||
typedef MutableBuffers mutable_buffers_type;
|
||||
|
||||
explicit ContentBodyBuffer (size_type blocksize = defaultBlocksize);
|
||||
|
||||
~ContentBodyBuffer ();
|
||||
|
||||
/** Swap the contents of this buffer with another.
|
||||
This is the preferred way to transfer ownership.
|
||||
*/
|
||||
void swapWith (ContentBodyBuffer& other);
|
||||
|
||||
/** Move bytes from the output to the input sequence.
|
||||
This will invalidate references to buffers.
|
||||
*/
|
||||
void commit (size_type n);
|
||||
|
||||
/** Returns a buffer to the input sequence. */
|
||||
ConstBuffers data () const;
|
||||
|
||||
/** Returns the size of the input sequence. */
|
||||
size_type size () const;
|
||||
|
||||
/** Reserve space in the output sequence.
|
||||
This also returns a buffer suitable for writing.
|
||||
*/
|
||||
MutableBuffers prepare (size_type n);
|
||||
|
||||
/** Reserve space in the output sequence. */
|
||||
void reserve (size_type n);
|
||||
|
||||
/** Release memory while preserving the input sequence. */
|
||||
void shrink_to_fit ();
|
||||
|
||||
private:
|
||||
typedef std::vector <void*> Handles;
|
||||
|
||||
size_type m_blocksize;
|
||||
size_type m_size;
|
||||
Handles m_handles;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,202 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_BASICS_FIXEDINPUTBUFFER_H_INCLUDED
|
||||
#define BEAST_ASIO_BASICS_FIXEDINPUTBUFFER_H_INCLUDED
|
||||
|
||||
#include <beast/asio/buffer_sequence.h>
|
||||
#include <array>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Represents a small, fixed size buffer.
|
||||
This provides a convenient interface for doing a bytewise
|
||||
verification/reject test on a handshake protocol.
|
||||
*/
|
||||
/** @{ */
|
||||
class FixedInputBuffer
|
||||
{
|
||||
protected:
|
||||
struct CtorParams
|
||||
{
|
||||
CtorParams (std::uint8_t const* begin_, std::size_t bytes_)
|
||||
: begin (begin_)
|
||||
, bytes (bytes_)
|
||||
{
|
||||
}
|
||||
|
||||
std::uint8_t const* begin;
|
||||
std::size_t bytes;
|
||||
};
|
||||
|
||||
FixedInputBuffer (CtorParams const& params)
|
||||
: m_begin (params.begin)
|
||||
, m_iter (m_begin)
|
||||
, m_end (m_begin + params.bytes)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
FixedInputBuffer (FixedInputBuffer const& other)
|
||||
: m_begin (other.m_begin)
|
||||
, m_iter (other.m_iter)
|
||||
, m_end (other.m_end)
|
||||
{
|
||||
}
|
||||
|
||||
FixedInputBuffer& operator= (FixedInputBuffer const& other)
|
||||
{
|
||||
m_begin = other.m_begin;
|
||||
m_iter = other.m_iter;
|
||||
m_end = other.m_end;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Returns the number of bytes consumed
|
||||
std::size_t used () const noexcept
|
||||
{
|
||||
return m_iter - m_begin;
|
||||
}
|
||||
|
||||
// Returns the size of what's remaining
|
||||
std::size_t size () const noexcept
|
||||
{
|
||||
return m_end - m_iter;
|
||||
}
|
||||
|
||||
void const* peek (std::size_t bytes)
|
||||
{
|
||||
return peek_impl (bytes, nullptr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool peek (T* t) const noexcept
|
||||
{
|
||||
return peek_impl (sizeof (T), t) != nullptr;
|
||||
}
|
||||
|
||||
bool consume (std::size_t bytes) noexcept
|
||||
{
|
||||
return read_impl (bytes, nullptr) != nullptr;
|
||||
}
|
||||
|
||||
bool read (std::size_t bytes) noexcept
|
||||
{
|
||||
return read_impl (bytes, nullptr) != nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool read (T* t) noexcept
|
||||
{
|
||||
return read_impl (sizeof (T), t) != nullptr;
|
||||
}
|
||||
|
||||
std::uint8_t operator[] (std::size_t index) const noexcept
|
||||
{
|
||||
bassert (index >= 0 && index < size ());
|
||||
return m_iter [index];
|
||||
}
|
||||
|
||||
// Reads an integraltype in network byte order
|
||||
template <typename IntegerType>
|
||||
bool readNetworkInteger (IntegerType* value)
|
||||
{
|
||||
// Must be an integral type!
|
||||
// not available in all versions of std:: unfortunately
|
||||
//static_bassert (std::is_integral <IntegerType>::value);
|
||||
IntegerType networkValue;
|
||||
if (! read (&networkValue))
|
||||
return false;
|
||||
*value = fromNetworkByteOrder (networkValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
void const* peek_impl (std::size_t bytes, void* buffer) const noexcept
|
||||
{
|
||||
if (size () >= bytes)
|
||||
{
|
||||
if (buffer != nullptr)
|
||||
memcpy (buffer, m_iter, bytes);
|
||||
return m_iter;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void const* read_impl (std::size_t bytes, void* buffer) noexcept
|
||||
{
|
||||
if (size () >= bytes)
|
||||
{
|
||||
if (buffer != nullptr)
|
||||
memcpy (buffer, m_iter, bytes);
|
||||
void const* data = m_iter;
|
||||
m_iter += bytes;
|
||||
return data;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::uint8_t const* m_begin;
|
||||
std::uint8_t const* m_iter;
|
||||
std::uint8_t const* m_end;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <int Bytes>
|
||||
class FixedInputBufferSize : public FixedInputBuffer
|
||||
{
|
||||
protected:
|
||||
struct SizedCtorParams
|
||||
{
|
||||
template <typename ConstBufferSequence, typename Storage>
|
||||
SizedCtorParams (ConstBufferSequence const& buffers, Storage& storage)
|
||||
{
|
||||
boost::asio::mutable_buffer buffer (boost::asio::buffer (storage));
|
||||
data = boost::asio::buffer_cast <std::uint8_t const*> (buffer);
|
||||
bytes = boost::asio::buffer_copy (buffer, buffers);
|
||||
}
|
||||
|
||||
operator CtorParams () const noexcept
|
||||
{
|
||||
return CtorParams (data, bytes);
|
||||
}
|
||||
|
||||
std::uint8_t const* data;
|
||||
std::size_t bytes;
|
||||
};
|
||||
|
||||
public:
|
||||
template <typename ConstBufferSequence>
|
||||
explicit FixedInputBufferSize (ConstBufferSequence const& buffers)
|
||||
: FixedInputBuffer (SizedCtorParams (buffers, m_storage))
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
std::array <std::uint8_t, Bytes> m_storage;
|
||||
boost::asio::mutable_buffer m_buffer;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,50 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
PeerRole::PeerRole (role_t role)
|
||||
: m_role (role)
|
||||
{
|
||||
}
|
||||
|
||||
String PeerRole::name () const noexcept
|
||||
{
|
||||
if (m_role == server)
|
||||
return "server";
|
||||
return "client";
|
||||
}
|
||||
|
||||
bool PeerRole::operator== (role_t role) const noexcept
|
||||
{
|
||||
return m_role == role;
|
||||
}
|
||||
|
||||
#if 0
|
||||
PeerRole::operator abstract_socket::handshake_type () const noexcept
|
||||
{
|
||||
if (m_role == server)
|
||||
return abstract_socket::server;
|
||||
return abstract_socket::client;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_BASICS_PEERROLE_H_INCLUDED
|
||||
#define BEAST_ASIO_BASICS_PEERROLE_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Identifies if the peer is a client or a server. */
|
||||
struct PeerRole
|
||||
{
|
||||
enum role_t
|
||||
{
|
||||
client,
|
||||
server
|
||||
};
|
||||
|
||||
PeerRole (role_t role);
|
||||
String name () const noexcept;
|
||||
bool operator== (role_t role) const noexcept;
|
||||
|
||||
private:
|
||||
role_t m_role;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,33 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
SSLContext::SSLContext (ContextType& context)
|
||||
: m_context (context)
|
||||
{
|
||||
}
|
||||
|
||||
SSLContext::~SSLContext ()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_BASICS_SSLCONTEXT_H_INCLUDED
|
||||
#define BEAST_ASIO_BASICS_SSLCONTEXT_H_INCLUDED
|
||||
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Simple base class for passing a context around.
|
||||
This lets derived classes hide their implementation from the headers.
|
||||
*/
|
||||
class SSLContext
|
||||
{
|
||||
public:
|
||||
virtual ~SSLContext ();
|
||||
|
||||
// Saves typing
|
||||
typedef boost::asio::ssl::context ContextType;
|
||||
|
||||
inline ContextType& get () noexcept
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
inline ContextType const& get () const noexcept
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
// implicit conversion
|
||||
inline operator ContextType& () noexcept
|
||||
{
|
||||
return get ();
|
||||
}
|
||||
|
||||
inline operator ContextType const& () const noexcept
|
||||
{
|
||||
return get ();
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit SSLContext (ContextType& context);
|
||||
|
||||
SSLContext(SSLContext const&) = delete;
|
||||
SSLContext& operator= (SSLContext const&) = delete;
|
||||
|
||||
ContextType& m_context;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,693 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/asio/wrap_handler.h>
|
||||
#include <beast/asio/placeholders.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <boost/asio/ssl/stream.hpp>
|
||||
#include <beast/cxx14/memory.h> // <memory>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
class HTTPClientType : public HTTPClientBase
|
||||
{
|
||||
public:
|
||||
class Session;
|
||||
|
||||
struct State
|
||||
{
|
||||
List <Session> list;
|
||||
};
|
||||
|
||||
typedef SharedData <State> SharedState;
|
||||
|
||||
SharedState m_state;
|
||||
Journal m_journal;
|
||||
double m_timeoutSeconds;
|
||||
std::size_t m_messageLimitBytes;
|
||||
std::size_t m_bufferSize;
|
||||
boost::asio::io_service m_io_service;
|
||||
WaitableEvent m_stopped;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
HTTPClientType (
|
||||
Journal journal,
|
||||
double timeoutSeconds,
|
||||
std::size_t messageLimitBytes,
|
||||
std::size_t bufferSize)
|
||||
: m_journal (journal)
|
||||
, m_timeoutSeconds (timeoutSeconds)
|
||||
, m_messageLimitBytes (messageLimitBytes)
|
||||
, m_bufferSize (bufferSize)
|
||||
, m_stopped (true, true) // manual reset, initially signaled
|
||||
{
|
||||
}
|
||||
|
||||
HTTPClientType(HTTPClientType const&) = delete;
|
||||
HTTPClientType& operator= (HTTPClientType const&) = delete;
|
||||
|
||||
~HTTPClientType ()
|
||||
{
|
||||
cancel();
|
||||
wait();
|
||||
}
|
||||
|
||||
result_type get (URL const& url)
|
||||
{
|
||||
result_type result;
|
||||
boost::asio::io_service io_service;
|
||||
async_get (io_service, url, std::bind (
|
||||
&HTTPClientType::handle_get, std::placeholders::_1, &result));
|
||||
io_service.run ();
|
||||
return result;
|
||||
}
|
||||
|
||||
void async_get (boost::asio::io_service& io_service, URL const& url,
|
||||
asio::shared_handler <void (result_type)> handler)
|
||||
{
|
||||
new Session (*this, io_service, url,
|
||||
handler, m_timeoutSeconds, m_messageLimitBytes, m_bufferSize);
|
||||
}
|
||||
|
||||
void cancel ()
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
for (List <Session>::iterator iter (state->list.begin());
|
||||
iter != state->list.end(); ++iter)
|
||||
iter->cancel();
|
||||
}
|
||||
|
||||
void wait()
|
||||
{
|
||||
m_stopped.wait();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void add (Session& session)
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
if (state->list.empty())
|
||||
m_stopped.reset();
|
||||
state->list.push_back (session);
|
||||
}
|
||||
|
||||
void remove (Session& session)
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
state->list.erase (state->list.iterator_to (session));
|
||||
if (state->list.empty())
|
||||
m_stopped.signal();
|
||||
}
|
||||
|
||||
static void handle_get (result_type const& result, result_type* dest)
|
||||
{
|
||||
*dest = result;
|
||||
}
|
||||
|
||||
Journal journal() const
|
||||
{
|
||||
return m_journal;
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service()
|
||||
{
|
||||
return m_io_service;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Helper function to get a const_buffer from a String. */
|
||||
static boost::asio::const_buffers_1 stringBuffer (String const& s)
|
||||
{
|
||||
return boost::asio::const_buffers_1 (s.getCharPointer (), s.length ());
|
||||
}
|
||||
|
||||
/** Helper function to fill out a Query from a URL. */
|
||||
template <typename Query>
|
||||
static Query queryFromURL (URL const& url)
|
||||
{
|
||||
if (url.port () != 0)
|
||||
{
|
||||
return Query (
|
||||
url.host(),
|
||||
url.port_string(),
|
||||
Query::numeric_service);
|
||||
}
|
||||
|
||||
return Query (
|
||||
url.host(),
|
||||
url.scheme());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
class Session
|
||||
: public SharedObject
|
||||
, public List <Session>::Node
|
||||
{
|
||||
public:
|
||||
typedef SharedPtr <Session> Ptr;
|
||||
typedef boost::asio::ip::tcp Protocol;
|
||||
typedef boost::system::error_code error_code;
|
||||
typedef HTTPClientBase::error_type error_type;
|
||||
typedef HTTPClientBase::value_type value_type;
|
||||
typedef HTTPClientBase::result_type result_type;
|
||||
|
||||
typedef Protocol::resolver resolver;
|
||||
typedef Protocol::socket socket;
|
||||
typedef resolver::query query;
|
||||
typedef resolver::iterator iterator;
|
||||
typedef iterator::value_type resolver_entry;
|
||||
|
||||
HTTPClientType& m_owner;
|
||||
boost::asio::io_service& m_io_service;
|
||||
boost::asio::io_service::strand m_strand;
|
||||
boost::asio::deadline_timer m_timer;
|
||||
resolver m_resolver;
|
||||
socket m_socket;
|
||||
asio::shared_handler <void (result_type)> m_handler;
|
||||
|
||||
URL m_url;
|
||||
boost::asio::ssl::context m_context;
|
||||
MemoryBlock m_buffer;
|
||||
HTTPResponseParser m_parser;
|
||||
std::size_t m_messageLimitBytes;
|
||||
std::size_t m_bytesReceived;
|
||||
|
||||
String m_get_string;
|
||||
WaitableEvent m_done;
|
||||
std::unique_ptr <abstract_socket> m_stream;
|
||||
|
||||
struct State
|
||||
{
|
||||
State () : complete (false)
|
||||
{
|
||||
}
|
||||
|
||||
bool complete;
|
||||
error_code error;
|
||||
SharedPtr <HTTPResponse> response;
|
||||
};
|
||||
typedef SharedData <State> SharedState;
|
||||
SharedState m_state;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
Session (HTTPClientType& owner,
|
||||
boost::asio::io_service& io_service,
|
||||
URL const& url,
|
||||
asio::shared_handler <void (result_type)> const& handler,
|
||||
double timeoutSeconds,
|
||||
std::size_t messageLimitBytes,
|
||||
std::size_t bufferSize)
|
||||
: m_owner (owner)
|
||||
, m_io_service (io_service)
|
||||
, m_strand (io_service)
|
||||
, m_timer (io_service)
|
||||
, m_resolver (io_service)
|
||||
, m_socket (io_service)
|
||||
, m_handler (handler)
|
||||
, m_url (url)
|
||||
, m_context (boost::asio::ssl::context::sslv23)
|
||||
, m_buffer (bufferSize)
|
||||
, m_messageLimitBytes (messageLimitBytes)
|
||||
, m_bytesReceived (0)
|
||||
{
|
||||
m_owner.add (*this);
|
||||
|
||||
// Configure the SSL context for certificate verification
|
||||
m_context.set_default_verify_paths ();
|
||||
m_context.set_options (
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
boost::asio::ssl::context::no_sslv3 |
|
||||
boost::asio::ssl::context::single_dh_use |
|
||||
boost::asio::ssl::context::default_workarounds);
|
||||
//m_context.set_verify_mode (boost::asio::ssl::verify_peer);
|
||||
|
||||
// Set the timer if a timeout is requested
|
||||
if (timeoutSeconds > 0)
|
||||
{
|
||||
m_timer.expires_from_now (
|
||||
boost::posix_time::milliseconds (
|
||||
long (timeoutSeconds * 1000)));
|
||||
|
||||
m_timer.async_wait (m_strand.wrap (asio::wrap_handler (
|
||||
std::bind (&Session::handle_timer, Ptr(this),
|
||||
asio::placeholders::error), m_handler)));
|
||||
}
|
||||
|
||||
// Start the operation on an io_service thread
|
||||
io_service.dispatch (m_strand.wrap (asio::wrap_handler (
|
||||
std::bind (&Session::handle_start, Ptr(this)), m_handler)));
|
||||
}
|
||||
|
||||
~Session ()
|
||||
{
|
||||
State result;
|
||||
{
|
||||
SharedState::ConstAccess state (m_state);
|
||||
result = *state;
|
||||
}
|
||||
|
||||
m_io_service.post (bind_handler (m_handler,
|
||||
std::make_pair (result.error, result.response)));
|
||||
|
||||
m_owner.remove (*this);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Called by the owner to cancel pending i/o.
|
||||
void cancel ()
|
||||
{
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
if (! state->complete)
|
||||
{
|
||||
state->complete = true;
|
||||
state->error = boost::asio::error::operation_aborted;
|
||||
}
|
||||
}
|
||||
|
||||
cancel_all();
|
||||
}
|
||||
|
||||
// Cancel all pending I/O
|
||||
void cancel_all ()
|
||||
{
|
||||
error_code ec;
|
||||
m_timer.cancel (ec);
|
||||
m_resolver.cancel ();
|
||||
m_socket.cancel (ec);
|
||||
m_socket.shutdown (socket::shutdown_both, ec);
|
||||
}
|
||||
|
||||
// Called by a completion handler when error is not eof or aborted.
|
||||
void failed (error_code ec)
|
||||
{
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
if (! state->complete)
|
||||
{
|
||||
state->complete = true;
|
||||
state->error = ec;
|
||||
state->response = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
cancel_all();
|
||||
}
|
||||
|
||||
void async_read_some ()
|
||||
{
|
||||
boost::asio::mutable_buffers_1 buf (
|
||||
m_buffer.getData (), m_buffer.getSize ());
|
||||
|
||||
m_stream->async_read_some (buf, m_strand.wrap (
|
||||
asio::wrap_handler (std::bind (&Session::handle_read,
|
||||
Ptr(this), asio::placeholders::error,
|
||||
asio::placeholders::bytes_transferred), m_handler)));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// Completion handlers
|
||||
//
|
||||
|
||||
// Called when the operation starts
|
||||
void handle_start ()
|
||||
{
|
||||
query q (queryFromURL <query> (m_url));
|
||||
|
||||
m_resolver.async_resolve (q, m_strand.wrap (
|
||||
asio::wrap_handler (std::bind (&Session::handle_resolve,
|
||||
Ptr(this), asio::placeholders::error,
|
||||
asio::placeholders::iterator), m_handler)));
|
||||
}
|
||||
|
||||
// Called when the timer completes
|
||||
void handle_timer (error_code ec)
|
||||
{
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
|
||||
if (ec != 0)
|
||||
{
|
||||
failed (ec);
|
||||
return;
|
||||
}
|
||||
|
||||
failed (boost::system::errc::make_error_code (
|
||||
boost::system::errc::timed_out));
|
||||
}
|
||||
|
||||
// Called when the resolver completes
|
||||
void handle_resolve (error_code ec, iterator iter)
|
||||
{
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
|
||||
if (ec != 0)
|
||||
{
|
||||
failed (ec);
|
||||
return;
|
||||
}
|
||||
|
||||
resolver_entry const entry (*iter);
|
||||
m_socket.async_connect (entry.endpoint (), m_strand.wrap (
|
||||
asio::wrap_handler (std::bind (&Session::handle_connect,
|
||||
Ptr(this), asio::placeholders::error), m_handler)));
|
||||
}
|
||||
|
||||
// Called when the connection attempt completes
|
||||
void handle_connect (error_code ec)
|
||||
{
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
|
||||
if (ec != 0)
|
||||
{
|
||||
failed (ec);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_url.scheme () == "https")
|
||||
{
|
||||
typedef boost::asio::ssl::stream <socket&> ssl_stream;
|
||||
m_stream = std::make_unique <
|
||||
socket_wrapper <ssl_stream>> (m_socket, m_context);
|
||||
/*
|
||||
m_stream->set_verify_mode (
|
||||
boost::asio::ssl::verify_peer |
|
||||
boost::asio::ssl::verify_fail_if_no_peer_cert);
|
||||
*/
|
||||
m_stream->async_handshake (abstract_socket::client, m_strand.wrap (
|
||||
asio::wrap_handler (std::bind (&Session::handle_handshake,
|
||||
Ptr(this), asio::placeholders::error), m_handler)));
|
||||
return;
|
||||
}
|
||||
|
||||
m_stream = std::make_unique <socket_wrapper <socket&>> (m_socket);
|
||||
handle_handshake (ec);
|
||||
}
|
||||
|
||||
// Called when the SSL handshake completes
|
||||
void handle_handshake (error_code ec)
|
||||
{
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
|
||||
if (ec != 0)
|
||||
{
|
||||
failed (ec);
|
||||
return;
|
||||
}
|
||||
|
||||
m_get_string =
|
||||
"GET " + m_url.path() + " HTTP/1.1\r\n" +
|
||||
"Host: " + m_url.host() + "\r\n" +
|
||||
"Accept: */*\r\n" +
|
||||
"Connection: close\r\n\r\n";
|
||||
|
||||
boost::asio::async_write (*m_stream, stringBuffer (
|
||||
m_get_string), m_strand.wrap (asio::wrap_handler (
|
||||
std::bind (&Session::handle_write, Ptr(this),
|
||||
asio::placeholders::error,
|
||||
asio::placeholders::bytes_transferred), m_handler)));
|
||||
|
||||
async_read_some ();
|
||||
}
|
||||
|
||||
// Called when the write operation completes
|
||||
void handle_write (error_code ec, std::size_t)
|
||||
{
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
|
||||
if (ec != 0)
|
||||
{
|
||||
failed (ec);
|
||||
return;
|
||||
}
|
||||
|
||||
if (! m_stream->needs_handshake ())
|
||||
m_socket.shutdown (socket::shutdown_send, ec);
|
||||
}
|
||||
|
||||
void handle_read (error_code ec,
|
||||
std::size_t bytes_transferred)
|
||||
{
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
|
||||
if (ec != 0)
|
||||
{
|
||||
failed (ec);
|
||||
return;
|
||||
}
|
||||
|
||||
m_bytesReceived += bytes_transferred;
|
||||
if (m_bytesReceived > m_messageLimitBytes)
|
||||
{
|
||||
failed (error_code (
|
||||
boost::system::errc::invalid_argument,
|
||||
boost::system::system_category ()));
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t const bytes_parsed (m_parser.process (
|
||||
m_buffer.getData (), bytes_transferred));
|
||||
|
||||
if (m_parser.error ())
|
||||
{
|
||||
failed (error_code (
|
||||
boost::system::errc::invalid_argument,
|
||||
boost::system::system_category ()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (bytes_parsed != bytes_transferred)
|
||||
{
|
||||
failed (error_code (
|
||||
boost::system::errc::invalid_argument,
|
||||
boost::system::system_category ()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ec == boost::asio::error::eof)
|
||||
m_parser.process_eof ();
|
||||
|
||||
if (m_parser.finished ())
|
||||
{
|
||||
if (m_stream->needs_handshake ())
|
||||
{
|
||||
m_stream->async_shutdown (m_strand.wrap (asio::wrap_handler (
|
||||
std::bind (&Session::handle_shutdown,
|
||||
Ptr(this), asio::placeholders::error), m_handler)));
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_shutdown (error_code ());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
async_read_some ();
|
||||
}
|
||||
|
||||
void handle_shutdown (error_code ec)
|
||||
{
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
|
||||
if (ec == boost::asio::error::eof)
|
||||
ec = error_code();
|
||||
|
||||
if (ec != 0)
|
||||
{
|
||||
failed (ec);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
if (! state->complete)
|
||||
{
|
||||
state->complete = true;
|
||||
state->response = m_parser.response();
|
||||
}
|
||||
}
|
||||
|
||||
cancel_all();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
HTTPClientBase* HTTPClientBase::New (Journal journal,
|
||||
double timeoutSeconds, std::size_t messageLimitBytes, std::size_t bufferSize)
|
||||
{
|
||||
return new HTTPClientType (
|
||||
journal, timeoutSeconds, messageLimitBytes, bufferSize);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class HTTPClient_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
class IoServiceThread : protected Thread
|
||||
{
|
||||
public:
|
||||
explicit IoServiceThread (String name = "io_service")
|
||||
: Thread (name)
|
||||
{
|
||||
}
|
||||
|
||||
~IoServiceThread ()
|
||||
{
|
||||
join ();
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service ()
|
||||
{
|
||||
return m_service;
|
||||
}
|
||||
|
||||
void start ()
|
||||
{
|
||||
startThread ();
|
||||
}
|
||||
|
||||
void join ()
|
||||
{
|
||||
this->waitForThreadToExit ();
|
||||
}
|
||||
|
||||
private:
|
||||
void run ()
|
||||
{
|
||||
m_service.run ();
|
||||
}
|
||||
|
||||
private:
|
||||
boost::asio::io_service m_service;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void print (HTTPMessage const& m)
|
||||
{
|
||||
for (int i = 0; i < m.headers().size(); ++i)
|
||||
{
|
||||
HTTPField const f (m.headers()[i]);
|
||||
std::stringstream ss;
|
||||
log <<
|
||||
"[ '" << f.name() <<
|
||||
"' , '" << f.value() + "' ]";
|
||||
}
|
||||
}
|
||||
|
||||
void print (HTTPClientBase::error_type error,
|
||||
HTTPClientBase::value_type const& response)
|
||||
{
|
||||
if (error != 0)
|
||||
{
|
||||
log <<
|
||||
"HTTPClient error: '" + error.message() << "'";
|
||||
}
|
||||
else if (! response.empty ())
|
||||
{
|
||||
log <<
|
||||
"Status: " <<
|
||||
String::fromNumber (response->status()).toStdString();
|
||||
|
||||
print (*response);
|
||||
}
|
||||
else
|
||||
{
|
||||
log <<
|
||||
"HTTPClient: no response";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void handle_get (HTTPClientBase::result_type result)
|
||||
{
|
||||
print (result.first, result.second);
|
||||
}
|
||||
|
||||
void testSync (String const& s, double timeoutSeconds)
|
||||
{
|
||||
std::unique_ptr <HTTPClientBase> client (
|
||||
HTTPClientBase::New (Journal(), timeoutSeconds));
|
||||
|
||||
HTTPClientBase::result_type const& result (
|
||||
client->get (parse_URL (s.toStdString ()).second));
|
||||
|
||||
print (result.first, result.second);
|
||||
}
|
||||
|
||||
void testAsync (String const& s, double timeoutSeconds)
|
||||
{
|
||||
IoServiceThread t;
|
||||
std::unique_ptr <HTTPClientBase> client (
|
||||
HTTPClientBase::New (Journal(), timeoutSeconds));
|
||||
|
||||
client->async_get (t.get_io_service (), parse_URL (s.toStdString ()).second,
|
||||
std::bind (&HTTPClient_test::handle_get, this,
|
||||
std::placeholders::_1));
|
||||
|
||||
t.start ();
|
||||
t.join ();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void run ()
|
||||
{
|
||||
testSync (
|
||||
"http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html",
|
||||
5);
|
||||
|
||||
testAsync (
|
||||
"http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html",
|
||||
5);
|
||||
|
||||
testAsync (
|
||||
"https://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html",
|
||||
5);
|
||||
|
||||
pass ();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE_MANUAL(HTTPClient,beast_asio,beast);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HTTPCLIENTTYPE_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPCLIENTTYPE_H_INCLUDED
|
||||
|
||||
#include <beast/asio/shared_handler.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
class HTTPClientBase
|
||||
{
|
||||
public:
|
||||
typedef boost::system::error_code error_type;
|
||||
typedef SharedPtr <HTTPResponse> value_type;
|
||||
typedef std::pair <error_type, value_type> result_type;
|
||||
|
||||
static HTTPClientBase* New (
|
||||
Journal journal = Journal(),
|
||||
double timeoutSeconds = 30,
|
||||
std::size_t messageLimitBytes = 256 * 1024,
|
||||
std::size_t bufferSize = 16 * 1024);
|
||||
|
||||
/** Destroy the client.
|
||||
This will cancel any pending i/o and block until all completion
|
||||
handlers have been called.
|
||||
*/
|
||||
virtual ~HTTPClientBase () { }
|
||||
|
||||
virtual result_type get (URL const& url) = 0;
|
||||
|
||||
/** Perform an asynchronous get on the specified URL.
|
||||
Handler will be called with this signature:
|
||||
void (result_type)
|
||||
*/
|
||||
virtual void async_get (boost::asio::io_service& io_service,
|
||||
URL const& url, asio::shared_handler <void (result_type)> handler) = 0;
|
||||
|
||||
/** Cancel all pending asynchronous operations. */
|
||||
virtual void cancel() = 0;
|
||||
|
||||
/** Block until all asynchronous i/o completes. */
|
||||
virtual void wait() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,147 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
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
|
||||
@@ -1,24 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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
|
||||
|
||||
#include <beast/module/asio/protocol/HandshakeDetectLogic.h>
|
||||
#include <beast/module/asio/protocol/InputParser.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** 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;
|
||||
|
||||
std::uint16_t sourcePort;
|
||||
std::uint16_t 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
|
||||
@@ -1,114 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
// Handshake for SSL 2
|
||||
//
|
||||
// http://tools.ietf.org/html/rfc5246#appendix-E.2
|
||||
//
|
||||
// std::uint8_t V2CipherSpec[3];
|
||||
// struct {
|
||||
// std::uint16_t msg_length;
|
||||
// std::uint8_t msg_type;
|
||||
// Version version; Should be 'ProtocolVersion'?
|
||||
// std::uint16_t cipher_spec_length;
|
||||
// std::uint16_t session_id_length;
|
||||
// std::uint16_t 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);
|
||||
|
||||
{
|
||||
std::uint8_t 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.
|
||||
//
|
||||
std::uint16_t 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 ();
|
||||
|
||||
std::uint8_t 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
|
||||
@@ -1,90 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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
|
||||
|
||||
#include <beast/ByteOrder.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
// 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)
|
||||
{
|
||||
std::uint16_t version;
|
||||
FixedInputBufferSize <bytesNeeded> in (buffer);
|
||||
|
||||
std::uint8_t 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);
|
||||
|
||||
std::uint16_t length;
|
||||
if (! in.read (&length))
|
||||
return;
|
||||
|
||||
length = fromNetworkByteOrder (length);
|
||||
|
||||
conclude ();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,220 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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
|
||||
|
||||
#include <beast/boost/get_pointer.h>
|
||||
#include <beast/asio/bind_handler.h>
|
||||
#include <beast/asio/wrap_handler.h>
|
||||
#include <beast/asio/placeholders.h>
|
||||
#include <beast/asio/shared_handler.h>
|
||||
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/streambuf.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** 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> BuffersType;
|
||||
|
||||
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 BuffersType::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 Allocator>
|
||||
void async_detect (Stream& stream,
|
||||
boost::asio::basic_streambuf <Allocator>& buffer,
|
||||
asio::shared_handler <void(error_code)> handler)
|
||||
{
|
||||
typedef AsyncOp <Allocator> Op;
|
||||
auto const op (std::make_shared <Op> (std::ref (m_logic),
|
||||
std::ref (stream), std::ref (buffer), std::cref (handler)));
|
||||
//op->start();
|
||||
stream.get_io_service().post (asio::wrap_handler (std::bind (
|
||||
&Op::start, op), handler));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Allocator>
|
||||
class AsyncOp
|
||||
: public std::enable_shared_from_this <AsyncOp <Allocator>>
|
||||
{
|
||||
public:
|
||||
typedef boost::asio::basic_streambuf <Allocator> BuffersType;
|
||||
|
||||
AsyncOp (HandshakeDetectLogicType <Logic>& logic, Stream& stream,
|
||||
BuffersType& buffer, asio::shared_handler <
|
||||
void(error_code)> const& handler)
|
||||
: m_logic (logic)
|
||||
, m_stream (stream)
|
||||
, m_buffer (buffer)
|
||||
, m_handler (handler)
|
||||
, m_continuation (false)
|
||||
{
|
||||
}
|
||||
|
||||
// Set breakpoint to prove it gets destroyed
|
||||
~AsyncOp ()
|
||||
{
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
async_read_some (error_code(), 0);
|
||||
}
|
||||
|
||||
void on_read (error_code ec, size_t bytes_transferred)
|
||||
{
|
||||
m_continuation = true;
|
||||
async_read_some (ec, bytes_transferred);
|
||||
}
|
||||
|
||||
void async_read_some (error_code ec, size_t bytes_transferred)
|
||||
{
|
||||
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 BuffersType::mutable_buffers_type buffers (
|
||||
m_buffer.prepare (needed - available));
|
||||
|
||||
m_stream.async_read_some (buffers, asio::wrap_handler (
|
||||
std::bind (&AsyncOp <Allocator>::on_read,
|
||||
this->shared_from_this(), asio::placeholders::error,
|
||||
asio::placeholders::bytes_transferred),
|
||||
m_handler, m_continuation));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t const consumed = m_logic.bytes_consumed ();
|
||||
m_buffer.consume (consumed);
|
||||
}
|
||||
|
||||
// Finalize with a call to the original handler.
|
||||
if (m_continuation)
|
||||
{
|
||||
m_handler (ec);
|
||||
return;
|
||||
}
|
||||
// Post, otherwise we would call the
|
||||
// handler from the initiating function.
|
||||
m_stream.get_io_service ().post (asio::bind_handler (
|
||||
m_handler, ec));
|
||||
}
|
||||
|
||||
private:
|
||||
HandshakeDetectLogicType <Logic>& m_logic;
|
||||
Stream& m_stream;
|
||||
BuffersType& m_buffer;
|
||||
asio::shared_handler <void(error_code)> m_handler;
|
||||
bool m_continuation;
|
||||
};
|
||||
|
||||
private:
|
||||
HandshakeDetectLogicType <Logic> m_logic;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,395 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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
|
||||
|
||||
#include <beast/module/asio/basics/FixedInputBuffer.h>
|
||||
#include <beast/strings/String.h>
|
||||
|
||||
#include <cctype>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
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
|
||||
{
|
||||
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; }
|
||||
explicit operator bool() const noexcept { return m_state == pass; }
|
||||
|
||||
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
|
||||
{
|
||||
std::uint32_t value;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Get <UInt32Str>
|
||||
{
|
||||
static State func (Input in, UInt32Str& t)
|
||||
{
|
||||
State state;
|
||||
std::uint32_t 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;
|
||||
|
||||
std::uint32_t 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
|
||||
{
|
||||
std::uint16_t 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 = std::uint16_t(v.value);
|
||||
return State::pass;
|
||||
}
|
||||
return State::fail;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// An unsigned 8 bit number expressed as a string
|
||||
struct UInt8Str
|
||||
{
|
||||
std::uint8_t 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 = std::uint8_t(v.value);
|
||||
return State::pass;
|
||||
}
|
||||
return State::fail;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// An dotted IPv4 address
|
||||
struct IPv4Address
|
||||
{
|
||||
std::uint8_t 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
|
||||
@@ -1,207 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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
|
||||
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** 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 <class Stream>
|
||||
class PrefilledReadStream
|
||||
{
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
static void throw_if (error_code const& ec)
|
||||
{
|
||||
throw boost::system::system_error (ec);
|
||||
}
|
||||
|
||||
public:
|
||||
PrefilledReadStream (PrefilledReadStream const&) = delete;
|
||||
PrefilledReadStream& operator= (PrefilledReadStream const&) = delete;
|
||||
|
||||
typedef std::remove_reference_t <Stream> 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 <class 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 <class Arg, class 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 <class ConstBufferSequence>
|
||||
void fill (ConstBufferSequence const& buffers)
|
||||
{
|
||||
// We don't assume the caller's buffers will
|
||||
// remain valid for the lifetime of this object.
|
||||
//
|
||||
m_buffer.commit (boost::asio::buffer_copy (
|
||||
m_buffer.prepare (boost::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;
|
||||
close (ec);
|
||||
throw_if (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 <class MutableBufferSequence>
|
||||
std::size_t read_some (MutableBufferSequence const& buffers)
|
||||
{
|
||||
error_code ec;
|
||||
std::size_t const amount = read_some (buffers, ec);
|
||||
throw_if (ec);
|
||||
return amount;
|
||||
}
|
||||
|
||||
template <class 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 <class ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers)
|
||||
{
|
||||
error_code ec;
|
||||
auto const amount (write_some (buffers, ec));
|
||||
throw_if (ec);
|
||||
return amount;
|
||||
}
|
||||
|
||||
template <class ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers,
|
||||
error_code& ec)
|
||||
{
|
||||
return m_next_layer.write_some (buffers, ec);
|
||||
}
|
||||
|
||||
template <class MutableBufferSequence, class ReadHandler>
|
||||
void async_read_some (MutableBufferSequence const& buffers,
|
||||
ReadHandler&& handler)
|
||||
{
|
||||
if (m_buffer.size () > 0)
|
||||
{
|
||||
auto const bytes_transferred (boost::asio::buffer_copy (
|
||||
buffers, m_buffer.data ()));
|
||||
m_buffer.consume (bytes_transferred);
|
||||
get_io_service ().post (bind_handler (
|
||||
std::forward <ReadHandler> (handler),
|
||||
error_code (), bytes_transferred));
|
||||
return;
|
||||
}
|
||||
m_next_layer.async_read_some (buffers,
|
||||
std::forward <ReadHandler> (handler));
|
||||
}
|
||||
|
||||
template <class ConstBufferSequence, class WriteHandler>
|
||||
void async_write_some (ConstBufferSequence const& buffers,
|
||||
WriteHandler&& handler)
|
||||
{
|
||||
m_next_layer.async_write_some (buffers,
|
||||
std::forward <WriteHandler> (handler));
|
||||
}
|
||||
|
||||
private:
|
||||
Stream m_next_layer;
|
||||
boost::asio::streambuf m_buffer;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,110 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
PeerTest::Result::Result ()
|
||||
: m_ec (TestPeerBasics::make_error (TestPeerBasics::errc::skipped))
|
||||
, m_message (m_ec.message ())
|
||||
{
|
||||
}
|
||||
|
||||
PeerTest::Result::Result (boost::system::error_code const& ec, String const& prefix)
|
||||
: m_ec (ec)
|
||||
, m_message ((prefix == String::empty) ? ec.message ()
|
||||
: prefix + ": " + ec.message ())
|
||||
{
|
||||
}
|
||||
|
||||
PeerTest::Result::Result (std::exception const& e, String const& prefix)
|
||||
: m_ec (TestPeerBasics::make_error (TestPeerBasics::errc::exceptioned))
|
||||
, m_message ((prefix == String::empty) ? e.what ()
|
||||
: prefix + ": " + e.what ())
|
||||
{
|
||||
}
|
||||
|
||||
bool PeerTest::Result::operator== (Result const& other) const noexcept
|
||||
{
|
||||
return m_ec == other.m_ec;
|
||||
}
|
||||
|
||||
bool PeerTest::Result::operator!= (Result const& other) const noexcept
|
||||
{
|
||||
return m_ec != other.m_ec;
|
||||
}
|
||||
|
||||
bool PeerTest::Result::failed () const noexcept
|
||||
{
|
||||
return TestPeerBasics::failure (m_ec);
|
||||
}
|
||||
|
||||
bool PeerTest::Result::timedout () const noexcept
|
||||
{
|
||||
return m_ec == TestPeerBasics::make_error (TestPeerBasics::errc::timeout);
|
||||
}
|
||||
|
||||
String PeerTest::Result::message () const noexcept
|
||||
{
|
||||
return m_message;
|
||||
}
|
||||
|
||||
bool PeerTest::Result::report (unit_test::suite& suite,
|
||||
bool reportPassingTests) const
|
||||
{
|
||||
bool const success = suite.expect (! failed (),
|
||||
message ().toStdString());
|
||||
if (reportPassingTests && success)
|
||||
suite.log <<
|
||||
"pass " + message().toStdString();
|
||||
return success;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
PeerTest::Results::Results ()
|
||||
: name ("unknown")
|
||||
{
|
||||
}
|
||||
|
||||
bool PeerTest::Results::operator== (Results const& other) const noexcept
|
||||
{
|
||||
return (client == other.client) && (server == other.server);
|
||||
}
|
||||
|
||||
bool PeerTest::Results::operator!= (Results const& other) const noexcept
|
||||
{
|
||||
return (client != other.client) || (server != other.server);
|
||||
}
|
||||
|
||||
bool PeerTest::Results::report (unit_test::suite& suite,
|
||||
bool beginTestCase) const
|
||||
{
|
||||
if (beginTestCase)
|
||||
suite.testcase << name.toStdString();
|
||||
bool success = true;
|
||||
if (! client.report (suite))
|
||||
success = false;
|
||||
if (! server.report (suite))
|
||||
success = false;
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,247 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TESTS_PEERTEST_H_INCLUDED
|
||||
#define BEAST_ASIO_TESTS_PEERTEST_H_INCLUDED
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Performs a test of two peers defined by template parameters. */
|
||||
class PeerTest
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
/** How long to wait before aborting a peer and reporting a timeout.
|
||||
|
||||
@note Aborting synchronous logics may cause undefined behavior.
|
||||
*/
|
||||
defaultTimeoutSeconds = 30
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Holds the test results for one peer.
|
||||
*/
|
||||
class Result
|
||||
{
|
||||
public:
|
||||
/** Default constructor indicates the test was skipped.
|
||||
*/
|
||||
Result ();
|
||||
|
||||
/** Construct from an error code.
|
||||
The prefix is prepended to the error message.
|
||||
*/
|
||||
explicit Result (boost::system::error_code const& ec, String const& prefix = "");
|
||||
explicit Result (std::exception const& e, String const& prefix = "");
|
||||
|
||||
/** Returns true if the error codes match (message is ignored).
|
||||
*/
|
||||
bool operator== (Result const& other) const noexcept;
|
||||
bool operator!= (Result const& other) const noexcept;
|
||||
|
||||
/** Returns true if the peer failed.
|
||||
*/
|
||||
bool failed () const noexcept;
|
||||
|
||||
/** Convenience for determining if the peer timed out.
|
||||
*/
|
||||
bool timedout () const noexcept;
|
||||
|
||||
/** Provides a descriptive message.
|
||||
This is suitable to pass to suite::fail.
|
||||
*/
|
||||
String message () const noexcept;
|
||||
|
||||
/** Report the result to a testsuite.
|
||||
A return value of true indicates success.
|
||||
*/
|
||||
bool report (unit_test::suite& suite,
|
||||
bool reportPassingTests = false) const;
|
||||
|
||||
private:
|
||||
boost::system::error_code m_ec;
|
||||
String m_message;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Holds the results for both peers in a test.
|
||||
*/
|
||||
struct Results
|
||||
{
|
||||
String name; // A descriptive name for this test case.
|
||||
Result client;
|
||||
Result server;
|
||||
|
||||
Results ();
|
||||
|
||||
/** Determines if client and server results match. */
|
||||
bool operator== (Results const& other) const noexcept;
|
||||
bool operator!= (Results const& other) const noexcept;
|
||||
|
||||
/** Report the results to a suite object.
|
||||
A return value of true indicates success.
|
||||
@param beginTestCase `true` to call test.beginTestCase for you
|
||||
*/
|
||||
bool report (unit_test::suite& suite, bool beginTestCase = true) const;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Test two peers and return the results.
|
||||
*/
|
||||
template <class Details, class ClientLogic, class ServerLogic,
|
||||
class ClientArg, class ServerArg>
|
||||
static Results run (ClientArg const& clientArg, ServerArg const& serverArg,
|
||||
int timeoutSeconds = defaultTimeoutSeconds)
|
||||
{
|
||||
Results results;
|
||||
|
||||
if (Process::isRunningUnderDebugger ())
|
||||
timeoutSeconds = -1;
|
||||
|
||||
try
|
||||
{
|
||||
TestPeerType <ServerLogic, Details> server (serverArg);
|
||||
|
||||
results.name = server.name () + Details::getArgName (serverArg);
|
||||
|
||||
try
|
||||
{
|
||||
TestPeerType <ClientLogic, Details> client (clientArg);
|
||||
|
||||
results.name << " / " + client.name () + Details::getArgName (clientArg);
|
||||
|
||||
try
|
||||
{
|
||||
server.start (timeoutSeconds);
|
||||
|
||||
try
|
||||
{
|
||||
client.start (timeoutSeconds);
|
||||
|
||||
boost::system::error_code const ec = client.join ();
|
||||
|
||||
results.client = Result (ec, client.name ());
|
||||
|
||||
try
|
||||
{
|
||||
boost::system::error_code const ec = server.join ();
|
||||
|
||||
results.server = Result (ec, server.name ());
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
results.server = Result (e, server.name ());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
results.server = Result (TestPeerBasics::make_error (
|
||||
TestPeerBasics::errc::exceptioned), server.name ());
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
results.server = Result (e, client.name ());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
results.client = Result (TestPeerBasics::make_error (
|
||||
TestPeerBasics::errc::exceptioned), client.name ());
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
results.server = Result (e, server.name ());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
results.server = Result (TestPeerBasics::make_error (
|
||||
TestPeerBasics::errc::exceptioned), server.name ());
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
results.server = Result (e, "client");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
results.client = Result (TestPeerBasics::make_error (
|
||||
TestPeerBasics::errc::exceptioned), "client");
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
results.server = Result (e, "server");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
results.server = Result (TestPeerBasics::make_error (
|
||||
TestPeerBasics::errc::exceptioned), "server");
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
template <class Details, class ClientLogic, class ServerLogic, class Arg>
|
||||
static Results run (Arg const& arg, int timeoutSeconds = defaultTimeoutSeconds)
|
||||
{
|
||||
return run <Details, ClientLogic, ServerLogic, Arg, Arg> (
|
||||
arg, arg, timeoutSeconds);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
template <class Details, class Arg>
|
||||
static void report_async (unit_test::suite& suite, Arg const& arg,
|
||||
int timeoutSeconds = defaultTimeoutSeconds,
|
||||
bool beginTestCase = true)
|
||||
{
|
||||
run <Details, TestPeerLogicAsyncClient, TestPeerLogicAsyncServer>
|
||||
(arg, timeoutSeconds).report (suite, beginTestCase);
|
||||
}
|
||||
|
||||
template <class Details, class Arg>
|
||||
static
|
||||
void
|
||||
report (unit_test::suite& suite, Arg const& arg,
|
||||
int timeoutSeconds = defaultTimeoutSeconds, bool beginTestCase = true)
|
||||
{
|
||||
run <Details, TestPeerLogicSyncClient, TestPeerLogicSyncServer>
|
||||
(arg, timeoutSeconds).report (suite, beginTestCase);
|
||||
|
||||
run <Details, TestPeerLogicAsyncClient, TestPeerLogicSyncServer>
|
||||
(arg, timeoutSeconds).report (suite, beginTestCase);
|
||||
|
||||
run <Details, TestPeerLogicSyncClient, TestPeerLogicAsyncServer>
|
||||
(arg, timeoutSeconds).report (suite, beginTestCase);
|
||||
|
||||
report_async <Details> (suite, arg, timeoutSeconds, beginTestCase);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,58 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TESTS_TESTPEER_H_INCLUDED
|
||||
#define BEAST_ASIO_TESTS_TESTPEER_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** An abstract peer for unit tests. */
|
||||
class TestPeer : public TestPeerBasics
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
// This should be long enough to go about your business.
|
||||
defaultTimeout = 10
|
||||
};
|
||||
|
||||
virtual ~TestPeer () { }
|
||||
|
||||
/** Get the name of this peer. */
|
||||
virtual String name () const = 0;
|
||||
|
||||
/** Start the peer.
|
||||
If timeoutSeconds is 0 or less, the wait is infinite.
|
||||
@param timeoutSeconds How long until the peer should be
|
||||
considered timed out.
|
||||
*/
|
||||
virtual void start (int timeoutSeconds = defaultTimeout) = 0;
|
||||
|
||||
/** Wait for the peer to finish.
|
||||
|
||||
@return Any error code generated during the server operation.
|
||||
*/
|
||||
virtual boost::system::error_code join () = 0;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,161 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
TestPeerBasics::Model::Model (model_t model)
|
||||
: m_model (model)
|
||||
{
|
||||
}
|
||||
|
||||
String TestPeerBasics::Model::name () const noexcept
|
||||
{
|
||||
if (m_model == async)
|
||||
return "async";
|
||||
return "sync";
|
||||
}
|
||||
|
||||
bool TestPeerBasics::Model::operator== (model_t model) const noexcept
|
||||
{
|
||||
return m_model == model;
|
||||
}
|
||||
|
||||
boost::asio::ssl::stream_base::handshake_type
|
||||
TestPeerBasics::to_handshake_type (PeerRole const& role)
|
||||
{
|
||||
if (role == PeerRole::client)
|
||||
return boost::asio::ssl::stream_base::client;
|
||||
return boost::asio::ssl::stream_base::server;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
boost::system::error_category const& TestPeerBasics::test_category () noexcept
|
||||
{
|
||||
struct test_category_type : boost::system::error_category
|
||||
{
|
||||
char const* name () const noexcept
|
||||
{
|
||||
return "TestPeer";
|
||||
}
|
||||
|
||||
std::string message (int ev) const
|
||||
{
|
||||
switch (ev)
|
||||
{
|
||||
case errc::none: return "No error";
|
||||
case errc::timeout: return "The timeout expired before the test could complete";
|
||||
case errc::unexpected: return "An unexpected test result was encountered";
|
||||
case errc::exceptioned: return "An unexpected exception was thrown";
|
||||
case errc::skipped: return "The test was skipped because of previous errors";
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
return "An unknown error";
|
||||
}
|
||||
|
||||
boost::system::error_condition default_error_condition (int ev) const noexcept
|
||||
{
|
||||
return boost::system::error_condition (ev, *this);
|
||||
}
|
||||
|
||||
bool equivalent (int ev, boost::system::error_condition const& condition) const noexcept
|
||||
{
|
||||
return default_error_condition (ev) == condition;
|
||||
}
|
||||
|
||||
bool equivalent (boost::system::error_code const& code, int ev) const noexcept
|
||||
{
|
||||
return *this == code.category() && code.value() == ev;
|
||||
}
|
||||
};
|
||||
|
||||
static test_category_type category;
|
||||
|
||||
return category;
|
||||
}
|
||||
|
||||
boost::system::error_code TestPeerBasics::make_error (errc::errc_t ev) noexcept
|
||||
{
|
||||
return boost::system::error_code (ev, test_category ());
|
||||
}
|
||||
|
||||
boost::system::error_code TestPeerBasics::make_error (errc::errc_t ev, boost::system::error_code& ec) noexcept
|
||||
{
|
||||
return ec = make_error (ev);
|
||||
}
|
||||
|
||||
bool TestPeerBasics::success (boost::system::error_code const& ec, bool eofIsOkay) noexcept
|
||||
{
|
||||
if (eofIsOkay && ec == boost::asio::error::eof)
|
||||
return true;
|
||||
if (! ec)
|
||||
return true;
|
||||
breakpoint (ec);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TestPeerBasics::failure (boost::system::error_code const& ec, bool eofIsOkay) noexcept
|
||||
{
|
||||
return ! success (ec, eofIsOkay);
|
||||
}
|
||||
|
||||
bool TestPeerBasics::expected (bool condition, boost::system::error_code& ec) noexcept
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
ec = boost::system::error_code ();
|
||||
}
|
||||
else
|
||||
{
|
||||
make_error (errc::unexpected, ec);
|
||||
breakpoint (ec);
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
bool TestPeerBasics::unexpected (bool condition, boost::system::error_code& ec) noexcept
|
||||
{
|
||||
return ! expected (condition, ec);
|
||||
}
|
||||
|
||||
bool TestPeerBasics::aborted (boost::system::error_code const& ec) noexcept
|
||||
{
|
||||
return ec == boost::asio::error::operation_aborted;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TestPeerBasics::breakpoint (boost::system::error_code const& ec)
|
||||
{
|
||||
// Set a breakpoint here to catch a failure
|
||||
std::string const& message = ec.message ();
|
||||
char const* const c_str = message.c_str ();
|
||||
|
||||
breakpoint (c_str);
|
||||
}
|
||||
|
||||
void TestPeerBasics::breakpoint (char const* const)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TESTS_TESTPEERBASICS_H_INCLUDED
|
||||
#define BEAST_ASIO_TESTS_TESTPEERBASICS_H_INCLUDED
|
||||
|
||||
#include <boost/asio/ssl/stream_base.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Common declarations for TestPeer.
|
||||
|
||||
@see TestPeer
|
||||
*/
|
||||
class TestPeerBasics
|
||||
{
|
||||
public:
|
||||
/** Selects between synchronous or asynchronous networking i/o usage. */
|
||||
struct Model
|
||||
{
|
||||
enum model_t
|
||||
{
|
||||
sync,
|
||||
async
|
||||
};
|
||||
|
||||
Model (model_t model);
|
||||
String name () const noexcept;
|
||||
bool operator== (model_t model) const noexcept;
|
||||
|
||||
private:
|
||||
model_t m_model;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Convert a PeerRole to boost::asio::ssl::stream_base_handshake_type */
|
||||
static boost::asio::ssl::stream_base::handshake_type to_handshake_type (PeerRole const& role);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Custom error codes for distinguishing test conditions
|
||||
struct errc
|
||||
{
|
||||
enum errc_t
|
||||
{
|
||||
none = 0,
|
||||
timeout, // The peer join timeout expired
|
||||
unexpected, // An expected condition was false
|
||||
exceptioned, // An exception occurred
|
||||
skipped // Test skipped due to previous errors
|
||||
};
|
||||
};
|
||||
|
||||
/** Returns the category that represents TestPeer errors.
|
||||
*/
|
||||
static boost::system::error_category const& test_category () noexcept;
|
||||
|
||||
/** Creates a test error_code from the give code value.
|
||||
*/
|
||||
static boost::system::error_code make_error (errc::errc_t ev) noexcept;
|
||||
|
||||
/** Sets the passed error_code to a test error and returns it.
|
||||
*/
|
||||
static boost::system::error_code make_error (errc::errc_t ev,
|
||||
boost::system::error_code& ec) noexcept;
|
||||
|
||||
/** Returns true if the error code indicates success.
|
||||
*/
|
||||
static bool success (boost::system::error_code const& ec, bool eofIsOkay = false) noexcept;
|
||||
|
||||
/** Returns false if the error code indicates failure.
|
||||
*/
|
||||
static bool failure (boost::system::error_code const& ec, bool eofIsOkay = false) noexcept;
|
||||
|
||||
/** Set the error based on a failed condition and return the success.
|
||||
*/
|
||||
static bool expected (bool condition, boost::system::error_code& ec) noexcept;
|
||||
|
||||
/** Set the error based on a passed condition and return the success.
|
||||
*/
|
||||
static bool unexpected (bool condition, boost::system::error_code& ec) noexcept;
|
||||
|
||||
/** Returns true if the error condition indicates an aborted I/O. */
|
||||
static bool aborted (boost::system::error_code const& ec) noexcept;
|
||||
|
||||
/** Provides a place to set a breakpoint to catch a failed condition. */
|
||||
static void breakpoint (boost::system::error_code const& ec);
|
||||
|
||||
/** Forces the variable to exist in the debugger. */
|
||||
static void breakpoint (char const* const message);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,52 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TESTS_TESTPEERDETAILS_H_INCLUDED
|
||||
#define BEAST_ASIO_TESTS_TESTPEERDETAILS_H_INCLUDED
|
||||
|
||||
#include <beast/asio/abstract_socket.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Base class of all detail objects. */
|
||||
class TestPeerDetails
|
||||
{
|
||||
public:
|
||||
virtual ~TestPeerDetails () { }
|
||||
|
||||
virtual String name () const = 0;
|
||||
|
||||
virtual abstract_socket& get_socket () = 0;
|
||||
|
||||
virtual abstract_socket& get_acceptor () = 0;
|
||||
|
||||
boost::asio::io_service& get_io_service ()
|
||||
{
|
||||
return m_io_service;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::asio::io_service m_io_service;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,115 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TESTS_TESTPEERDETAILSTCP_H_INCLUDED
|
||||
#define BEAST_ASIO_TESTS_TESTPEERDETAILSTCP_H_INCLUDED
|
||||
|
||||
#include <beast/asio/socket_wrapper.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Some predefined Detail classes for TestPeer */
|
||||
struct TcpDetails : public TestPeerDetails
|
||||
{
|
||||
protected:
|
||||
typedef boost::asio::ip::tcp protocol_type;
|
||||
typedef protocol_type::socket socket_type;
|
||||
typedef protocol_type::acceptor acceptor_type;
|
||||
typedef protocol_type::endpoint endpoint_type;
|
||||
typedef protocol_type::resolver resolver_type;
|
||||
|
||||
public:
|
||||
typedef protocol_type arg_type;
|
||||
typedef socket_type native_socket_type;
|
||||
typedef acceptor_type native_acceptor_type;
|
||||
|
||||
explicit TcpDetails (arg_type protocol)
|
||||
: m_protocol (protocol)
|
||||
, m_socket (get_io_service ())
|
||||
, m_acceptor (get_io_service ())
|
||||
, m_socket_wrapper (m_socket)
|
||||
, m_acceptor_wrapper (m_acceptor)
|
||||
{
|
||||
}
|
||||
|
||||
static String getArgName (arg_type arg)
|
||||
{
|
||||
if (arg == protocol_type::v4 ())
|
||||
return ".tcpv4";
|
||||
else if (arg == protocol_type::v6 ())
|
||||
return ".tcpv6";
|
||||
return ".tcp?";
|
||||
}
|
||||
|
||||
String name () const
|
||||
{
|
||||
return getArgName (m_protocol);
|
||||
}
|
||||
|
||||
abstract_socket& get_socket ()
|
||||
{
|
||||
return m_socket_wrapper;
|
||||
}
|
||||
|
||||
abstract_socket& get_acceptor ()
|
||||
{
|
||||
return m_acceptor_wrapper;
|
||||
}
|
||||
|
||||
socket_type& get_native_socket ()
|
||||
{
|
||||
return m_socket;
|
||||
}
|
||||
|
||||
acceptor_type& get_native_acceptor ()
|
||||
{
|
||||
return m_acceptor;
|
||||
}
|
||||
|
||||
endpoint_type get_endpoint (PeerRole role)
|
||||
{
|
||||
if (m_protocol == protocol_type::v4 ())
|
||||
{
|
||||
if (role == PeerRole::server)
|
||||
return endpoint_type (m_protocol, 1053);
|
||||
else
|
||||
return endpoint_type (boost::asio::ip::address_v4::loopback (), 1053);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (role == PeerRole::server)
|
||||
return endpoint_type (m_protocol, 1052);
|
||||
else
|
||||
return endpoint_type (boost::asio::ip::address_v6 ().from_string ("::1"), 1052);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
protocol_type m_protocol;
|
||||
socket_type m_socket;
|
||||
acceptor_type m_acceptor;
|
||||
socket_wrapper <socket_type&> m_socket_wrapper;
|
||||
socket_wrapper <acceptor_type&> m_acceptor_wrapper;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,69 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
TestPeerLogic::TestPeerLogic (abstract_socket& socket)
|
||||
: m_socket (&socket)
|
||||
{
|
||||
}
|
||||
|
||||
TestPeerLogic::error_code& TestPeerLogic::error () noexcept
|
||||
{
|
||||
return m_ec;
|
||||
}
|
||||
|
||||
TestPeerLogic::error_code const& TestPeerLogic::error () const noexcept
|
||||
{
|
||||
return m_ec;
|
||||
}
|
||||
|
||||
TestPeerLogic::error_code const& TestPeerLogic::error (error_code const& ec) noexcept
|
||||
{
|
||||
return m_ec = ec;
|
||||
}
|
||||
|
||||
abstract_socket& TestPeerLogic::socket () noexcept
|
||||
{
|
||||
return *m_socket;
|
||||
}
|
||||
|
||||
void TestPeerLogic::on_connect ()
|
||||
{
|
||||
pure_virtual ();
|
||||
}
|
||||
|
||||
void TestPeerLogic::on_connect_async (error_code const&)
|
||||
{
|
||||
pure_virtual ();
|
||||
}
|
||||
|
||||
void TestPeerLogic::finished ()
|
||||
{
|
||||
pure_virtual ();
|
||||
}
|
||||
|
||||
void TestPeerLogic::pure_virtual ()
|
||||
{
|
||||
fatal_error ("A TestPeerLogic function was called incorrectly");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TESTS_TESTPEERLOGIC_H_INCLUDED
|
||||
#define BEAST_ASIO_TESTS_TESTPEERLOGIC_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Interface for implementing the logic part of a peer test. */
|
||||
class TestPeerLogic : public TestPeerBasics
|
||||
{
|
||||
public:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
explicit TestPeerLogic (abstract_socket& socket);
|
||||
|
||||
error_code& error () noexcept;
|
||||
error_code const& error () const noexcept;
|
||||
error_code const& error (error_code const& ec) noexcept; // assigns to m_ec
|
||||
|
||||
abstract_socket& socket () noexcept;
|
||||
|
||||
virtual PeerRole get_role () const noexcept = 0;
|
||||
|
||||
virtual Model get_model () const noexcept = 0;
|
||||
|
||||
virtual void on_connect ();
|
||||
|
||||
virtual void on_connect_async (error_code const&);
|
||||
|
||||
// asynchronous logic classes
|
||||
// must call this when they are done
|
||||
virtual void finished ();
|
||||
|
||||
static void pure_virtual ();
|
||||
|
||||
private:
|
||||
error_code m_ec;
|
||||
abstract_socket* m_socket;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,164 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/asio/placeholders.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
TestPeerLogicAsyncClient::TestPeerLogicAsyncClient (abstract_socket& socket)
|
||||
: TestPeerLogic (socket)
|
||||
{
|
||||
}
|
||||
|
||||
PeerRole TestPeerLogicAsyncClient::get_role () const noexcept
|
||||
{
|
||||
return PeerRole::client;
|
||||
}
|
||||
|
||||
TestPeerBasics::Model TestPeerLogicAsyncClient::get_model () const noexcept
|
||||
{
|
||||
return Model::async;
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncClient::on_connect_async (error_code const& ec)
|
||||
{
|
||||
if (aborted (ec) || failure (error (ec)))
|
||||
return finished ();
|
||||
|
||||
if (socket ().needs_handshake ())
|
||||
{
|
||||
socket ().async_handshake (abstract_socket::client,
|
||||
std::bind (&TestPeerLogicAsyncClient::on_handshake, this,
|
||||
beast::asio::placeholders::error));
|
||||
}
|
||||
else
|
||||
{
|
||||
on_handshake (ec);
|
||||
}
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncClient::on_handshake (error_code const& ec)
|
||||
{
|
||||
if (aborted (ec) || failure (error (ec)))
|
||||
return finished ();
|
||||
|
||||
boost::asio::async_write (socket (), boost::asio::buffer ("hello", 5),
|
||||
std::bind (&TestPeerLogicAsyncClient::on_write, this,
|
||||
beast::asio::placeholders::error,
|
||||
beast::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncClient::on_write (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (aborted (ec) || failure (error (ec)))
|
||||
return finished ();
|
||||
|
||||
if (unexpected (bytes_transferred == 5, error ()))
|
||||
return finished ();
|
||||
|
||||
boost::asio::async_read_until (socket (), m_buf, std::string ("goodbye"),
|
||||
std::bind (&TestPeerLogicAsyncClient::on_read, this,
|
||||
beast::asio::placeholders::error, beast::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncClient::on_read (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (aborted (ec) || failure (error (ec)))
|
||||
return finished ();
|
||||
|
||||
if (unexpected (bytes_transferred == 7, error ()))
|
||||
return finished ();
|
||||
|
||||
// should check the data here?
|
||||
m_buf.consume (bytes_transferred);
|
||||
|
||||
// Fire up a 1 byte read, to wait for the server to
|
||||
// shut down its end of the connection.
|
||||
boost::asio::async_read (socket (), m_buf.prepare (1),
|
||||
std::bind (&TestPeerLogicAsyncClient::on_read_final, this,
|
||||
beast::asio::placeholders::error, beast::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncClient::on_read_final (error_code const& ec, std::size_t)
|
||||
{
|
||||
if (aborted (ec))
|
||||
return finished ();
|
||||
|
||||
// An eof is the normal case. The server should have closed shop.
|
||||
//
|
||||
if (ec == boost::asio::error::eof)
|
||||
{
|
||||
if (socket ().needs_handshake ())
|
||||
{
|
||||
socket ().async_shutdown (std::bind (&TestPeerLogicAsyncClient::on_shutdown, this,
|
||||
beast::asio::placeholders::error));
|
||||
}
|
||||
else
|
||||
{
|
||||
// on_shutdown will call finished ()
|
||||
error_code ec;
|
||||
on_shutdown (socket ().shutdown (abstract_socket::shutdown_send, ec));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we don't get eof, then there should be some other
|
||||
// error in there. We don't expect the server to send more bytes!
|
||||
//
|
||||
// This statement will do the following:
|
||||
//
|
||||
// error (ec) save ec into our error state
|
||||
// success () return true if ec represents success
|
||||
// unexpected () changes error() to 'unexpected' result if
|
||||
// success() returned true
|
||||
//
|
||||
unexpected (success (error (ec)), error ());
|
||||
|
||||
return finished ();
|
||||
}
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncClient::on_shutdown (error_code const& ec)
|
||||
{
|
||||
if (! aborted (ec))
|
||||
{
|
||||
if (success (error (ec), true))
|
||||
{
|
||||
if (socket ().needs_handshake ())
|
||||
{
|
||||
socket ().shutdown (abstract_socket::shutdown_send, error ());
|
||||
}
|
||||
|
||||
if (! error ())
|
||||
{
|
||||
if (success (socket ().close (error ())))
|
||||
{
|
||||
// doing nothing here is intended,
|
||||
// as the calls to success() may set error()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finished ();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TESTS_TESTPEERLOGICASYNCCLIENT_H_INCLUDED
|
||||
#define BEAST_ASIO_TESTS_TESTPEERLOGICASYNCCLIENT_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
class TestPeerLogicAsyncClient : public TestPeerLogic
|
||||
{
|
||||
public:
|
||||
explicit TestPeerLogicAsyncClient (abstract_socket& socket);
|
||||
PeerRole get_role () const noexcept;
|
||||
Model get_model () const noexcept;
|
||||
void on_connect_async (error_code const& ec);
|
||||
void on_handshake (error_code const& ec);
|
||||
void on_write (error_code const& ec, std::size_t bytes_transferred);
|
||||
void on_read (error_code const& ec, std::size_t bytes_transferred);
|
||||
void on_read_final (error_code const& ec, std::size_t);
|
||||
void on_shutdown (error_code const& ec);
|
||||
private:
|
||||
boost::asio::streambuf m_buf;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,126 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/asio/placeholders.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
TestPeerLogicAsyncServer::TestPeerLogicAsyncServer (abstract_socket& socket)
|
||||
: TestPeerLogic (socket)
|
||||
{
|
||||
}
|
||||
|
||||
PeerRole TestPeerLogicAsyncServer::get_role () const noexcept
|
||||
{
|
||||
return PeerRole::server;
|
||||
}
|
||||
|
||||
TestPeerBasics::Model TestPeerLogicAsyncServer::get_model () const noexcept
|
||||
{
|
||||
return Model::async;
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncServer::on_connect_async (error_code const& ec)
|
||||
{
|
||||
if (aborted (ec) || failure (error (ec)))
|
||||
return finished ();
|
||||
|
||||
if (socket ().needs_handshake ())
|
||||
{
|
||||
socket ().async_handshake (abstract_socket::server,
|
||||
std::bind (&TestPeerLogicAsyncServer::on_handshake, this,
|
||||
beast::asio::placeholders::error));
|
||||
}
|
||||
else
|
||||
{
|
||||
on_handshake (ec);
|
||||
}
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncServer::on_handshake (error_code const& ec)
|
||||
{
|
||||
if (aborted (ec) || failure (error (ec)))
|
||||
return finished ();
|
||||
|
||||
boost::asio::async_read_until (socket (), m_buf, std::string ("hello"),
|
||||
std::bind (&TestPeerLogicAsyncServer::on_read, this,
|
||||
beast::asio::placeholders::error, beast::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncServer::on_read (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (aborted (ec) || failure (error (ec)))
|
||||
return finished ();
|
||||
|
||||
if (unexpected (bytes_transferred == 5, error ()))
|
||||
return finished ();
|
||||
|
||||
boost::asio::async_write (socket (), boost::asio::buffer ("goodbye", 7),
|
||||
std::bind (&TestPeerLogicAsyncServer::on_write, this,
|
||||
beast::asio::placeholders::error, beast::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncServer::on_write (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (aborted (ec) || failure (error (ec)))
|
||||
return finished ();
|
||||
|
||||
if (unexpected (bytes_transferred == 7, error ()))
|
||||
return finished ();
|
||||
|
||||
if (socket ().needs_handshake ())
|
||||
{
|
||||
socket ().async_shutdown (std::bind (&TestPeerLogicAsyncServer::on_shutdown, this,
|
||||
beast::asio::placeholders::error));
|
||||
}
|
||||
else
|
||||
{
|
||||
// on_shutdown will call finished ()
|
||||
// we need another instance of ec so we can call on_shutdown()
|
||||
error_code ec;
|
||||
on_shutdown (socket ().shutdown (abstract_socket::shutdown_receive, ec));
|
||||
}
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncServer::on_shutdown (error_code const& ec)
|
||||
{
|
||||
if (! aborted (ec))
|
||||
{
|
||||
if (success (error (ec), true))
|
||||
{
|
||||
if (socket ().needs_handshake ())
|
||||
{
|
||||
socket ().shutdown (abstract_socket::shutdown_receive, error ());
|
||||
}
|
||||
|
||||
if (success (socket ().close (error ())))
|
||||
{
|
||||
// doing nothing here is intended,
|
||||
// as the calls to success() may set error()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finished ();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TESTS_TESTPEERLOGICASYNCSERVER_H_INCLUDED
|
||||
#define BEAST_ASIO_TESTS_TESTPEERLOGICASYNCSERVER_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
class TestPeerLogicAsyncServer : public TestPeerLogic
|
||||
{
|
||||
public:
|
||||
explicit TestPeerLogicAsyncServer (abstract_socket& socket);
|
||||
PeerRole get_role () const noexcept;
|
||||
Model get_model () const noexcept;
|
||||
void on_connect_async (error_code const& ec);
|
||||
void on_handshake (error_code const& ec);
|
||||
void on_read (error_code const& ec, std::size_t bytes_transferred);
|
||||
void on_write (error_code const& ec, std::size_t bytes_transferred);
|
||||
void on_shutdown (error_code const& ec);
|
||||
private:
|
||||
boost::asio::streambuf m_buf;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,42 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
TestPeerLogicProxyClient::TestPeerLogicProxyClient (abstract_socket& socket)
|
||||
: TestPeerLogicSyncClient (socket)
|
||||
{
|
||||
}
|
||||
|
||||
void TestPeerLogicProxyClient::on_pre_handshake ()
|
||||
{
|
||||
//ProxyHandshakeParser h;
|
||||
|
||||
static std::string line (
|
||||
"PROXY TCP4 255.255.255.255 255.255.255.255 65535 65535\r\n"
|
||||
// 56 chars
|
||||
);
|
||||
|
||||
boost::asio::write (socket (), boost::asio::buffer (line), error ());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TESTS_TESTPEERLOGICPROXYCLIENT_H_INCLUDED
|
||||
#define BEAST_ASIO_TESTS_TESTPEERLOGICPROXYCLIENT_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** A synchronous client logic that sends a PROXY protocol pre-handshake. */
|
||||
class TestPeerLogicProxyClient : public TestPeerLogicSyncClient
|
||||
{
|
||||
public:
|
||||
explicit TestPeerLogicProxyClient (abstract_socket& socket);
|
||||
void on_pre_handshake ();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,115 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
TestPeerLogicSyncClient::TestPeerLogicSyncClient (abstract_socket& socket)
|
||||
: TestPeerLogic (socket)
|
||||
{
|
||||
}
|
||||
|
||||
PeerRole TestPeerLogicSyncClient::get_role () const noexcept
|
||||
{
|
||||
return PeerRole::client;
|
||||
}
|
||||
|
||||
TestPeerBasics::Model TestPeerLogicSyncClient::get_model () const noexcept
|
||||
{
|
||||
return Model::sync;
|
||||
}
|
||||
|
||||
void TestPeerLogicSyncClient::on_connect ()
|
||||
{
|
||||
{
|
||||
// pre-handshake hook is optional
|
||||
on_pre_handshake ();
|
||||
if (failure (error ()))
|
||||
return ;
|
||||
}
|
||||
|
||||
if (socket ().needs_handshake ())
|
||||
{
|
||||
if (failure (socket ().handshake (to_handshake_type (get_role ()), error ())))
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::size_t const amount = boost::asio::write (
|
||||
socket (), boost::asio::buffer ("hello", 5), error ());
|
||||
|
||||
if (failure (error ()))
|
||||
return;
|
||||
|
||||
if (unexpected (amount == 5, error ()))
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
char data [7];
|
||||
|
||||
size_t const amount = boost::asio::read (
|
||||
socket (), boost::asio::buffer (data, 7), error ());
|
||||
|
||||
if (failure (error ()))
|
||||
return;
|
||||
|
||||
if (unexpected (amount == 7, error ()))
|
||||
return;
|
||||
|
||||
if (unexpected (memcmp (&data, "goodbye", 7) == 0, error ()))
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait for 1 byte which should never come. Instead,
|
||||
// the server should close its end and we will get eof
|
||||
{
|
||||
char data [1];
|
||||
boost::asio::read (socket (), boost::asio::buffer (data, 1), error ());
|
||||
|
||||
if (error () == boost::asio::error::eof)
|
||||
{
|
||||
error () = error_code ();
|
||||
}
|
||||
else if (unexpected (failure (error ()), error ()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (socket ().needs_handshake ())
|
||||
{
|
||||
if (failure (socket ().shutdown (error ()), true))
|
||||
return;
|
||||
error () = error_code ();
|
||||
}
|
||||
|
||||
if (failure (socket ().shutdown (abstract_socket::shutdown_send, error ())))
|
||||
return;
|
||||
|
||||
if (failure (socket ().close (error ())))
|
||||
return;
|
||||
}
|
||||
|
||||
void TestPeerLogicSyncClient::on_pre_handshake ()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TESTS_TESTPEERLOGICSYNCCLIENT_H_INCLUDED
|
||||
#define BEAST_ASIO_TESTS_TESTPEERLOGICSYNCCLIENT_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
class TestPeerLogicSyncClient : public TestPeerLogic
|
||||
{
|
||||
public:
|
||||
explicit TestPeerLogicSyncClient (abstract_socket& socket);
|
||||
PeerRole get_role () const noexcept;
|
||||
Model get_model () const noexcept;
|
||||
void on_connect ();
|
||||
virtual void on_pre_handshake ();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,86 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
TestPeerLogicSyncServer::TestPeerLogicSyncServer (abstract_socket& socket)
|
||||
: TestPeerLogic (socket)
|
||||
{
|
||||
}
|
||||
|
||||
PeerRole TestPeerLogicSyncServer::get_role () const noexcept
|
||||
{
|
||||
return PeerRole::server;
|
||||
}
|
||||
|
||||
TestPeerBasics::Model TestPeerLogicSyncServer::get_model () const noexcept
|
||||
{
|
||||
return Model::sync;
|
||||
}
|
||||
|
||||
void TestPeerLogicSyncServer::on_connect ()
|
||||
{
|
||||
if (socket ().needs_handshake ())
|
||||
{
|
||||
if (failure (socket ().handshake (to_handshake_type (get_role ()), error ())))
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
boost::asio::streambuf buf (5);
|
||||
std::size_t const amount = boost::asio::read_until (
|
||||
socket (), buf, "hello", error ());
|
||||
|
||||
if (failure (error ()))
|
||||
return;
|
||||
|
||||
if (unexpected (amount == 5, error ()))
|
||||
return;
|
||||
|
||||
if (unexpected (buf.size () == 5, error ()))
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::size_t const amount = boost::asio::write (
|
||||
socket (), boost::asio::buffer ("goodbye", 7), error ());
|
||||
|
||||
if (failure (error ()))
|
||||
return;
|
||||
|
||||
if (unexpected (amount == 7, error ()))
|
||||
return;
|
||||
}
|
||||
|
||||
if (socket ().needs_handshake ())
|
||||
{
|
||||
if (failure (socket ().shutdown (error ()), true))
|
||||
return;
|
||||
}
|
||||
|
||||
if (failure (socket ().shutdown (abstract_socket::shutdown_send, error ())))
|
||||
return;
|
||||
|
||||
if (failure (socket ().close (error ())))
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TESTS_TESTPEERLOGICSYNCSERVER_H_INCLUDED
|
||||
#define BEAST_ASIO_TESTS_TESTPEERLOGICSYNCSERVER_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
class TestPeerLogicSyncServer : public TestPeerLogic
|
||||
{
|
||||
public:
|
||||
explicit TestPeerLogicSyncServer (abstract_socket& socket);
|
||||
PeerRole get_role () const noexcept;
|
||||
Model get_model () const noexcept;
|
||||
void on_connect ();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,404 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TESTS_TESTPEERTYPE_H_INCLUDED
|
||||
#define BEAST_ASIO_TESTS_TESTPEERTYPE_H_INCLUDED
|
||||
|
||||
#include <beast/asio/placeholders.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
template <typename Logic, typename Details>
|
||||
class TestPeerType
|
||||
: public Details
|
||||
, public Logic
|
||||
, public TestPeer
|
||||
, public Thread
|
||||
{
|
||||
protected:
|
||||
// TestPeerDetails
|
||||
using Details::get_socket;
|
||||
using Details::get_acceptor;
|
||||
using Details::get_io_service;
|
||||
|
||||
// Details
|
||||
typedef typename Details::protocol_type protocol_type;
|
||||
typedef typename Details::socket_type socket_type;
|
||||
typedef typename Details::acceptor_type acceptor_type;
|
||||
typedef typename Details::endpoint_type endpoint_type;
|
||||
typedef typename Details::resolver_type resolver_type;
|
||||
|
||||
using Details::get_native_socket;
|
||||
using Details::get_native_acceptor;
|
||||
using Details::get_endpoint;
|
||||
|
||||
// TestPeerLogic
|
||||
typedef typename Logic::error_code error_code;
|
||||
using Logic::error;
|
||||
using Logic::socket;
|
||||
using Logic::get_role;
|
||||
using Logic::get_model;
|
||||
using Logic::on_connect;
|
||||
using Logic::on_connect_async;
|
||||
using Logic::pure_virtual;
|
||||
|
||||
typedef TestPeerType <Logic, Details> This;
|
||||
|
||||
public:
|
||||
// Details
|
||||
typedef typename Details::arg_type arg_type;
|
||||
typedef typename Details::native_socket_type native_socket_type;
|
||||
typedef typename Details::native_acceptor_type native_acceptor_type;
|
||||
|
||||
TestPeerType (arg_type const& arg)
|
||||
: Details (arg)
|
||||
, Logic (get_socket ())
|
||||
, Thread (name ())
|
||||
, m_timer (get_io_service ())
|
||||
, m_timer_set (false)
|
||||
, m_timed_out (false)
|
||||
{
|
||||
}
|
||||
|
||||
~TestPeerType ()
|
||||
{
|
||||
}
|
||||
|
||||
String name () const
|
||||
{
|
||||
return get_model ().name () + "_" + get_role ().name ();
|
||||
}
|
||||
|
||||
bool is_async () const noexcept
|
||||
{
|
||||
return get_model () == Model::async;
|
||||
}
|
||||
|
||||
void start (int timeoutSeconds)
|
||||
{
|
||||
if (is_async ())
|
||||
{
|
||||
if (timeoutSeconds > 0)
|
||||
{
|
||||
m_timer.expires_from_now (
|
||||
boost::posix_time::seconds (timeoutSeconds));
|
||||
|
||||
m_timer.async_wait (std::bind (&This::on_deadline,
|
||||
this, beast::asio::placeholders::error));
|
||||
|
||||
m_timer_set = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't set the timer, so infinite wait.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Save the value for when join() is called later.
|
||||
//
|
||||
m_timeoutSeconds = timeoutSeconds;
|
||||
}
|
||||
|
||||
startThread ();
|
||||
|
||||
// For server roles block until the thread is litening.
|
||||
//
|
||||
if (get_role () == PeerRole::server)
|
||||
m_listening.wait ();
|
||||
}
|
||||
|
||||
error_code join ()
|
||||
{
|
||||
if (is_async ())
|
||||
{
|
||||
// If the timer expired, then all our i/o should be
|
||||
// aborted and the thread will exit. So we will wait
|
||||
// for the thread for an infinite amount of time to
|
||||
// prevent undefined behavior. If an asynchronous logic
|
||||
// fails to end when the deadline timer expires, it
|
||||
// means there's a bug in the logic code.
|
||||
//
|
||||
m_join.wait ();
|
||||
|
||||
// The wait was satisfied but now the thread is still on
|
||||
// it's way out of the thread function, so block until
|
||||
// we know its done.
|
||||
//
|
||||
stopThread ();
|
||||
|
||||
// If we timed out then always report the custom error
|
||||
if (m_timed_out)
|
||||
return error (make_error (errc::timeout));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_timeoutSeconds > 0)
|
||||
{
|
||||
// Wait for the thread to finish
|
||||
//
|
||||
if (! m_join.wait (m_timeoutSeconds * 1000))
|
||||
{
|
||||
// Uh oh, we timed out! This is bad.
|
||||
// The synchronous model requires that the thread
|
||||
// be forcibly killed, which can result in undefined
|
||||
// behavior. It's best not to perform tests with
|
||||
// synchronous Logic objects that are supposed to time out.
|
||||
|
||||
// Force the thread to be killed, without waiting.
|
||||
stopThread (0);
|
||||
|
||||
error () = make_error (errc::timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
stopThread ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// They requested an infinite wait.
|
||||
//
|
||||
m_join.wait ();
|
||||
|
||||
stopThread ();
|
||||
}
|
||||
}
|
||||
|
||||
return error ();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void run ()
|
||||
{
|
||||
if (is_async ())
|
||||
{
|
||||
if (get_role () == PeerRole::server)
|
||||
{
|
||||
run_async_server ();
|
||||
}
|
||||
else if (get_role () == PeerRole::client)
|
||||
{
|
||||
run_async_client ();
|
||||
}
|
||||
else
|
||||
{
|
||||
error () = make_error (errc::unexpected);
|
||||
}
|
||||
}
|
||||
else if (get_model () == Model::sync)
|
||||
{
|
||||
if (get_role () == PeerRole::server)
|
||||
{
|
||||
run_sync_server ();
|
||||
}
|
||||
else if (get_role () == PeerRole::client)
|
||||
{
|
||||
run_sync_client ();
|
||||
}
|
||||
else
|
||||
{
|
||||
error () = make_error (errc::unexpected);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error () = make_error (errc::unexpected);
|
||||
}
|
||||
|
||||
get_io_service ().run ();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void run_sync_server ()
|
||||
{
|
||||
do_listen ();
|
||||
|
||||
if (failure (error ()))
|
||||
return finished ();
|
||||
|
||||
if (failure (get_acceptor ().accept (get_socket (), error ())))
|
||||
return finished ();
|
||||
|
||||
if (failure (get_acceptor ().close (error ())))
|
||||
return finished ();
|
||||
|
||||
this->on_connect ();
|
||||
|
||||
finished ();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void on_accept (error_code const& ec)
|
||||
{
|
||||
if (failure (ec))
|
||||
return finished ();
|
||||
|
||||
// Close the acceptor down so we don't block the io_service forever
|
||||
//
|
||||
// VFALCO NOTE what difference between cancel and close?
|
||||
#if 0
|
||||
if (failure (get_acceptor ().close (error ())))
|
||||
return finished ();
|
||||
#endif
|
||||
|
||||
this->on_connect_async (ec);
|
||||
}
|
||||
|
||||
void run_async_server ()
|
||||
{
|
||||
do_listen ();
|
||||
|
||||
if (failure (error ()))
|
||||
return finished ();
|
||||
|
||||
get_acceptor ().async_accept (get_socket (), std::bind (
|
||||
&This::on_accept, this, beast::asio::placeholders::error));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void run_sync_client ()
|
||||
{
|
||||
if (failure (get_native_socket ().connect (get_endpoint (get_role ()), error ())))
|
||||
return finished ();
|
||||
|
||||
this->on_connect ();
|
||||
|
||||
finished ();
|
||||
}
|
||||
|
||||
void run_async_client ()
|
||||
{
|
||||
get_native_socket ().async_connect (get_endpoint (get_role ()),
|
||||
std::bind (&Logic::on_connect_async, this,
|
||||
beast::asio::placeholders::error));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void do_listen ()
|
||||
{
|
||||
if (failure (get_native_acceptor ().open (
|
||||
get_endpoint (get_role ()).protocol (), error ())))
|
||||
return;
|
||||
|
||||
// VFALCO TODO Figure out how to not hard code boost::asio::socket_base
|
||||
if (failure (get_native_acceptor ().set_option (
|
||||
boost::asio::socket_base::reuse_address (true), error ())))
|
||||
return;
|
||||
|
||||
if (failure (get_native_acceptor ().bind (get_endpoint (get_role ()), error ())))
|
||||
return;
|
||||
|
||||
// VFALCO TODO Figure out how to not hard code boost::asio::socket_base
|
||||
if (failure (get_native_acceptor ().listen (
|
||||
boost::asio::socket_base::max_connections, error ())))
|
||||
return;
|
||||
|
||||
m_listening.signal ();
|
||||
}
|
||||
|
||||
void on_deadline (error_code const& ec)
|
||||
{
|
||||
m_timer_set = false;
|
||||
|
||||
if (ec != boost::asio::error::operation_aborted)
|
||||
{
|
||||
// We expect that ec represents no error, since the
|
||||
// timer expired and the operation wasn't aborted.
|
||||
//
|
||||
// If by some chance there is an error in ec we will
|
||||
// report that as an unexpected test condition instead
|
||||
// of a timeout.
|
||||
//
|
||||
if (expected (! ec, error ()))
|
||||
m_timed_out = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The timer was canceled because the Logic
|
||||
// called finished(), so we do nothing here.
|
||||
}
|
||||
|
||||
finished ();
|
||||
}
|
||||
|
||||
void finished ()
|
||||
{
|
||||
// If the server errors out it will come through
|
||||
// here so signal the listening event and unblock
|
||||
// the main thread.
|
||||
//
|
||||
if (get_role () == PeerRole::server)
|
||||
m_listening.signal ();
|
||||
|
||||
if (m_timer_set)
|
||||
{
|
||||
error_code ec;
|
||||
std::size_t const amount = m_timer.cancel (ec);
|
||||
|
||||
// The Logic should not have any I/O pending when
|
||||
// it calls finished, so amount should be zero.
|
||||
//
|
||||
unexpected (amount == 0, ec);
|
||||
}
|
||||
|
||||
// The logic should close the socket at the end of
|
||||
// its operations, unless it encounters an error.
|
||||
// Therefore, we will clean everything up and squelch
|
||||
// any errors, so that io_service::run() will return.
|
||||
//
|
||||
{
|
||||
error_code ec;
|
||||
this->get_socket ().close (ec);
|
||||
}
|
||||
|
||||
// The acceptor will not have closed if the client
|
||||
// never established the connection, so do it here.
|
||||
{
|
||||
error_code ec;
|
||||
this->get_acceptor ().close (ec);
|
||||
}
|
||||
|
||||
// Wake up the thread blocked on join()
|
||||
m_join.signal ();
|
||||
}
|
||||
|
||||
private:
|
||||
WaitableEvent m_listening;
|
||||
WaitableEvent m_join;
|
||||
|
||||
// for async peers
|
||||
boost::asio::deadline_timer m_timer;
|
||||
bool m_timer_set;
|
||||
bool m_timed_out;
|
||||
|
||||
// for sync peers
|
||||
int m_timeoutSeconds;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,54 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Test suite for the TestPeer family of objects. */
|
||||
class TestPeer_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
|
||||
template <typename Details, typename Arg >
|
||||
void testDetails (Arg const& arg = Arg ())
|
||||
{
|
||||
PeerTest::report <Details> (*this, arg, timeoutSeconds);
|
||||
}
|
||||
|
||||
void run ()
|
||||
{
|
||||
typedef boost::asio::ip::tcp protocol;
|
||||
testDetails <TcpDetails, TcpDetails::arg_type> (protocol::v4 ());
|
||||
testDetails <TcpDetails, TcpDetails::arg_type> (protocol::v6 ());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
timeoutSeconds = 10
|
||||
};
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(TestPeer,beast_asio,beast);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/core/diagnostic/FatalError.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef BEAST_CORE_FATALERROR_H_INCLUDED
|
||||
#define BEAST_CORE_FATALERROR_H_INCLUDED
|
||||
|
||||
#include <beast/strings/String.h>
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
@@ -39,7 +41,7 @@ class FatalError
|
||||
public:
|
||||
struct Reporter
|
||||
{
|
||||
virtual ~Reporter () { }
|
||||
virtual ~Reporter() = default;
|
||||
|
||||
/** Called when a fatal error is raised.
|
||||
|
||||
|
||||
@@ -60,7 +60,8 @@ public:
|
||||
ConstBufferType (void const* buffer, size_type bytes);
|
||||
*/
|
||||
template <typename ConstBufferType>
|
||||
std::vector <ConstBufferType> data () const
|
||||
std::vector <ConstBufferType>
|
||||
data () const
|
||||
{
|
||||
std::vector <ConstBufferType> buffers;
|
||||
buffers.reserve (m_buffers.size());
|
||||
@@ -81,7 +82,8 @@ public:
|
||||
MutableBufferType (void* buffer, size_type bytes);
|
||||
*/
|
||||
template <typename MutableBufferType>
|
||||
std::vector <MutableBufferType> prepare (size_type amount)
|
||||
std::vector <MutableBufferType>
|
||||
prepare (size_type amount)
|
||||
{
|
||||
std::vector <MutableBufferType> buffers;
|
||||
buffers.reserve (m_buffers.size());
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <ripple/basics/LoggedTimings.h>
|
||||
#include <ripple/basics/Sustain.h>
|
||||
#include <ripple/common/seconds_clock.h>
|
||||
#include <ripple/common/RippleSSLContext.h>
|
||||
#include <ripple/app/main/Tuning.h>
|
||||
#include <ripple/app/misc/ProofOfWorkFactory.h>
|
||||
#include <ripple/core/LoadFeeTrack.h>
|
||||
@@ -193,8 +194,8 @@ public:
|
||||
std::unique_ptr <DatabaseCon> mLedgerDB;
|
||||
std::unique_ptr <DatabaseCon> mWalletDB;
|
||||
|
||||
std::unique_ptr <beast::asio::SSLContext> m_peerSSLContext;
|
||||
std::unique_ptr <beast::asio::SSLContext> m_wsSSLContext;
|
||||
std::unique_ptr <SSLContext> m_peerSSLContext;
|
||||
std::unique_ptr <SSLContext> m_wsSSLContext;
|
||||
std::unique_ptr <Overlay> m_peers;
|
||||
std::unique_ptr <RPCDoor> m_rpcDoor;
|
||||
std::unique_ptr <WSDoor> m_wsPublicDoor;
|
||||
|
||||
@@ -20,20 +20,65 @@
|
||||
#ifndef RIPPLE_COMMON_SSLCONTEXT_H_INCLUDED
|
||||
#define RIPPLE_COMMON_SSLCONTEXT_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/basics/SSLContext.h>
|
||||
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#include <beast/utility/noexcept.h>
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Simple base class for passing a context around.
|
||||
This lets derived classes hide their implementation from the headers.
|
||||
*/
|
||||
class SSLContext
|
||||
{
|
||||
public:
|
||||
virtual ~SSLContext ();
|
||||
|
||||
// Saves typing
|
||||
typedef boost::asio::ssl::context ContextType;
|
||||
|
||||
inline ContextType& get () noexcept
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
inline ContextType const& get () const noexcept
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
// implicit conversion
|
||||
inline operator ContextType& () noexcept
|
||||
{
|
||||
return get ();
|
||||
}
|
||||
|
||||
inline operator ContextType const& () const noexcept
|
||||
{
|
||||
return get ();
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit SSLContext (ContextType& context);
|
||||
|
||||
SSLContext(SSLContext const&) = delete;
|
||||
SSLContext& operator= (SSLContext const&) = delete;
|
||||
|
||||
ContextType& m_context;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** The SSL contexts used by Ripple.
|
||||
|
||||
This is what Ripple uses for its secure connections. The ECDSA curve
|
||||
parameters are predefined and verified to be secure. The context is set to
|
||||
sslv23, Transport Layer Security / General. This is primarily used for peer to peer servers that don't care
|
||||
about certificates or identity verification.
|
||||
sslv23, Transport Layer Security / General. This is primarily used for
|
||||
peer to peer servers that don't care about certificates or
|
||||
identity verification.
|
||||
*/
|
||||
class RippleSSLContext : public beast::asio::SSLContext
|
||||
// VFALCO NOTE The comment above is out of date
|
||||
class RippleSSLContext : public SSLContext
|
||||
{
|
||||
public:
|
||||
/** Retrieve raw DH parameters.
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
#include <ripple/common/ResolverAsio.h>
|
||||
#include <beast/asio/IPAddressConversion.h>
|
||||
#include <beast/asio/placeholders.h>
|
||||
#include <beast/module/asio/asio.h>
|
||||
#include <beast/module/asio/AsyncObject.h>
|
||||
#include <beast/threads/WaitableEvent.h>
|
||||
#include <boost/asio.hpp>
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
|
||||
@@ -18,12 +18,10 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/common/RippleSSLContext.h>
|
||||
|
||||
#include <ripple/common/seconds_clock.h>
|
||||
#include <beast/container/aged_unordered_set.h>
|
||||
|
||||
#include <beast/module/core/diagnostic/FatalError.h>
|
||||
#include <beast/utility/static_initializer.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <sstream>
|
||||
|
||||
@@ -413,4 +411,17 @@ std::string RippleSSLContext::getRawDHParams (int keySize)
|
||||
return RippleSSLContextImp::getRawDHParams (keySize);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
SSLContext::SSLContext (ContextType& context)
|
||||
: m_context (context)
|
||||
{
|
||||
}
|
||||
|
||||
SSLContext::~SSLContext ()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef RIPPLE_HTTP_SERVER_H_INCLUDED
|
||||
#define RIPPLE_HTTP_SERVER_H_INCLUDED
|
||||
|
||||
#include <ripple/common/RippleSSLContext.h>
|
||||
#include <beast/net/IPEndpoint.h>
|
||||
#include <beast/module/asio/basics/SSLContext.h>
|
||||
#include <beast/utility/Journal.h>
|
||||
#include <beast/utility/PropertyStream.h>
|
||||
#include <boost/system/error_code.hpp>
|
||||
@@ -47,13 +47,13 @@ struct Port
|
||||
Security security;
|
||||
std::uint16_t port;
|
||||
beast::IP::Endpoint addr;
|
||||
beast::asio::SSLContext* context;
|
||||
SSLContext* context;
|
||||
|
||||
Port ();
|
||||
Port (Port const& other);
|
||||
Port& operator= (Port const& other);
|
||||
Port (std::uint16_t port_, beast::IP::Endpoint const& addr_,
|
||||
Security security_, beast::asio::SSLContext* context_);
|
||||
Security security_, SSLContext* context_);
|
||||
};
|
||||
|
||||
bool operator== (Port const& lhs, Port const& rhs);
|
||||
|
||||
@@ -21,10 +21,9 @@
|
||||
#define RIPPLE_HTTP_SESSION_H_INCLUDED
|
||||
|
||||
#include <beast/http/message.h>
|
||||
#include <beast/smart_ptr/SharedPtr.h>
|
||||
#include <beast/net/IPEndpoint.h>
|
||||
#include <beast/utility/Journal.h>
|
||||
#include <beast/module/asio/http/HTTPRequest.h>
|
||||
#include <beast/module/asio/HTTPRequest.h>
|
||||
#include <ostream>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -45,7 +45,7 @@ Port& Port::operator= (Port const& other)
|
||||
}
|
||||
|
||||
Port::Port (std::uint16_t port_, beast::IP::Endpoint const& addr_,
|
||||
Security security_, beast::asio::SSLContext* context_)
|
||||
Security security_, SSLContext* context_)
|
||||
: security (security_)
|
||||
, port (port_)
|
||||
, addr (addr_)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#define RIPPLE_SITEFILES_LOGIC_H_INCLUDED
|
||||
|
||||
#include <beast/http/URL.h>
|
||||
#include <beast/module/asio/http/HTTPResponse.h> // DEPRECATED
|
||||
#include <beast/module/asio/HTTPResponse.h> // DEPRECATED
|
||||
#include <boost/regex.hpp>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
Reference in New Issue
Block a user