Update to Beast 1.0.0-b34:

Merge commit 'd8dea963fa5dc26b4be699ce6d4bf699a429ca92' into develop
This commit is contained in:
Vinnie Falco
2017-04-20 13:40:52 -07:00
79 changed files with 501 additions and 315 deletions

View File

@@ -264,6 +264,8 @@
</ClInclude>
<ClInclude Include="..\..\src\beast\extras\beast\unit_test\thread.hpp">
</ClInclude>
<ClInclude Include="..\..\src\beast\include\beast\config.hpp">
</ClInclude>
<ClInclude Include="..\..\src\beast\include\beast\core\async_completion.hpp">
</ClInclude>
<ClInclude Include="..\..\src\beast\include\beast\core\bind_handler.hpp">
@@ -400,8 +402,6 @@
</ClInclude>
<ClInclude Include="..\..\src\beast\include\beast\http\reason.hpp">
</ClInclude>
<ClInclude Include="..\..\src\beast\include\beast\http\resume_context.hpp">
</ClInclude>
<ClInclude Include="..\..\src\beast\include\beast\http\rfc7230.hpp">
</ClInclude>
<ClInclude Include="..\..\src\beast\include\beast\http\streambuf_body.hpp">

View File

@@ -555,6 +555,9 @@
<ClInclude Include="..\..\src\beast\extras\beast\unit_test\thread.hpp">
<Filter>beast\unit_test</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\include\beast\config.hpp">
<Filter>beast</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\include\beast\core\async_completion.hpp">
<Filter>beast\core</Filter>
</ClInclude>
@@ -759,9 +762,6 @@
<ClInclude Include="..\..\src\beast\include\beast\http\reason.hpp">
<Filter>beast\http</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\include\beast\http\resume_context.hpp">
<Filter>beast\http</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\include\beast\http\rfc7230.hpp">
<Filter>beast\http</Filter>
</ClInclude>

View File

@@ -1,3 +1,47 @@
1.0.0-b34
* Fix and tidy up CMake build scripts
--------------------------------------------------------------------------------
1.0.0-b33
* Require Visual Studio 2015 Update 3 or later
HTTP
* Use fwrite return value in file_body
WebSocket
* Set internal state correctly when writing frames
* Add decorator unit test
* Add write_frames unit test
--------------------------------------------------------------------------------
1.0.0-b32
* Add io_service completion invariants test
* Update CMake scripts for finding packages
API Changes:
* Remove http Writer suspend and resume feature
--------------------------------------------------------------------------------
1.0.0-b31
* Tidy up build settings
* Add missing dynabuf_readstream member
WebSocket
* Move the handler, don't copy it
--------------------------------------------------------------------------------
1.0.0-b30
WebSocket

View File

