Remove lowest_layer, add get_lowest_layer (API Change):

fix #1417

* New get_lowest_layer free function works for any object
* New lowest_layer_type trait works for any object
* New examples and documentation on layered streams

API Changes:

* The member function lowest_layer is removed from all
  types provided by the library:

Actions Required:

* Call the free function get_lowest_layer instead of
  member lowest_layer.
This commit is contained in:
Vinnie Falco
2019-01-10 20:25:10 -08:00
parent ff32f44682
commit 6a658b5c3a
66 changed files with 1130 additions and 125 deletions

View File

@@ -118,6 +118,9 @@ matrix:
- TOOLSET=clang
- COMPILER=clang++
- CXXSTD=14
before_install:
- brew install openssl
- export OPENSSL_ROOT=$(brew --prefix openssl)
install:
- export BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
@@ -198,10 +201,13 @@ install:
script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
cp libs/beast/tools/user-config.jam ~/user-config.jam
- |-
echo "using $TOOLSET : : $COMPILER ;" >> ~/user-config.jam
- cd ../boost-root
- libs/beast/tools/retry.sh libs/beast/tools/build-and-test.sh
after_script:
- cat nohup.out || echo "nohup.out already deleted"

View File

@@ -1,3 +1,10 @@
Version 208:
* Add get_lowest_layer free function
* Add lowest_layer_type metafunction
--------------------------------------------------------------------------------
Version 207
* Send from the strand

View File

@@ -8,6 +8,7 @@
#
cmake_minimum_required (VERSION 3.5.1)
cmake_policy (SET CMP0074 NEW)
project (Beast VERSION 207)

82
Jamfile
View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
# Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,7 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
import os ;
import feature ;
import boost ;
@@ -16,39 +17,19 @@ import ../../config/checks/config : requires ;
boost.use-project ;
if [ os.name ] = SOLARIS
{
lib socket ;
lib nsl ;
}
else if [ os.name ] = NT
{
lib ws2_32 ;
lib mswsock ;
}
else if [ os.name ] = HPUX
{
lib ipv6 ;
}
else if [ os.name ] = QNXNTO
{
lib socket ;
}
else if [ os.name ] = HAIKU
{
lib network ;
}
lib socket ; # SOLARIS, QNXNTO
lib nsl ; # SOLARIS
lib ws2_32 ; # NT
lib mswsock ; # NT
lib ipv6 ; # HPUX
lib network ; # HAIKU
if [ os.name ] = NT
{
lib ssl : : <name>ssleay32 ;
lib crypto : : <name>libeay32 ;
}
else
{
lib ssl ;
lib crypto ;
}
lib ssl ;
lib crypto ;
lib crypt32 ;
lib ssl : : <target-os>windows <name>ssleay32 ;
lib crypto : : <target-os>windows <name>libeay32 ;
variant coverage
: debug
@@ -87,21 +68,24 @@ lib static_asio
<define>BOOST_ASIO_DISABLE_BOOST_REGEX=1
<define>BOOST_ASIO_SEPARATE_COMPILATION
<define>BOOST_COROUTINES_NO_DEPRECATION_WARNING=1
<os>NT:<define>_WIN32_WINNT=0x0601
<target-os>windows:<define>_WIN32_WINNT=0x0501
<link>static
;
project /boost/beast
: requirements
<implicit-dependency>/boost//headers
<include>.
<include>./test/extras/include
<library>/boost/coroutine//boost_coroutine
<library>/boost/filesystem//boost_filesystem
<library>static_asio
<implicit-dependency>/boost//headers
<threading>multi
<runtime-link>shared
<debug-symbols>on
<runtime-link>shared
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
<define>BOOST_ALL_NO_LIB=1
<define>BOOST_ASIO_NO_DEPRECATED=1
<define>BOOST_ASIO_DISABLE_BOOST_ARRAY=1
@@ -116,13 +100,23 @@ project /boost/beast
<toolset>msvc:<define>_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING
<toolset>msvc:<define>_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING
<toolset>msvc,<variant>release:<cxxflags>"/Ob2 /Oi /Ot"
<os>SOLARIS:<library>socket
<os>SOLARIS:<library>nsl
<os>NT:<define>_WIN32_WINNT=0x0601
<os>NT,<toolset>cw:<library>ws2_32
<os>NT,<toolset>cw:<library>mswsock
<os>NT,<toolset>gcc:<library>ws2_32
<os>NT,<toolset>gcc:<library>mswsock
<os>NT,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
<target-os>linux:<define>_XOPEN_SOURCE=600
<target-os>linux:<define>_GNU_SOURCE=1
<target-os>solaris:<define>_XOPEN_SOURCE=500
<target-os>solaris:<define>__EXTENSIONS__
<target-os>solaris:<library>socket
<target-os>solaris:<library>nsl
<target-os>windows:<define>_WIN32_WINNT=0x0501
<target-os>windows,<toolset>cw:<library>ws2_32
<target-os>windows,<toolset>cw:<library>mswsock
<target-os>windows,<toolset>gcc:<library>ws2_32
<target-os>windows,<toolset>gcc:<library>mswsock
<target-os>windows,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
<target-os>hpux,<toolset>gcc:<define>_XOPEN_SOURCE_EXTENDED
<target-os>hpux:<library>ipv6
<target-os>qnxnto:<library>socket
<target-os>haiku:<library>network
: usage-requirements
;

