diff --git a/Builds/VisualStudio2015/RippleD.vcxproj b/Builds/VisualStudio2015/RippleD.vcxproj index 2b8fe0fb2..d919a37f5 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 9bf79914a..62447e0c6 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 383491ba7..2dcb1650c 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 61a243c03..c82014589 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 543305236..277100ab2 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 ef9b317d7..1dcf4b52a 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 96002191c..874c5a693 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 90d4e6e39..aef4601ce 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 6d9e8edb3..edb8e3339 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 8aef3f2de..00f2b5434 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 000000000..b87262c77 --- /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 ed777e54b..9377cd99f 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 af5c67d2c..8c7f64d9f 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 a9094abb4..1b2d11daf 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 cd2062621..a0c892a71 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 5348724b0..545689eb3 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 9dadf7f13..36220d056 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 8e09ac584..4d8d42a64 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 44501a658..e914d434d 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 f94e52b5c..b8c78687c 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 4037efc51..08a395c3e 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 2e3854d37..e118072ae 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 2ff589ad4..53112e7f1 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 46dc5265c..52650656e 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 5272bb28e..c11277893 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 2d05aa316..ab0fae645 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 4f1d6f1aa..7db31b5b8 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 748111b02..75ced50a3 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 96e842ef1..6ba5332ca 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 6e7765736..5f0ba3adf 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 3683f68a9..537094c1a 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 110022e0c..e391ea2d5 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 54c365a53..646e78749 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 dcb327918..b4c7734f1 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 cdae120aa..a2c090149 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 30913c8fe..2589c827a 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 939cf2c63..cda14a002 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 fabdd1b56..a437fe183 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 9d43080cf..2e83fe7a4 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 a1efddc29..40f549d9f 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 649fbf779..7c2ef2a59 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 40f532054..c6f732d21 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 7e97eebd4..a6e640254 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 51cd8ae6c..70cfbf19c 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 b99fb57fd..bcc8b0f52 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 3dfcc0372..7b0dc08c0 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 a86ac0503..be1aed1e2 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 598180362..54dd57963 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 1cdeced92..fce97e9d1 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 45da149be..000000000 --- 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 defca9bf0..1f73194db 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 0e0186a91..974a3f3ca 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 9fbd16047..707709c11 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 d5d7e1f25..b190e2e62 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 f91d01a9d..2ba20a08a 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 55ec413b1..1cec37cd4 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 b41e8d6d7..8189a1c2a 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 8c715de5e..4defa6743 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 4b0106788..373399472 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 7d7ca602c..005ae7b23 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 de72e9c25..3acb11e53 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 394929595..d10dafdf4 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 3a469c904..5f58042af 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 6666d8f5b..a42279766 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 80e3cf07b..16bbb78fc 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 31fd57351..aae355d06 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 489d09220..d593917ba 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 6f2b49e90..e6c42021e 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 e038998f3..b06f679e1 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 4a80f6ae7..ff15cb4d4 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 6f275a396..018ec76f7 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 0809b6217..7b9efac24 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 2d575cd8a..766627e3e 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 a01c92cb6..5505e37dc 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 bd4cde264..54356d4f0 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 10eeb92c0..79fe11ab5 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 9a3260c7c..5d2856edb 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 d02dd2f4b..47e0c833a 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 b4fcfd935..4d955e26a 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()