diff --git a/Builds/VisualStudio2015/RippleD.vcxproj b/Builds/VisualStudio2015/RippleD.vcxproj index 2b8fe0fb23..d919a37f53 100644 --- a/Builds/VisualStudio2015/RippleD.vcxproj +++ b/Builds/VisualStudio2015/RippleD.vcxproj @@ -264,6 +264,8 @@ + + @@ -400,8 +402,6 @@ - - diff --git a/Builds/VisualStudio2015/RippleD.vcxproj.filters b/Builds/VisualStudio2015/RippleD.vcxproj.filters index 9bf79914ac..62447e0c69 100644 --- a/Builds/VisualStudio2015/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2015/RippleD.vcxproj.filters @@ -555,6 +555,9 @@ beast\unit_test + + beast + beast\core @@ -759,9 +762,6 @@ beast\http - - beast\http - beast\http diff --git a/src/beast/CHANGELOG.md b/src/beast/CHANGELOG.md index 383491ba70..2dcb1650c7 100644 --- a/src/beast/CHANGELOG.md +++ b/src/beast/CHANGELOG.md @@ -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 diff --git a/src/beast/CMakeLists.txt b/src/beast/CMakeLists.txt index 61a243c030..c82014589f 100644 --- a/src/beast/CMakeLists.txt +++ b/src/beast/CMakeLists.txt @@ -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) diff --git a/src/beast/Jamroot b/src/beast/Jamroot index 543305236a..277100ab23 100644 --- a/src/beast/Jamroot +++ b/src/beast/Jamroot @@ -93,19 +93,20 @@ project beast /boost/filesystem//boost_filesystem /boost/program_options//boost_program_options BOOST_ALL_NO_LIB=1 + BOOST_COROUTINES_NO_DEPRECATION_WARNING=1 multi shared on gcc:-std=c++11 gcc:-Wno-unused-parameter + gcc:-Wno-unused-variable # Temporary until we can figure out -isystem clang:-std=c++11 clang:-Wno-unused-parameter - gcc:-Wno-unused-variable # Temporary until we can figure out -isystem clang:-Wno-unused-variable # Temporary until we can figure out -isystem msvc:_SCL_SECURE_NO_WARNINGS=1 msvc:_CRT_SECURE_NO_WARNINGS=1 - msvc:"/wd4100 /bigobj" - msvc,release:"/Ob2 /Oi /Ot" + msvc:"/wd4100 /wd4251 /bigobj" + msvc:release:"/Ob2 /Oi /Ot" LINUX:_XOPEN_SOURCE=600 LINUX:_GNU_SOURCE=1 SOLARIS:_XOPEN_SOURCE=500 diff --git a/src/beast/README.md b/src/beast/README.md index ef9b317d7a..1dcf4b52a1 100644 --- a/src/beast/README.md +++ b/src/beast/README.md @@ -1,12 +1,7 @@ Beast -[![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 diff --git a/src/beast/doc/quickref.xml b/src/beast/doc/quickref.xml index 96002191c7..874c5a6936 100644 --- a/src/beast/doc/quickref.xml +++ b/src/beast/doc/quickref.xml @@ -42,7 +42,6 @@ request_header response response_header - resume_context streambuf_body string_body @@ -190,6 +189,7 @@ buffer_cat prepare_buffer prepare_buffers + system_category to_string write diff --git a/src/beast/doc/types/Writer.qbk b/src/beast/doc/types/Writer.qbk index 90d4e6e396..aef4601ce4 100644 --- a/src/beast/doc/types/Writer.qbk +++ b/src/beast/doc/types/Writer.qbk @@ -28,8 +28,6 @@ In this table: * `m` denotes a value of type `message const&` where `std::is_same: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 - boost::tribool + bool write( - resume_context&&, error_code&, WriteFunction&& wf) noexcept; }; diff --git a/src/beast/examples/CMakeLists.txt b/src/beast/examples/CMakeLists.txt index 6d9e8edb36..edb8e3339e 100644 --- a/src/beast/examples/CMakeLists.txt +++ b/src/beast/examples/CMakeLists.txt @@ -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() diff --git a/src/beast/examples/file_body.hpp b/src/beast/examples/file_body.hpp index 8aef3f2de6..00f2b5434d 100644 --- a/src/beast/examples/file_body.hpp +++ b/src/beast/examples/file_body.hpp @@ -10,10 +10,9 @@ #include #include -#include #include +#include #include -#include #include #include @@ -38,7 +37,8 @@ struct file_body writer& operator=(writer const&) = delete; template - writer(message const& m) noexcept + writer(message 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(errno)); + ec = error_code{errno, + system_category()}; else size_ = boost::filesystem::file_size(path_); } @@ -67,19 +67,25 @@ struct file_body } template - 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( 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_; } }; diff --git a/src/beast/include/beast/config.hpp b/src/beast/include/beast/config.hpp new file mode 100644 index 0000000000..b87262c779 --- /dev/null +++ b/src/beast/include/beast/config.hpp @@ -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 diff --git a/src/beast/include/beast/core.hpp b/src/beast/include/beast/core.hpp index ed777e54ba..9377cd99fe 100644 --- a/src/beast/include/beast/core.hpp +++ b/src/beast/include/beast/core.hpp @@ -8,6 +8,8 @@ #ifndef BEAST_CORE_HPP #define BEAST_CORE_HPP +#include + #include #include #include diff --git a/src/beast/include/beast/core/async_completion.hpp b/src/beast/include/beast/core/async_completion.hpp index af5c67d2cf..8c7f64d9ff 100644 --- a/src/beast/include/beast/core/async_completion.hpp +++ b/src/beast/include/beast/core/async_completion.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_ASYNC_COMPLETION_HPP #define BEAST_ASYNC_COMPLETION_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/bind_handler.hpp b/src/beast/include/beast/core/bind_handler.hpp index a9094abb4a..1b2d11daf8 100644 --- a/src/beast/include/beast/core/bind_handler.hpp +++ b/src/beast/include/beast/core/bind_handler.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_BIND_HANDLER_HPP #define BEAST_BIND_HANDLER_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/buffer_cat.hpp b/src/beast/include/beast/core/buffer_cat.hpp index cd2062621a..a0c892a716 100644 --- a/src/beast/include/beast/core/buffer_cat.hpp +++ b/src/beast/include/beast/core/buffer_cat.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_BUFFER_CAT_HPP #define BEAST_BUFFER_CAT_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/buffer_concepts.hpp b/src/beast/include/beast/core/buffer_concepts.hpp index 5348724b0b..545689eb3f 100644 --- a/src/beast/include/beast/core/buffer_concepts.hpp +++ b/src/beast/include/beast/core/buffer_concepts.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_BUFFER_CONCEPTS_HPP #define BEAST_BUFFER_CONCEPTS_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/buffers_adapter.hpp b/src/beast/include/beast/core/buffers_adapter.hpp index 9dadf7f133..36220d0564 100644 --- a/src/beast/include/beast/core/buffers_adapter.hpp +++ b/src/beast/include/beast/core/buffers_adapter.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_BUFFERS_ADAPTER_HPP #define BEAST_BUFFERS_ADAPTER_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/consuming_buffers.hpp b/src/beast/include/beast/core/consuming_buffers.hpp index 8e09ac5846..4d8d42a641 100644 --- a/src/beast/include/beast/core/consuming_buffers.hpp +++ b/src/beast/include/beast/core/consuming_buffers.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_CONSUMING_BUFFERS_HPP #define BEAST_CONSUMING_BUFFERS_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/dynabuf_readstream.hpp b/src/beast/include/beast/core/dynabuf_readstream.hpp index 44501a658b..e914d434d3 100644 --- a/src/beast/include/beast/core/dynabuf_readstream.hpp +++ b/src/beast/include/beast/core/dynabuf_readstream.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_DYNABUF_READSTREAM_HPP #define BEAST_DYNABUF_READSTREAM_HPP +#include #include #include #include @@ -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() diff --git a/src/beast/include/beast/core/error.hpp b/src/beast/include/beast/core/error.hpp index f94e52b5ce..b8c78687c0 100644 --- a/src/beast/include/beast/core/error.hpp +++ b/src/beast/include/beast/core/error.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_ERROR_HPP #define BEAST_ERROR_HPP +#include #include #include @@ -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; diff --git a/src/beast/include/beast/core/handler_alloc.hpp b/src/beast/include/beast/core/handler_alloc.hpp index 4037efc512..08a395c3ec 100644 --- a/src/beast/include/beast/core/handler_alloc.hpp +++ b/src/beast/include/beast/core/handler_alloc.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HANDLER_ALLOC_HPP #define BEAST_HANDLER_ALLOC_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/handler_concepts.hpp b/src/beast/include/beast/core/handler_concepts.hpp index 2e3854d374..e118072aeb 100644 --- a/src/beast/include/beast/core/handler_concepts.hpp +++ b/src/beast/include/beast/core/handler_concepts.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HANDLER_CONCEPTS_HPP #define BEAST_HANDLER_CONCEPTS_HPP +#include #include #include diff --git a/src/beast/include/beast/core/handler_helpers.hpp b/src/beast/include/beast/core/handler_helpers.hpp index 2ff589ad46..53112e7f15 100644 --- a/src/beast/include/beast/core/handler_helpers.hpp +++ b/src/beast/include/beast/core/handler_helpers.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HANDLER_HELPERS_HPP #define BEAST_HANDLER_HELPERS_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/handler_ptr.hpp b/src/beast/include/beast/core/handler_ptr.hpp index 46dc5265c6..52650656e4 100644 --- a/src/beast/include/beast/core/handler_ptr.hpp +++ b/src/beast/include/beast/core/handler_ptr.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HANDLER_PTR_HPP #define BEAST_HANDLER_PTR_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/placeholders.hpp b/src/beast/include/beast/core/placeholders.hpp index 5272bb28e8..c112778936 100644 --- a/src/beast/include/beast/core/placeholders.hpp +++ b/src/beast/include/beast/core/placeholders.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_PLACEHOLDERS_HPP #define BEAST_PLACEHOLDERS_HPP +#include #include namespace beast { diff --git a/src/beast/include/beast/core/prepare_buffer.hpp b/src/beast/include/beast/core/prepare_buffer.hpp index 2d05aa3160..ab0fae645b 100644 --- a/src/beast/include/beast/core/prepare_buffer.hpp +++ b/src/beast/include/beast/core/prepare_buffer.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_PREPARE_BUFFER_HPP #define BEAST_PREPARE_BUFFER_HPP +#include #include #include diff --git a/src/beast/include/beast/core/prepare_buffers.hpp b/src/beast/include/beast/core/prepare_buffers.hpp index 4f1d6f1aaa..7db31b5b80 100644 --- a/src/beast/include/beast/core/prepare_buffers.hpp +++ b/src/beast/include/beast/core/prepare_buffers.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_PREPARE_BUFFERS_HPP #define BEAST_PREPARE_BUFFERS_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/static_streambuf.hpp b/src/beast/include/beast/core/static_streambuf.hpp index 748111b021..75ced50a37 100644 --- a/src/beast/include/beast/core/static_streambuf.hpp +++ b/src/beast/include/beast/core/static_streambuf.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_STATIC_STREAMBUF_HPP #define BEAST_STATIC_STREAMBUF_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/static_string.hpp b/src/beast/include/beast/core/static_string.hpp index 96e842ef1d..6ba5332cac 100644 --- a/src/beast/include/beast/core/static_string.hpp +++ b/src/beast/include/beast/core/static_string.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_WEBSOCKET_STATIC_STRING_HPP #define BEAST_WEBSOCKET_STATIC_STRING_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/stream_concepts.hpp b/src/beast/include/beast/core/stream_concepts.hpp index 6e77657360..5f0ba3adfa 100644 --- a/src/beast/include/beast/core/stream_concepts.hpp +++ b/src/beast/include/beast/core/stream_concepts.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_STREAM_CONCEPTS_HPP #define BEAST_STREAM_CONCEPTS_HPP +#include #include #include diff --git a/src/beast/include/beast/core/streambuf.hpp b/src/beast/include/beast/core/streambuf.hpp index 3683f68a96..537094c1a4 100644 --- a/src/beast/include/beast/core/streambuf.hpp +++ b/src/beast/include/beast/core/streambuf.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_STREAMBUF_HPP #define BEAST_STREAMBUF_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/to_string.hpp b/src/beast/include/beast/core/to_string.hpp index 110022e0c5..e391ea2d57 100644 --- a/src/beast/include/beast/core/to_string.hpp +++ b/src/beast/include/beast/core/to_string.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_TO_STRING_HPP #define BEAST_TO_STRING_HPP +#include #include #include #include diff --git a/src/beast/include/beast/core/write_dynabuf.hpp b/src/beast/include/beast/core/write_dynabuf.hpp index 54c365a539..646e787498 100644 --- a/src/beast/include/beast/core/write_dynabuf.hpp +++ b/src/beast/include/beast/core/write_dynabuf.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_WRITE_DYNABUF_HPP #define BEAST_WRITE_DYNABUF_HPP +#include #include #include #include diff --git a/src/beast/include/beast/http.hpp b/src/beast/include/beast/http.hpp index dcb3279187..b4c7734f17 100644 --- a/src/beast/include/beast/http.hpp +++ b/src/beast/include/beast/http.hpp @@ -8,6 +8,8 @@ #ifndef BEAST_HTTP_HPP #define BEAST_HTTP_HPP +#include + #include #include #include @@ -19,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/src/beast/include/beast/http/basic_dynabuf_body.hpp b/src/beast/include/beast/http/basic_dynabuf_body.hpp index cdae120aaf..a2c090149e 100644 --- a/src/beast/include/beast/http/basic_dynabuf_body.hpp +++ b/src/beast/include/beast/http/basic_dynabuf_body.hpp @@ -8,12 +8,11 @@ #ifndef BEAST_HTTP_BASIC_DYNABUF_BODY_HPP #define BEAST_HTTP_BASIC_DYNABUF_BODY_HPP +#include #include #include -#include #include #include -#include namespace beast { namespace http { @@ -87,9 +86,8 @@ private: } template - boost::tribool - write(resume_context&&, error_code&, - WriteFunction&& wf) noexcept + bool + write(error_code&, WriteFunction&& wf) noexcept { wf(body_.data()); return true; diff --git a/src/beast/include/beast/http/basic_fields.hpp b/src/beast/include/beast/http/basic_fields.hpp index 30913c8fe4..2589c827a9 100644 --- a/src/beast/include/beast/http/basic_fields.hpp +++ b/src/beast/include/beast/http/basic_fields.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_BASIC_FIELDS_HPP #define BEAST_HTTP_BASIC_FIELDS_HPP +#include #include #include #include diff --git a/src/beast/include/beast/http/basic_parser_v1.hpp b/src/beast/include/beast/http/basic_parser_v1.hpp index 939cf2c63c..cda14a0023 100644 --- a/src/beast/include/beast/http/basic_parser_v1.hpp +++ b/src/beast/include/beast/http/basic_parser_v1.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_BASIC_PARSER_v1_HPP #define BEAST_HTTP_BASIC_PARSER_v1_HPP +#include #include #include #include diff --git a/src/beast/include/beast/http/chunk_encode.hpp b/src/beast/include/beast/http/chunk_encode.hpp index fabdd1b563..a437fe1839 100644 --- a/src/beast/include/beast/http/chunk_encode.hpp +++ b/src/beast/include/beast/http/chunk_encode.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_CHUNK_ENCODE_HPP #define BEAST_HTTP_CHUNK_ENCODE_HPP +#include #include #include #include diff --git a/src/beast/include/beast/http/concepts.hpp b/src/beast/include/beast/http/concepts.hpp index 9d43080cf3..2e83fe7a48 100644 --- a/src/beast/include/beast/http/concepts.hpp +++ b/src/beast/include/beast/http/concepts.hpp @@ -8,11 +8,10 @@ #ifndef BEAST_HTTP_TYPE_CHECK_HPP #define BEAST_HTTP_TYPE_CHECK_HPP +#include #include #include -#include #include -#include #include #include @@ -50,38 +49,6 @@ struct has_content_length> -struct is_Writer : std::false_type {}; - -template -struct is_Writer().init( - std::declval()) - // VFALCO This is unfortunate, we have to provide the template - // argument type because this is not a deduced context? - // - ,std::declval().template write( - std::declval(), - std::declval(), - std::declval()) - )> > : std::integral_constant::value && - std::is_convertible().template write( - std::declval(), - std::declval(), - std::declval())), - boost::tribool>::value - > -{ - static_assert(std::is_same< - typename M::body_type::writer, T>::value, - "Mismatched writer and message"); -}; - -#else - template class is_Writer { @@ -99,10 +66,9 @@ class is_Writer template().template write( - std::declval(), std::declval(), std::declval())) - , boost::tribool>> + , bool>> static R check2(int); template static std::false_type check2(...); @@ -120,8 +86,6 @@ public: >; }; -#endif - template class is_Parser { diff --git a/src/beast/include/beast/http/empty_body.hpp b/src/beast/include/beast/http/empty_body.hpp index a1efddc29a..40f549d9f4 100644 --- a/src/beast/include/beast/http/empty_body.hpp +++ b/src/beast/include/beast/http/empty_body.hpp @@ -8,12 +8,11 @@ #ifndef BEAST_HTTP_EMPTY_BODY_HPP #define BEAST_HTTP_EMPTY_BODY_HPP +#include #include #include -#include #include #include -#include #include #include @@ -59,9 +58,8 @@ private: } template - boost::tribool - write(resume_context&&, error_code&, - WriteFunction&& wf) noexcept + bool + write(error_code&, WriteFunction&& wf) noexcept { wf(boost::asio::null_buffers{}); return true; diff --git a/src/beast/include/beast/http/fields.hpp b/src/beast/include/beast/http/fields.hpp index 649fbf7795..7c2ef2a59a 100644 --- a/src/beast/include/beast/http/fields.hpp +++ b/src/beast/include/beast/http/fields.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_FIELDS_HPP #define BEAST_HTTP_FIELDS_HPP +#include #include #include diff --git a/src/beast/include/beast/http/header_parser_v1.hpp b/src/beast/include/beast/http/header_parser_v1.hpp index 40f532054c..c6f732d21a 100644 --- a/src/beast/include/beast/http/header_parser_v1.hpp +++ b/src/beast/include/beast/http/header_parser_v1.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_HEADERS_PARSER_V1_HPP #define BEAST_HTTP_HEADERS_PARSER_V1_HPP +#include #include #include #include diff --git a/src/beast/include/beast/http/impl/write.ipp b/src/beast/include/beast/http/impl/write.ipp index 7e97eebd43..a6e640254d 100644 --- a/src/beast/include/beast/http/impl/write.ipp +++ b/src/beast/include/beast/http/impl/write.ipp @@ -9,7 +9,6 @@ #define BEAST_HTTP_IMPL_WRITE_IPP #include -#include #include #include #include @@ -21,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -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(h), s, std::forward(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 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 lock(m); - ready = true; - cv.notify_one(); - }}; - auto copy = resume; - boost::tribool result = - wp.w.write(std::move(copy), ec, - detail::writef0_lambda{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 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 lock(m); - cv.wait(lock, [&]{ return ready; }); - ready = false; } } if(wp.chunked) diff --git a/src/beast/include/beast/http/message.hpp b/src/beast/include/beast/http/message.hpp index 51cd8ae6c3..70cfbf19c1 100644 --- a/src/beast/include/beast/http/message.hpp +++ b/src/beast/include/beast/http/message.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_MESSAGE_HPP #define BEAST_HTTP_MESSAGE_HPP +#include #include #include #include diff --git a/src/beast/include/beast/http/parse.hpp b/src/beast/include/beast/http/parse.hpp index b99fb57fd4..bcc8b0f521 100644 --- a/src/beast/include/beast/http/parse.hpp +++ b/src/beast/include/beast/http/parse.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_PARSE_HPP #define BEAST_HTTP_PARSE_HPP +#include #include #include diff --git a/src/beast/include/beast/http/parse_error.hpp b/src/beast/include/beast/http/parse_error.hpp index 3dfcc03729..7b0dc08c0a 100644 --- a/src/beast/include/beast/http/parse_error.hpp +++ b/src/beast/include/beast/http/parse_error.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_PARSE_ERROR_HPP #define BEAST_HTTP_PARSE_ERROR_HPP +#include #include namespace beast { diff --git a/src/beast/include/beast/http/parser_v1.hpp b/src/beast/include/beast/http/parser_v1.hpp index a86ac0503a..be1aed1e2d 100644 --- a/src/beast/include/beast/http/parser_v1.hpp +++ b/src/beast/include/beast/http/parser_v1.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_PARSER_V1_HPP #define BEAST_HTTP_PARSER_V1_HPP +#include #include #include #include diff --git a/src/beast/include/beast/http/read.hpp b/src/beast/include/beast/http/read.hpp index 5981803627..54dd57963e 100644 --- a/src/beast/include/beast/http/read.hpp +++ b/src/beast/include/beast/http/read.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_READ_HPP #define BEAST_HTTP_READ_HPP +#include #include #include #include diff --git a/src/beast/include/beast/http/reason.hpp b/src/beast/include/beast/http/reason.hpp index 1cdeced929..fce97e9d1f 100644 --- a/src/beast/include/beast/http/reason.hpp +++ b/src/beast/include/beast/http/reason.hpp @@ -8,6 +8,8 @@ #ifndef BEAST_HTTP_REASON_HPP #define BEAST_HTTP_REASON_HPP +#include + namespace beast { namespace http { diff --git a/src/beast/include/beast/http/resume_context.hpp b/src/beast/include/beast/http/resume_context.hpp deleted file mode 100644 index 45da149bef..0000000000 --- a/src/beast/include/beast/http/resume_context.hpp +++ /dev/null @@ -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 - -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; - -} // http -} // beast - -#endif diff --git a/src/beast/include/beast/http/rfc7230.hpp b/src/beast/include/beast/http/rfc7230.hpp index defca9bf0f..1f73194db1 100644 --- a/src/beast/include/beast/http/rfc7230.hpp +++ b/src/beast/include/beast/http/rfc7230.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_RFC7230_HPP #define BEAST_HTTP_RFC7230_HPP +#include #include namespace beast { diff --git a/src/beast/include/beast/http/streambuf_body.hpp b/src/beast/include/beast/http/streambuf_body.hpp index 0e0186a91d..974a3f3caf 100644 --- a/src/beast/include/beast/http/streambuf_body.hpp +++ b/src/beast/include/beast/http/streambuf_body.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_STREAMBUF_BODY_HPP #define BEAST_HTTP_STREAMBUF_BODY_HPP +#include #include #include diff --git a/src/beast/include/beast/http/string_body.hpp b/src/beast/include/beast/http/string_body.hpp index 9fbd160478..707709c113 100644 --- a/src/beast/include/beast/http/string_body.hpp +++ b/src/beast/include/beast/http/string_body.hpp @@ -8,12 +8,11 @@ #ifndef BEAST_HTTP_STRING_BODY_HPP #define BEAST_HTTP_STRING_BODY_HPP +#include #include #include -#include #include #include -#include #include #include @@ -87,9 +86,8 @@ private: } template - boost::tribool - write(resume_context&&, error_code&, - WriteFunction&& wf) noexcept + bool + write(error_code&, WriteFunction&& wf) noexcept { wf(boost::asio::buffer(body_)); return true; diff --git a/src/beast/include/beast/http/write.hpp b/src/beast/include/beast/http/write.hpp index d5d7e1f252..b190e2e627 100644 --- a/src/beast/include/beast/http/write.hpp +++ b/src/beast/include/beast/http/write.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_HTTP_WRITE_HPP #define BEAST_HTTP_WRITE_HPP +#include #include #include #include diff --git a/src/beast/include/beast/version.hpp b/src/beast/include/beast/version.hpp index f91d01a9d7..2ba20a08a2 100644 --- a/src/beast/include/beast/version.hpp +++ b/src/beast/include/beast/version.hpp @@ -8,6 +8,8 @@ #ifndef BEAST_VERSION_HPP #define BEAST_VERSION_HPP +#include + // 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 diff --git a/src/beast/include/beast/websocket.hpp b/src/beast/include/beast/websocket.hpp index 55ec413b11..1cec37cd4a 100644 --- a/src/beast/include/beast/websocket.hpp +++ b/src/beast/include/beast/websocket.hpp @@ -8,6 +8,8 @@ #ifndef BEAST_WEBSOCKET_HPP #define BEAST_WEBSOCKET_HPP +#include + #include #include #include diff --git a/src/beast/include/beast/websocket/error.hpp b/src/beast/include/beast/websocket/error.hpp index b41e8d6d70..8189a1c2ab 100644 --- a/src/beast/include/beast/websocket/error.hpp +++ b/src/beast/include/beast/websocket/error.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_WEBSOCKET_ERROR_HPP #define BEAST_WEBSOCKET_ERROR_HPP +#include #include namespace beast { diff --git a/src/beast/include/beast/websocket/impl/read.ipp b/src/beast/include/beast/websocket/impl/read.ipp index 8c715de5ec..4defa6743e 100644 --- a/src/beast/include/beast/websocket/impl/read.ipp +++ b/src/beast/include/beast/websocket/impl/read.ipp @@ -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 diff --git a/src/beast/include/beast/websocket/impl/write.ipp b/src/beast/include/beast/websocket/impl/write.ipp index 4b0106788d..3733994724 100644 --- a/src/beast/include/beast/websocket/impl/write.ipp +++ b/src/beast/include/beast/websocket/impl/write.ipp @@ -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(fh_buf, fh); boost::asio::write(stream_, diff --git a/src/beast/include/beast/websocket/option.hpp b/src/beast/include/beast/websocket/option.hpp index 7d7ca602c8..005ae7b238 100644 --- a/src/beast/include/beast/websocket/option.hpp +++ b/src/beast/include/beast/websocket/option.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_WEBSOCKET_OPTION_HPP #define BEAST_WEBSOCKET_OPTION_HPP +#include #include #include #include diff --git a/src/beast/include/beast/websocket/rfc6455.hpp b/src/beast/include/beast/websocket/rfc6455.hpp index de72e9c255..3acb11e53d 100644 --- a/src/beast/include/beast/websocket/rfc6455.hpp +++ b/src/beast/include/beast/websocket/rfc6455.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_WEBSOCKET_RFC6455_HPP #define BEAST_WEBSOCKET_RFC6455_HPP +#include #include #include #include diff --git a/src/beast/include/beast/websocket/ssl.hpp b/src/beast/include/beast/websocket/ssl.hpp index 394929595d..d10dafdf44 100644 --- a/src/beast/include/beast/websocket/ssl.hpp +++ b/src/beast/include/beast/websocket/ssl.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_WEBSOCKET_SSL_HPP #define BEAST_WEBSOCKET_SSL_HPP +#include #include #include #include diff --git a/src/beast/include/beast/websocket/stream.hpp b/src/beast/include/beast/websocket/stream.hpp index 3a469c9048..5f58042af4 100644 --- a/src/beast/include/beast/websocket/stream.hpp +++ b/src/beast/include/beast/websocket/stream.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_WEBSOCKET_STREAM_HPP #define BEAST_WEBSOCKET_STREAM_HPP +#include #include #include #include diff --git a/src/beast/include/beast/websocket/teardown.hpp b/src/beast/include/beast/websocket/teardown.hpp index 6666d8f5b2..a42279766e 100644 --- a/src/beast/include/beast/websocket/teardown.hpp +++ b/src/beast/include/beast/websocket/teardown.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_WEBSOCKET_TEARDOWN_HPP #define BEAST_WEBSOCKET_TEARDOWN_HPP +#include #include #include #include diff --git a/src/beast/include/beast/zlib.hpp b/src/beast/include/beast/zlib.hpp index 80e3cf07bd..16bbb78fcc 100644 --- a/src/beast/include/beast/zlib.hpp +++ b/src/beast/include/beast/zlib.hpp @@ -8,6 +8,8 @@ #ifndef BEAST_ZLIB_HPP #define BEAST_ZLIB_HPP +#include + #include #include diff --git a/src/beast/include/beast/zlib/deflate_stream.hpp b/src/beast/include/beast/zlib/deflate_stream.hpp index 31fd573511..aae355d06a 100644 --- a/src/beast/include/beast/zlib/deflate_stream.hpp +++ b/src/beast/include/beast/zlib/deflate_stream.hpp @@ -35,6 +35,7 @@ #ifndef BEAST_ZLIB_DEFLATE_STREAM_HPP #define BEAST_ZLIB_DEFLATE_STREAM_HPP +#include #include #include #include diff --git a/src/beast/include/beast/zlib/error.hpp b/src/beast/include/beast/zlib/error.hpp index 489d092202..d593917baa 100644 --- a/src/beast/include/beast/zlib/error.hpp +++ b/src/beast/include/beast/zlib/error.hpp @@ -35,6 +35,7 @@ #ifndef BEAST_ZLIB_ERROR_HPP #define BEAST_ZLIB_ERROR_HPP +#include #include namespace beast { diff --git a/src/beast/include/beast/zlib/inflate_stream.hpp b/src/beast/include/beast/zlib/inflate_stream.hpp index 6f2b49e903..e6c42021e6 100644 --- a/src/beast/include/beast/zlib/inflate_stream.hpp +++ b/src/beast/include/beast/zlib/inflate_stream.hpp @@ -35,6 +35,7 @@ #ifndef BEAST_ZLIB_INFLATE_STREAM_HPP #define BEAST_ZLIB_INFLATE_STREAM_HPP +#include #include namespace beast { diff --git a/src/beast/include/beast/zlib/zlib.hpp b/src/beast/include/beast/zlib/zlib.hpp index e038998f37..b06f679e19 100644 --- a/src/beast/include/beast/zlib/zlib.hpp +++ b/src/beast/include/beast/zlib/zlib.hpp @@ -35,6 +35,7 @@ #ifndef BEAST_ZLIB_ZLIB_HPP #define BEAST_ZLIB_ZLIB_HPP +#include #include #include diff --git a/src/beast/test/CMakeLists.txt b/src/beast/test/CMakeLists.txt index 4a80f6ae71..ff15cb4d4f 100644 --- a/src/beast/test/CMakeLists.txt +++ b/src/beast/test/CMakeLists.txt @@ -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() diff --git a/src/beast/test/Jamfile b/src/beast/test/Jamfile index 6f275a3966..018ec76f7f 100644 --- a/src/beast/test/Jamfile +++ b/src/beast/test/Jamfile @@ -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 diff --git a/src/beast/test/http/resume_context.cpp b/src/beast/test/config.cpp similarity index 87% rename from src/beast/test/http/resume_context.cpp rename to src/beast/test/config.cpp index 0809b62179..7b9efac24c 100644 --- a/src/beast/test/http/resume_context.cpp +++ b/src/beast/test/config.cpp @@ -6,4 +6,4 @@ // // Test that header file is self-contained. -#include +#include diff --git a/src/beast/test/core/CMakeLists.txt b/src/beast/test/core/CMakeLists.txt index 2d575cd8a9..766627e3ec 100644 --- a/src/beast/test/core/CMakeLists.txt +++ b/src/beast/test/core/CMakeLists.txt @@ -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() diff --git a/src/beast/test/http/CMakeLists.txt b/src/beast/test/http/CMakeLists.txt index a01c92cb6f..5505e37dc1 100644 --- a/src/beast/test/http/CMakeLists.txt +++ b/src/beast/test/http/CMakeLists.txt @@ -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() diff --git a/src/beast/test/http/read.cpp b/src/beast/test/http/read.cpp index bd4cde264c..54356d4f06 100644 --- a/src/beast/test/http/read.cpp +++ b/src/beast/test/http/read.cpp @@ -17,6 +17,7 @@ #include #include #include +#include namespace beast { namespace http { @@ -374,6 +375,55 @@ public: } } + // Ensure completion handlers are not leaked + struct handler + { + static std::atomic& + count() { static std::atomic 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 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 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 - diff --git a/src/beast/test/http/write.cpp b/src/beast/test/http/write.cpp index 10eeb92c07..79fe11ab55 100644 --- a/src/beast/test/http/write.cpp +++ b/src/beast/test/http/write.cpp @@ -55,9 +55,8 @@ public: } template - 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 @@ -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 - 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& + count() { static std::atomic 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 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 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(); } }; diff --git a/src/beast/test/websocket/CMakeLists.txt b/src/beast/test/websocket/CMakeLists.txt index 9a3260c7c3..5d2856edb3 100644 --- a/src/beast/test/websocket/CMakeLists.txt +++ b/src/beast/test/websocket/CMakeLists.txt @@ -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) diff --git a/src/beast/test/websocket/stream.cpp b/src/beast/test/websocket/stream.cpp index d02dd2f4b9..47e0c833a0 100644 --- a/src/beast/test/websocket/stream.cpp +++ b/src/beast/test/websocket/stream.cpp @@ -109,26 +109,38 @@ public: return false; } - struct identity + struct test_decorator { - template - void - operator()(http::message&) + int& what; + + test_decorator(test_decorator const&) = default; + + test_decorator(int& what_) + : what(what_) { + what = 0; } - template + template void - operator()(http::message&) + operator()(http::header&) const { + what |= 1; + } + + template + void + operator()(http::header&) const + { + what |= 2; } }; - void testOptions() + void + testOptions() { stream 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 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 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); diff --git a/src/beast/test/zlib/CMakeLists.txt b/src/beast/test/zlib/CMakeLists.txt index b4fcfd935b..4d955e26ad 100644 --- a/src/beast/test/zlib/CMakeLists.txt +++ b/src/beast/test/zlib/CMakeLists.txt @@ -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()