View File

@@ -109,6 +109,7 @@
[def __serializer__ [link beast.ref.boost__beast__http__serializer `serializer`]]
[def __flat_static_buffer__ [link beast.ref.boost__beast__flat_static_buffer `flat_static_buffer`]]
[def __flat_static_buffer_base__ [link beast.ref.boost__beast__flat_static_buffer_base `flat_static_buffer_base`]]
[def __websocket_stream__ [link beast.ref.boost__beast__websocket__stream `websocket::stream`]]
[import ../../example/common/detect_ssl.hpp]
[import ../../example/doc/http_examples.hpp]
@@ -120,6 +121,7 @@
[import ../../test/doc/exemplars.cpp]
[import ../../test/doc/core_snippets.cpp]
[import ../../test/doc/core_3_layers.cpp]
[import ../../test/doc/http_snippets.cpp]
[import ../../test/doc/websocket_snippets.cpp]

View File

@@ -94,9 +94,10 @@ effect:
[include 03_core/1_refresher.qbk]
[include 03_core/2_streams.qbk]
[include 03_core/3_buffers.qbk]
[include 03_core/4_files.qbk]
[include 03_core/5_composed.qbk]
[include 03_core/6_detect_ssl.qbk]
[include 03_core/3_layers.qbk]
[include 03_core/4_buffers.qbk]
[include 03_core/5_files.qbk]
[include 03_core/6_composed.qbk]
[include 03_core/7_detect_ssl.qbk]
[endsect]

View File