@@ -1,6 +1,6 @@
# Part of Beast
cmake_minimum_required (VERSION 3.2)
cmake_minimum_required (VERSION 3.5.2)
project (Beast)
@@ -8,10 +8,13 @@ set_property (GLOBAL PROPERTY USE_FOLDERS ON)
if (MSVC)
# /wd4244 /wd4127
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244 /MP /W4 /wd4100 /bigobj /D _WIN32_WINNT=0x0601 /D _SCL_SECURE_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ob2 /Oi /Ot /GL /MT")
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi /Ot /MT")
add_definitions (-D_WIN32_WINNT=0x0601)
add_definitions (-D_SCL_SECURE_NO_WARNINGS=1)
add_definitions (-D_CRT_SECURE_NO_WARNINGS=1)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4100 /wd4244 /wd4251 /MP /W4 /bigobj")
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ob2 /Oi /Ot /GL")
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi /Ot")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
set (CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
@@ -19,17 +22,12 @@ if (MSVC)
# for RelWithDebInfo builds, disable incremental linking
# since CMake sets it ON by default for that build type and it
# causes warnings
#
string (REPLACE "/INCREMENTAL" "/INCREMENTAL:NO" replacement_flags
${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO})
set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO ${replacement_flags})
else()
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
find_package(Boost REQUIRED COMPONENTS coroutine context thread filesystem program_options system)
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIR})
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
@@ -37,7 +35,42 @@ else()
"${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wpedantic -Wno-unused-parameter")
endif()
add_definitions ("-DBOOST_COROUTINES_NO_DEPRECATION_WARNING")
#-------------------------------------------------------------------------------
#
# Boost
#
option (Boost_USE_STATIC_LIBS "Use static libraries for boost" ON)
set (Boost_NO_SYSTEM_PATHS ON)
set (Boost_USE_MULTITHREADED ON)
unset (Boost_INCLUDE_DIR CACHE)
unset (Boost_LIBRARY_DIRS CACHE)
find_package (Boost REQUIRED COMPONENTS
coroutine
context
filesystem
program_options
system
thread
)
include_directories (SYSTEM ${Boost_INCLUDE_DIRS})
link_libraries (${Boost_LIBRARIES})
if (MSVC)
add_definitions (-DBOOST_ALL_NO_LIB) # disable autolinking
elseif (MINGW)
link_libraries(ws2_32 mswsock)
endif()
add_definitions (-DBOOST_COROUTINES_NO_DEPRECATION_WARNING=1) # for asio
#-------------------------------------------------------------------------------
#
# OpenSSL
#
if (APPLE AND NOT DEFINED ENV{OPENSSL_ROOT_DIR})
find_program(HOMEBREW brew)
@@ -50,9 +83,29 @@ endif()
find_package(OpenSSL)
if (MINGW)
link_libraries(${Boost_LIBRARIES} ws2_32 mswsock)
endif()
#
#-------------------------------------------------------------------------------
function(DoGroupSources curdir rootdir folder)
file(GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} ${PROJECT_SOURCE_DIR}/${curdir}/*)
foreach(child ${children})
if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child})
DoGroupSources(${curdir}/${child} ${rootdir} ${folder})
elseif(${child} STREQUAL "CMakeLists.txt")
source_group("" FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
else()
string(REGEX REPLACE ^${rootdir} ${folder} groupname ${curdir})
string(REPLACE "/" "\\" groupname ${groupname})
source_group(${groupname} FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
endif()
endforeach()
endfunction()
function(GroupSources curdir folder)
DoGroupSources(${curdir} ${curdir} ${folder})
endfunction()
#-------------------------------------------------------------------------------
if ("${VARIANT}" STREQUAL "coverage")
set(CMAKE_CXX_FLAGS
@@ -75,25 +128,6 @@ elseif ("${VARIANT}" STREQUAL "release")
set(CMAKE_BUILD_TYPE RELEASE)
endif()
function(DoGroupSources curdir rootdir folder)
file(GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} ${PROJECT_SOURCE_DIR}/${curdir}/*)
foreach(child ${children})
if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child})
DoGroupSources(${curdir}/${child} ${rootdir} ${folder})
elseif(${child} STREQUAL "CMakeLists.txt")
source_group("" FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
else()
string(REGEX REPLACE ^${rootdir} ${folder} groupname ${curdir})
string(REPLACE "/" "\\" groupname ${groupname})
source_group(${groupname} FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
endif()
endforeach()
endfunction()
function(GroupSources curdir folder)
DoGroupSources(${curdir} ${curdir} ${folder})
endfunction()
include_directories (extras)
include_directories (include)

View File

@@ -93,19 +93,20 @@ project beast
<library>/boost/filesystem//boost_filesystem
<library>/boost/program_options//boost_program_options
<define>BOOST_ALL_NO_LIB=1
<define>BOOST_COROUTINES_NO_DEPRECATION_WARNING=1
<threading>multi
<runtime-link>shared
<debug-symbols>on
<toolset>gcc:<cxxflags>-std=c++11
<toolset>gcc:<cxxflags>-Wno-unused-parameter
<toolset>gcc:<cxxflags>-Wno-unused-variable # Temporary until we can figure out -isystem
<toolset>clang:<cxxflags>-std=c++11
<toolset>clang:<cxxflags>-Wno-unused-parameter
<toolset>gcc:<cxxflags>-Wno-unused-variable # Temporary until we can figure out -isystem
<toolset>clang:<cxxflags>-Wno-unused-variable # Temporary until we can figure out -isystem
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS=1
<toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS=1
<toolset>msvc:<cxxflags>"/wd4100 /bigobj"
<toolset>msvc,<variant>release:<cxxflags>"/Ob2 /Oi /Ot"
<toolset>msvc:<cxxflags>"/wd4100 /wd4251 /bigobj"
<toolset>msvc:<variant>release:<cxxflags>"/Ob2 /Oi /Ot"
<os>LINUX:<define>_XOPEN_SOURCE=600
<os>LINUX:<define>_GNU_SOURCE=1
<os>SOLARIS:<define>_XOPEN_SOURCE=500

View File

@@ -1,12 +1,7 @@
<img width="880" height = "80" alt = "Beast"
src="https://raw.githubusercontent.com/vinniefalco/Beast/master/doc/images/readme.png">
[![Join the chat at https://gitter.im/vinniefalco/Beast](https://badges.gitter.im/vinniefalco/Beast.svg)](https://gitter.im/vinniefalco/Beast?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status]
(https://travis-ci.org/vinniefalco/Beast.svg?branch=master)](https://travis-ci.org/vinniefalco/Beast) [![codecov]
(https://codecov.io/gh/vinniefalco/Beast/branch/master/graph/badge.svg)](https://codecov.io/gh/vinniefalco/Beast) [![coveralls]
(https://coveralls.io/repos/github/vinniefalco/Beast/badge.svg?branch=master)](https://coveralls.io/github/vinniefalco/Beast?branch=master) [![Documentation]
(https://img.shields.io/badge/documentation-master-brightgreen.svg)](http://vinniefalco.github.io/beast/) [![License]
(https://img.shields.io/badge/license-boost-brightgreen.svg)](LICENSE_1_0.txt)
[![Join the chat at https://gitter.im/vinniefalco/Beast](https://badges.gitter.im/vinniefalco/Beast.svg)](https://gitter.im/vinniefalco/Beast?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/vinniefalco/Beast.svg?branch=master)](https://travis-ci.org/vinniefalco/Beast) [![codecov](https://codecov.io/gh/vinniefalco/Beast/branch/master/graph/badge.svg)](https://codecov.io/gh/vinniefalco/Beast) [![coveralls](https://coveralls.io/repos/github/vinniefalco/Beast/badge.svg?branch=master)](https://coveralls.io/github/vinniefalco/Beast?branch=master) [![Documentation](https://img.shields.io/badge/documentation-master-brightgreen.svg)](http://vinniefalco.github.io/beast/) [![License](https://img.shields.io/badge/license-boost-brightgreen.svg)](LICENSE_1_0.txt)
# HTTP and WebSocket built on Boost.Asio in C++11
@@ -78,9 +73,17 @@ The library has been submitted to the
## Requirements
* Boost 1.58 or higher
* C++11 or greater
* Boost 1.58 or later
* C++11 or later
When using Microsoft Visual C++, Visual Studio 2015 Update 3 or later is required.
These components are optionally required in order to build the
tests and examples:
* OpenSSL (optional)
* CMake 3.7.2 or later (optional)
* Properly configured bjam/b2 (optional)
## Building
@@ -102,19 +105,27 @@ Boost.Coroutine library. Please visit the Boost documentation for
instructions on how to do this for your particular build system.
For the examples and tests, Beast provides build scripts for Boost.Build (bjam)
and CMake. Developers using Microsoft Visual Studio can generate Visual Studio
and CMake. It is possible to generate Microsoft Visual Studio or Apple
Developers using Microsoft Visual Studio can generate Visual Studio
project files by executing these commands from the root of the repository:
```
cd bin
cmake .. # for 32-bit Windows build
cmake .. # for 32-bit Windows builds
cd ../bin64
cmake .. # for Linux/Mac builds, OR
cmake -G"Visual Studio 14 2015 Win64" .. # for 64-bit Windows builds
```
When using Apple Xcode it is possible to generate Xcode project files
using these commands:
```
cd bin
cmake -G Xcode .. # for Apple Xcode builds
```
To build with Boost.Build, it is necessary to have the bjam executable
in your path. And bjam needs to know how to find the Boost sources. The
easiest way to do this is make sure that the version of bjam in your path

View File

@@ -42,7 +42,6 @@
<member><link linkend="beast.ref.http__request_header">request_header</link></member>
<member><link linkend="beast.ref.http__response">response</link></member>
<member><link linkend="beast.ref.http__response_header">response_header</link></member>
<member><link linkend="beast.ref.http__resume_context">resume_context</link></member>
<member><link linkend="beast.ref.http__streambuf_body">streambuf_body</link></member>
<member><link linkend="beast.ref.http__string_body">string_body</link></member>
</simplelist>
@@ -190,6 +189,7 @@
<member><link linkend="beast.ref.buffer_cat">buffer_cat</link></member>
<member><link linkend="beast.ref.prepare_buffer">prepare_buffer</link></member>
<member><link linkend="beast.ref.prepare_buffers">prepare_buffers</link></member>
<member><link linkend="beast.ref.system_category">system_category</link></member>
<member><link linkend="beast.ref.to_string">to_string</link></member>
<member><link linkend="beast.ref.write">write</link></member>
</simplelist>

View File

@@ -28,8 +28,6 @@ In this table:
* `m` denotes a value of type `message const&` where
`std::is_same<decltype(m.body), Body::value_type>:value == true`.
* `rc` is an object of type [link beast.ref.http__resume_context `resume_context`].
* `ec` is a value of type [link beast.ref.error_code `error_code&`]
* `wf` is a [*write function]: a function object of unspecified type provided
@@ -72,8 +70,8 @@ In this table:
]
]
[
[`a.write(rc, ec, wf)`]
[`boost::tribool`]
[`a.write(ec, wf)`]
[`bool`]
[
Called repeatedly after `init` succeeds. `wf` is a function object
which takes as its single parameter any value meeting the requirements
@@ -81,12 +79,7 @@ In this table:
must remain valid until the next member function of `writer` is
invoked (which may be the destructor). This function returns `true`
to indicate all message body data has been written, or `false` if
there is more body data. If the return value is `boost::indeterminate`,
the implementation will suspend the operation until the writer invokes
`rc`. It is the writers responsibility when returning
`boost::indeterminate`, to acquire ownership of `rc` via move
construction and eventually call it or else undefined behavior
results. This function must be `noexcept`.
there is more body data.
]
]
]
@@ -139,7 +132,6 @@ public:
Postconditions:
If return value is `true`:
* Callee does not take ownership of resume.
* Callee made zero or one calls to `write`.
* There is no more data remaining to write.
@@ -147,18 +139,6 @@ public:
* Callee does not take ownership of resume.
* Callee made one call to `write`.
If return value is boost::indeterminate:
* Callee takes ownership of `resume`.
* Caller suspends the write operation
until `resume` is invoked.
When the caller takes ownership of resume, the
asynchronous operation will not complete until the
caller destroys the object.
@param resume A functor to call to resume the write operation
after the writer has returned boost::indeterminate.
@param ec Set to indicate an error. This will cause an
asynchronous write operation to complete with the error.
@@ -167,17 +147,12 @@ public:
the writer must guarantee that the buffers remain valid until the
next member function is invoked, which may be the destructor.
@return `true` if there is no more data to send,
`false` when there may be more data,
boost::indeterminate to suspend.
@note Undefined behavior if the callee takes ownership
of resume but does not return boost::indeterminate.
@return `true` if there is no more data to send,
`false` when there may be more data.
*/
template<class WriteFunction>
boost::tribool
bool
write(
resume_context&&,
error_code&,
WriteFunction&& wf) noexcept;
};

View File

@@ -15,6 +15,8 @@ add_executable (http-crawl
if (NOT WIN32)
target_link_libraries(http-crawl ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(http-crawl ${Boost_LIBRARIES})
endif()
add_executable (http-server
@@ -29,8 +31,11 @@ add_executable (http-server
if (NOT WIN32)
target_link_libraries(http-server ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(http-server ${Boost_LIBRARIES})
endif()
add_executable (http-example
${BEAST_INCLUDES}
${EXTRAS_INCLUDES}
@@ -39,8 +44,11 @@ add_executable (http-example
if (NOT WIN32)
target_link_libraries(http-example ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(http-example ${Boost_LIBRARIES})
endif()
add_executable (websocket-echo
${BEAST_INCLUDES}
websocket_async_echo_server.hpp
@@ -50,8 +58,11 @@ add_executable (websocket-echo
if (NOT WIN32)
target_link_libraries(websocket-echo ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(websocket-echo ${Boost_LIBRARIES})
endif()
add_executable (websocket-example
${BEAST_INCLUDES}
${EXTRAS_INCLUDES}
@@ -60,4 +71,6 @@ add_executable (websocket-example
if (NOT WIN32)
target_link_libraries(websocket-example ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(websocket-example ${Boost_LIBRARIES})
endif()

View File

@@ -10,10 +10,9 @@
#include <beast/core/error.hpp>
#include <beast/http/message.hpp>
#include <beast/http/resume_context.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/logic/tribool.hpp>
#include <cstdio>
#include <cstdint>
@@ -38,7 +37,8 @@ struct file_body
writer& operator=(writer const&) = delete;
template<bool isRequest, class Fields>
writer(message<isRequest, file_body, Fields> const& m) noexcept
writer(message<isRequest,
file_body, Fields> const& m) noexcept
: path_(m.body)
{
}
@@ -54,8 +54,8 @@ struct file_body
{
file_ = fopen(path_.c_str(), "rb");
if(! file_)
ec = boost::system::errc::make_error_code(
static_cast<boost::system::errc::errc_t>(errno));
ec = error_code{errno,
system_category()};
else
size_ = boost::filesystem::file_size(path_);
}
@@ -67,19 +67,25 @@ struct file_body
}
template<class WriteFunction>
boost::tribool
write(resume_context&&, error_code&,
WriteFunction&& wf) noexcept
bool
write(error_code& ec, WriteFunction&& wf) noexcept
{
if(size_ - offset_ < sizeof(buf_))
buf_len_ = static_cast<std::size_t>(
size_ - offset_);
else
buf_len_ = sizeof(buf_);
auto const nread = fread(buf_, 1, sizeof(buf_), file_);
(void)nread;
offset_ += buf_len_;
wf(boost::asio::buffer(buf_, buf_len_));
auto const nread = fread(
buf_, 1, sizeof(buf_), file_);
if(ferror(file_))
{
ec = error_code(errno,
system_category());
return true;
}
BOOST_ASSERT(nread != 0);
offset_ += nread;
wf(boost::asio::buffer(buf_, nread));
return offset_ >= size_;
}
};

View File

@@ -0,0 +1,27 @@
//
// Copyright (c) 2013-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)
//
#ifndef BEAST_CONFIG_HPP
#define BEAST_CONFIG_HPP
/*
_MSC_VER and _MSC_FULL_VER by version:
14.0 (2015) 1900 190023026
14.0 (2015 Update 1) 1900 190023506
14.0 (2015 Update 2) 1900 190023918
14.0 (2015 Update 3) 1900 190024210
*/
#if defined(_MSC_FULL_VER)
#if _MSC_FULL_VER < 190024210
static_assert(false,
"This library requires Visual Studio 2015 Update 3 or later");
#endif
#endif
#endif

View File

@@ -8,6 +8,8 @@
#ifndef BEAST_CORE_HPP
#define BEAST_CORE_HPP
#include <beast/config.hpp>
#include <beast/core/async_completion.hpp>
#include <beast/core/bind_handler.hpp>
#include <beast/core/buffer_cat.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_ASYNC_COMPLETION_HPP
#define BEAST_ASYNC_COMPLETION_HPP
#include <beast/config.hpp>
#include <beast/core/handler_concepts.hpp>
#include <boost/asio/async_result.hpp>
#include <boost/asio/handler_type.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_BIND_HANDLER_HPP
#define BEAST_BIND_HANDLER_HPP
#include <beast/config.hpp>
#include <beast/core/handler_concepts.hpp>
#include <beast/core/detail/bind_handler.hpp>
#include <type_traits>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_BUFFER_CAT_HPP
#define BEAST_BUFFER_CAT_HPP
#include <beast/config.hpp>
#include <beast/core/detail/buffer_cat.hpp>
#include <boost/asio/buffer.hpp>
#include <cstdint>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_BUFFER_CONCEPTS_HPP
#define BEAST_BUFFER_CONCEPTS_HPP
#include <beast/config.hpp>
#include <beast/core/detail/buffer_concepts.hpp>
#include <boost/asio/buffer.hpp>
#include <type_traits>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_BUFFERS_ADAPTER_HPP
#define BEAST_BUFFERS_ADAPTER_HPP
#include <beast/config.hpp>
#include <beast/core/buffer_concepts.hpp>
#include <boost/asio/buffer.hpp>
#include <type_traits>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_CONSUMING_BUFFERS_HPP
#define BEAST_CONSUMING_BUFFERS_HPP
#include <beast/config.hpp>
#include <beast/core/buffer_concepts.hpp>
#include <boost/asio/buffer.hpp>
#include <cstdint>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_DYNABUF_READSTREAM_HPP
#define BEAST_DYNABUF_READSTREAM_HPP
#include <beast/config.hpp>
#include <beast/core/async_completion.hpp>
#include <beast/core/buffer_concepts.hpp>
#include <beast/core/error.hpp>
@@ -145,6 +146,13 @@ public:
return next_layer_;
}
/// Get a const reference to the next layer.
next_layer_type const&
next_layer() const
{
return next_layer_;
}
/// Get a reference to the lowest layer.
lowest_layer_type&
lowest_layer()

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_ERROR_HPP
#define BEAST_ERROR_HPP
#include <beast/config.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
@@ -22,6 +23,14 @@ using system_error = boost::system::system_error;
/// The type of error category used by the library
using error_category = boost::system::error_category;
/// A function to return the system error category used by the library
#if GENERATING_DOCS
error_category const&
system_category();
#else
using boost::system::system_category;
#endif
/// The type of error condition used by the library
using error_condition = boost::system::error_condition;

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HANDLER_ALLOC_HPP
#define BEAST_HANDLER_ALLOC_HPP
#include <beast/config.hpp>
#include <beast/core/handler_helpers.hpp>
#include <cstdlib>
#include <memory>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HANDLER_CONCEPTS_HPP
#define BEAST_HANDLER_CONCEPTS_HPP
#include <beast/config.hpp>
#include <beast/core/detail/is_call_possible.hpp>
#include <type_traits>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HANDLER_HELPERS_HPP
#define BEAST_HANDLER_HELPERS_HPP
#include <beast/config.hpp>
#include <boost/asio/handler_alloc_hook.hpp>
#include <boost/asio/handler_continuation_hook.hpp>
#include <boost/asio/handler_invoke_hook.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HANDLER_PTR_HPP
#define BEAST_HANDLER_PTR_HPP
#include <beast/config.hpp>
#include <beast/core/detail/type_traits.hpp>
#include <atomic>
#include <cstdint>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_PLACEHOLDERS_HPP
#define BEAST_PLACEHOLDERS_HPP
#include <beast/config.hpp>
#include <functional>
namespace beast {

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_PREPARE_BUFFER_HPP
#define BEAST_PREPARE_BUFFER_HPP
#include <beast/config.hpp>
#include <boost/asio/buffer.hpp>
#include <algorithm>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_PREPARE_BUFFERS_HPP
#define BEAST_PREPARE_BUFFERS_HPP
#include <beast/config.hpp>
#include <beast/core/detail/prepare_buffers.hpp>
#include <boost/asio/buffer.hpp>
#include <algorithm>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_STATIC_STREAMBUF_HPP
#define BEAST_STATIC_STREAMBUF_HPP
#include <beast/config.hpp>
#include <boost/utility/base_from_member.hpp>
#include <algorithm>
#include <array>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_WEBSOCKET_STATIC_STRING_HPP
#define BEAST_WEBSOCKET_STATIC_STRING_HPP
#include <beast/config.hpp>
#include <beast/core/detail/type_traits.hpp>
#include <array>
#include <cstdint>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_STREAM_CONCEPTS_HPP
#define BEAST_STREAM_CONCEPTS_HPP
#include <beast/config.hpp>
#include <beast/core/detail/stream_concepts.hpp>
#include <type_traits>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_STREAMBUF_HPP
#define BEAST_STREAMBUF_HPP
#include <beast/config.hpp>
#include <beast/core/detail/empty_base_optimization.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/intrusive/list.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_TO_STRING_HPP
#define BEAST_TO_STRING_HPP
#include <beast/config.hpp>
#include <beast/core/buffer_concepts.hpp>
#include <boost/asio/buffer.hpp>
#include <string>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_WRITE_DYNABUF_HPP
#define BEAST_WRITE_DYNABUF_HPP
#include <beast/config.hpp>
#include <beast/core/buffer_concepts.hpp>
#include <beast/core/detail/write_dynabuf.hpp>
#include <type_traits>

View File

@@ -8,6 +8,8 @@
#ifndef BEAST_HTTP_HPP
#define BEAST_HTTP_HPP
#include <beast/config.hpp>
#include <beast/http/basic_fields.hpp>
#include <beast/http/basic_parser_v1.hpp>
#include <beast/http/chunk_encode.hpp>
@@ -19,7 +21,6 @@
#include <beast/http/parser_v1.hpp>
#include <beast/http/read.hpp>
#include <beast/http/reason.hpp>
#include <beast/http/resume_context.hpp>
#include <beast/http/rfc7230.hpp>
#include <beast/http/streambuf_body.hpp>
#include <beast/http/string_body.hpp>

View File

@@ -8,12 +8,11 @@
#ifndef BEAST_HTTP_BASIC_DYNABUF_BODY_HPP
#define BEAST_HTTP_BASIC_DYNABUF_BODY_HPP
#include <beast/config.hpp>
#include <beast/core/error.hpp>
#include <beast/http/message.hpp>
#include <beast/http/resume_context.hpp>
#include <beast/core/detail/type_traits.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/logic/tribool.hpp>
namespace beast {
namespace http {
@@ -87,9 +86,8 @@ private:
}
template<class WriteFunction>
boost::tribool
write(resume_context&&, error_code&,
WriteFunction&& wf) noexcept
bool
write(error_code&, WriteFunction&& wf) noexcept
{
wf(body_.data());
return true;

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_BASIC_FIELDS_HPP
#define BEAST_HTTP_BASIC_FIELDS_HPP
#include <beast/config.hpp>
#include <beast/core/detail/empty_base_optimization.hpp>
#include <beast/http/detail/basic_fields.hpp>
#include <boost/lexical_cast.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_BASIC_PARSER_v1_HPP
#define BEAST_HTTP_BASIC_PARSER_v1_HPP
#include <beast/config.hpp>
#include <beast/http/message.hpp>
#include <beast/http/parse_error.hpp>
#include <beast/http/rfc7230.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_CHUNK_ENCODE_HPP
#define BEAST_HTTP_CHUNK_ENCODE_HPP
#include <beast/config.hpp>
#include <beast/core/buffer_cat.hpp>
#include <beast/http/detail/chunk_encode.hpp>
#include <boost/asio/buffer.hpp>

View File

@@ -8,11 +8,10 @@
#ifndef BEAST_HTTP_TYPE_CHECK_HPP
#define BEAST_HTTP_TYPE_CHECK_HPP
#include <beast/config.hpp>
#include <beast/core/error.hpp>
#include <beast/core/detail/type_traits.hpp>
#include <beast/http/resume_context.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/logic/tribool.hpp>
#include <type_traits>
#include <utility>
@@ -50,38 +49,6 @@ struct has_content_length<T, beast::detail::void_t<decltype(
"Writer::content_length requirements not met");
};
#if 0
template<class T, class M, class = beast::detail::void_t<>>
struct is_Writer : std::false_type {};
template<class T, class M>
struct is_Writer<T, M, beast::detail::void_t<decltype(
std::declval<T>().init(
std::declval<error_code&>())
// VFALCO This is unfortunate, we have to provide the template
// argument type because this is not a deduced context?
//
,std::declval<T>().template write<detail::write_function>(
std::declval<resume_context>(),
std::declval<error_code&>(),
std::declval<detail::write_function>())
)> > : std::integral_constant<bool,
std::is_nothrow_constructible<T, M const&>::value &&
std::is_convertible<decltype(
std::declval<T>().template write<detail::write_function>(
std::declval<resume_context>(),
std::declval<error_code&>(),
std::declval<detail::write_function>())),
boost::tribool>::value
>
{
static_assert(std::is_same<
typename M::body_type::writer, T>::value,
"Mismatched writer and message");
};
#else
template<class T, class M>
class is_Writer
{
@@ -99,10 +66,9 @@ class is_Writer
template<class U, class R =
std::is_convertible<decltype(
std::declval<U>().template write<detail::write_function>(
std::declval<resume_context>(),
std::declval<error_code&>(),
std::declval<detail::write_function>()))
, boost::tribool>>
, bool>>
static R check2(int);
template<class>
static std::false_type check2(...);
@@ -120,8 +86,6 @@ public:
>;
};
#endif
template<class T>
class is_Parser
{

View File

@@ -8,12 +8,11 @@
#ifndef BEAST_HTTP_EMPTY_BODY_HPP
#define BEAST_HTTP_EMPTY_BODY_HPP
#include <beast/config.hpp>
#include <beast/core/error.hpp>
#include <beast/http/message.hpp>
#include <beast/http/resume_context.hpp>
#include <beast/core/detail/type_traits.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/logic/tribool.hpp>
#include <memory>
#include <string>
@@ -59,9 +58,8 @@ private:
}
template<class WriteFunction>
boost::tribool
write(resume_context&&, error_code&,
WriteFunction&& wf) noexcept
bool
write(error_code&, WriteFunction&& wf) noexcept
{
wf(boost::asio::null_buffers{});
return true;

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_FIELDS_HPP
#define BEAST_HTTP_FIELDS_HPP
#include <beast/config.hpp>
#include <beast/http/basic_fields.hpp>
#include <memory>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_HEADERS_PARSER_V1_HPP
#define BEAST_HTTP_HEADERS_PARSER_V1_HPP
#include <beast/config.hpp>
#include <beast/http/basic_parser_v1.hpp>
#include <beast/http/concepts.hpp>
#include <beast/http/message.hpp>

View File

@@ -9,7 +9,6 @@
#define BEAST_HTTP_IMPL_WRITE_IPP
#include <beast/http/concepts.hpp>
#include <beast/http/resume_context.hpp>
#include <beast/http/chunk_encode.hpp>
#include <beast/core/buffer_cat.hpp>
#include <beast/core/bind_handler.hpp>
@@ -21,7 +20,6 @@
#include <beast/core/write_dynabuf.hpp>
#include <beast/core/detail/sync_ostream.hpp>
#include <boost/asio/write.hpp>
#include <boost/logic/tribool.hpp>
#include <condition_variable>
#include <mutex>
#include <ostream>
@@ -296,8 +294,6 @@ class write_op
// VFALCO How do we use handler_alloc in write_preparation?
write_preparation<
isRequest, Body, Fields> wp;
resume_context resume;
resume_context copy;
int state = 0;
data(Handler& handler, Stream& s_,
@@ -375,27 +371,9 @@ public:
: d_(std::forward<DeducedHandler>(h),
s, std::forward<Args>(args)...)
{
auto& d = *d_;
auto sp = d_;
d.resume = {
[sp]() mutable
{
write_op self{std::move(sp)};
self.d_->cont = false;
auto& ios = self.d_->s.get_io_service();
ios.dispatch(bind_handler(std::move(self),
error_code{}, 0, false));
}};
d.copy = d.resume;
(*this)(error_code{}, 0, false);
}
explicit
write_op(handler_ptr<data, Handler> d)
: d_(std::move(d))
{
}
void
operator()(error_code ec,
std::size_t bytes_transferred, bool again = true);
@@ -460,8 +438,9 @@ operator()(error_code ec, std::size_t, bool again)
case 1:
{
boost::tribool const result = d.wp.w.write(
std::move(d.copy), ec, writef0_lambda{*this});
auto const result =
d.wp.w.write(ec,
writef0_lambda{*this});
if(ec)
{
// call handler
@@ -470,12 +449,6 @@ operator()(error_code ec, std::size_t, bool again)
std::move(*this), ec, false));
return;
}
if(boost::indeterminate(result))
{
// suspend
d.copy = d.resume;
return;
}
if(result)
d.state = d.wp.chunked ? 4 : 5;
else
@@ -491,20 +464,15 @@ operator()(error_code ec, std::size_t, bool again)
case 3:
{
boost::tribool result = d.wp.w.write(
std::move(d.copy), ec, writef_lambda{*this});
auto const result =
d.wp.w.write(ec,
writef_lambda{*this});
if(ec)
{
// call handler
d.state = 99;
break;
}
if(boost::indeterminate(result))
{
// suspend
d.copy = d.resume;
return;
}
if(result)
d.state = d.wp.chunked ? 4 : 5;
else
@@ -533,8 +501,6 @@ operator()(error_code ec, std::size_t, bool again)
break;
}
}
d.copy = {};
d.resume = {};
d_.invoke(ec);
}
@@ -640,37 +606,12 @@ write(SyncWriteStream& stream,
wp.init(ec);
if(ec)
return;
std::mutex m;
std::condition_variable cv;
bool ready = false;
resume_context resume{
[&]
{
std::lock_guard<std::mutex> lock(m);
ready = true;
cv.notify_one();
}};
auto copy = resume;
boost::tribool result =
wp.w.write(std::move(copy), ec,
detail::writef0_lambda<SyncWriteStream,
decltype(wp.sb)>{stream,
wp.sb, wp.chunked, ec});
auto result = wp.w.write(
ec, detail::writef0_lambda<
SyncWriteStream, decltype(wp.sb)>{
stream, wp.sb, wp.chunked, ec});
if(ec)
return;
if(boost::indeterminate(result))
{
copy = resume;
{
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [&]{ return ready; });
ready = false;
}
boost::asio::write(stream, wp.sb.data(), ec);
if(ec)
return;
result = false;
}
wp.sb.consume(wp.sb.size());
if(! result)
{
@@ -678,17 +619,11 @@ write(SyncWriteStream& stream,
stream, wp.chunked, ec};
for(;;)
{
result = wp.w.write(std::move(copy), ec, wf);
result = wp.w.write(ec, wf);
if(ec)
return;
if(result)
break;
if(! result)
continue;
copy = resume;
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [&]{ return ready; });
ready = false;
}
}
if(wp.chunked)

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_MESSAGE_HPP
#define BEAST_HTTP_MESSAGE_HPP
#include <beast/config.hpp>
#include <beast/http/fields.hpp>
#include <beast/core/detail/integer_sequence.hpp>
#include <memory>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_PARSE_HPP
#define BEAST_HTTP_PARSE_HPP
#include <beast/config.hpp>
#include <beast/core/error.hpp>
#include <beast/core/async_completion.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_PARSE_ERROR_HPP
#define BEAST_HTTP_PARSE_ERROR_HPP
#include <beast/config.hpp>
#include <beast/core/error.hpp>
namespace beast {

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_PARSER_V1_HPP
#define BEAST_HTTP_PARSER_V1_HPP
#include <beast/config.hpp>
#include <beast/http/concepts.hpp>
#include <beast/http/header_parser_v1.hpp>
#include <beast/http/message.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_READ_HPP
#define BEAST_HTTP_READ_HPP
#include <beast/config.hpp>
#include <beast/core/async_completion.hpp>
#include <beast/core/error.hpp>
#include <beast/http/message.hpp>

View File

@@ -8,6 +8,8 @@
#ifndef BEAST_HTTP_REASON_HPP
#define BEAST_HTTP_REASON_HPP
#include <beast/config.hpp>
namespace beast {
namespace http {

View File

@@ -1,34 +0,0 @@
//
// Copyright (c) 2013-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)
//
#ifndef BEAST_HTTP_RESUME_CONTEXT_HPP
#define BEAST_HTTP_RESUME_CONTEXT_HPP
#include <functional>
namespace beast {
namespace http {
/** A functor that resumes a write operation.
An rvalue reference to an object of this type is provided by the
write implementation to the `writer` associated with the body of
a message being sent.
If it is desired that the `writer` suspend the write operation (for
example, to wait until data is ready), it can take ownership of
the resume context using a move. Then, it returns `boost::indeterminate`
to indicate that the write operation should suspend. Later, the calling
code invokes the resume function and the write operation continues
from where it left off.
*/
using resume_context = std::function<void(void)>;
} // http
} // beast
#endif

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_RFC7230_HPP
#define BEAST_HTTP_RFC7230_HPP
#include <beast/config.hpp>
#include <beast/http/detail/rfc7230.hpp>
namespace beast {

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_STREAMBUF_BODY_HPP
#define BEAST_HTTP_STREAMBUF_BODY_HPP
#include <beast/config.hpp>
#include <beast/http/basic_dynabuf_body.hpp>
#include <beast/core/streambuf.hpp>

View File

@@ -8,12 +8,11 @@
#ifndef BEAST_HTTP_STRING_BODY_HPP
#define BEAST_HTTP_STRING_BODY_HPP
#include <beast/config.hpp>
#include <beast/core/error.hpp>
#include <beast/http/message.hpp>
#include <beast/http/resume_context.hpp>
#include <beast/core/detail/type_traits.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/logic/tribool.hpp>
#include <memory>
#include <string>
@@ -87,9 +86,8 @@ private:
}
template<class WriteFunction>
boost::tribool
write(resume_context&&, error_code&,
WriteFunction&& wf) noexcept
bool
write(error_code&, WriteFunction&& wf) noexcept
{
wf(boost::asio::buffer(body_));
return true;

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_WRITE_HPP
#define BEAST_HTTP_WRITE_HPP
#include <beast/config.hpp>
#include <beast/http/message.hpp>
#include <beast/core/error.hpp>
#include <beast/core/async_completion.hpp>

View File

@@ -8,6 +8,8 @@
#ifndef BEAST_VERSION_HPP
#define BEAST_VERSION_HPP
#include <beast/config.hpp>
// follows http://semver.org
// BEAST_VERSION % 100 is the patch level
@@ -16,6 +18,6 @@
//
#define BEAST_VERSION 100000
#define BEAST_VERSION_STRING "1.0.0-b30"
#define BEAST_VERSION_STRING "1.0.0-b34"
#endif

View File

@@ -8,6 +8,8 @@
#ifndef BEAST_WEBSOCKET_HPP
#define BEAST_WEBSOCKET_HPP
#include <beast/config.hpp>
#include <beast/websocket/error.hpp>
#include <beast/websocket/option.hpp>
#include <beast/websocket/rfc6455.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_WEBSOCKET_ERROR_HPP
#define BEAST_WEBSOCKET_ERROR_HPP
#include <beast/config.hpp>
#include <beast/core/error.hpp>
namespace beast {

View File

@@ -1059,15 +1059,8 @@ operator()(error_code const& ec, bool again)
case 0:
// read payload
d.state = 1;
#if 0
// VFALCO This causes dereference of null, because
// the handler is moved from the data block
// before asio_handler_deallocate is called.
d.ws.async_read_frame(
d.fi, d.db, std::move(*this));
#else
d.ws.async_read_frame(d.fi, d.db, *this);
#endif
return;
// got payload

View File

@@ -770,6 +770,7 @@ write_frame(bool fin,
fh.len = n;
remain -= n;
fh.fin = fin ? remain == 0 : false;
wr_.cont = ! fh.fin;
detail::fh_streambuf fh_buf;
detail::write<static_streambuf>(fh_buf, fh);
boost::asio::write(stream_,

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_WEBSOCKET_OPTION_HPP
#define BEAST_WEBSOCKET_OPTION_HPP
#include <beast/config.hpp>
#include <beast/websocket/rfc6455.hpp>
#include <beast/websocket/detail/decorator.hpp>
#include <beast/core/detail/type_traits.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_WEBSOCKET_RFC6455_HPP
#define BEAST_WEBSOCKET_RFC6455_HPP
#include <beast/config.hpp>
#include <beast/core/static_string.hpp>
#include <boost/optional.hpp>
#include <array>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_WEBSOCKET_SSL_HPP
#define BEAST_WEBSOCKET_SSL_HPP
#include <beast/config.hpp>
#include <beast/websocket/teardown.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/stream.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_WEBSOCKET_STREAM_HPP
#define BEAST_WEBSOCKET_STREAM_HPP
#include <beast/config.hpp>
#include <beast/websocket/option.hpp>
#include <beast/websocket/detail/stream_base.hpp>
#include <beast/http/message.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef BEAST_WEBSOCKET_TEARDOWN_HPP
#define BEAST_WEBSOCKET_TEARDOWN_HPP
#include <beast/config.hpp>
#include <beast/websocket/error.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <type_traits>

View File

@@ -8,6 +8,8 @@
#ifndef BEAST_ZLIB_HPP
#define BEAST_ZLIB_HPP
#include <beast/config.hpp>
#include <beast/zlib/deflate_stream.hpp>
#include <beast/zlib/inflate_stream.hpp>

View File

@@ -35,6 +35,7 @@
#ifndef BEAST_ZLIB_DEFLATE_STREAM_HPP
#define BEAST_ZLIB_DEFLATE_STREAM_HPP
#include <beast/config.hpp>
#include <beast/zlib/error.hpp>
#include <beast/zlib/zlib.hpp>
#include <beast/zlib/detail/deflate_stream.hpp>

View File

@@ -35,6 +35,7 @@
#ifndef BEAST_ZLIB_ERROR_HPP
#define BEAST_ZLIB_ERROR_HPP
#include <beast/config.hpp>
#include <beast/core/error.hpp>
namespace beast {

View File

@@ -35,6 +35,7 @@
#ifndef BEAST_ZLIB_INFLATE_STREAM_HPP
#define BEAST_ZLIB_INFLATE_STREAM_HPP
#include <beast/config.hpp>
#include <beast/zlib/detail/inflate_stream.hpp>
namespace beast {

View File

@@ -35,6 +35,7 @@
#ifndef BEAST_ZLIB_ZLIB_HPP
#define BEAST_ZLIB_ZLIB_HPP
#include <beast/config.hpp>
#include <cstdint>
#include <cstdlib>

View File

@@ -8,6 +8,7 @@ add_executable (lib-tests
${BEAST_INCLUDES}
${EXTRAS_INCLUDES}
../extras/beast/unit_test/main.cpp
config.cpp
core.cpp
http.cpp
version.cpp
@@ -16,6 +17,8 @@ add_executable (lib-tests
)
if (NOT WIN32)
target_link_libraries(lib-tests ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(lib-tests ${Boost_LIBRARIES})
endif()

View File

@@ -7,6 +7,7 @@
import os ;
compile config.cpp : : ;
compile core.cpp : : ;
compile http.cpp : : ;
compile version.cpp : : ;
@@ -58,7 +59,6 @@ unit-test http-tests :
http/parser_v1.cpp
http/read.cpp
http/reason.cpp
http/resume_context.cpp
http/rfc7230.cpp
http/streambuf_body.cpp
http/string_body.cpp

View File

@@ -6,4 +6,4 @@
//
// Test that header file is self-contained.
#include <beast/http/resume_context.hpp>
#include <beast/config.hpp>

View File

@@ -39,4 +39,6 @@ add_executable (core-tests
if (NOT WIN32)
target_link_libraries(core-tests ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(core-tests ${Boost_LIBRARIES})
endif()

View File

@@ -23,7 +23,6 @@ add_executable (http-tests
parser_v1.cpp
read.cpp
reason.cpp
resume_context.cpp
rfc7230.cpp
streambuf_body.cpp
string_body.cpp
@@ -33,6 +32,8 @@ add_executable (http-tests
if (NOT WIN32)
target_link_libraries(http-tests ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(http-tests ${Boost_LIBRARIES})
endif()
add_executable (bench-tests
@@ -45,5 +46,7 @@ add_executable (bench-tests
)
if (NOT WIN32)
target_link_libraries(bench-tests ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(bench-tests ${Boost_LIBRARIES})
endif()

View File

@@ -17,6 +17,7 @@
#include <beast/test/yield_to.hpp>
#include <beast/unit_test/suite.hpp>
#include <boost/asio/spawn.hpp>
#include <atomic>
namespace beast {
namespace http {
@@ -374,6 +375,55 @@ public:
}
}
// Ensure completion handlers are not leaked
struct handler
{
static std::atomic<std::size_t>&
count() { static std::atomic<std::size_t> n; return n; }
handler() { ++count(); }
~handler() { --count(); }
handler(handler const&) { ++count(); }
void operator()(error_code const&) const {}
};
void
testIoService()
{
{
// Make sure handlers are not destroyed
// after calling io_service::stop
boost::asio::io_service ios;
test::string_istream is{ios,
"GET / HTTP/1.1\r\n\r\n"};
BEAST_EXPECT(handler::count() == 0);
streambuf sb;
message<true, streambuf_body, fields> m;
async_read(is, sb, m, handler{});
BEAST_EXPECT(handler::count() > 0);
ios.stop();
BEAST_EXPECT(handler::count() > 0);
ios.reset();
BEAST_EXPECT(handler::count() > 0);
ios.run_one();
BEAST_EXPECT(handler::count() == 0);
}
{
// Make sure uninvoked handlers are
// destroyed when calling ~io_service
{
boost::asio::io_service ios;
test::string_istream is{ios,
"GET / HTTP/1.1\r\n\r\n"};
BEAST_EXPECT(handler::count() == 0);
streambuf sb;
message<true, streambuf_body, fields> m;
async_read(is, sb, m, handler{});
BEAST_EXPECT(handler::count() > 0);
}
BEAST_EXPECT(handler::count() == 0);
}
}
void run() override
{
testThrow();
@@ -382,6 +432,8 @@ public:
yield_to(&read_test::testReadHeaders, this);
yield_to(&read_test::testRead, this);
yield_to(&read_test::testEof, this);
testIoService();
}
};
@@ -389,4 +441,3 @@ BEAST_DEFINE_TESTSUITE(read,http,beast);
} // http
} // beast

View File

@@ -55,9 +55,8 @@ public:
}
template<class WriteFunction>
boost::tribool
write(resume_context&&, error_code&,
WriteFunction&& wf) noexcept
bool
write(error_code&, WriteFunction&& wf) noexcept
{
wf(boost::asio::buffer(body_));
return true;
@@ -103,8 +102,6 @@ public:
{
std::size_t n_ = 0;
value_type const& body_;
bool suspend_ = false;
enable_yield_to yt_;
public:
template<bool isRequest, class Allocator>
@@ -120,37 +117,12 @@ public:
body_.fc_.fail(ec);
}
class do_resume
{
resume_context rc_;
public:
explicit
do_resume(resume_context&& rc)
: rc_(std::move(rc))
{
}
void
operator()()
{
rc_();
}
};
template<class WriteFunction>
boost::tribool
write(resume_context&& rc, error_code& ec,
WriteFunction&& wf) noexcept
bool
write(error_code& ec, WriteFunction&& wf) noexcept
{
if(body_.fc_.fail(ec))
return false;
suspend_ = ! suspend_;
if(suspend_)
{
yt_.get_io_service().post(do_resume{std::move(rc)});
return boost::indeterminate;
}
if(n_ >= body_.s_.size())
return true;
wf(boost::asio::buffer(body_.s_.data() + n_, 1));
@@ -639,6 +611,61 @@ public:
}
}
// Ensure completion handlers are not leaked
struct handler
{
static std::atomic<std::size_t>&
count() { static std::atomic<std::size_t> n; return n; }
handler() { ++count(); }
~handler() { --count(); }
handler(handler const&) { ++count(); }
void operator()(error_code const&) const {}
};
void
testIoService()
{
{
// Make sure handlers are not destroyed
// after calling io_service::stop
boost::asio::io_service ios;
test::string_ostream os{ios};
BEAST_EXPECT(handler::count() == 0);
message<true, string_body, fields> m;
m.method = "GET";
m.version = 11;
m.url = "/";
m.fields["Content-Length"] = "5";
m.body = "*****";
async_write(os, m, handler{});
BEAST_EXPECT(handler::count() > 0);
ios.stop();
BEAST_EXPECT(handler::count() > 0);
ios.reset();
BEAST_EXPECT(handler::count() > 0);
ios.run_one();
BEAST_EXPECT(handler::count() == 0);
}
{
// Make sure uninvoked handlers are
// destroyed when calling ~io_service
{
boost::asio::io_service ios;
test::string_ostream is{ios};
BEAST_EXPECT(handler::count() == 0);
message<true, string_body, fields> m;
m.method = "GET";
m.version = 11;
m.url = "/";
m.fields["Content-Length"] = "5";
m.body = "*****";
async_write(is, m, handler{});
BEAST_EXPECT(handler::count() > 0);
}
BEAST_EXPECT(handler::count() == 0);
}
}
void run() override
{
yield_to(&write_test::testAsyncWriteHeaders, this);
@@ -647,6 +674,7 @@ public:
testOutput();
test_std_ostream();
testOstream();
testIoService();
}
};

View File

@@ -22,6 +22,8 @@ add_executable (websocket-tests
if (NOT WIN32)
target_link_libraries(websocket-tests ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(websocket-tests ${Boost_LIBRARIES})
endif()
if (MINGW)

View File

@@ -109,26 +109,38 @@ public:
return false;
}
struct identity
struct test_decorator
{
template<class Body, class Fields>
void
operator()(http::message<true, Body, Fields>&)
int& what;
test_decorator(test_decorator const&) = default;
test_decorator(int& what_)
: what(what_)
{
what = 0;
}
template<class Body, class Fields>
template<class Fields>
void
operator()(http::message<false, Body, Fields>&)
operator()(http::header<true, Fields>&) const
{
what |= 1;
}
template<class Fields>
void
operator()(http::header<false, Fields>&) const
{
what |= 2;
}
};
void testOptions()
void
testOptions()
{
stream<socket_type> ws(ios_);
ws.set_option(auto_fragment{true});
ws.set_option(decorate(identity{}));
ws.set_option(keep_alive{false});
ws.set_option(write_buffer_size{2048});
ws.set_option(message_type{opcode::text});
@@ -411,6 +423,24 @@ public:
);
}
void
testDecorator(endpoint_type const& ep)
{
error_code ec;
socket_type sock{ios_};
sock.connect(ep, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
stream<socket_type&> ws{sock};
int what;
ws.set_option(decorate(test_decorator{what}));
BEAST_EXPECT(what == 0);
ws.handshake("localhost", "/", ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
BEAST_EXPECT(what == 1);
}
void testMask(endpoint_type const& ep,
yield_context do_yield)
{
@@ -775,6 +805,32 @@ public:
}
#endif
/*
https://github.com/vinniefalco/Beast/issues/300
Write a message as two individual frames
*/
void
testWriteFrames(endpoint_type const& ep)
{
error_code ec;
socket_type sock{ios_};
sock.connect(ep, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
stream<socket_type&> ws{sock};
ws.handshake("localhost", "/", ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
ws.write_frame(false, sbuf("u"));
ws.write_frame(true, sbuf("v"));
streambuf sb;
opcode op;
ws.read(op, sb, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
}
void
testAsyncWriteFrame(endpoint_type const& ep)
{
@@ -1251,17 +1307,24 @@ public:
testBadHandshakes();
testBadResponses();
permessage_deflate pmd;
pmd.client_enable = false;
pmd.server_enable = false;
{
error_code ec;
::websocket::sync_echo_server server{nullptr};
server.set_option(pmd);
server.open(any, ec);
BEAST_EXPECTS(! ec, ec.message());
auto const ep = server.local_endpoint();
testDecorator(ep);
//testInvokable1(ep);
testInvokable2(ep);
testInvokable3(ep);
testInvokable4(ep);
//testInvokable5(ep);
testWriteFrames(ep);
testAsyncWriteFrame(ep);
}
@@ -1309,8 +1372,6 @@ public:
}
};
permessage_deflate pmd;
pmd.client_enable = false;
pmd.server_enable = false;
doClientTests(pmd);

View File

@@ -21,4 +21,6 @@ add_executable (zlib-tests
if (NOT WIN32)
target_link_libraries(zlib-tests ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(zlib-tests ${Boost_LIBRARIES})
endif()