@@ -0,0 +1,115 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Official repository: https://github.com/boostorg/beast
]
[section Layered Streams]
Networking's __ssl_stream__ is a class template meeting the requirements
of both synchronous and asynchronous read and write streams, implemented
in terms of a "next layer" object whose type is determined by a class
template parameter. The SSL stream constructs an instance of the next
layer object internally, while allowing external access through the
observer `net::ssl::stream::next_layer()`. This declares an SSL stream
which uses a regular TCP/IP socket as the next layer:
[code_core_3_layers_1]
Objects using this design pattern are referred to in networking as "a
stack of stream layers". In Beast we use the term ['layered stream],
although the property of having a next layer is not exclusive to streams.
As with the SSL stream, __websocket_stream__ is a class template
parameterized on a next layer object. This declares a websocket
stream which uses a regular TCP/IP socket as the next layer:
[code_core_3_layers_2]
If a Secure WebSockets stream is desired, this is accomplished simply
by changing the type of the next layer and adjusting the constructor
arguments to match:
[code_core_3_layers_3]
Higher level abstractions can be developed in this fashion by nesting
stream layers to arbitrary degree. The stack of stream layers effectively
forms a compile-time singly linked list. The object at the end of
this list is called the ['lowest layer], and is special from the
others because it typically represents the underlying socket.
Beast comes with several layered stream wrappers, as well as
facilities for authoring and working with layered streams:
[table Layered Stream Algorithms and Types
[[Name][Description]]
[[
[link beast.ref.boost__beast__timeout_stream `timeout_stream`]
[link beast.ref.boost__beast__basic_timeout_stream `basic_timeout_stream`]
][
A timeout stream meets the requirements for synchronous and asynchronous
read and write streams, and additionally provides configurable timeouts
for logical operations that include reading, writing, and/or connecting.
]]
[[
[link beast.ref.boost__beast__buffered_read_stream `buffered_read_stream`]
][
A timeout stream meets the requirements for synchronous and asynchronous
read and write streams, and additionally implements configurable buffering
for reads.
]]
[[
[link beast.ref.boost__beast__flat_stream `flat_stream`]
][
A flat stream operates as a transparent stream which helps to work around
a limitation of `net::ssl::stream`. It is used in the implementation
of [link beast.ref.boost__beast__ssl_stream `ssl_stream`].
]]
[[
[link beast.ref.boost__beast__http__icy_stream `http::icy_stream`]
][
An ICY stream transparently converts the non-standard "ICY 200 OK"
HTTP response from Shoutcast servers into a conforming 200 level
HTTP response.
]]
[[
[link beast.ref.boost__beast__ssl_stream `ssl_stream`]
][
The SSL stream is a drop-in replacement for `net::ssl::stream` which
allows for move-construction and move-assignment, and also implements
a work-around for a performance limitation in the original SSL stream.
]]
[[
[link beast.ref.boost__beast__get_lowest_layer `get_lowest_layer`]
][
Returns the lowest layer in a stack of stream layers by recursively
calling the `next_layer` member function on each object until reaching
an object which lacks the member. This example
puts a layered stream into non-blocking mode by retrieving the
TCP/IP socket in the lowest layer and changing the socket option:
[code_core_3_layers_4]
]]
[[
[link beast.ref.boost__beast__lowest_layer_type `lowest_layer_type`]
][
A metafunction to return the type of the lowest layer used in
a type representing a stack of stream layers. This is the type
of reference returned by
[link beast.ref.boost__beast__get_lowest_layer `get_lowest_layer`]
]]
]
[heading Example]
This example shows the definition of a layered stream which keeps individual
counts of the total number of bytes read from and written to the next layer.
It meets the requirements for synchronous and asynchronous read and write
streams:
[code_core_3_layers_5]
[endsect]

View File

@@ -33,7 +33,7 @@ implementation strategies:
size of the character sequence. This is the implementation approach
currently offered by __multi_buffer__.
[heading Associated Types]
[heading Associated With]
* `boost::asio::is_dynamic_buffer`
* __ConstBufferSequence__

View File

@@ -12,8 +12,8 @@
A stream in the context of Beast and networking, represents a full-duplex
connection between two programs or hosts, where data represented as
bytes may be received reliably in the same order they were written.
Streams can be support synchronous transfers, asynchronous transfers,
or both.
Streams may support any combination of synchronous and/or asynchronous
reading and writing.
Stream concepts are based on named requirements in networking:

View File

@@ -234,7 +234,9 @@
<member><link linkend="beast.ref.boost__beast__buffers_range">buffers_range</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_range_ref">buffers_range_ref</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_to_string">buffers_to_string</link></member>
<member><link linkend="beast.ref.boost__beast__close_socket">close_socket</link></member>
<member><link linkend="beast.ref.boost__beast__generic_category">generic_category</link></member>
<member><link linkend="beast.ref.boost__beast__get_lowest_layer">get_lowest_layer</link></member>
<member><link linkend="beast.ref.boost__beast__iequals">iequals</link></member>
<member><link linkend="beast.ref.boost__beast__make_printable">make_printable</link></member>
<member><link linkend="beast.ref.boost__beast__ostream">ostream</link></member>
@@ -248,6 +250,7 @@
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__buffers_type">buffers_type</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_iterator_type">buffers_iterator_type</link></member>
<member><link linkend="beast.ref.boost__beast__lowest_layer_type">lowest_layer_type</link></member>
<member><link linkend="beast.ref.boost__beast__has_get_executor">has_get_executor</link></member>
<member><link linkend="beast.ref.boost__beast__is_async_read_stream">is_async_read_stream</link></member>
<member><link linkend="beast.ref.boost__beast__is_async_write_stream">is_async_write_stream</link></member>

View File

@@ -9,5 +9,5 @@
build-project server ;
# VFALCO How do I make this work on Windows and if OpenSSL is not available?
#build-project server-flex ;
# SSL
build-project server-flex ;

View File

@@ -23,7 +23,7 @@ if (OPENSSL_FOUND)
set_property(TARGET advanced-server-flex PROPERTY FOLDER "example-advanced-server")
target_link_libraries (advanced-server-flex
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe advanced-server-flex :

View File

@@ -12,7 +12,7 @@ build-project coro ;
build-project crawl ;
build-project sync ;
# VFALCO How do I make this work on Windows and if OpenSSL is not available?
#build-project async-ssl ;
#build-project coro-ssl ;
#build-project sync-ssl ;
# SSL
build-project async-ssl ;
build-project coro-ssl ;
build-project sync-ssl ;

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET http-client-async-ssl PROPERTY FOLDER "example-http-client")
target_link_libraries (http-client-async-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe http-client-async-ssl :

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET http-client-coro-ssl PROPERTY FOLDER "example-http-client")
target_link_libraries (http-client-coro-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe http-client-coro-ssl :

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET http-client-sync-ssl PROPERTY FOLDER "example-http-client")
target_link_libraries (http-client-sync-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe http-client-sync-ssl :

View File

@@ -14,9 +14,9 @@ build-project small ;
build-project stackless ;
build-project sync ;
# VFALCO How do I make this work on Windows and if OpenSSL is not available?
#build-project async-ssl ;
#build-project coro-ssl ;
#build-project flex ;
#build-project stackless-ssl ;
#build-project sync-ssl ;
# SSL
build-project async-ssl ;
build-project coro-ssl ;
build-project flex ;
build-project stackless-ssl ;
build-project sync-ssl ;

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET http-server-async-ssl PROPERTY FOLDER "example-http-server")
target_link_libraries (http-server-async-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe http-server-async-ssl :

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET http-server-coro-ssl PROPERTY FOLDER "example-http-server")
target_link_libraries (http-server-coro-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe http-server-coro-ssl :

View File

@@ -23,7 +23,7 @@ if (OPENSSL_FOUND)
set_property(TARGET http-server-flex PROPERTY FOLDER "example-http-server")
target_link_libraries (http-server-flex
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,14 +7,16 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe http-server-async-ssl :
http_server_async_ssl.cpp
exe http-server-flex :
http_server_flex.cpp
:
<variant>coverage:<build>no
<variant>ubasan:<build>no

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET http-server-stackless-ssl PROPERTY FOLDER "example-http-server")
target_link_libraries (http-server-stackless-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,14 +7,16 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe http-server-async-ssl :
http_server_async_ssl.cpp
exe http-server-stackless-ssl :
http_server_stackless_ssl.cpp
:
<variant>coverage:<build>no
<variant>ubasan:<build>no

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET http-server-sync-ssl PROPERTY FOLDER "example-http-server")
target_link_libraries (http-server-sync-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe http-server-sync-ssl :

View File

@@ -11,7 +11,7 @@ build-project async ;
build-project coro ;
build-project sync ;
# VFALCO How do I make this work on Windows and if OpenSSL is not available?
#build-project async-ssl ;
#build-project coro-ssl ;
#build-project sync-ssl ;
# SSL
build-project async-ssl ;
build-project coro-ssl ;
build-project sync-ssl ;

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET websocket-client-async-ssl PROPERTY FOLDER "example-websocket-client")
target_link_libraries (websocket-client-async-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe websocket-client-async-ssl :

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET websocket-client-coro-ssl PROPERTY FOLDER "example-websocket-client")
target_link_libraries (websocket-client-coro-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe websocket-client-coro-ssl :

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET websocket-client-sync-ssl PROPERTY FOLDER "example-websocket-client")
target_link_libraries (websocket-client-sync-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe websocket-client-sync-ssl :

View File

@@ -14,8 +14,8 @@ build-project fast ;
build-project stackless ;
build-project sync ;
# VFALCO How do I make this work on Windows and if OpenSSL is not available?
#build-project async-ssl ;
#build-project coro-ssl ;
#build-project stackless-ssl ;
#build-project sync-ssl ;
# SSL
build-project async-ssl ;
build-project coro-ssl ;
build-project stackless-ssl ;
build-project sync-ssl ;

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET websocket-server-async-ssl PROPERTY FOLDER "example-websocket-server")
target_link_libraries (websocket-server-async-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe websocket-server-async-ssl :

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET websocket-server-coro-ssl PROPERTY FOLDER "example-websocket-server")
target_link_libraries (websocket-server-coro-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe websocket-server-coro-ssl :

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET websocket-server-stackless-ssl PROPERTY FOLDER "example-websocket-server")
target_link_libraries (websocket-server-stackless-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe websocket-server-stackless-ssl :

View File

@@ -22,7 +22,7 @@ if (OPENSSL_FOUND)
set_property(TARGET websocket-server-sync-ssl PROPERTY FOLDER "example-websocket-server")
target_link_libraries (websocket-server-sync-ssl
${OPENSSL_LIBRARIES}
OpenSSL::SSL OpenSSL::Crypto
)
endif()

View File

@@ -7,10 +7,12 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
<library>ssl
<library>crypto
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
exe websocket-server-sync-ssl :

View File

@@ -22,6 +22,7 @@
#include <boost/beast/core/buffers_range.hpp>
#include <boost/beast/core/buffers_suffix.hpp>
#include <boost/beast/core/buffers_to_string.hpp>
#include <boost/beast/core/close_socket.hpp>
#include <boost/beast/core/error.hpp>
#include <boost/beast/core/file.hpp>
#include <boost/beast/core/file_base.hpp>
@@ -30,6 +31,7 @@
#include <boost/beast/core/file_win32.hpp>
#include <boost/beast/core/flat_buffer.hpp>
#include <boost/beast/core/flat_static_buffer.hpp>
#include <boost/beast/core/get_lowest_layer.hpp>
#include <boost/beast/core/handler_ptr.hpp>
#include <boost/beast/core/make_printable.hpp>
#include <boost/beast/core/multi_buffer.hpp>

View File

@@ -0,0 +1,47 @@
//
// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
#ifndef BOOST_BEAST_CLOSE_SOCKET_HPP
#define BOOST_BEAST_CLOSE_SOCKET_HPP
#include <boost/beast/core/detail/config.hpp>
#include <boost/asio/basic_socket.hpp>
namespace boost {
namespace beast {
namespace detail {
template<class Protocol>
void
beast_close_socket(
net::basic_socket<Protocol>& sock)
{
boost::system::error_code ec;
sock.close(ec);
}
} // detail
/** Close a socket.
@param sock The socket to close.
*/
template<class Socket>
void
close_socket(Socket& sock)
{
using detail::beast_close_socket;
beast_close_socket(sock);
}
} // beast
} // boost
#endif

View File

@@ -0,0 +1,73 @@
//
// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
#ifndef BOOST_BEAST_DETAIL_GET_LOWEST_LAYER_HPP
#define BOOST_BEAST_DETAIL_GET_LOWEST_LAYER_HPP
#include <boost/type_traits/make_void.hpp>
#include <type_traits>
namespace boost {
namespace beast {
namespace detail {
template<class T, class = void>
struct has_next_layer : std::false_type
{
};
template<class T>
struct has_next_layer<T, boost::void_t<
decltype(std::declval<T>().next_layer())>>
: std::true_type
{
};
template<class T, class = void>
struct lowest_layer_type_impl
{
using type = typename std::remove_reference<T>::type;
};
template<class T>
struct lowest_layer_type_impl<T, boost::void_t<
decltype(std::declval<T>().next_layer())>>
{
using type = typename lowest_layer_type_impl<
decltype(std::declval<T>().next_layer())>::type;
};
template<class T>
using lowest_layer_type = typename
lowest_layer_type_impl<T>::type;
template<class T>
lowest_layer_type<T>&
get_lowest_layer_impl(
T& t, std::true_type) noexcept
{
using type = typename std::decay<
decltype(t.next_layer())>::type;
return get_lowest_layer_impl(t.next_layer(),
has_next_layer<type>{});
}
template<class T>
T&
get_lowest_layer_impl(
T& t, std::false_type) noexcept
{
return t;
}
} // detail
} // beast
} // boost
#endif

View File

@@ -0,0 +1,88 @@
//
// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
#ifndef BOOST_BEAST_GET_LOWEST_LAYER_HPP
#define BOOST_BEAST_GET_LOWEST_LAYER_HPP
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/detail/get_lowest_layer.hpp>
namespace boost {
namespace beast {
/** Return the type of the lowest layer of a type representing a stack of stream layers.
This type alias will return the type of lowest layer object for a type
which defines a stack of stream layers.
@param T The type determine the lowest layer type of.
@return The type of the lowest layer.
*/
template<class T>
#if BOOST_BEAST_DOXYGEN
using lowest_layer_type = __see_below__;
#else
using lowest_layer_type = detail::lowest_layer_type<T>;
#endif
/** Return the lowest layer in a stack of stream layers.
If `t.next_layer()` is well-defined, returns
`lowest_layer(t.next_layer())`. Otherwise, it returns `t`.
A stream layer is an object of class type which wraps another object through
composition, and meets some or all of the named requirements of the wrapped
type while optionally changing behavior. Examples of stream layers include
`net::ssl::stream` or @ref beast::websocket::stream. The owner of a stream
layer can interact directly with the wrapper, by passing it to stream
algorithms. Or, the owner can obtain a reference to the wrapped object by
calling `next_layer()` and accessing its members. This is necessary when it is
desired to access functionality in the next layer which is not available
in the wrapper. For example, @ref websocket::stream permits reading and
writing, but in order to establish the underlying connection, members
of the wrapped stream (such as `connect`) must be invoked directly.
Usually the last object in the chain of composition is the concrete socket
object (for example, a `net::basic_socket` or a class derived from it).
The function @ref get_lowest_layer exists to easily obtain the concrete
socket when it is desired to perform an action that is not prescribed by
a named requirement, such as changing a socket option, cancelling all
pending asynchronous I/O, or closing the socket (perhaps by using
@ref close_socket).
@par Example
@code
// Set non-blocking mode on a stack of stream
// layers with a regular socket at the lowest layer.
template <class Stream>
void set_non_blocking (Stream& stream)
{
error_code ec;
// A compile error here means your lowest layer is not the right type!
get_lowest_layer(stream).non_blocking(true, ec);
if(ec)
throw system_error{ec};
}
@endcode
@param t The layer in a stack of layered objects for which the lowest layer is returned.
*/
template<class T>
lowest_layer_type<T>&
get_lowest_layer(T& t) noexcept
{
return detail::get_lowest_layer_impl(
t, detail::has_next_layer<T>{});
}
} // beast
} // boost
#endif

View File

@@ -1 +1,15 @@
//
// Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// This file is used to build the asio static library,
// used with BOOST_ASIO_SEPARATE_COMPILATION which helps
// reduce compilation time
#include <boost/asio/impl/src.hpp>
#include <boost/asio/ssl/impl/src.hpp>

View File

@@ -40,6 +40,7 @@ add_executable (tests-beast-core
buffers_range.cpp
buffers_suffix.cpp
buffers_to_string.cpp
close_socket.cpp
error.cpp
file.cpp
file_posix.cpp
@@ -47,6 +48,7 @@ add_executable (tests-beast-core
file_win32.cpp
flat_buffer.cpp
flat_static_buffer.cpp
get_lowest_layer.cpp
handler_ptr.cpp
make_printable.cpp
multi_buffer.cpp

View File

@@ -28,6 +28,7 @@ local SOURCES =
buffers_range.cpp
buffers_suffix.cpp
buffers_to_string.cpp
close_socket.cpp
error.cpp
file.cpp
file_posix.cpp
@@ -35,6 +36,7 @@ local SOURCES =
file_win32.cpp
flat_buffer.cpp
flat_static_buffer.cpp
get_lowest_layer.cpp
handler_ptr.cpp
make_printable.cpp
multi_buffer.cpp

View File

@@ -0,0 +1,73 @@
//
// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include <boost/beast/core/close_socket.hpp>
#include <boost/beast/_experimental/unit_test/suite.hpp>
#include <boost/beast/core/get_lowest_layer.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <utility>
namespace boost {
namespace beast {
class close_socket_test : public beast::unit_test::suite
{
public:
template<class T>
struct layer
{
T t;
template<class U>
explicit
layer(U&& u)
: t(std::forward<U>(u))
{
}
T& next_layer()
{
return t;
}
};
void
testClose()
{
net::io_context ioc;
{
net::ip::tcp::socket sock(ioc);
sock.open(net::ip::tcp::v4());
BEAST_EXPECT(sock.is_open());
close_socket(get_lowest_layer(sock));
BEAST_EXPECT(! sock.is_open());
}
{
layer<net::ip::tcp::socket> layer(ioc);
layer.next_layer().open(net::ip::tcp::v4());
BEAST_EXPECT(layer.next_layer().is_open());
close_socket(get_lowest_layer(layer));
BEAST_EXPECT(! layer.next_layer().is_open());
}
}
void
run() override
{
testClose();
}
};
BEAST_DEFINE_TESTSUITE(beast,core,close_socket);
} // beast
} // boost

View File

@@ -0,0 +1,191 @@
//
// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include <boost/beast/core/get_lowest_layer.hpp>
#include <boost/beast/_experimental/unit_test/suite.hpp>
#include <boost/beast/core/error.hpp>
#include <boost/beast/core/type_traits.hpp>
namespace boost {
namespace beast {
class get_lowest_layer_test
: public beast::unit_test::suite
{
public:
struct without
{
int dummy = 0;
without() = default;
template<class T>
std::size_t write_some(T const&)
{
return 0;
}
template<class T>
std::size_t write_some(T const&, error_code&)
{
return 0;
}
};
template<class T>
struct with
{
T t;
with() = default;
T&
next_layer()
{
return t;
}
T const&
next_layer() const
{
return t;
}
};
BOOST_STATIC_ASSERT(
! detail::has_next_layer<without>::value);
BOOST_STATIC_ASSERT(
detail::has_next_layer<with<without>>::value);
BOOST_STATIC_ASSERT(
detail::has_next_layer<with<with<without>>>::value);
void
testGetLowestLayer()
{
{
without w{};
BEAST_EXPECT(&get_lowest_layer(w) == &w);
}
{
without const w{};
BEAST_EXPECT(&get_lowest_layer(w) == &w);
}
{
with<without> w{};
BEAST_EXPECT(&get_lowest_layer(w) == &w.t);
}
{
with<without> const w{};
BEAST_EXPECT(&get_lowest_layer(w) == &w.t);
}
{
with<with<without>> w{};
BEAST_EXPECT(&get_lowest_layer(w) == &w.t.t);
}
{
with<with<without>> const w{};
BEAST_EXPECT(&get_lowest_layer(w) == &w.t.t);
}
{
with<with<with<without>>> w{};
BEAST_EXPECT(&get_lowest_layer(w) == &w.t.t.t);
}
{
with<with<with<without>>> const w{};
BEAST_EXPECT(&get_lowest_layer(w) == &w.t.t.t);
}
}
//--------------------------------------------------------------------------
/*
@par Example
This code implements a <em>SyncWriteStream</em> wrapper which calls
`std::terminate` upon any error.
*/
template <class NextLayer>
class write_stream
{
NextLayer next_layer_;
public:
static_assert(is_sync_write_stream<NextLayer>::value,
"SyncWriteStream requirements not met");
template<class... Args>
explicit
write_stream(Args&&... args)
: next_layer_(std::forward<Args>(args)...)
{
}
NextLayer& next_layer() noexcept
{
return next_layer_;
}
NextLayer const& next_layer() const noexcept
{
return next_layer_;
}
template<class ConstBufferSequence>
std::size_t
write_some(ConstBufferSequence const& buffers)
{
error_code ec;
auto const bytes_transferred = next_layer_.write_some(buffers, ec);
if(ec)
std::terminate();
return bytes_transferred;
}
template<class ConstBufferSequence>
std::size_t
write_some(ConstBufferSequence const& buffers, error_code& ec)
{
auto const bytes_transferred = next_layer_.write_some(buffers, ec);
if(ec)
std::terminate();
return bytes_transferred;
}
};
void
testJavadoc()
{
using type = write_stream<without>;
type s;
BOOST_STATIC_ASSERT(std::is_same<
decltype(get_lowest_layer(s)), without&>::value);
#if 0
BEAST_EXPECT(static_cast<
std::size_t(type::*)(net::const_buffer)>(
&type::write_some<net::const_buffer>));
#endif
}
//--------------------------------------------------------------------------
void
run() override
{
testGetLowestLayer();
testJavadoc();
}
};
BEAST_DEFINE_TESTSUITE(beast,core,get_lowest_layer);
} // beast
} // boost

View File

@@ -17,8 +17,10 @@ add_executable (tests-doc
${EXTRAS_FILES}
${TEST_MAIN}
Jamfile
snippets.ipp
core_examples.cpp
core_snippets.cpp
core_3_layers.cpp
http_examples.cpp
http_snippets.cpp
websocket_snippets.cpp

View File

@@ -7,17 +7,27 @@
# Official repository: https://github.com/boostorg/beast
#
import ac ;
project
: requirements
[ ac.check-library /boost/beast//ssl : <library>/boost/beast//ssl : <build>no ]
<library>/boost/beast//crypto
;
alias run-tests :
[ compile core_snippets.cpp ]
[ compile http_snippets.cpp ]
[ compile websocket_snippets.cpp ]
[ run core_examples.cpp $(TEST_MAIN) ]
[ run core_3_layers.cpp $(TEST_MAIN) ]
[ run http_examples.cpp $(TEST_MAIN) ]
;
exe fat-tests :
$(TEST_MAIN)
core_examples.cpp
core_3_layers.cpp
http_examples.cpp
;

281
test/doc/core_3_layers.cpp Normal file
View File

@@ -0,0 +1,281 @@
//
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
#include "snippets.hpp"
#include <boost/beast/_experimental/unit_test/suite.hpp>
#include <boost/beast/_experimental/test/stream.hpp>
#include <boost/beast/core/async_op_base.hpp>
#include <boost/beast/core/error.hpp>
#include <boost/beast/core/detail/get_executor_type.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/async_result.hpp>
#include <cstdlib>
#include <utility>
namespace boost {
namespace beast {
namespace {
void
snippets()
{
#include "snippets.ipp"
{
//[code_core_3_layers_1
net::ssl::stream<net::ip::tcp::socket> ss(ioc, ctx);
//]
}
{
//[code_core_3_layers_2
websocket::stream<net::ip::tcp::socket> ws(ioc);
//]
}
//[code_core_3_layers_3
websocket::stream<net::ssl::stream<net::ip::tcp::socket>> ws(ioc, ctx);
//]
}
//[code_core_3_layers_4
// Set non-blocking mode on a stack of stream
// layers with a regular socket at the lowest layer.
template <class Stream>
void set_non_blocking (Stream& stream)
{
error_code ec;
// A compile error here means your lowest layer is not the right type!
get_lowest_layer(stream).non_blocking(true, ec);
if(ec)
throw system_error{ec};
}
//]
//[code_core_3_layers_5
// A layered stream which counts the bytes read and bytes written on the next layer
template <class NextLayer>
class counted_stream
{
NextLayer next_layer_;
std::size_t bytes_read_ = 0;
std::size_t bytes_written_ = 0;
public:
/// The type of executor used by this stream
using executor_type = detail::get_executor_type<NextLayer>;
/// Constructor
template <class... Args>
explicit
counted_stream(Args&&... args)
: next_layer_(std::forward<Args>(args)...)
{
}
/// Returns an instance of the executor used to submit completion handlers
executor_type get_executor() noexcept
{
return next_layer_.get_executor();
}
/// Returns a reference to the next layer
NextLayer& next_layer() noexcept
{
return next_layer_;
}
/// Returns a reference to the next layer
NextLayer const& next_layer() const noexcept
{
return next_layer_;
}
/// Returns the total number of bytes read since the stream was constructed
std::size_t bytes_read() const noexcept
{
return bytes_read_;
}
/// Returns the total number of bytes written since the stream was constructed
std::size_t bytes_written() const noexcept
{
return bytes_written_;
}
/// Read some data from the stream
template <class MutableBufferSequence>
std::size_t read_some(MutableBufferSequence const& buffers)
{
auto const bytes_transferred = next_layer_.read_some(buffers);
bytes_read_ += bytes_transferred;
return bytes_transferred;
}
/// Read some data from the stream
template <class MutableBufferSequence>
std::size_t read_some(MutableBufferSequence const& buffers, error_code& ec)
{
auto const bytes_transferred = next_layer_.read_some(buffers, ec);
bytes_read_ += bytes_transferred;
return bytes_transferred;
}
/// Write some data to the stream
template <class ConstBufferSequence>
std::size_t write_some(ConstBufferSequence const& buffers)
{
auto const bytes_transferred = next_layer_.write_some(buffers);
bytes_written_ += bytes_transferred;
return bytes_transferred;
}
/// Write some data to the stream
template <class ConstBufferSequence>
std::size_t write_some(ConstBufferSequence const& buffers, error_code& ec)
{
auto const bytes_transferred = next_layer_.write_some(buffers, ec);
bytes_written_ += bytes_transferred;
return bytes_transferred;
}
/// Read some data from the stream asynchronously
template<class MutableBufferSequence, class ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void(error_code, std::size_t))
async_read_some(
MutableBufferSequence const& buffers,
ReadHandler&& handler)
{
using handler_type = BOOST_ASIO_HANDLER_TYPE(
ReadHandler, void(error_code, std::size_t));
struct op : async_op_base<handler_type, executor_type>
{
counted_stream& stream_;
op(
counted_stream& stream,
handler_type&& handler,
MutableBufferSequence const& buffers)
: async_op_base<handler_type, executor_type>(
std::move(handler), stream.get_executor())
, stream_(stream)
{
stream_.next_layer().async_read_some(buffers, std::move(*this));
}
void operator()(error_code ec, std::size_t bytes_transferred)
{
stream_.bytes_read_ += bytes_transferred;
this->invoke(ec, bytes_transferred);
}
};
net::async_completion<ReadHandler, void(error_code, std::size_t)> init{handler};
op(*this, std::move(init.completion_handler), buffers);
return init.result.get();
}
/// Write some data to the stream asynchronously
template<class ConstBufferSequence, class WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
void(error_code, std::size_t))
async_write_some(
ConstBufferSequence const& buffers,
WriteHandler&& handler)
{
using handler_type = BOOST_ASIO_HANDLER_TYPE(
WriteHandler, void(error_code, std::size_t));
struct op : async_op_base<handler_type, executor_type>
{
counted_stream& stream_;
op( counted_stream& stream,
handler_type&& handler,
ConstBufferSequence const& buffers)
: async_op_base<handler_type, executor_type>(
std::move(handler), stream.get_executor())
, stream_(stream)
{
stream_.next_layer().async_write_some(buffers, std::move(*this));
}
void operator()(error_code ec, std::size_t bytes_transferred)
{
stream_.bytes_written_ += bytes_transferred;
this->invoke(ec, bytes_transferred);
}
};
net::async_completion<WriteHandler, void(error_code, std::size_t)> init{handler};
op(*this, std::move(init.completion_handler), buffers);
return init.result.get();
}
};
//]
BOOST_STATIC_ASSERT(is_sync_read_stream<counted_stream<test::stream>>::value);
BOOST_STATIC_ASSERT(is_sync_write_stream<counted_stream<test::stream>>::value);
BOOST_STATIC_ASSERT(is_async_read_stream<counted_stream<test::stream>>::value);
BOOST_STATIC_ASSERT(is_async_write_stream<counted_stream<test::stream>>::value);
} // (anon)
struct core_3_layers_test
: public beast::unit_test::suite
{
struct handler
{
void operator()(error_code, std::size_t)
{
}
};
void
run() override
{
BEAST_EXPECT(&snippets);
BEAST_EXPECT(&set_non_blocking<net::ip::tcp::socket>);
BEAST_EXPECT(&counted_stream<test::stream>::get_executor);
BEAST_EXPECT(static_cast<
test::stream&(counted_stream<test::stream>::*)()>(
&counted_stream<test::stream>::next_layer));
BEAST_EXPECT(static_cast<
test::stream const&(counted_stream<test::stream>::*)() const>(
&counted_stream<test::stream>::next_layer));
BEAST_EXPECT(&counted_stream<test::stream>::bytes_read);
BEAST_EXPECT(&counted_stream<test::stream>::bytes_written);
BEAST_EXPECT(static_cast<
std::size_t(counted_stream<test::stream>::*)(net::mutable_buffer const&)>(
&counted_stream<test::stream>::read_some));
BEAST_EXPECT(static_cast<
std::size_t(counted_stream<test::stream>::*)(net::mutable_buffer const&, error_code&)>(
&counted_stream<test::stream>::read_some));
BEAST_EXPECT(static_cast<
std::size_t(counted_stream<test::stream>::*)(net::const_buffer const&)>(
&counted_stream<test::stream>::write_some));
BEAST_EXPECT(static_cast<
std::size_t(counted_stream<test::stream>::*)(net::const_buffer const&, error_code&)>(
&counted_stream<test::stream>::write_some));
BEAST_EXPECT((&counted_stream<test::stream>::async_read_some<net::mutable_buffer, handler>));
BEAST_EXPECT((&counted_stream<test::stream>::async_write_some<net::const_buffer, handler>));
}
};
BEAST_DEFINE_TESTSUITE(beast,doc,core_3_layers);
} // beast
} // boost

21
test/doc/snippets.hpp Normal file
View File

@@ -0,0 +1,21 @@
//
// Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
#ifndef SNIPPETS_HPP
#define SNIPPETS_HPP
// This file must be included before including snippets.ipp
#include <boost/beast/core.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <iostream>
#include <thread>
#endif

26
test/doc/snippets.ipp Normal file
View File

@@ -0,0 +1,26 @@
//
// Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// This header file is designed to be included multiple times
// inside of function bodies holding documentation snippets.
using namespace boost::beast;
namespace net = boost::asio;
namespace ssl = boost::asio::ssl;
using tcp = net::ip::tcp;
error_code ec;
net::io_context ioc;
auto work = net::make_work_guard(ioc);
std::thread t{[&](){ ioc.run(); }};
tcp::socket sock(ioc);
ssl::context ctx(ssl::context::sslv23);

12
tools/user-config.jam Normal file
View File

@@ -0,0 +1,12 @@
# Used on CI
import os ;
local OPENSSL_ROOT = [ os.environ OPENSSL_ROOT ] ;
project
: requirements
<include>$(OPENSSL_ROOT)/include
<variant>debug:<library-path>$(OPENSSL_ROOT)/debug/lib
<variant>release:<library-path>$(OPENSSL_ROOT)/lib
;