mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-28 15:05:53 +00:00
Merge subtree Beast 1.0.0-b4:
Merge commit 'c0952e54db7bd519440dc0611db7347cb048296d' into
This commit is contained in:
@@ -12,7 +12,7 @@ if (WIN32)
|
||||
else()
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
find_package(Boost REQUIRED COMPONENTS filesystem program_options system)
|
||||
find_package(Boost REQUIRED COMPONENTS coroutine context thread filesystem program_options system)
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
link_directories(${Boost_LIBRARY_DIR})
|
||||
|
||||
@@ -20,34 +20,45 @@ else()
|
||||
find_package(Threads)
|
||||
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -g -std=c++11 -Wall /Wextra /Wpedantic /Wconversion -Wno-unused-variable")
|
||||
"${CMAKE_CXX_FLAGS} -g -std=c++11 -Wall -Wpedantic")
|
||||
endif()
|
||||
|
||||
message ("cxx Flags: " ${CMAKE_CXX_FLAGS})
|
||||
|
||||
macro(GroupSources curdir)
|
||||
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})
|
||||
GroupSources(${curdir}/${child})
|
||||
DoGroupSources(${curdir}/${child} ${rootdir} ${folder})
|
||||
elseif(${child} STREQUAL "CMakeLists.txt")
|
||||
source_group("" FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
|
||||
else()
|
||||
string(REPLACE "/" "\\" groupname ${curdir})
|
||||
string(REPLACE "src" "Common" groupname ${groupname})
|
||||
string(REGEX REPLACE ^${rootdir} ${folder} groupname ${curdir})
|
||||
#set(groupname ${curdir})
|
||||
string(REPLACE "/" "\\" groupname ${groupname})
|
||||
source_group(${groupname} FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
function(GroupSources curdir folder)
|
||||
DoGroupSources(${curdir} ${curdir} ${folder})
|
||||
endfunction()
|
||||
|
||||
include_directories (extras)
|
||||
include_directories (include)
|
||||
|
||||
file(GLOB_RECURSE BEAST_INCLUDES
|
||||
${PROJECT_SOURCE_DIR}/include/beast/*.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/beast/*.ipp
|
||||
${PROJECT_SOURCE_DIR}/extras/beast/*.hpp
|
||||
${PROJECT_SOURCE_DIR}/extras/beast/*.ipp
|
||||
)
|
||||
|
||||
add_subdirectory (test)
|
||||
add_subdirectory (examples)
|
||||
add_subdirectory (test)
|
||||
add_subdirectory (test/core)
|
||||
add_subdirectory (test/http)
|
||||
add_subdirectory (test/websocket)
|
||||
|
||||
#enable_testing()
|
||||
|
||||
@@ -64,6 +64,7 @@ variant asan
|
||||
project beast
|
||||
: requirements
|
||||
<include>.
|
||||
<include>./extras
|
||||
<include>./include
|
||||
#<use>/boost//headers
|
||||
<library>/boost/system//boost_system
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
# Beast [](https://travis-ci.org/vinniefalco/Beast) [](https://codecov.io/gh/sublimator/Beast)
|
||||
# Beast
|
||||
|
||||
[](https://travis-ci.org/vinniefalco/Beast) [![codecov]
|
||||
(https://codecov.io/gh/vinniefalco/Beast/branch/master/graph/badge.svg)](https://codecov.io/gh/vinniefalco/Beast) [![Documentation]
|
||||
(https://img.shields.io/badge/documentation-master-brightgreen.svg)](http://vinniefalco.github.io/beast/)
|
||||
|
||||
Beast provides implementations of the HTTP and WebSocket protocols
|
||||
built on top of Boost.Asio and other parts of boost.
|
||||
@@ -9,10 +13,72 @@ Requirements:
|
||||
* C++11 or greater
|
||||
* OpenSSL (optional)
|
||||
|
||||
Linking applications with beast:
|
||||
Example WebSocket program:
|
||||
```C++
|
||||
#include <beast/to_string.hpp>
|
||||
#include <beast/websocket.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
You need to include the .cpp file `src/beast_http_nodejs_parser.cpp`
|
||||
in the build script or Makefile for your program in order to link.
|
||||
int main()
|
||||
{
|
||||
// Normal boost::asio setup
|
||||
std::string const host = "echo.websocket.org";
|
||||
boost::asio::io_service ios;
|
||||
boost::asio::ip::tcp::resolver r(ios);
|
||||
boost::asio::ip::tcp::socket sock(ios);
|
||||
boost::asio::connect(sock,
|
||||
r.resolve(boost::asio::ip::tcp::resolver::query{host, "80"}));
|
||||
|
||||
// WebSocket connect and send message using beast
|
||||
beast::websocket::stream<boost::asio::ip::tcp::socket&> ws(sock);
|
||||
ws.handshake(host, "/");
|
||||
ws.write(boost::asio::buffer("Hello, world!"));
|
||||
|
||||
// Receive WebSocket message, print and close using beast
|
||||
beast::streambuf sb;
|
||||
beast::websocket::opcode op;
|
||||
ws.read(op, sb);
|
||||
ws.close(beast::websocket::close_code::normal);
|
||||
std::cout << to_string(sb.data()) << "\n";
|
||||
}
|
||||
```
|
||||
|
||||
Example HTTP program:
|
||||
```C++
|
||||
#include <beast/http.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Normal boost::asio setup
|
||||
std::string const host = "boost.org";
|
||||
boost::asio::io_service ios;
|
||||
boost::asio::ip::tcp::resolver r(ios);
|
||||
boost::asio::ip::tcp::socket sock(ios);
|
||||
boost::asio::connect(sock,
|
||||
r.resolve(boost::asio::ip::tcp::resolver::query{host, "http"}));
|
||||
|
||||
// Send HTTP request using beast
|
||||
beast::http::request_v1<beast::http::empty_body> req;
|
||||
req.method = "GET";
|
||||
req.url = "/";
|
||||
req.version = 11;
|
||||
req.headers.replace("Host", host + ":" + std::to_string(sock.remote_endpoint().port()));
|
||||
req.headers.replace("User-Agent", "Beast");
|
||||
beast::http::prepare(req);
|
||||
beast::http::write(sock, req);
|
||||
|
||||
// Receive and print HTTP response using beast
|
||||
beast::streambuf sb;
|
||||
beast::http::response_v1<beast::http::streambuf_body> resp;
|
||||
beast::http::read(sock, sb, resp);
|
||||
std::cout << resp;
|
||||
}
|
||||
```
|
||||
|
||||
Links:
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
General:
|
||||
* Use SFINAE on return values (search for "class =")
|
||||
* Remove http,websocket error_code types and use the one in <beast/error.hpp>
|
||||
|
||||
Boost.Http
|
||||
* Use enum instead of bool in isRequest
|
||||
@@ -17,22 +18,25 @@ Docs:
|
||||
- See if we can include them now that xsl is fixed
|
||||
* Implement cleanup-param to remove spaces around template arguments
|
||||
e.g. in basic_streambuf move constructor members
|
||||
* Don't put using namespace at file scope in examples,
|
||||
do something like "using ba = boost::asio" instead.
|
||||
|
||||
Core:
|
||||
* Replace Jamroot with Jamfile
|
||||
* Fix bidirectional buffers iterators operator->()
|
||||
* Complete allocator testing in basic_streambuf, basic_headers
|
||||
* Complete allocator testing in basic_streambuf
|
||||
|
||||
WebSocket:
|
||||
* optimized versions of key/masking, choose prepared_key size
|
||||
* invokable unit test
|
||||
* Finish up all of static_string including tests
|
||||
* Don't rely on default constructible mutable buffers
|
||||
type in read_frame_op (smb_type). To see the error, use
|
||||
boost::asio::streambuf in websocket_async_echo_peer
|
||||
* Don't try to read requests into empty_body
|
||||
* Give callers control over the http request/response used during handshake
|
||||
* Investigate poor autobahn results in Debug builds
|
||||
|
||||
HTTP:
|
||||
* Define Parser concept in HTTP
|
||||
- Need parse version of read() so caller can set parser options
|
||||
like maximum size of headers, maximum body size, etc
|
||||
* trim public interface of rfc2616.h to essentials only
|
||||
* add bool should_close(message_v1 const&) to replace the use
|
||||
of eof return value from write and async_write
|
||||
@@ -40,6 +44,17 @@ HTTP:
|
||||
* More fine grained parser errors
|
||||
* HTTP parser size limit with test (configurable?)
|
||||
* HTTP parser trailers with test
|
||||
* URL parser, strong URL checking in HTTP parser
|
||||
* Decode chunk encoding parameters
|
||||
* URL parser, strong URL character checking in HTTP parser
|
||||
* Update for rfc7230
|
||||
* Consider rename to MessageBody concept
|
||||
* Fix prepare() calling content_length() without init()
|
||||
* Use construct,destroy allocator routines in basic_headers
|
||||
* Complete allocator testing in basic_streambuf, basic_headers
|
||||
* Add tests for writer using the resume function / coros
|
||||
* Custom HTTP error codes for various situations
|
||||
* Make empty_body write-only, remove reader nested type
|
||||
* Add concepts WritableBody ReadableBody with type checks,
|
||||
check them in read and write functions
|
||||
* Branch prediction hints in parser
|
||||
* Check basic_parser_v1 against rfc7230 for leading message whitespace
|
||||
|
||||
@@ -104,6 +104,7 @@ WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = \
|
||||
../include/beast/ \
|
||||
../include/beast/core \
|
||||
../include/beast/http \
|
||||
../include/beast/websocket \
|
||||
../include/beast/doc_debug.hpp \
|
||||
|
||||
@@ -40,11 +40,11 @@
|
||||
|
||||
[section:intro Introduction]
|
||||
|
||||
Beast is a cross-platform C++ library built on Boost, containing two modules
|
||||
implementing widely used network protocols. Beast.HTTP offers a universal
|
||||
model for describing, sending, and receiving HTTP messages while Beast.WebSocket
|
||||
provides a complete implementation of the WebSocket protocol. Their design
|
||||
achieves these goals:
|
||||
Beast is a cross-platform C++ library built on Boost.Asio and Boost, containing
|
||||
two modules implementing widely used network protocols. Beast.HTTP offers a
|
||||
universal model for describing, sending, and receiving HTTP messages while
|
||||
Beast.WebSocket provides a complete implementation of the WebSocket protocol.
|
||||
Their design achieves these goals:
|
||||
|
||||
* [*Symmetry.] Interfaces are role-agnostic; the same interfaces can be
|
||||
used to build clients, servers, or both.
|
||||
@@ -60,7 +60,7 @@ strategies; important decisions such as buffer or thread management are
|
||||
left to users of the library.
|
||||
|
||||
* [*Performance.] The implementation performs competitively, making it a
|
||||
realistic choice for building a high performance network server.
|
||||
realistic choice for building high performance network servers.
|
||||
|
||||
* [*Scalability.] Development of network applications that scale to thousands
|
||||
of concurrent connections is possible with the implementation.
|
||||
@@ -112,19 +112,20 @@ int main()
|
||||
boost::asio::connect(sock,
|
||||
r.resolve(boost::asio::ip::tcp::resolver::query{host, "http"}));
|
||||
|
||||
using namespace beast::http;
|
||||
|
||||
// Send HTTP request using beast
|
||||
request<empty_body> req({"GET", "/", 11});
|
||||
beast::http::request_v1<beast::http::empty_body> req;
|
||||
req.method = "GET";
|
||||
req.url = "/";
|
||||
req.version = 11;
|
||||
req.headers.replace("Host", host + ":" + std::to_string(sock.remote_endpoint().port()));
|
||||
req.headers.replace("User-Agent", "Beast");
|
||||
prepare(req);
|
||||
write(sock, req);
|
||||
beast::http::prepare(req);
|
||||
beast::http::write(sock, req);
|
||||
|
||||
// Receive and print HTTP response using beast
|
||||
beast::streambuf sb;
|
||||
response<streambuf_body> resp;
|
||||
read(sock, sb, resp);
|
||||
beast::http::response_v1<beast::http::streambuf_body> resp;
|
||||
beast::http::read(sock, sb, resp);
|
||||
std::cout << resp;
|
||||
}
|
||||
```
|
||||
@@ -147,18 +148,16 @@ int main()
|
||||
boost::asio::connect(sock,
|
||||
r.resolve(boost::asio::ip::tcp::resolver::query{host, "80"}));
|
||||
|
||||
using namespace beast::websocket;
|
||||
|
||||
// WebSocket connect and send message using beast
|
||||
stream<boost::asio::ip::tcp::socket&> ws(sock);
|
||||
beast::websocket::stream<boost::asio::ip::tcp::socket&> ws(sock);
|
||||
ws.handshake(host, "/");
|
||||
ws.write(boost::asio::buffer("Hello, world!"));
|
||||
|
||||
// Receive WebSocket message, print and close using beast
|
||||
beast::streambuf sb;
|
||||
opcode op;
|
||||
beast::websocket::opcode op;
|
||||
ws.read(op, sb);
|
||||
ws.close(close_code::normal);
|
||||
ws.close(beast::websocket::close_code::normal);
|
||||
std::cout << to_string(sb.data()) << "\n";
|
||||
}
|
||||
```
|
||||
@@ -169,12 +168,16 @@ int main()
|
||||
|
||||
[section:credits Credits]
|
||||
|
||||
Boost.Asio is the inspiration behind which all of the interfaces and
|
||||
implementation strategies are built. Some parts of the documentation are
|
||||
written to closely resemble the wording and presentation of Boost.Asio
|
||||
documentation. Credit goes to Christopher Kohloff for the wonderful
|
||||
Asio library and the ideas upon which Beast is built.
|
||||
|
||||
Beast would not be possible without the considerable time and patience
|
||||
contributed by David Schwartz, Edward Hennis, Howard Hinnant, Miguel Portilla,
|
||||
Nikolaos Bougalis, Scott Determan, Scott Schurr, and Ripple Labs for
|
||||
supporting its development. Thanks also to Christopher Kohloff, whose Asio
|
||||
C++ library is the inspiration behind which much of the design and
|
||||
documentation is based.
|
||||
supporting its development.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ their associated operations including synchronous and asynchronous reading and
|
||||
writing of messages in the HTTP/1 wire format using Boost.Asio.
|
||||
|
||||
The HTTP protocol is described fully in
|
||||
[@https://tools.ietf.org/html/rfc2616 rfc2616]
|
||||
[@https://tools.ietf.org/html/rfc7230 rfc7230]
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ libraries. It is not designed to be end-user facing. There is no convenient
|
||||
class that implements the core of a web server, nor is there a convenient
|
||||
class to quickly perform common operations such as fetching a file or
|
||||
connecting and retrieving a document from a secure connection. These
|
||||
use-cases are important. But this library does not try to do that. Instead,
|
||||
use-cases are important, but this library does not try to do that. Instead,
|
||||
it offers primitives that can be used to build those user-facing algorithms.
|
||||
|
||||
A HTTP message (referred to hereafter as "message") contains request or
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
<member><link linkend="beast.ref.http__basic_parser_v1">basic_parser_v1</link></member>
|
||||
<member><link linkend="beast.ref.http__basic_streambuf_body">basic_streambuf_body</link></member>
|
||||
<member><link linkend="beast.ref.http__empty_body">empty_body</link></member>
|
||||
<member><link linkend="beast.ref.http__error_code">error_code</link></member>
|
||||
<member><link linkend="beast.ref.http__headers">headers</link></member>
|
||||
<member><link linkend="beast.ref.http__message">message</link></member>
|
||||
<member><link linkend="beast.ref.http__resume_context">resume_context</link></member>
|
||||
@@ -119,6 +118,7 @@
|
||||
<member><link linkend="beast.ref.basic_streambuf">basic_streambuf</link></member>
|
||||
<member><link linkend="beast.ref.buffers_adapter">buffers_adapter</link></member>
|
||||
<member><link linkend="beast.ref.consuming_buffers">consuming_buffers</link></member>
|
||||
<member><link linkend="beast.ref.error_code">error_code</link></member>
|
||||
<member><link linkend="beast.ref.handler_alloc">handler_alloc</link></member>
|
||||
<member><link linkend="beast.ref.prepared_buffers">prepared_buffers</link></member>
|
||||
<member><link linkend="beast.ref.static_streambuf">static_streambuf</link></member>
|
||||
@@ -126,6 +126,7 @@
|
||||
<member><link linkend="beast.ref.static_string">static_string</link></member>
|
||||
<member><link linkend="beast.ref.streambuf">streambuf</link></member>
|
||||
<member><link linkend="beast.ref.streambuf_readstream">streambuf_readstream</link></member>
|
||||
<member><link linkend="beast.ref.system_error">system_error</link></member>
|
||||
</simplelist>
|
||||
</entry>
|
||||
<entry valign="top">
|
||||
|
||||
@@ -774,6 +774,9 @@
|
||||
<xsl:value-of select="substring-after($file, 'include/')"/>
|
||||
<xsl:text>] 

</xsl:text>
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains($file, 'beast/core')">
|
||||
<xsl:text>['Convenience header: ][^beast/core.hpp]</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="contains($file, 'beast/http')">
|
||||
<xsl:text>['Convenience header: ][^beast/http.hpp]</xsl:text>
|
||||
</xsl:when>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Part of Beast
|
||||
|
||||
GroupSources(include/beast)
|
||||
GroupSources(examples)
|
||||
GroupSources(test)
|
||||
GroupSources(extras/beast beast)
|
||||
GroupSources(include/beast beast)
|
||||
|
||||
GroupSources(examples "/")
|
||||
|
||||
add_executable (http-crawl
|
||||
${BEAST_INCLUDES}
|
||||
@@ -22,7 +23,6 @@ add_executable (http-server
|
||||
http_stream.hpp
|
||||
http_stream.ipp
|
||||
http_sync_server.hpp
|
||||
../test/sig_wait.hpp
|
||||
http_server.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_EXAMPLE_FILE_BODY_H_INCLUDED
|
||||
#define BEAST_EXAMPLE_FILE_BODY_H_INCLUDED
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_EXAMPLE_HTTP_ASYNC_SERVER_H_INCLUDED
|
||||
#define BEAST_EXAMPLE_HTTP_ASYNC_SERVER_H_INCLUDED
|
||||
@@ -23,7 +11,7 @@
|
||||
#include "file_body.hpp"
|
||||
#include "http_stream.hpp"
|
||||
|
||||
#include <beast/placeholders.hpp>
|
||||
#include <beast/core/placeholders.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
@@ -127,8 +115,10 @@ private:
|
||||
path = root_ + path;
|
||||
if(! boost::filesystem::exists(path))
|
||||
{
|
||||
response_v1<string_body> resp(
|
||||
{404, "Not Found", req_.version});
|
||||
response_v1<string_body> resp;
|
||||
resp.status = 404;
|
||||
resp.reason = "Not Found";
|
||||
resp.version = req_.version;
|
||||
resp.headers.replace("Server", "http_async_server");
|
||||
resp.body = "The file '" + path + "' was not found";
|
||||
prepare(resp);
|
||||
@@ -137,8 +127,10 @@ private:
|
||||
asio::placeholders::error));
|
||||
return;
|
||||
}
|
||||
resp_type resp(
|
||||
{200, "OK", req_.version});
|
||||
resp_type resp;
|
||||
resp.status = 200;
|
||||
resp.reason = "OK";
|
||||
resp.version = req_.version;
|
||||
resp.headers.replace("Server", "http_async_server");
|
||||
resp.headers.replace("Content-Type", "text/html");
|
||||
resp.body = path;
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
//
|
||||
// Copyright (c) 2013-2016 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)
|
||||
//
|
||||
|
||||
#include "http_stream.hpp"
|
||||
#include "urls_large_data.hpp"
|
||||
@@ -28,7 +16,7 @@ using namespace boost::asio;
|
||||
|
||||
template<class String>
|
||||
void
|
||||
err(error_code const& ec, String const& what)
|
||||
err(beast::error_code const& ec, String const& what)
|
||||
{
|
||||
std::cerr << what << ": " << ec.message() << std::endl;
|
||||
}
|
||||
@@ -46,7 +34,10 @@ int main(int, char const*[])
|
||||
stream<ip::tcp::socket> hs(ios);
|
||||
connect(hs.lowest_layer(), it);
|
||||
auto ep = hs.lowest_layer().remote_endpoint();
|
||||
request_v1<empty_body> req({"GET", "/", 11});
|
||||
request_v1<empty_body> req;
|
||||
req.method = "GET";
|
||||
req.url = "/";
|
||||
req.version = 11;
|
||||
req.headers.insert("Host", host +
|
||||
std::string(":") + std::to_string(ep.port()));
|
||||
req.headers.insert("User-Agent", "beast/http");
|
||||
|
||||
@@ -20,18 +20,19 @@ int main()
|
||||
boost::asio::connect(sock,
|
||||
r.resolve(boost::asio::ip::tcp::resolver::query{host, "http"}));
|
||||
|
||||
using namespace beast::http;
|
||||
|
||||
// Send HTTP request using beast
|
||||
request_v1<empty_body> req({"GET", "/", 11});
|
||||
beast::http::request_v1<beast::http::empty_body> req;
|
||||
req.method = "GET";
|
||||
req.url = "/";
|
||||
req.version = 11;
|
||||
req.headers.replace("Host", host + ":" + std::to_string(sock.remote_endpoint().port()));
|
||||
req.headers.replace("User-Agent", "Beast");
|
||||
prepare(req);
|
||||
write(sock, req);
|
||||
beast::http::prepare(req);
|
||||
beast::http::write(sock, req);
|
||||
|
||||
// Receive and print HTTP response using beast
|
||||
beast::streambuf sb;
|
||||
response_v1<streambuf_body> resp;
|
||||
read(sock, sb, resp);
|
||||
beast::http::response_v1<beast::http::streambuf_body> resp;
|
||||
beast::http::read(sock, sb, resp);
|
||||
std::cout << resp;
|
||||
}
|
||||
|
||||
@@ -1,26 +1,14 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
//
|
||||
// Copyright (c) 2013-2016 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)
|
||||
//
|
||||
|
||||
#include "http_async_server.hpp"
|
||||
#include "http_sync_server.hpp"
|
||||
#include "../test/sig_wait.hpp"
|
||||
|
||||
#include <beast/test/sig_wait.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <iostream>
|
||||
@@ -72,5 +60,5 @@ int main(int ac, char const* av[])
|
||||
http_sync_server server(ep, root);
|
||||
else
|
||||
http_async_server server(ep, threads, root);
|
||||
sig_wait();
|
||||
beast::test::sig_wait();
|
||||
}
|
||||
|
||||
@@ -1,28 +1,16 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_STREAM_H_INCLUDED
|
||||
#define BEAST_HTTP_STREAM_H_INCLUDED
|
||||
|
||||
#include <beast/core/async_completion.hpp>
|
||||
#include <beast/core/basic_streambuf.hpp>
|
||||
#include <beast/http.hpp>
|
||||
#include <beast/async_completion.hpp>
|
||||
#include <beast/basic_streambuf.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <memory>
|
||||
@@ -234,7 +222,7 @@ public:
|
||||
error_code ec;
|
||||
cancel(ec);
|
||||
if(ec)
|
||||
throw boost::system::system_error{ec};
|
||||
throw system_error{ec};
|
||||
}
|
||||
|
||||
/** Cancel pending operations.
|
||||
@@ -273,7 +261,7 @@ public:
|
||||
error_code ec;
|
||||
read(msg, ec);
|
||||
if(ec)
|
||||
throw boost::system::system_error{ec};
|
||||
throw system_error{ec};
|
||||
}
|
||||
|
||||
/** Read a HTTP message from the stream.
|
||||
@@ -370,7 +358,7 @@ public:
|
||||
error_code ec;
|
||||
write(msg, ec);
|
||||
if(ec)
|
||||
throw boost::system::system_error{ec};
|
||||
throw system_error{ec};
|
||||
}
|
||||
|
||||
/** Write a HTTP message to the stream.
|
||||
|
||||
@@ -1,30 +1,18 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_STREAM_IPP_INCLUDED
|
||||
#define BEAST_HTTP_STREAM_IPP_INCLUDED
|
||||
|
||||
#include <beast/core/bind_handler.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
#include <beast/http/read.hpp>
|
||||
#include <beast/http/write.hpp>
|
||||
#include <beast/bind_handler.hpp>
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <cassert>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_EXAMPLE_HTTP_SYNC_SERVER_H_INCLUDED
|
||||
#define BEAST_EXAMPLE_HTTP_SYNC_SERVER_H_INCLUDED
|
||||
@@ -155,8 +143,10 @@ public:
|
||||
path = root_ + path;
|
||||
if(! boost::filesystem::exists(path))
|
||||
{
|
||||
response_v1<string_body> resp(
|
||||
{404, "Not Found", req.version});
|
||||
response_v1<string_body> resp;
|
||||
resp.status = 404;
|
||||
resp.reason = "Not Found";
|
||||
resp.version = req.version;
|
||||
resp.headers.replace("Server", "http_sync_server");
|
||||
resp.body = "The file '" + path + "' was not found";
|
||||
prepare(resp);
|
||||
@@ -164,8 +154,10 @@ public:
|
||||
if(ec)
|
||||
break;
|
||||
}
|
||||
resp_type resp(
|
||||
{200, "OK", req.version});
|
||||
resp_type resp;
|
||||
resp.status = 200;
|
||||
resp.reason = "OK";
|
||||
resp.version = req.version;
|
||||
resp.headers.replace("Server", "http_sync_server");
|
||||
resp.headers.replace("Content-Type", "text/html");
|
||||
resp.body = path;
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
//
|
||||
// Copyright (c) 2013-2016 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)
|
||||
//
|
||||
|
||||
#include "urls_large_data.hpp"
|
||||
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
//
|
||||
// Copyright (c) 2013-2016 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 URLS_LARGE_DATA_H_INCLUDED
|
||||
#define URLS_LARGE_DATA_H_INCLUDED
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <beast/to_string.hpp>
|
||||
#include <beast/core/to_string.hpp>
|
||||
#include <beast/websocket.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <iostream>
|
||||
@@ -21,17 +21,15 @@ int main()
|
||||
boost::asio::connect(sock,
|
||||
r.resolve(boost::asio::ip::tcp::resolver::query{host, "80"}));
|
||||
|
||||
using namespace beast::websocket;
|
||||
|
||||
// WebSocket connect and send message using beast
|
||||
stream<boost::asio::ip::tcp::socket&> ws(sock);
|
||||
beast::websocket::stream<boost::asio::ip::tcp::socket&> ws(sock);
|
||||
ws.handshake(host, "/");
|
||||
ws.write(boost::asio::buffer("Hello, world!"));
|
||||
|
||||
// Receive WebSocket message, print and close using beast
|
||||
beast::streambuf sb;
|
||||
opcode op;
|
||||
beast::websocket::opcode op;
|
||||
ws.read(op, sb);
|
||||
ws.close(close_code::normal);
|
||||
ws.close(beast::websocket::close_code::normal);
|
||||
std::cout << to_string(sb.data()) << "\n";
|
||||
}
|
||||
|
||||
3
src/beast/extras/README.md
Normal file
3
src/beast/extras/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Extras
|
||||
|
||||
These are not part of the official public Beast interface but they are used by the tests and some third party programs.
|
||||
69
src/beast/extras/beast/test/fail_counter.hpp
Normal file
69
src/beast/extras/beast/test/fail_counter.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_TEST_FAIL_COUNTER_HPP
|
||||
#define BEAST_TEST_FAIL_COUNTER_HPP
|
||||
|
||||
#include <beast/core/error.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
/** A countdown to simulated failure.
|
||||
|
||||
On the Nth operation, the class will fail with the specified
|
||||
error code, or the default error code of invalid_argument.
|
||||
*/
|
||||
class fail_counter
|
||||
{
|
||||
std::size_t n_;
|
||||
error_code ec_;
|
||||
|
||||
public:
|
||||
fail_counter(fail_counter&&) = default;
|
||||
|
||||
/** Construct a counter.
|
||||
|
||||
@param The 0-based index of the operation to fail on or after.
|
||||
*/
|
||||
explicit
|
||||
fail_counter(std::size_t n = 0)
|
||||
: n_(n)
|
||||
, ec_(boost::system::errc::make_error_code(
|
||||
boost::system::errc::errc_t::invalid_argument))
|
||||
{
|
||||
}
|
||||
|
||||
/// Throw an exception on the Nth failure
|
||||
void
|
||||
fail()
|
||||
{
|
||||
if(n_ > 0)
|
||||
--n_;
|
||||
if(! n_)
|
||||
throw system_error{ec_};
|
||||
}
|
||||
|
||||
/// Set an error code on the Nth failure
|
||||
bool
|
||||
fail(error_code& ec)
|
||||
{
|
||||
if(n_ > 0)
|
||||
--n_;
|
||||
if(! n_)
|
||||
{
|
||||
ec = ec_;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
182
src/beast/extras/beast/test/fail_stream.hpp
Normal file
182
src/beast/extras/beast/test/fail_stream.hpp
Normal file
@@ -0,0 +1,182 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_TEST_FAIL_STREAM_HPP
|
||||
#define BEAST_TEST_FAIL_STREAM_HPP
|
||||
|
||||
#include <beast/core/async_completion.hpp>
|
||||
#include <beast/core/bind_handler.hpp>
|
||||
#include <beast/core/error.hpp>
|
||||
#include <beast/core/detail/get_lowest_layer.hpp>
|
||||
#include <beast/websocket/teardown.hpp>
|
||||
#include <beast/test/fail_counter.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
/** A stream wrapper that fails.
|
||||
|
||||
On the Nth operation, the stream will fail with the specified
|
||||
error code, or the default error code of invalid_argument.
|
||||
*/
|
||||
template<class NextLayer>
|
||||
class fail_stream
|
||||
{
|
||||
fail_counter* pfc_;
|
||||
fail_counter fc_;
|
||||
NextLayer next_layer_;
|
||||
|
||||
public:
|
||||
using next_layer_type =
|
||||
typename std::remove_reference<NextLayer>::type;
|
||||
|
||||
using lowest_layer_type =
|
||||
typename beast::detail::get_lowest_layer<
|
||||
next_layer_type>::type;
|
||||
|
||||
fail_stream(fail_stream&&) = delete;
|
||||
fail_stream(fail_stream const&) = delete;
|
||||
fail_stream& operator=(fail_stream&&) = delete;
|
||||
fail_stream& operator=(fail_stream const&) = delete;
|
||||
|
||||
template<class... Args>
|
||||
explicit
|
||||
fail_stream(std::size_t n, Args&&... args)
|
||||
: pfc_(&fc_)
|
||||
, fc_(n)
|
||||
, next_layer_(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
template<class... Args>
|
||||
explicit
|
||||
fail_stream(fail_counter& fc, Args&&... args)
|
||||
: pfc_(&fc)
|
||||
, next_layer_(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
next_layer_type&
|
||||
next_layer()
|
||||
{
|
||||
return next_layer_;
|
||||
}
|
||||
|
||||
lowest_layer_type&
|
||||
lowest_layer()
|
||||
{
|
||||
return next_layer_.lowest_layer();
|
||||
}
|
||||
|
||||
lowest_layer_type const&
|
||||
lowest_layer() const
|
||||
{
|
||||
return next_layer_.lowest_layer();
|
||||
}
|
||||
|
||||
boost::asio::io_service&
|
||||
get_io_service()
|
||||
{
|
||||
return next_layer_.get_io_service();
|
||||
}
|
||||
|
||||
template<class MutableBufferSequence>
|
||||
std::size_t
|
||||
read_some(MutableBufferSequence const& buffers)
|
||||
{
|
||||
pfc_->fail();
|
||||
return next_layer_.read_some(buffers);
|
||||
}
|
||||
|
||||
template<class MutableBufferSequence>
|
||||
std::size_t
|
||||
read_some(MutableBufferSequence const& buffers, error_code& ec)
|
||||
{
|
||||
if(pfc_->fail(ec))
|
||||
return 0;
|
||||
return next_layer_.read_some(buffers, ec);
|
||||
}
|
||||
|
||||
template<class MutableBufferSequence, class ReadHandler>
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
async_read_some(MutableBufferSequence const& buffers,
|
||||
ReadHandler&& handler)
|
||||
{
|
||||
error_code ec;
|
||||
if(pfc_->fail(ec))
|
||||
{
|
||||
async_completion<
|
||||
ReadHandler, void(error_code, std::size_t)
|
||||
> completion(handler);
|
||||
next_layer_.get_io_service().post(
|
||||
bind_handler(completion.handler, ec, 0));
|
||||
return completion.result.get();
|
||||
}
|
||||
return next_layer_.async_read_some(buffers,
|
||||
std::forward<ReadHandler>(handler));
|
||||
}
|
||||
|
||||
template<class ConstBufferSequence>
|
||||
std::size_t
|
||||
write_some(ConstBufferSequence const& buffers)
|
||||
{
|
||||
pfc_->fail();
|
||||
return next_layer_.write_some(buffers);
|
||||
}
|
||||
|
||||
template<class ConstBufferSequence>
|
||||
std::size_t
|
||||
write_some(ConstBufferSequence const& buffers, error_code& ec)
|
||||
{
|
||||
if(pfc_->fail(ec))
|
||||
return 0;
|
||||
return next_layer_.write_some(buffers, ec);
|
||||
}
|
||||
|
||||
template<class ConstBufferSequence, class WriteHandler>
|
||||
typename async_completion<
|
||||
WriteHandler, void(error_code)>::result_type
|
||||
async_write_some(ConstBufferSequence const& buffers,
|
||||
WriteHandler&& handler)
|
||||
{
|
||||
error_code ec;
|
||||
if(pfc_->fail(ec))
|
||||
{
|
||||
async_completion<
|
||||
WriteHandler, void(error_code, std::size_t)
|
||||
> completion(handler);
|
||||
next_layer_.get_io_service().post(
|
||||
bind_handler(completion.handler, ec, 0));
|
||||
return completion.result.get();
|
||||
}
|
||||
return next_layer_.async_write_some(buffers,
|
||||
std::forward<WriteHandler>(handler));
|
||||
}
|
||||
};
|
||||
|
||||
template<class NextLayer>
|
||||
void
|
||||
teardown(fail_stream<NextLayer>& stream,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
websocket_helpers::call_teardown(stream.next_layer(), ec);
|
||||
}
|
||||
|
||||
template<class NextLayer, class TeardownHandler>
|
||||
void
|
||||
async_teardown(fail_stream<NextLayer>& stream,
|
||||
TeardownHandler&& handler)
|
||||
{
|
||||
websocket_helpers::call_async_teardown(
|
||||
stream.next_layer(), std::forward<TeardownHandler>(handler));
|
||||
}
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
36
src/beast/extras/beast/test/sig_wait.hpp
Normal file
36
src/beast/extras/beast/test/sig_wait.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_TEST_SIG_WAIT_HPP
|
||||
#define BEAST_TEST_SIG_WAIT_HPP
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
/// Block until SIGINT or SIGTERM is received.
|
||||
inline
|
||||
void
|
||||
sig_wait()
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
boost::asio::signal_set signals(
|
||||
ios, SIGINT, SIGTERM);
|
||||
signals.async_wait(
|
||||
[&](boost::system::error_code const&, int)
|
||||
{
|
||||
});
|
||||
ios.run();
|
||||
}
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
126
src/beast/extras/beast/test/string_stream.hpp
Normal file
126
src/beast/extras/beast/test/string_stream.hpp
Normal file
@@ -0,0 +1,126 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_TEST_STRING_STREAM_HPP
|
||||
#define BEAST_TEST_STRING_STREAM_HPP
|
||||
|
||||
#include <beast/core/bind_handler.hpp>
|
||||
#include <beast/core/error.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
/** A SyncStream and AsyncStream that reads from a string.
|
||||
|
||||
This class behaves like a socket, except that written data is simply
|
||||
discarded, and when data is read it comes from a string provided
|
||||
at construction.
|
||||
*/
|
||||
class string_stream
|
||||
{
|
||||
std::string s_;
|
||||
boost::asio::io_service& ios_;
|
||||
|
||||
public:
|
||||
string_stream(boost::asio::io_service& ios,
|
||||
std::string s)
|
||||
: s_(std::move(s))
|
||||
, ios_(ios)
|
||||
{
|
||||
}
|
||||
|
||||
boost::asio::io_service&
|
||||
get_io_service()
|
||||
{
|
||||
return ios_;
|
||||
}
|
||||
|
||||
template<class MutableBufferSequence>
|
||||
std::size_t
|
||||
read_some(MutableBufferSequence const& buffers)
|
||||
{
|
||||
error_code ec;
|
||||
auto const n = read_some(buffers, ec);
|
||||
if(ec)
|
||||
throw system_error{ec};
|
||||
return n;
|
||||
}
|
||||
|
||||
template<class MutableBufferSequence>
|
||||
std::size_t
|
||||
read_some(MutableBufferSequence const& buffers,
|
||||
error_code& ec)
|
||||
{
|
||||
auto const n = boost::asio::buffer_copy(
|
||||
buffers, boost::asio::buffer(s_));
|
||||
if(n > 0)
|
||||
s_.erase(0, n);
|
||||
else
|
||||
ec = boost::asio::error::eof;
|
||||
return n;
|
||||
}
|
||||
|
||||
template<class MutableBufferSequence, class ReadHandler>
|
||||
typename async_completion<ReadHandler,
|
||||
void(error_code, std::size_t)>::result_type
|
||||
async_read_some(MutableBufferSequence const& buffers,
|
||||
ReadHandler&& handler)
|
||||
{
|
||||
auto const n = boost::asio::buffer_copy(
|
||||
buffers, boost::asio::buffer(s_));
|
||||
error_code ec;
|
||||
if(n > 0)
|
||||
s_.erase(0, n);
|
||||
else
|
||||
ec = boost::asio::error::eof;
|
||||
async_completion<ReadHandler,
|
||||
void(error_code, std::size_t)> completion(handler);
|
||||
ios_.post(bind_handler(
|
||||
completion.handler, ec, n));
|
||||
return completion.result.get();
|
||||
}
|
||||
|
||||
template<class ConstBufferSequence>
|
||||
std::size_t
|
||||
write_some(ConstBufferSequence const& buffers)
|
||||
{
|
||||
error_code ec;
|
||||
auto const n = write_some(buffers, ec);
|
||||
if(ec)
|
||||
throw system_error{ec};
|
||||
return n;
|
||||
}
|
||||
|
||||
template<class ConstBufferSequence>
|
||||
std::size_t
|
||||
write_some(ConstBufferSequence const& buffers,
|
||||
error_code&)
|
||||
{
|
||||
return boost::asio::buffer_size(buffers);
|
||||
}
|
||||
|
||||
template<class ConstBuffeSequence, class WriteHandler>
|
||||
typename async_completion<WriteHandler,
|
||||
void(error_code, std::size_t)>::result_type
|
||||
async_write_some(ConstBuffeSequence const& buffers,
|
||||
WriteHandler&& handler)
|
||||
{
|
||||
async_completion<WriteHandler,
|
||||
void(error_code, std::size_t)> completion(handler);
|
||||
ios_.post(bind_handler(completion.handler,
|
||||
error_code{}, boost::asio::buffer_size(buffers)));
|
||||
return completion.result.get();
|
||||
}
|
||||
};
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
108
src/beast/extras/beast/test/yield_to.hpp
Normal file
108
src/beast/extras/beast/test/yield_to.hpp
Normal file
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_TEST_YIELD_TO_HPP
|
||||
#define BEAST_TEST_YIELD_TO_HPP
|
||||
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/spawn.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
namespace beast {
|
||||
namespace test {
|
||||
|
||||
/** Mix-in to support tests using asio coroutines.
|
||||
|
||||
Derive from this class and use yield_to to launch test functions
|
||||
inside coroutines. This is handy for testing asynchronous asio
|
||||
code.
|
||||
*/
|
||||
class enable_yield_to
|
||||
{
|
||||
protected:
|
||||
boost::asio::io_service ios_;
|
||||
|
||||
private:
|
||||
boost::optional<boost::asio::io_service::work> work_;
|
||||
std::thread thread_;
|
||||
std::mutex m_;
|
||||
std::condition_variable cv_;
|
||||
bool running_ = false;
|
||||
|
||||
public:
|
||||
/// The type of yield context passed to functions.
|
||||
using yield_context =
|
||||
boost::asio::yield_context;
|
||||
|
||||
enable_yield_to()
|
||||
: work_(ios_)
|
||||
, thread_([&]
|
||||
{
|
||||
ios_.run();
|
||||
}
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
~enable_yield_to()
|
||||
{
|
||||
work_ = boost::none;
|
||||
thread_.join();
|
||||
}
|
||||
|
||||
/// Return the `io_service` associated with the object
|
||||
boost::asio::io_service&
|
||||
get_io_service()
|
||||
{
|
||||
return ios_;
|
||||
}
|
||||
|
||||
/** Run a function in a coroutine.
|
||||
|
||||
This call will block until the coroutine terminates.
|
||||
|
||||
Function will be called with this signature:
|
||||
|
||||
@code
|
||||
void f(yield_context);
|
||||
@endcode
|
||||
*/
|
||||
template<class Function>
|
||||
void
|
||||
yield_to(Function&& f);
|
||||
};
|
||||
|
||||
template<class Function>
|
||||
void
|
||||
enable_yield_to::yield_to(Function&& f)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_);
|
||||
running_ = true;
|
||||
}
|
||||
boost::asio::spawn(ios_,
|
||||
[&](boost::asio::yield_context do_yield)
|
||||
{
|
||||
f(do_yield);
|
||||
std::lock_guard<std::mutex> lock(m_);
|
||||
running_ = false;
|
||||
cv_.notify_all();
|
||||
}
|
||||
, boost::coroutines::attributes(2 * 1024 * 1024));
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_);
|
||||
cv_.wait(lock, [&]{ return ! running_; });
|
||||
}
|
||||
|
||||
} // test
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,18 +5,16 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_STREAM_ABSTRACT_OSTREAM_HPP
|
||||
#define BEAST_DETAIL_STREAM_ABSTRACT_OSTREAM_HPP
|
||||
#ifndef BEAST_UNIT_TEST_ABSTRACT_OSTREAM_HPP
|
||||
#define BEAST_UNIT_TEST_ABSTRACT_OSTREAM_HPP
|
||||
|
||||
#include <beast/detail/stream/basic_abstract_ostream.hpp>
|
||||
#include <beast/unit_test/basic_abstract_ostream.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
/** An abstract ostream for `char`. */
|
||||
using abstract_ostream = basic_abstract_ostream <char>;
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,17 +5,14 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_UNIT_TEST_AMOUNT_HPP
|
||||
#define BEAST_DETAIL_UNIT_TEST_AMOUNT_HPP
|
||||
#ifndef BEAST_UNIT_TEST_AMOUNT_HPP
|
||||
#define BEAST_UNIT_TEST_AMOUNT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
|
||||
/** Utility for producing nicely composed output of amounts with units. */
|
||||
@@ -53,7 +50,6 @@ operator<< (std::ostream& s, amount const& t)
|
||||
}
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,16 +5,15 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_STREAM_BASIC_ABSTRACT_OSTREAM_HPP
|
||||
#define BEAST_DETAIL_STREAM_BASIC_ABSTRACT_OSTREAM_HPP
|
||||
#ifndef BEAST_UNIT_TEST_BASIC_ABSTRACT_OSTREAM_HPP
|
||||
#define BEAST_UNIT_TEST_BASIC_ABSTRACT_OSTREAM_HPP
|
||||
|
||||
#include <beast/detail/stream/basic_scoped_ostream.hpp>
|
||||
#include <beast/unit_test/basic_scoped_ostream.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
/** Abstraction for an output stream similar to std::basic_ostream. */
|
||||
template <
|
||||
@@ -81,7 +80,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,8 +5,8 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_STREAM_BASIC_SCOPED_OSTREAM_HPP
|
||||
#define BEAST_DETAIL_STREAM_BASIC_SCOPED_OSTREAM_HPP
|
||||
#ifndef BEAST_UNIT_TEST_BASIC_SCOPED_OSTREAM_HPP
|
||||
#define BEAST_UNIT_TEST_BASIC_SCOPED_OSTREAM_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@@ -24,7 +24,6 @@
|
||||
#endif
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template <
|
||||
class CharT,
|
||||
@@ -132,7 +131,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,14 +5,13 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_STREAM_BASIC_STD_OSTREAM_H_INCLUDED
|
||||
#define BEAST_DETAIL_STREAM_BASIC_STD_OSTREAM_H_INCLUDED
|
||||
#ifndef BEAST_UNIT_TEST_BASIC_STD_OSTREAM_HPP
|
||||
#define BEAST_UNIT_TEST_BASIC_STD_OSTREAM_HPP
|
||||
|
||||
#include <beast/detail/stream/basic_abstract_ostream.hpp>
|
||||
#include <beast/unit_test/basic_abstract_ostream.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
/** Wraps an existing std::basic_ostream as an abstract_ostream. */
|
||||
template <
|
||||
@@ -56,7 +55,6 @@ make_std_ostream (std::basic_ostream <CharT, Traits>& stream)
|
||||
return basic_std_ostream <CharT, Traits> (stream);
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,10 +5,10 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_STREAM_DEBUG_OSTREAM_HPP
|
||||
#define BEAST_DETAIL_STREAM_DEBUG_OSTREAM_HPP
|
||||
#ifndef BEAST_UNIT_TEST_DEBUG_OSTREAM_HPP
|
||||
#define BEAST_UNIT_TEST_DEBUG_OSTREAM_HPP
|
||||
|
||||
#include <beast/detail/stream/abstract_ostream.hpp>
|
||||
#include <beast/unit_test/abstract_ostream.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -28,7 +28,6 @@
|
||||
#endif
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/** A basic_abstract_ostream that redirects output to an attached debugger. */
|
||||
@@ -74,7 +73,6 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,10 +5,11 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_CONST_CONTAINER_HPP
|
||||
#define BEAST_DETAIL_CONST_CONTAINER_HPP
|
||||
#ifndef BEAST_UNIT_TEST_DETAIL_CONST_CONTAINER_HPP
|
||||
#define BEAST_UNIT_TEST_DETAIL_CONST_CONTAINER_HPP
|
||||
|
||||
namespace beast {
|
||||
namespace unit_test {
|
||||
namespace detail {
|
||||
|
||||
/** Adapter to constrain a container interface.
|
||||
@@ -84,6 +85,7 @@ public:
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // unit_test
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,15 +5,12 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_UNIT_TEST_GLOBAL_SUITES_HPP
|
||||
#define BEAST_DETAIL_UNIT_TEST_GLOBAL_SUITES_HPP
|
||||
#ifndef BEAST_UNIT_TEST_GLOBAL_SUITES_HPP
|
||||
#define BEAST_UNIT_TEST_GLOBAL_SUITES_HPP
|
||||
|
||||
#include <beast/detail/unit_test/suite_list.hpp>
|
||||
#include <beast/unit_test/suite_list.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
|
||||
namespace detail {
|
||||
@@ -54,7 +51,6 @@ global_suites()
|
||||
}
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -1,28 +1,16 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2013-2016 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)
|
||||
//
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/detail/unit_test/amount.hpp>
|
||||
#include <beast/detail/unit_test/global_suites.hpp>
|
||||
#include <beast/detail/unit_test/match.hpp>
|
||||
#include <beast/detail/unit_test/reporter.hpp>
|
||||
#include <beast/detail/unit_test/suite.hpp>
|
||||
#include <beast/detail/stream/debug_ostream.hpp>
|
||||
#include <beast/unit_test/amount.hpp>
|
||||
#include <beast/unit_test/global_suites.hpp>
|
||||
#include <beast/unit_test/match.hpp>
|
||||
#include <beast/unit_test/reporter.hpp>
|
||||
#include <beast/unit_test/suite.hpp>
|
||||
#include <beast/unit_test/debug_ostream.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
@@ -40,7 +28,6 @@
|
||||
#include <cstdlib>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
namespace unit_test {
|
||||
|
||||
std::string
|
||||
@@ -80,7 +67,6 @@ print(Log& log)
|
||||
}
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
// Simple main used to produce stand
|
||||
@@ -88,7 +74,7 @@ print(Log& log)
|
||||
int main(int ac, char const* av[])
|
||||
{
|
||||
using namespace std;
|
||||
using namespace beast::detail::unit_test;
|
||||
using namespace beast::unit_test;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
{
|
||||
@@ -111,7 +97,7 @@ int main(int ac, char const* av[])
|
||||
po::store(po::parse_command_line(ac, av, desc), vm);
|
||||
po::notify(vm);
|
||||
|
||||
beast::detail::debug_ostream log;
|
||||
beast::debug_ostream log;
|
||||
|
||||
if(vm.count("help"))
|
||||
{
|
||||
@@ -5,16 +5,13 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_UNIT_TEST_MATCH_HPP
|
||||
#define BEAST_DETAIL_UNIT_TEST_MATCH_HPP
|
||||
#ifndef BEAST_UNIT_TEST_MATCH_HPP
|
||||
#define BEAST_UNIT_TEST_MATCH_HPP
|
||||
|
||||
#include <beast/detail/unit_test/suite_info.hpp>
|
||||
#include <beast/unit_test/suite_info.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
|
||||
// Predicate for implementing matches
|
||||
@@ -171,7 +168,6 @@ match_library (std::string const& name)
|
||||
}
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,28 +5,25 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_UNIT_TEST_PRINT_H_INCLUDED
|
||||
#define BEAST_DETAIL_UNIT_TEST_PRINT_H_INCLUDED
|
||||
#ifndef BEAST_UNIT_TEST_PRINT_H_INCLUDED
|
||||
#define BEAST_UNIT_TEST_PRINT_H_INCLUDED
|
||||
|
||||
#include <beast/detail/unit_test/amount.hpp>
|
||||
#include <beast/detail/unit_test/results.hpp>
|
||||
#include <beast/detail/stream/abstract_ostream.hpp>
|
||||
#include <beast/detail/stream/basic_std_ostream.hpp>
|
||||
#include <beast/unit_test/amount.hpp>
|
||||
#include <beast/unit_test/results.hpp>
|
||||
#include <beast/unit_test/abstract_ostream.hpp>
|
||||
#include <beast/unit_test/basic_std_ostream.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
|
||||
/** Write test results to the specified output stream. */
|
||||
/** @{ */
|
||||
template <class = void>
|
||||
void
|
||||
print (results const& r, beast::detail::abstract_ostream& stream)
|
||||
print (results const& r, abstract_ostream& stream)
|
||||
{
|
||||
for (auto const& s : r)
|
||||
{
|
||||
@@ -65,7 +62,6 @@ print (results const& r, std::ostream& stream = std::cout)
|
||||
}
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,16 +5,13 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_UNIT_TEST_RECORDER_HPP
|
||||
#define BEAST_DETAIL_UNIT_TEST_RECORDER_HPP
|
||||
#ifndef BEAST_UNIT_TEST_RECORDER_HPP
|
||||
#define BEAST_UNIT_TEST_RECORDER_HPP
|
||||
|
||||
#include <beast/detail/unit_test/results.hpp>
|
||||
#include <beast/detail/unit_test/runner.hpp>
|
||||
#include <beast/unit_test/results.hpp>
|
||||
#include <beast/unit_test/runner.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
|
||||
/** A test runner that stores the results. */
|
||||
@@ -90,7 +87,6 @@ private:
|
||||
};
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,13 +5,13 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_UNIT_TEST_REPORTER_HPP
|
||||
#define BEAST_DETAIL_UNIT_TEST_REPORTER_HPP
|
||||
#ifndef BEAST_UNIT_TEST_REPORTER_HPP
|
||||
#define BEAST_UNIT_TEST_REPORTER_HPP
|
||||
|
||||
#include <beast/detail/unit_test/amount.hpp>
|
||||
#include <beast/detail/unit_test/recorder.hpp>
|
||||
#include <beast/detail/stream/abstract_ostream.hpp>
|
||||
#include <beast/detail/stream/basic_std_ostream.hpp>
|
||||
#include <beast/unit_test/amount.hpp>
|
||||
#include <beast/unit_test/recorder.hpp>
|
||||
#include <beast/unit_test/abstract_ostream.hpp>
|
||||
#include <beast/unit_test/basic_std_ostream.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
@@ -23,9 +23,6 @@
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
|
||||
namespace detail {
|
||||
@@ -87,7 +84,7 @@ private:
|
||||
};
|
||||
|
||||
boost::optional <std_ostream> std_ostream_;
|
||||
std::reference_wrapper <beast::detail::abstract_ostream> stream_;
|
||||
std::reference_wrapper <beast::abstract_ostream> stream_;
|
||||
results results_;
|
||||
suite_results suite_results_;
|
||||
case_results case_results_;
|
||||
@@ -102,7 +99,7 @@ public:
|
||||
reporter (std::ostream& stream = std::cout);
|
||||
|
||||
explicit
|
||||
reporter (beast::detail::abstract_ostream& stream);
|
||||
reporter (beast::abstract_ostream& stream);
|
||||
|
||||
private:
|
||||
static
|
||||
@@ -229,7 +226,7 @@ reporter<_>::~reporter()
|
||||
|
||||
template <class _>
|
||||
reporter<_>::reporter (
|
||||
beast::detail::abstract_ostream& stream)
|
||||
abstract_ostream& stream)
|
||||
: stream_ (stream)
|
||||
{
|
||||
}
|
||||
@@ -318,7 +315,6 @@ reporter<_>::on_log (
|
||||
using reporter = detail::reporter<>;
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,18 +5,15 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_UNIT_TEST_RESULTS_HPP
|
||||
#define BEAST_DETAIL_UNIT_TEST_RESULTS_HPP
|
||||
#ifndef BEAST_UNIT_TEST_RESULTS_HPP
|
||||
#define BEAST_UNIT_TEST_RESULTS_HPP
|
||||
|
||||
#include <beast/detail/const_container.hpp>
|
||||
#include <beast/unit_test/detail/const_container.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
|
||||
/** Holds a set of test condition outcomes in a testcase. */
|
||||
@@ -43,7 +40,7 @@ public:
|
||||
|
||||
private:
|
||||
class tests_t
|
||||
: public const_container <std::vector <test>>
|
||||
: public detail::const_container <std::vector <test>>
|
||||
{
|
||||
private:
|
||||
std::size_t failed_;
|
||||
@@ -85,7 +82,7 @@ private:
|
||||
};
|
||||
|
||||
class log_t
|
||||
: public const_container <std::vector <std::string>>
|
||||
: public detail::const_container <std::vector <std::string>>
|
||||
{
|
||||
public:
|
||||
/** Insert a string into the log. */
|
||||
@@ -122,7 +119,7 @@ public:
|
||||
|
||||
/** Holds the set of testcase results in a suite. */
|
||||
class suite_results
|
||||
: public const_container <std::vector <case_results>>
|
||||
: public detail::const_container <std::vector <case_results>>
|
||||
{
|
||||
private:
|
||||
std::string name_;
|
||||
@@ -181,7 +178,7 @@ public:
|
||||
// VFALCO TODO Make this a template class using scoped allocators
|
||||
/** Holds the results of running a set of testsuites. */
|
||||
class results
|
||||
: public const_container <std::vector <suite_results>>
|
||||
: public detail::const_container <std::vector <suite_results>>
|
||||
{
|
||||
private:
|
||||
std::size_t m_cases;
|
||||
@@ -240,7 +237,6 @@ public:
|
||||
};
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,19 +5,16 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_UNIT_TEST_RUNNER_H_INCLUDED
|
||||
#define BEAST_DETAIL_UNIT_TEST_RUNNER_H_INCLUDED
|
||||
#ifndef BEAST_UNIT_TEST_RUNNER_H_INCLUDED
|
||||
#define BEAST_UNIT_TEST_RUNNER_H_INCLUDED
|
||||
|
||||
#include <beast/detail/unit_test/suite_info.hpp>
|
||||
#include <beast/detail/stream/abstract_ostream.hpp>
|
||||
#include <beast/unit_test/suite_info.hpp>
|
||||
#include <beast/unit_test/abstract_ostream.hpp>
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
|
||||
/** Unit test runner interface.
|
||||
@@ -28,7 +25,7 @@ class runner
|
||||
{
|
||||
private:
|
||||
// Reroutes log output to the runner
|
||||
class stream_t : public beast::detail::abstract_ostream
|
||||
class stream_t : public abstract_ostream
|
||||
{
|
||||
private:
|
||||
runner& owner_;
|
||||
@@ -332,7 +329,6 @@ runner::log (std::string const& s)
|
||||
}
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,17 +5,14 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_UNIT_TEST_SUITE_HPP
|
||||
#define BEAST_DETAIL_UNIT_TEST_SUITE_HPP
|
||||
#ifndef BEAST_UNIT_TEST_SUITE_HPP
|
||||
#define BEAST_UNIT_TEST_SUITE_HPP
|
||||
|
||||
#include <beast/detail/unit_test/runner.hpp>
|
||||
#include <beast/unit_test/runner.hpp>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
|
||||
class thread;
|
||||
@@ -537,7 +534,6 @@ suite::run (runner& r)
|
||||
}
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -545,9 +541,9 @@ suite::run (runner& r)
|
||||
// detail:
|
||||
// This inserts the suite with the given manual flag
|
||||
#define BEAST_DEFINE_TESTSUITE_INSERT(Class,Module,Library,manual) \
|
||||
static beast::detail::unit_test::detail::insert_suite <Class##_test> \
|
||||
static beast::unit_test::detail::insert_suite <Class##_test> \
|
||||
Library ## Module ## Class ## _test_instance ( \
|
||||
#Class, #Module, #Library, manual);
|
||||
#Class, #Module, #Library, manual)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -593,7 +589,7 @@ suite::run (runner& r)
|
||||
#define BEAST_DEFINE_TESTSUITE(Class,Module,Library)
|
||||
|
||||
#else
|
||||
#include <beast/detail/unit_test/global_suites.hpp>
|
||||
#include <beast/unit_test/global_suites.hpp>
|
||||
#define BEAST_DEFINE_TESTSUITE(Class,Module,Library) \
|
||||
BEAST_DEFINE_TESTSUITE_INSERT(Class,Module,Library,false)
|
||||
#define BEAST_DEFINE_TESTSUITE_MANUAL(Class,Module,Library) \
|
||||
@@ -5,17 +5,14 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_UNIT_TEST_SUITE_INFO_HPP
|
||||
#define BEAST_DETAIL_UNIT_TEST_SUITE_INFO_HPP
|
||||
#ifndef BEAST_UNIT_TEST_SUITE_INFO_HPP
|
||||
#define BEAST_UNIT_TEST_SUITE_INFO_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
|
||||
class runner;
|
||||
@@ -113,7 +110,6 @@ make_suite_info (std::string const& name, std::string const& module,
|
||||
}
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,25 +5,22 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_UNIT_TEST_SUITE_LIST_HPP
|
||||
#define BEAST_DETAIL_UNIT_TEST_SUITE_LIST_HPP
|
||||
#ifndef BEAST_UNIT_TEST_SUITE_LIST_HPP
|
||||
#define BEAST_UNIT_TEST_SUITE_LIST_HPP
|
||||
|
||||
#include <beast/detail/unit_test/suite_info.hpp>
|
||||
#include <beast/detail/const_container.hpp>
|
||||
#include <beast/unit_test/suite_info.hpp>
|
||||
#include <beast/unit_test/detail/const_container.hpp>
|
||||
#include <cassert>
|
||||
#include <typeindex>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
|
||||
/** A container of test suites. */
|
||||
class suite_list
|
||||
: public const_container <std::set <suite_info>>
|
||||
: public detail::const_container <std::set <suite_info>>
|
||||
{
|
||||
private:
|
||||
#ifndef NDEBUG
|
||||
@@ -68,7 +65,6 @@ suite_list::insert (char const* name, char const* module, char const* library,
|
||||
}
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -5,18 +5,15 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_UNIT_TEST_THREAD_HPP
|
||||
#define BEAST_DETAIL_UNIT_TEST_THREAD_HPP
|
||||
#ifndef BEAST_UNIT_TEST_THREAD_HPP
|
||||
#define BEAST_UNIT_TEST_THREAD_HPP
|
||||
|
||||
#include <beast/detail/unit_test/suite.hpp>
|
||||
#include <beast/unit_test/suite.hpp>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
|
||||
/** Replacement for std::thread that handles exceptions in unit tests. */
|
||||
@@ -122,7 +119,6 @@ private:
|
||||
};
|
||||
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
31
src/beast/include/beast/core.hpp
Normal file
31
src/beast/include/beast/core.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_CORE_HPP
|
||||
#define BEAST_CORE_HPP
|
||||
|
||||
#include <beast/core/async_completion.hpp>
|
||||
#include <beast/core/basic_streambuf.hpp>
|
||||
#include <beast/core/bind_handler.hpp>
|
||||
#include <beast/core/buffer_cat.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <beast/core/buffers_adapter.hpp>
|
||||
#include <beast/core/consuming_buffers.hpp>
|
||||
#include <beast/core/error.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/core/handler_concepts.hpp>
|
||||
#include <beast/core/placeholders.hpp>
|
||||
#include <beast/core/prepare_buffers.hpp>
|
||||
#include <beast/core/static_streambuf.hpp>
|
||||
#include <beast/core/static_string.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <beast/core/streambuf_readstream.hpp>
|
||||
#include <beast/core/to_string.hpp>
|
||||
#include <beast/core/write_streambuf.hpp>
|
||||
|
||||
#endif
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_ASYNC_COMPLETION_HPP
|
||||
#define BEAST_ASYNC_COMPLETION_HPP
|
||||
|
||||
#include <beast/handler_concepts.hpp>
|
||||
#include <beast/core/handler_concepts.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/handler_type.hpp>
|
||||
#include <type_traits>
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_BASIC_STREAMBUF_HPP
|
||||
#define BEAST_BASIC_STREAMBUF_HPP
|
||||
|
||||
#include <beast/detail/empty_base_optimization.hpp>
|
||||
#include <beast/core/detail/empty_base_optimization.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <iterator>
|
||||
@@ -298,6 +298,6 @@ operator<<(basic_streambuf<Allocator>& streambuf, T const& t);
|
||||
|
||||
} // beast
|
||||
|
||||
#include <beast/impl/basic_streambuf.ipp>
|
||||
#include <beast/core/impl/basic_streambuf.ipp>
|
||||
|
||||
#endif
|
||||
@@ -8,8 +8,8 @@
|
||||
#ifndef BEAST_BIND_HANDLER_HPP
|
||||
#define BEAST_BIND_HANDLER_HPP
|
||||
|
||||
#include <beast/handler_concepts.hpp>
|
||||
#include <beast/detail/bind_handler.hpp>
|
||||
#include <beast/core/handler_concepts.hpp>
|
||||
#include <beast/core/detail/bind_handler.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_BUFFER_CAT_HPP
|
||||
#define BEAST_BUFFER_CAT_HPP
|
||||
|
||||
#include <beast/detail/buffer_cat.hpp>
|
||||
#include <beast/core/detail/buffer_cat.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_BUFFER_CONCEPTS_HPP
|
||||
#define BEAST_BUFFER_CONCEPTS_HPP
|
||||
|
||||
#include <beast/detail/buffer_concepts.hpp>
|
||||
#include <beast/core/detail/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_BUFFERS_ADAPTER_HPP
|
||||
#define BEAST_BUFFERS_ADAPTER_HPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -31,7 +31,6 @@ namespace beast {
|
||||
template<class MutableBufferSequence>
|
||||
class buffers_adapter
|
||||
{
|
||||
private:
|
||||
static_assert(is_MutableBufferSequence<MutableBufferSequence>::value,
|
||||
"MutableBufferSequence requirements not met");
|
||||
|
||||
@@ -146,6 +145,6 @@ public:
|
||||
|
||||
} // beast
|
||||
|
||||
#include <beast/impl/buffers_adapter.ipp>
|
||||
#include <beast/core/impl/buffers_adapter.ipp>
|
||||
|
||||
#endif
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_CONSUMING_BUFFERS_HPP
|
||||
#define BEAST_CONSUMING_BUFFERS_HPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
@@ -135,6 +135,6 @@ consumed_buffers(BufferSequence const& buffers, std::size_t n);
|
||||
|
||||
} // beast
|
||||
|
||||
#include <beast/impl/consuming_buffers.ipp>
|
||||
#include <beast/core/impl/consuming_buffers.ipp>
|
||||
|
||||
#endif
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_BIND_DETAIL_HANDLER_HPP
|
||||
#define BEAST_BIND_DETAIL_HANDLER_HPP
|
||||
|
||||
#include <beast/detail/integer_sequence.hpp>
|
||||
#include <beast/core/detail/integer_sequence.hpp>
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
@@ -197,7 +197,6 @@ private:
|
||||
void
|
||||
move(C<sizeof...(Bs)>, const_iterator&&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
@@ -216,7 +215,6 @@ private:
|
||||
void
|
||||
copy(C<sizeof...(Bs)>, const_iterator const&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
@@ -218,13 +218,13 @@ transform(
|
||||
|
||||
struct sha1_context
|
||||
{
|
||||
static unsigned int const block_size = sha1::BLOCK_BYTES;
|
||||
static unsigned int const digest_size = 20;
|
||||
static unsigned int constexpr block_size = sha1::BLOCK_BYTES;
|
||||
static unsigned int constexpr digest_size = 20;
|
||||
|
||||
std::uint32_t digest[5];
|
||||
std::uint8_t buf[block_size];
|
||||
std::size_t buflen;
|
||||
std::size_t blocks;
|
||||
std::uint32_t digest[5];
|
||||
std::uint8_t buf[block_size];
|
||||
};
|
||||
|
||||
template<class = void>
|
||||
@@ -232,12 +232,12 @@ void
|
||||
init(sha1_context& ctx) noexcept
|
||||
{
|
||||
ctx.buflen = 0;
|
||||
ctx.blocks = 0;
|
||||
ctx.digest[0] = 0x67452301;
|
||||
ctx.digest[1] = 0xefcdab89;
|
||||
ctx.digest[2] = 0x98badcfe;
|
||||
ctx.digest[3] = 0x10325476;
|
||||
ctx.digest[4] = 0xc3d2e1f0;
|
||||
ctx.blocks = 0;
|
||||
}
|
||||
|
||||
template<class = void>
|
||||
@@ -275,15 +275,14 @@ finish(sha1_context& ctx, void* digest) noexcept
|
||||
std::uint64_t total_bits =
|
||||
(ctx.blocks*64 + ctx.buflen) * 8;
|
||||
// pad
|
||||
auto const buflen = ctx.buflen;
|
||||
ctx.buf[ctx.buflen++] = 0x80;
|
||||
auto const buflen = ctx.buflen;
|
||||
while(ctx.buflen < 64)
|
||||
ctx.buf[ctx.buflen++] = 0x00;
|
||||
std::uint32_t block[BLOCK_INTS];
|
||||
sha1::make_block(ctx.buf, block);
|
||||
if (buflen > BLOCK_BYTES - 8)
|
||||
{
|
||||
++ctx.blocks;
|
||||
sha1::transform(ctx.digest, block);
|
||||
for (size_t i = 0; i < BLOCK_INTS - 2; i++)
|
||||
block[i] = 0;
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_DETAIL_STREAM_CONCEPTS_HPP
|
||||
#define BEAST_DETAIL_STREAM_CONCEPTS_HPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <type_traits>
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_DETAIL_WRITE_STREAMBUF_HPP
|
||||
#define BEAST_DETAIL_WRITE_STREAMBUF_HPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <utility>
|
||||
@@ -5,18 +5,20 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_HTTP_ERROR_HPP
|
||||
#define BEAST_HTTP_ERROR_HPP
|
||||
#ifndef BEAST_ERROR_HPP
|
||||
#define BEAST_ERROR_HPP
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/// The type of error code used by the library
|
||||
using error_code = boost::system::error_code;
|
||||
|
||||
} // http
|
||||
/// The type of system error thrown by the library
|
||||
using system_error = boost::system::system_error;
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_HANDLER_CONCEPTS_HPP
|
||||
#define BEAST_HANDLER_CONCEPTS_HPP
|
||||
|
||||
#include <beast/detail/is_call_possible.hpp>
|
||||
#include <beast/core/detail/is_call_possible.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_IMPL_BASIC_STREAMBUF_IPP
|
||||
#define BEAST_IMPL_BASIC_STREAMBUF_IPP
|
||||
|
||||
#include <beast/detail/write_streambuf.hpp>
|
||||
#include <beast/core/detail/write_streambuf.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
@@ -582,7 +582,7 @@ basic_streambuf<Allocator>::prepare(size_type n) ->
|
||||
list_.push_back(e);
|
||||
if(out_ == list_.end())
|
||||
out_ = list_.iterator_to(e);
|
||||
if(n > e.size())
|
||||
if(n >= e.size())
|
||||
{
|
||||
out_end_ = e.size();
|
||||
n -= e.size();
|
||||
@@ -855,8 +855,11 @@ std::size_t
|
||||
read_size_helper(basic_streambuf<
|
||||
Allocator> const& streambuf, std::size_t max_size)
|
||||
{
|
||||
return std::min<std::size_t>(max_size,
|
||||
std::max<std::size_t>(512, streambuf.prepare_size()));
|
||||
auto const avail = streambuf.prepare_size();
|
||||
if(avail == 0)
|
||||
return std::min(max_size,
|
||||
std::max<std::size_t>(512, streambuf.alloc_size_));
|
||||
return std::min(max_size, avail);
|
||||
}
|
||||
|
||||
template<class Alloc, class T>
|
||||
@@ -469,9 +469,8 @@ template<class MutableBufferSequence>
|
||||
void
|
||||
buffers_adapter<MutableBufferSequence>::consume(std::size_t n)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if(begin_ != out_)
|
||||
using boost::asio::buffer_size;
|
||||
while(begin_ != out_)
|
||||
{
|
||||
auto const avail =
|
||||
buffer_size(*begin_) - in_pos_;
|
||||
@@ -479,15 +478,13 @@ buffers_adapter<MutableBufferSequence>::consume(std::size_t n)
|
||||
{
|
||||
in_size_ -= n;
|
||||
in_pos_ += n;
|
||||
break;
|
||||
return;
|
||||
}
|
||||
n -= avail;
|
||||
in_size_ -= avail;
|
||||
in_pos_ = 0;
|
||||
++begin_;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const avail = out_pos_ - in_pos_;
|
||||
if(n < avail)
|
||||
{
|
||||
@@ -497,22 +494,8 @@ buffers_adapter<MutableBufferSequence>::consume(std::size_t n)
|
||||
else
|
||||
{
|
||||
in_size_ -= avail;
|
||||
if(out_pos_ != out_end_||
|
||||
out_ != std::prev(bs_.end()))
|
||||
{
|
||||
in_pos_ = out_pos_;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the whole buffer now.
|
||||
in_pos_ = 0;
|
||||
out_pos_ = 0;
|
||||
out_end_ = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_IMPL_CONSUMING_BUFFERS_IPP
|
||||
#define BEAST_IMPL_CONSUMING_BUFFERS_IPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
@@ -8,9 +8,9 @@
|
||||
#ifndef BEAST_IMPL_STREAMBUF_READSTREAM_IPP
|
||||
#define BEAST_IMPL_STREAMBUF_READSTREAM_IPP
|
||||
|
||||
#include <beast/bind_handler.hpp>
|
||||
#include <beast/handler_concepts.hpp>
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <beast/core/bind_handler.hpp>
|
||||
#include <beast/core/handler_concepts.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
|
||||
@@ -26,16 +26,16 @@ class streambuf_readstream<
|
||||
|
||||
struct data
|
||||
{
|
||||
streambuf_readstream& brs;
|
||||
streambuf_readstream& srs;
|
||||
MutableBufferSequence bs;
|
||||
Handler h;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_,
|
||||
streambuf_readstream& brs_,
|
||||
streambuf_readstream& srs_,
|
||||
MutableBufferSequence const& bs_)
|
||||
: brs(brs_)
|
||||
: srs(srs_)
|
||||
, bs(bs_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
{
|
||||
@@ -49,9 +49,10 @@ public:
|
||||
read_some_op(read_some_op const&) = default;
|
||||
|
||||
template<class DeducedHandler, class... Args>
|
||||
read_some_op(DeducedHandler&& h, Args&&... args)
|
||||
read_some_op(DeducedHandler&& h,
|
||||
streambuf_readstream& srs, Args&&... args)
|
||||
: d_(std::allocate_shared<data>(alloc_type{h},
|
||||
std::forward<DeducedHandler>(h),
|
||||
std::forward<DeducedHandler>(h), srs,
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
(*this)(error_code{}, 0);
|
||||
@@ -106,44 +107,44 @@ read_some_op<MutableBufferSequence, Handler>::operator()(
|
||||
switch(d.state)
|
||||
{
|
||||
case 0:
|
||||
if(d.brs.sb_.size() == 0)
|
||||
if(d.srs.sb_.size() == 0)
|
||||
{
|
||||
d.state =
|
||||
d.brs.size_ > 0 ? 2 : 1;
|
||||
d.srs.capacity_ > 0 ? 2 : 1;
|
||||
break;
|
||||
}
|
||||
d.state = 4;
|
||||
d.brs.get_io_service().post(
|
||||
d.srs.get_io_service().post(
|
||||
bind_handler(std::move(*this), ec, 0));
|
||||
return;
|
||||
|
||||
case 1:
|
||||
// read (unbuffered)
|
||||
d.state = 99;
|
||||
d.brs.next_layer_.async_read_some(
|
||||
d.srs.next_layer_.async_read_some(
|
||||
d.bs, std::move(*this));
|
||||
return;
|
||||
|
||||
case 2:
|
||||
// read
|
||||
d.state = 3;
|
||||
d.brs.next_layer_.async_read_some(
|
||||
d.brs.sb_.prepare(d.brs.size_),
|
||||
d.srs.next_layer_.async_read_some(
|
||||
d.srs.sb_.prepare(d.srs.capacity_),
|
||||
std::move(*this));
|
||||
return;
|
||||
|
||||
// got data
|
||||
case 3:
|
||||
d.state = 4;
|
||||
d.brs.sb_.commit(bytes_transferred);
|
||||
d.srs.sb_.commit(bytes_transferred);
|
||||
break;
|
||||
|
||||
// copy
|
||||
case 4:
|
||||
bytes_transferred =
|
||||
boost::asio::buffer_copy(
|
||||
d.bs, d.brs.sb_.data());
|
||||
d.brs.sb_.consume(bytes_transferred);
|
||||
d.bs, d.srs.sb_.data());
|
||||
d.srs.sb_.consume(bytes_transferred);
|
||||
// call handler
|
||||
d.state = 99;
|
||||
break;
|
||||
@@ -198,7 +199,7 @@ read_some(
|
||||
error_code ec;
|
||||
auto n = read_some(buffers, ec);
|
||||
if(ec)
|
||||
throw boost::system::system_error{ec};
|
||||
throw system_error{ec};
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -216,14 +217,12 @@ read_some(MutableBufferSequence const& buffers,
|
||||
"MutableBufferSequence requirements not met");
|
||||
using boost::asio::buffer_size;
|
||||
using boost::asio::buffer_copy;
|
||||
if(buffer_size(buffers) == 0)
|
||||
return 0;
|
||||
if(size_ == 0)
|
||||
return next_layer_.read_some(buffers, ec);
|
||||
if(sb_.size() == 0)
|
||||
{
|
||||
if(capacity_ == 0)
|
||||
return next_layer_.read_some(buffers, ec);
|
||||
sb_.commit(next_layer_.read_some(
|
||||
sb_.prepare(size_), ec));
|
||||
sb_.prepare(capacity_), ec));
|
||||
if(ec)
|
||||
return 0;
|
||||
}
|
||||
@@ -152,6 +152,6 @@ prepare_buffers(std::size_t n, BufferSequence const& buffers);
|
||||
|
||||
} // beast
|
||||
|
||||
#include <beast/impl/prepare_buffers.ipp>
|
||||
#include <beast/core/impl/prepare_buffers.ipp>
|
||||
|
||||
#endif
|
||||
@@ -184,6 +184,6 @@ public:
|
||||
|
||||
} // beast
|
||||
|
||||
#include <beast/impl/static_streambuf.ipp>
|
||||
#include <beast/core/impl/static_streambuf.ipp>
|
||||
|
||||
#endif
|
||||
@@ -1,21 +1,9 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_WEBSOCKET_STATIC_STRING_HPP
|
||||
#define BEAST_WEBSOCKET_STATIC_STRING_HPP
|
||||
@@ -279,13 +267,6 @@ public:
|
||||
return N;
|
||||
}
|
||||
|
||||
/// Reduces memory usage by freeing unused memory.
|
||||
void
|
||||
shrink_to_fit()
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
/// Clears the contents.
|
||||
void
|
||||
clear()
|
||||
@@ -310,7 +291,8 @@ public:
|
||||
|
||||
/// Compare two character sequences.
|
||||
template<std::size_t M>
|
||||
int compare(static_string<M, CharT, Traits> const& rhs) const;
|
||||
int
|
||||
compare(static_string<M, CharT, Traits> const& rhs) const;
|
||||
|
||||
/// Return the characters as a `basic_string`.
|
||||
std::basic_string<CharT, Traits>
|
||||
@@ -488,7 +470,8 @@ assign(CharT const* s)
|
||||
namespace detail {
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
int compare(
|
||||
int
|
||||
compare(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
const CharT (&s)[M])
|
||||
{
|
||||
@@ -512,27 +495,13 @@ int compare(
|
||||
}
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
int compare(
|
||||
inline
|
||||
int
|
||||
compare(
|
||||
const CharT (&s)[M],
|
||||
static_string<N, CharT, Traits> const& rhs)
|
||||
{
|
||||
if(M-1 < rhs.size())
|
||||
{
|
||||
auto const v = Traits::compare(
|
||||
&s[0], rhs.data(), M-1);
|
||||
if(v == 0)
|
||||
return -1;
|
||||
return v;
|
||||
}
|
||||
else if(M-1 > rhs.size())
|
||||
{
|
||||
auto const v = Traits::compare(
|
||||
&s[0], rhs.data(), rhs.size());
|
||||
if(v == 0)
|
||||
return 1;
|
||||
return v;
|
||||
}
|
||||
return Traits::compare(&s[0], rhs.data(), M-1);
|
||||
return -compare(rhs, s);
|
||||
}
|
||||
|
||||
} // detail
|
||||
@@ -540,7 +509,8 @@ int compare(
|
||||
#if ! GENERATING_DOCS
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
bool operator==(
|
||||
bool
|
||||
operator==(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
static_string<M, CharT, Traits> const& rhs)
|
||||
{
|
||||
@@ -548,7 +518,8 @@ bool operator==(
|
||||
}
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
bool operator!=(
|
||||
bool
|
||||
operator!=(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
static_string<M, CharT, Traits> const& rhs)
|
||||
{
|
||||
@@ -556,7 +527,8 @@ bool operator!=(
|
||||
}
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
bool operator<(
|
||||
bool
|
||||
operator<(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
static_string<M, CharT, Traits> const& rhs)
|
||||
{
|
||||
@@ -564,7 +536,8 @@ bool operator<(
|
||||
}
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
bool operator<=(
|
||||
bool
|
||||
operator<=(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
static_string<M, CharT, Traits> const& rhs)
|
||||
{
|
||||
@@ -572,7 +545,8 @@ bool operator<=(
|
||||
}
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
bool operator>(
|
||||
bool
|
||||
operator>(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
static_string<M, CharT, Traits> const& rhs)
|
||||
{
|
||||
@@ -580,7 +554,8 @@ bool operator>(
|
||||
}
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
bool operator>=(
|
||||
bool
|
||||
operator>=(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
static_string<M, CharT, Traits> const& rhs)
|
||||
{
|
||||
@@ -590,7 +565,8 @@ bool operator>=(
|
||||
//---
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
bool operator==(
|
||||
bool
|
||||
operator==(
|
||||
const CharT (&s)[N],
|
||||
static_string<M, CharT, Traits> const& rhs)
|
||||
{
|
||||
@@ -598,7 +574,8 @@ bool operator==(
|
||||
}
|
||||
|
||||
template<std::size_t N, class CharT, class Traits, std::size_t M>
|
||||
bool operator==(
|
||||
bool
|
||||
operator==(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
const CharT (&s)[M])
|
||||
{
|
||||
@@ -606,7 +583,8 @@ bool operator==(
|
||||
}
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
bool operator!=(
|
||||
bool
|
||||
operator!=(
|
||||
const CharT (&s)[N],
|
||||
static_string<M, CharT, Traits> const& rhs)
|
||||
{
|
||||
@@ -614,7 +592,8 @@ bool operator!=(
|
||||
}
|
||||
|
||||
template<std::size_t N, class CharT, class Traits, std::size_t M>
|
||||
bool operator!=(
|
||||
bool
|
||||
operator!=(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
const CharT (&s)[M])
|
||||
{
|
||||
@@ -622,7 +601,8 @@ bool operator!=(
|
||||
}
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
bool operator<(
|
||||
bool
|
||||
operator<(
|
||||
const CharT (&s)[N],
|
||||
static_string<M, CharT, Traits> const& rhs)
|
||||
{
|
||||
@@ -630,7 +610,8 @@ bool operator<(
|
||||
}
|
||||
|
||||
template<std::size_t N, class CharT, class Traits, std::size_t M>
|
||||
bool operator<(
|
||||
bool
|
||||
operator<(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
const CharT (&s)[M])
|
||||
{
|
||||
@@ -638,7 +619,8 @@ bool operator<(
|
||||
}
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
bool operator<=(
|
||||
bool
|
||||
operator<=(
|
||||
const CharT (&s)[N],
|
||||
static_string<M, CharT, Traits> const& rhs)
|
||||
{
|
||||
@@ -646,7 +628,8 @@ bool operator<=(
|
||||
}
|
||||
|
||||
template<std::size_t N, class CharT, class Traits, std::size_t M>
|
||||
bool operator<=(
|
||||
bool
|
||||
operator<=(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
const CharT (&s)[M])
|
||||
{
|
||||
@@ -654,7 +637,8 @@ bool operator<=(
|
||||
}
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
bool operator>(
|
||||
bool
|
||||
operator>(
|
||||
const CharT (&s)[N],
|
||||
static_string<M, CharT, Traits> const& rhs)
|
||||
{
|
||||
@@ -662,7 +646,8 @@ bool operator>(
|
||||
}
|
||||
|
||||
template<std::size_t N, class CharT, class Traits, std::size_t M>
|
||||
bool operator>(
|
||||
bool
|
||||
operator>(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
const CharT (&s)[M])
|
||||
{
|
||||
@@ -670,7 +655,8 @@ bool operator>(
|
||||
}
|
||||
|
||||
template<std::size_t N, std::size_t M, class CharT, class Traits>
|
||||
bool operator>=(
|
||||
bool
|
||||
operator>=(
|
||||
const CharT (&s)[N],
|
||||
static_string<M, CharT, Traits> const& rhs)
|
||||
{
|
||||
@@ -678,7 +664,8 @@ bool operator>=(
|
||||
}
|
||||
|
||||
template<std::size_t N, class CharT, class Traits, std::size_t M>
|
||||
bool operator>=(
|
||||
bool
|
||||
operator>=(
|
||||
static_string<N, CharT, Traits> const& lhs,
|
||||
const CharT (&s)[M])
|
||||
{
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_STREAM_CONCEPTS_HPP
|
||||
#define BEAST_STREAM_CONCEPTS_HPP
|
||||
|
||||
#include <beast/detail/stream_concepts.hpp>
|
||||
#include <beast/core/detail/stream_concepts.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_STREAMBUF_HPP
|
||||
#define BEAST_STREAMBUF_HPP
|
||||
|
||||
#include <beast/basic_streambuf.hpp>
|
||||
#include <beast/core/basic_streambuf.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
#ifndef BEAST_STREAMBUF_READSTREAM_HPP
|
||||
#define BEAST_STREAMBUF_READSTREAM_HPP
|
||||
|
||||
#include <beast/async_completion.hpp>
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/stream_concepts.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <beast/detail/get_lowest_layer.hpp>
|
||||
#include <beast/core/async_completion.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <beast/core/error.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <beast/core/detail/get_lowest_layer.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
@@ -98,7 +99,7 @@ class streambuf_readstream
|
||||
class read_some_op;
|
||||
|
||||
Streambuf sb_;
|
||||
std::size_t size_ = 0;
|
||||
std::size_t capacity_ = 0;
|
||||
Stream next_layer_;
|
||||
|
||||
public:
|
||||
@@ -210,9 +211,9 @@ public:
|
||||
than the amount of data in the buffer, no bytes are discarded.
|
||||
*/
|
||||
void
|
||||
reserve(std::size_t size)
|
||||
capacity(std::size_t size)
|
||||
{
|
||||
size_ = size;
|
||||
capacity_ = size;
|
||||
}
|
||||
|
||||
/// Write the given data to the stream. Returns the number of bytes written.
|
||||
@@ -276,6 +277,6 @@ public:
|
||||
|
||||
} // beast
|
||||
|
||||
#include <beast/impl/streambuf_readstream.ipp>
|
||||
#include <beast/core/impl/streambuf_readstream.ipp>
|
||||
|
||||
#endif
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_TO_STRING_HPP
|
||||
#define BEAST_TO_STRING_HPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <string>
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#ifndef BEAST_WRITE_STREAMBUF_HPP
|
||||
#define BEAST_WRITE_STREAMBUF_HPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/detail/write_streambuf.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <beast/core/detail/write_streambuf.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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)
|
||||
//
|
||||
|
||||
#include <beast/detail/unit_test/amount.hpp>
|
||||
#include <beast/detail/unit_test/global_suites.hpp>
|
||||
#include <beast/detail/unit_test/suite.hpp>
|
||||
#include <string>
|
||||
|
||||
// Include this .cpp in your project to gain access to the printing suite
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
namespace unit_test {
|
||||
namespace detail {
|
||||
|
||||
/** A suite that prints the list of globally defined suites. */
|
||||
class print_test : public suite
|
||||
{
|
||||
private:
|
||||
template <class = void>
|
||||
void
|
||||
do_run();
|
||||
|
||||
public:
|
||||
template <class = void>
|
||||
static
|
||||
std::string
|
||||
prefix (suite_info const& s);
|
||||
|
||||
template <class = void>
|
||||
void
|
||||
print (suite_list &c);
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
do_run();
|
||||
}
|
||||
};
|
||||
|
||||
template <class>
|
||||
void
|
||||
print_test::do_run()
|
||||
{
|
||||
log << "------------------------------------------";
|
||||
print (global_suites());
|
||||
log << "------------------------------------------";
|
||||
pass();
|
||||
}
|
||||
|
||||
template <class>
|
||||
std::string
|
||||
print_test::prefix (suite_info const& s)
|
||||
{
|
||||
if (s.manual())
|
||||
return "|M| ";
|
||||
return " ";
|
||||
}
|
||||
|
||||
template <class>
|
||||
void
|
||||
print_test::print (suite_list &c)
|
||||
{
|
||||
std::size_t manual (0);
|
||||
for (auto const& s : c)
|
||||
{
|
||||
log <<
|
||||
prefix (s) <<
|
||||
s.full_name();
|
||||
if (s.manual())
|
||||
++manual;
|
||||
}
|
||||
log <<
|
||||
amount (c.size(), "suite") << " total, " <<
|
||||
amount (manual, "manual suite")
|
||||
;
|
||||
}
|
||||
|
||||
BEAST_DEFINE_TESTSUITE_MANUAL(print,unit_test,beast);
|
||||
|
||||
} // detail
|
||||
} // unit_test
|
||||
} // detail
|
||||
} // beast
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <beast/http/basic_parser_v1.hpp>
|
||||
#include <beast/http/body_type.hpp>
|
||||
#include <beast/http/empty_body.hpp>
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/headers.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#ifndef BEAST_HTTP_BASIC_HEADERS_HPP
|
||||
#define BEAST_HTTP_BASIC_HEADERS_HPP
|
||||
|
||||
#include <beast/detail/ci_char_traits.hpp>
|
||||
#include <beast/detail/empty_base_optimization.hpp>
|
||||
#include <beast/core/detail/ci_char_traits.hpp>
|
||||
#include <beast/core/detail/empty_base_optimization.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
@@ -36,11 +36,26 @@ enum values
|
||||
};
|
||||
} // parse_flag
|
||||
|
||||
/** Base class for parsing HTTP/1 requests and responses.
|
||||
/** A parser for decoding HTTP/1 wire format messages.
|
||||
|
||||
During parsing, callbacks will be made to the derived class
|
||||
if those members are present (detected through SFINAE). The
|
||||
signatures which can be present in the derived class are:<br>
|
||||
This parser is designed to efficiently parse messages in the
|
||||
HTTP/1 wire format. It allocates no memory and uses minimal
|
||||
state. It will handle chunked encoding and it understands the
|
||||
semantics of the Connection and Content-Length header fields.
|
||||
|
||||
The interface uses CRTP (Curiously Recurring Template Pattern).
|
||||
To use this class, derive from basic_parser. When bytes are
|
||||
presented, the implementation will make a series of zero or
|
||||
more calls to derived class members functions (referred to as
|
||||
"callbacks" from here on) matching a specific signature.
|
||||
|
||||
Callbacks are detected through SFINAE. The derived class may
|
||||
implement as few or as many of the members as needed.
|
||||
These are the signatures of the callbacks:<br>
|
||||
|
||||
@li `void on_start(error_code&)`
|
||||
|
||||
Called when the first valid octet of a new message is received
|
||||
|
||||
@li `void on_method(boost::string_ref const&, error_code&)`
|
||||
|
||||
@@ -106,6 +121,9 @@ enum values
|
||||
|
||||
If a callback sets an error, parsing stops at the current octet
|
||||
and the error is returned to the caller.
|
||||
|
||||
@tparam isRequest A `bool` indicating whether the parser will be
|
||||
presented with request or response message.
|
||||
*/
|
||||
template<bool isRequest, class Derived>
|
||||
class basic_parser_v1
|
||||
@@ -188,7 +206,8 @@ private:
|
||||
s_chunk_data_done,
|
||||
|
||||
s_complete,
|
||||
s_restart
|
||||
s_restart,
|
||||
s_closed_complete
|
||||
};
|
||||
|
||||
enum field_state : std::uint8_t
|
||||
@@ -341,7 +360,7 @@ public:
|
||||
bool
|
||||
complete() const
|
||||
{
|
||||
return s_ == s_restart;
|
||||
return s_ == s_restart || s_ == s_closed_complete;
|
||||
}
|
||||
|
||||
/** Write a sequence of buffers to the parser.
|
||||
@@ -411,6 +430,24 @@ private:
|
||||
bool
|
||||
needs_eof(std::false_type) const;
|
||||
|
||||
template<class C>
|
||||
class has_on_start_t
|
||||
{
|
||||
template<class T, class R =
|
||||
decltype(std::declval<T>().on_start(
|
||||
std::declval<error_code&>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template <class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<C>(0));
|
||||
public:
|
||||
static bool const value = type::value;
|
||||
};
|
||||
template<class C>
|
||||
using has_on_start =
|
||||
std::integral_constant<bool, has_on_start_t<C>::value>;
|
||||
|
||||
template<class C>
|
||||
class has_on_method_t
|
||||
{
|
||||
@@ -596,6 +633,20 @@ private:
|
||||
using has_on_complete =
|
||||
std::integral_constant<bool, has_on_complete_t<C>::value>;
|
||||
|
||||
void call_on_start(error_code& ec, std::true_type)
|
||||
{
|
||||
impl().on_start(ec);
|
||||
}
|
||||
|
||||
void call_on_start(error_code& ec, std::false_type)
|
||||
{
|
||||
}
|
||||
|
||||
void call_on_start(error_code& ec)
|
||||
{
|
||||
call_on_start(ec, has_on_start<Derived>{});
|
||||
}
|
||||
|
||||
void call_on_method(error_code& ec,
|
||||
boost::string_ref const& s, std::true_type)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// Convenience header to include everything
|
||||
// needed when declarating a user defined Body type.
|
||||
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/core/error.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/resume_context.hpp>
|
||||
#include <boost/logic/tribool.hpp>
|
||||
|
||||
@@ -132,7 +132,7 @@ to_value_char(char c)
|
||||
}
|
||||
|
||||
inline
|
||||
std::uint8_t
|
||||
std::int8_t
|
||||
unhex(char c)
|
||||
{
|
||||
static std::array<std::int8_t, 256> constexpr tab = {{
|
||||
@@ -146,7 +146,7 @@ unhex(char c)
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 112
|
||||
}};
|
||||
return tab[static_cast<std::uint8_t>(c)];
|
||||
};
|
||||
}
|
||||
|
||||
template<class = void>
|
||||
struct parser_str_t
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
#ifndef BEAST_HTTP_DETAIL_CHUNK_ENCODE_HPP
|
||||
#define BEAST_HTTP_DETAIL_CHUNK_ENCODE_HPP
|
||||
|
||||
#include <beast/core/buffer_cat.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/logic/tribool.hpp>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
@@ -20,244 +22,94 @@ namespace beast {
|
||||
namespace http {
|
||||
namespace detail {
|
||||
|
||||
template <class Buffers>
|
||||
class chunk_encoded_buffers
|
||||
class chunk_encode_text
|
||||
{
|
||||
private:
|
||||
using const_buffer = boost::asio::const_buffer;
|
||||
|
||||
Buffers buffers_;
|
||||
const_buffer head_;
|
||||
const_buffer tail_;
|
||||
boost::asio::const_buffer cb_;
|
||||
|
||||
// Storage for the longest hex string we might need, plus delimiters.
|
||||
std::array<char, 2 * sizeof(std::size_t) + 2> data_;
|
||||
std::array<char, 2 * sizeof(std::size_t) + 2> buf_;
|
||||
|
||||
template <class OutIter>
|
||||
static
|
||||
OutIter
|
||||
to_hex(OutIter last, std::size_t n)
|
||||
{
|
||||
if(n == 0)
|
||||
{
|
||||
*--last = '0';
|
||||
return last;
|
||||
}
|
||||
while(n)
|
||||
{
|
||||
*--last = "0123456789abcdef"[n&0xf];
|
||||
n>>=4;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = boost::asio::const_buffer;
|
||||
|
||||
class const_iterator;
|
||||
using const_iterator = value_type const*;
|
||||
|
||||
chunk_encoded_buffers() = delete;
|
||||
chunk_encoded_buffers (chunk_encoded_buffers const&) = default;
|
||||
chunk_encoded_buffers& operator= (chunk_encoded_buffers const&) = default;
|
||||
chunk_encode_text(chunk_encode_text const& other)
|
||||
{
|
||||
auto const n =
|
||||
boost::asio::buffer_size(other.cb_);
|
||||
buf_ = other.buf_;
|
||||
cb_ = boost::asio::const_buffer(
|
||||
&buf_[buf_.size() - n], n);
|
||||
}
|
||||
|
||||
chunk_encoded_buffers (Buffers const& buffers, bool final_chunk);
|
||||
explicit
|
||||
chunk_encode_text(std::size_t n)
|
||||
{
|
||||
buf_[buf_.size() - 2] = '\r';
|
||||
buf_[buf_.size() - 1] = '\n';
|
||||
auto it = to_hex(buf_.end() - 2, n);
|
||||
cb_ = boost::asio::const_buffer{&*it,
|
||||
static_cast<std::size_t>(
|
||||
std::distance(it, buf_.end()))};
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return const_iterator(*this, false);
|
||||
return &cb_;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const
|
||||
{
|
||||
return const_iterator(*this, true);
|
||||
return begin() + 1;
|
||||
}
|
||||
|
||||
private:
|
||||
// Unchecked conversion of unsigned to hex string
|
||||
template<class OutIter, class Unsigned>
|
||||
static
|
||||
typename std::enable_if<
|
||||
std::is_unsigned<Unsigned>::value, OutIter>::type
|
||||
to_hex(OutIter const first, OutIter const last, Unsigned n);
|
||||
};
|
||||
|
||||
template <class Buffers>
|
||||
class chunk_encoded_buffers<Buffers>::const_iterator
|
||||
: public std::iterator<std::bidirectional_iterator_tag, const_buffer>
|
||||
{
|
||||
private:
|
||||
using iterator = typename Buffers::const_iterator;
|
||||
enum class Where { head, input, end };
|
||||
chunk_encoded_buffers const* buffers_;
|
||||
Where where_;
|
||||
iterator iter_;
|
||||
/** Returns a chunk-encoded ConstBufferSequence.
|
||||
|
||||
public:
|
||||
const_iterator();
|
||||
const_iterator (const_iterator const&) = default;
|
||||
const_iterator& operator= (const_iterator const&) = default;
|
||||
bool operator== (const_iterator const& other) const;
|
||||
bool operator!= (const_iterator const& other) const;
|
||||
const_iterator& operator++();
|
||||
const_iterator& operator--();
|
||||
const_iterator operator++(int) const;
|
||||
const_iterator operator--(int) const;
|
||||
const_buffer operator*() const;
|
||||
|
||||
private:
|
||||
friend class chunk_encoded_buffers;
|
||||
const_iterator(chunk_encoded_buffers const& buffers, bool past_the_end);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Buffers>
|
||||
chunk_encoded_buffers<Buffers>::chunk_encoded_buffers (
|
||||
Buffers const& buffers, bool final_chunk)
|
||||
: buffers_(buffers)
|
||||
{
|
||||
auto const size = boost::asio::buffer_size(buffers);
|
||||
data_[data_.size() - 2] = '\r';
|
||||
data_[data_.size() - 1] = '\n';
|
||||
auto pos = to_hex(data_.begin(), data_.end() - 2, size);
|
||||
head_ = const_buffer(&*pos,
|
||||
std::distance(pos, data_.end()));
|
||||
if (size > 0 && final_chunk)
|
||||
tail_ = const_buffer("\r\n0\r\n\r\n", 7);
|
||||
else
|
||||
tail_ = const_buffer("\r\n", 2);
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
template <class OutIter, class Unsigned>
|
||||
typename std::enable_if<
|
||||
std::is_unsigned<Unsigned>::value, OutIter>::type
|
||||
chunk_encoded_buffers<Buffers>::to_hex(
|
||||
OutIter const first, OutIter const last, Unsigned n)
|
||||
{
|
||||
assert(first != last);
|
||||
OutIter iter = last;
|
||||
if(n == 0)
|
||||
{
|
||||
*--iter = '0';
|
||||
return iter;
|
||||
}
|
||||
while(n)
|
||||
{
|
||||
assert(iter != first);
|
||||
*--iter = "0123456789abcdef"[n&0xf];
|
||||
n>>=4;
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::const_iterator()
|
||||
: buffers_(nullptr)
|
||||
, where_(Where::end)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
bool
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator==(
|
||||
const_iterator const& other) const
|
||||
{
|
||||
return buffers_ == other.buffers_ &&
|
||||
where_ == other.where_ && iter_ == other.iter_;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
bool
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator!=(
|
||||
const_iterator const& other) const
|
||||
{
|
||||
return buffers_ != other.buffers_ ||
|
||||
where_ != other.where_ || iter_ != other.iter_;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
auto
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator++() ->
|
||||
const_iterator&
|
||||
{
|
||||
assert(buffers_);
|
||||
assert(where_ != Where::end);
|
||||
if (where_ == Where::head)
|
||||
where_ = Where::input;
|
||||
else if (iter_ != buffers_->buffers_.end())
|
||||
++iter_;
|
||||
else
|
||||
where_ = Where::end;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
auto
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator--() ->
|
||||
const_iterator&
|
||||
{
|
||||
assert(buffers_);
|
||||
assert(where_ != Where::head);
|
||||
if (where_ == Where::end)
|
||||
where_ = Where::input;
|
||||
else if (iter_ != buffers_->buffers_.begin())
|
||||
--iter_;
|
||||
else
|
||||
where_ = Where::head;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
auto
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator++(int) const ->
|
||||
const_iterator
|
||||
{
|
||||
auto iter = *this;
|
||||
++iter;
|
||||
return iter;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
auto
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator--(int) const ->
|
||||
const_iterator
|
||||
{
|
||||
auto iter = *this;
|
||||
--iter;
|
||||
return iter;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
auto
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator*() const ->
|
||||
const_buffer
|
||||
{
|
||||
assert(buffers_);
|
||||
assert(where_ != Where::end);
|
||||
if (where_ == Where::head)
|
||||
return buffers_->head_;
|
||||
if (iter_ != buffers_->buffers_.end())
|
||||
return *iter_;
|
||||
return buffers_->tail_;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::const_iterator(
|
||||
chunk_encoded_buffers const& buffers, bool past_the_end)
|
||||
: buffers_(&buffers)
|
||||
, where_(past_the_end ? Where::end : Where::head)
|
||||
, iter_(past_the_end ? buffers_->buffers_.end() :
|
||||
buffers_->buffers_.begin())
|
||||
{
|
||||
}
|
||||
|
||||
/* Returns a chunk-encoded BufferSequence.
|
||||
|
||||
See:
|
||||
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1
|
||||
This returns a buffer sequence representing the
|
||||
first chunk of a chunked transfer coded body.
|
||||
|
||||
@param buffers The input buffer sequence.
|
||||
|
||||
@param final_chunk `true` If this should include a final-chunk.
|
||||
|
||||
@return A chunk-encoded ConstBufferSequence representing the input.
|
||||
|
||||
@see <a href=https://tools.ietf.org/html/rfc7230#section-4.1.3>rfc7230 section 4.1.3</a>
|
||||
*/
|
||||
template<class ConstBufferSequence>
|
||||
#if GENERATING_DOCS
|
||||
implementation_defined
|
||||
#else
|
||||
detail::chunk_encoded_buffers<ConstBufferSequence>
|
||||
beast::detail::buffer_cat_helper<boost::asio::const_buffer,
|
||||
chunk_encode_text, ConstBufferSequence, boost::asio::const_buffers_1>
|
||||
#endif
|
||||
chunk_encode(ConstBufferSequence const& buffers,
|
||||
bool final_chunk = false)
|
||||
chunk_encode(ConstBufferSequence const& buffers)
|
||||
{
|
||||
return detail::chunk_encoded_buffers<
|
||||
ConstBufferSequence>{buffers, final_chunk};
|
||||
using boost::asio::buffer_size;
|
||||
return buffer_cat(
|
||||
chunk_encode_text{buffer_size(buffers)},
|
||||
buffers,
|
||||
boost::asio::const_buffers_1{"\r\n", 2});
|
||||
}
|
||||
|
||||
/// Returns a chunked encoding final chunk.
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define BEAST_HTTP_EMPTY_BODY_HPP
|
||||
|
||||
#include <beast/http/body_type.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
@@ -136,8 +136,6 @@ basic_headers(basic_headers&& other)
|
||||
, detail::basic_headers_base(
|
||||
std::move(other.set_), std::move(other.list_))
|
||||
{
|
||||
other.list_.clear();
|
||||
other.set_.clear();
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
#ifndef BEAST_HTTP_IMPL_BASIC_PARSER_V1_IPP
|
||||
#define BEAST_HTTP_IMPL_BASIC_PARSER_V1_IPP
|
||||
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <cassert>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
@@ -88,6 +89,11 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
s_ = s_closed;
|
||||
return used();
|
||||
};
|
||||
auto errc = [&]
|
||||
{
|
||||
s_ = s_closed;
|
||||
return used();
|
||||
};
|
||||
auto piece = [&]
|
||||
{
|
||||
return boost::string_ref{
|
||||
@@ -113,6 +119,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
switch(s_)
|
||||
{
|
||||
case s_closed:
|
||||
case s_closed_complete:
|
||||
return err(parse_error::connection_closed);
|
||||
break;
|
||||
|
||||
@@ -126,6 +133,9 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
case s_req_method_start:
|
||||
if(! is_token(ch))
|
||||
return err(parse_error::bad_method);
|
||||
call_on_start(ec);
|
||||
if(ec)
|
||||
return errc();
|
||||
cb_ = &self::call_on_method;
|
||||
s_ = s_req_method;
|
||||
break;
|
||||
@@ -134,7 +144,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
if(! is_token(ch))
|
||||
{
|
||||
if(cb(nullptr))
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_req_space_before_url;
|
||||
goto redo;
|
||||
}
|
||||
@@ -147,23 +157,29 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
break;
|
||||
|
||||
case s_req_url_start:
|
||||
{
|
||||
if(ch == ' ')
|
||||
return err(parse_error::bad_uri);
|
||||
// VFALCO TODO Require valid URL character
|
||||
if(cb(&self::call_on_uri))
|
||||
return used();
|
||||
// VFALCO TODO Better checking for valid URL characters
|
||||
if(! is_text(ch))
|
||||
return err(parse_error::bad_uri);
|
||||
assert(! cb_);
|
||||
cb(&self::call_on_uri);
|
||||
s_ = s_req_url;
|
||||
break;
|
||||
}
|
||||
|
||||
case s_req_url:
|
||||
if(ch == ' ')
|
||||
{
|
||||
if(cb(nullptr))
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_req_http_start;
|
||||
break;
|
||||
}
|
||||
// VFALCO TODO Require valid URL character
|
||||
// VFALCO TODO Better checking for valid URL characters
|
||||
if(! is_text(ch))
|
||||
return err(parse_error::bad_uri);
|
||||
break;
|
||||
|
||||
case s_req_http_start:
|
||||
@@ -241,7 +257,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
return err(parse_error::bad_crlf);
|
||||
call_on_request(ec);
|
||||
if(ec)
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_header_field_start;
|
||||
break;
|
||||
|
||||
@@ -253,7 +269,14 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
content_length_ = no_content_length;
|
||||
switch(ch)
|
||||
{
|
||||
case 'H': s_ = s_res_H; break;
|
||||
case 'H':
|
||||
call_on_start(ec);
|
||||
if(ec)
|
||||
return errc();
|
||||
s_ = s_res_H;
|
||||
break;
|
||||
// VFALCO NOTE this allows whitespace at the beginning,
|
||||
// need to check rfc7230
|
||||
case '\r':
|
||||
case '\n':
|
||||
break;
|
||||
@@ -361,13 +384,16 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
s_ = s_res_line_almost_done;
|
||||
break;
|
||||
}
|
||||
// VFALCO Is this up to spec?
|
||||
if(ch == '\n')
|
||||
{
|
||||
s_ = s_header_field_start;
|
||||
break;
|
||||
}
|
||||
if(! is_text(ch))
|
||||
return err(parse_error::bad_status);
|
||||
if(cb(&self::call_on_reason))
|
||||
return used();
|
||||
return errc();
|
||||
pos_ = 0;
|
||||
s_ = s_res_status;
|
||||
break;
|
||||
@@ -376,17 +402,19 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
if(ch == '\r')
|
||||
{
|
||||
if(cb(nullptr))
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_res_line_almost_done;
|
||||
break;
|
||||
}
|
||||
if(ch == '\n')
|
||||
{
|
||||
if(cb(nullptr))
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_header_field_start;
|
||||
break;
|
||||
}
|
||||
if(! is_text(ch))
|
||||
return err(parse_error::bad_status);
|
||||
break;
|
||||
|
||||
case s_res_line_almost_done:
|
||||
@@ -398,7 +426,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
case s_res_line_done:
|
||||
call_on_response(ec);
|
||||
if(ec)
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_header_field_start;
|
||||
goto redo;
|
||||
|
||||
@@ -427,8 +455,8 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
fs_ = h_general;
|
||||
break;
|
||||
}
|
||||
if(cb(&self::call_on_field))
|
||||
return used();
|
||||
assert(! cb_);
|
||||
cb(&self::call_on_field);
|
||||
s_ = s_header_field;
|
||||
break;
|
||||
}
|
||||
@@ -525,7 +553,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
if(ch == ':')
|
||||
{
|
||||
if(cb(nullptr))
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_header_value_start;
|
||||
break;
|
||||
}
|
||||
@@ -575,7 +603,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
}
|
||||
call_on_value(ec, boost::string_ref{"", 0});
|
||||
if(ec)
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_header_field_start;
|
||||
goto redo;
|
||||
|
||||
@@ -625,7 +653,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
}
|
||||
pos_ = 0;
|
||||
if(cb(&self::call_on_value))
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_header_value_text;
|
||||
break;
|
||||
}
|
||||
@@ -637,7 +665,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
if(ch == '\r')
|
||||
{
|
||||
if(cb(nullptr))
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_header_value_discard_lWs;
|
||||
break;
|
||||
}
|
||||
@@ -771,9 +799,9 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
return err(parse_error::bad_value);
|
||||
call_on_value(ec, boost::string_ref(" ", 1));
|
||||
if(ec)
|
||||
return used();
|
||||
return errc();
|
||||
if(cb(&self::call_on_value))
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_header_value_text;
|
||||
break;
|
||||
|
||||
@@ -807,7 +835,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
return err(parse_error::bad_crlf);
|
||||
if(flags_ & parse_flag::trailing)
|
||||
{
|
||||
//if(cb(&self::call_on_chunk_complete)) return used();
|
||||
//if(cb(&self::call_on_chunk_complete)) return errc();
|
||||
s_ = s_complete;
|
||||
goto redo;
|
||||
}
|
||||
@@ -817,7 +845,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
(parse_flag::upgrade | parse_flag::connection_upgrade)) /*|| method == "connect"*/;
|
||||
auto const maybe_skip = call_on_headers(ec);
|
||||
if(ec)
|
||||
return used();
|
||||
return errc();
|
||||
switch(maybe_skip)
|
||||
{
|
||||
case 0: break;
|
||||
@@ -835,7 +863,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
assert(! cb_);
|
||||
call_on_headers(ec);
|
||||
if(ec)
|
||||
return used();
|
||||
return errc();
|
||||
bool const hasBody =
|
||||
(flags_ & parse_flag::chunked) || (content_length_ > 0 &&
|
||||
content_length_ != no_content_length);
|
||||
@@ -874,8 +902,8 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
}
|
||||
|
||||
case s_body_identity0:
|
||||
if(cb(&self::call_on_body))
|
||||
return used();
|
||||
assert(! cb_);
|
||||
cb(&self::call_on_body);
|
||||
s_ = s_body_identity;
|
||||
goto redo; // VFALCO fall through?
|
||||
|
||||
@@ -899,8 +927,8 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
}
|
||||
|
||||
case s_body_identity_eof0:
|
||||
if(cb(&self::call_on_body))
|
||||
return used();
|
||||
assert(! cb_);
|
||||
cb(&self::call_on_body);
|
||||
s_ = s_body_identity_eof;
|
||||
goto redo; // VFALCO fall through?
|
||||
|
||||
@@ -959,13 +987,13 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
s_ = s_header_field_start;
|
||||
break;
|
||||
}
|
||||
//call_chunk_header(ec); if(ec) return used();
|
||||
//call_chunk_header(ec); if(ec) return errc();
|
||||
s_ = s_chunk_data_start;
|
||||
break;
|
||||
|
||||
case s_chunk_data_start:
|
||||
if(cb(&self::call_on_body))
|
||||
return used();
|
||||
assert(! cb_);
|
||||
cb(&self::call_on_body);
|
||||
s_ = s_chunk_data;
|
||||
goto redo; // VFALCO fall through?
|
||||
|
||||
@@ -987,7 +1015,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
if(ch != '\r')
|
||||
return err(parse_error::bad_crlf);
|
||||
if(cb(nullptr))
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_chunk_data_done;
|
||||
break;
|
||||
|
||||
@@ -1001,10 +1029,10 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
case s_complete:
|
||||
++p;
|
||||
if(cb(nullptr))
|
||||
return used();
|
||||
return errc();
|
||||
call_on_complete(ec);
|
||||
if(ec)
|
||||
return used();
|
||||
return errc();
|
||||
s_ = s_restart;
|
||||
return used();
|
||||
|
||||
@@ -1020,7 +1048,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
{
|
||||
(this->*cb_)(ec, piece());
|
||||
if(ec)
|
||||
return used();
|
||||
return errc();
|
||||
}
|
||||
return used();
|
||||
}
|
||||
@@ -1032,17 +1060,31 @@ write_eof(error_code& ec)
|
||||
{
|
||||
switch(s_)
|
||||
{
|
||||
case s_restart:
|
||||
s_ = s_closed_complete;
|
||||
break;
|
||||
|
||||
case s_closed:
|
||||
case s_closed_complete:
|
||||
break;
|
||||
|
||||
case s_body_identity_eof0:
|
||||
case s_body_identity_eof:
|
||||
cb_ = nullptr;
|
||||
call_on_complete(ec);
|
||||
if(ec)
|
||||
return;
|
||||
return;
|
||||
default:
|
||||
{
|
||||
s_ = s_closed;
|
||||
break;
|
||||
}
|
||||
ec = parse_error::short_read;
|
||||
s_ = s_closed_complete;
|
||||
break;
|
||||
|
||||
default:
|
||||
s_ = s_closed;
|
||||
ec = parse_error::short_read;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<bool isRequest, class Derived>
|
||||
|
||||
@@ -16,28 +16,6 @@
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
message_v1<isRequest, Body, Headers>::
|
||||
message_v1(request_params params)
|
||||
{
|
||||
static_assert(isRequest, "message is not a request");
|
||||
this->method = params.method;
|
||||
this->url = std::move(params.url);
|
||||
version = params.version;
|
||||
}
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
message_v1<isRequest, Body, Headers>::
|
||||
message_v1(response_params params)
|
||||
{
|
||||
static_assert(! isRequest, "message is not a response");
|
||||
this->status = params.status;
|
||||
this->reason = std::move(params.reason);
|
||||
version = params.version;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
bool
|
||||
is_keep_alive(message_v1<isRequest, Body, Headers> const& msg)
|
||||
@@ -228,12 +206,6 @@ prepare(message_v1<isRequest, Body, Headers>& msg,
|
||||
msg.headers["Connection"], "upgrade"))
|
||||
throw std::invalid_argument(
|
||||
"invalid version for Connection: upgrade");
|
||||
|
||||
// rfc7230 3.3.2
|
||||
if(msg.headers.exists("Content-Length") &&
|
||||
msg.headers.exists("Transfer-Encoding"))
|
||||
throw std::invalid_argument(
|
||||
"Content-Length and Transfer-Encoding cannot be combined");
|
||||
}
|
||||
|
||||
} // http
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
#define BEAST_HTTP_IMPL_READ_IPP_HPP
|
||||
|
||||
#include <beast/http/parser_v1.hpp>
|
||||
#include <beast/bind_handler.hpp>
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <beast/stream_concepts.hpp>
|
||||
#include <beast/http/type_check.hpp>
|
||||
#include <beast/core/bind_handler.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
#include <cassert>
|
||||
|
||||
namespace beast {
|
||||
@@ -19,6 +20,185 @@ namespace http {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class Stream,
|
||||
class Streambuf, class Parser, class Handler>
|
||||
class parse_op
|
||||
{
|
||||
using alloc_type =
|
||||
handler_alloc<char, Handler>;
|
||||
|
||||
struct data
|
||||
{
|
||||
Stream& s;
|
||||
Streambuf& sb;
|
||||
Parser& p;
|
||||
Handler h;
|
||||
bool started = false;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, Stream& s_,
|
||||
Streambuf& sb_, Parser& p_)
|
||||
: s(s_)
|
||||
, sb(sb_)
|
||||
, p(p_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<data> d_;
|
||||
|
||||
public:
|
||||
parse_op(parse_op&&) = default;
|
||||
parse_op(parse_op const&) = default;
|
||||
|
||||
template<class DeducedHandler, class... Args>
|
||||
parse_op(DeducedHandler&& h, Stream& s, Args&&... args)
|
||||
: d_(std::allocate_shared<data>(alloc_type{h},
|
||||
std::forward<DeducedHandler>(h), s,
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
(*this)(error_code{}, 0, false);
|
||||
}
|
||||
|
||||
void
|
||||
operator()(error_code ec,
|
||||
std::size_t bytes_transferred, bool again = true);
|
||||
|
||||
friend
|
||||
void* asio_handler_allocate(
|
||||
std::size_t size, parse_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, op->d_->h);
|
||||
}
|
||||
|
||||
friend
|
||||
void asio_handler_deallocate(
|
||||
void* p, std::size_t size, parse_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, op->d_->h);
|
||||
}
|
||||
|
||||
friend
|
||||
bool asio_handler_is_continuation(parse_op* op)
|
||||
{
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, parse_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke(f, op->d_->h);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Stream,
|
||||
class Streambuf, class Parser, class Handler>
|
||||
void
|
||||
parse_op<Stream, Streambuf, Parser, Handler>::
|
||||
operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
||||
{
|
||||
auto& d = *d_;
|
||||
d.cont = d.cont || again;
|
||||
while(d.state != 99)
|
||||
{
|
||||
switch(d.state)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
auto const used =
|
||||
d.p.write(d.sb.data(), ec);
|
||||
if(ec)
|
||||
{
|
||||
// call handler
|
||||
d.state = 99;
|
||||
d.s.get_io_service().post(
|
||||
bind_handler(std::move(*this), ec, 0));
|
||||
return;
|
||||
}
|
||||
if(used > 0)
|
||||
d.started = true;
|
||||
d.sb.consume(used);
|
||||
if(d.p.complete())
|
||||
{
|
||||
// call handler
|
||||
d.state = 99;
|
||||
d.s.get_io_service().post(
|
||||
bind_handler(std::move(*this), ec, 0));
|
||||
return;
|
||||
}
|
||||
d.state = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
// read
|
||||
d.state = 2;
|
||||
d.s.async_read_some(d.sb.prepare(
|
||||
read_size_helper(d.sb, 65536)),
|
||||
std::move(*this));
|
||||
return;
|
||||
|
||||
// got data
|
||||
case 2:
|
||||
{
|
||||
if(ec == boost::asio::error::eof)
|
||||
{
|
||||
if(! d.started)
|
||||
{
|
||||
// call handler
|
||||
d.state = 99;
|
||||
break;
|
||||
}
|
||||
// Caller will see eof on next read.
|
||||
ec = {};
|
||||
d.p.write_eof(ec);
|
||||
assert(ec || d.p.complete());
|
||||
// call handler
|
||||
d.state = 99;
|
||||
break;
|
||||
}
|
||||
if(ec)
|
||||
{
|
||||
// call handler
|
||||
d.state = 99;
|
||||
break;
|
||||
}
|
||||
d.sb.commit(bytes_transferred);
|
||||
auto const used = d.p.write(d.sb.data(), ec);
|
||||
if(ec)
|
||||
{
|
||||
// call handler
|
||||
d.state = 99;
|
||||
break;
|
||||
}
|
||||
if(used > 0)
|
||||
d.started = true;
|
||||
d.sb.consume(used);
|
||||
if(d.p.complete())
|
||||
{
|
||||
// call handler
|
||||
d.state = 99;
|
||||
break;
|
||||
}
|
||||
d.state = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
d.h(ec);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class Stream, class Streambuf,
|
||||
bool isRequest, class Body, class Headers,
|
||||
class Handler>
|
||||
@@ -64,17 +244,16 @@ public:
|
||||
read_op(read_op const&) = default;
|
||||
|
||||
template<class DeducedHandler, class... Args>
|
||||
read_op(DeducedHandler&& h, Stream&s, Args&&... args)
|
||||
read_op(DeducedHandler&& h, Stream& s, Args&&... args)
|
||||
: d_(std::allocate_shared<data>(alloc_type{h},
|
||||
std::forward<DeducedHandler>(h), s,
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
(*this)(error_code{}, 0, false);
|
||||
(*this)(error_code{}, false);
|
||||
}
|
||||
|
||||
void
|
||||
operator()(error_code ec,
|
||||
std::size_t bytes_transferred, bool again = true);
|
||||
operator()(error_code ec, bool again = true);
|
||||
|
||||
friend
|
||||
void* asio_handler_allocate(
|
||||
@@ -112,98 +291,25 @@ template<class Stream, class Streambuf,
|
||||
class Handler>
|
||||
void
|
||||
read_op<Stream, Streambuf, isRequest, Body, Headers, Handler>::
|
||||
operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
||||
operator()(error_code ec, bool again)
|
||||
{
|
||||
auto& d = *d_;
|
||||
d.cont = d.cont || again;
|
||||
while(d.state != 99)
|
||||
while(! ec && d.state != 99)
|
||||
{
|
||||
switch(d.state)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
auto const used =
|
||||
d.p.write(d.sb.data(), ec);
|
||||
if(ec)
|
||||
{
|
||||
// call handler
|
||||
d.state = 99;
|
||||
d.s.get_io_service().post(
|
||||
bind_handler(std::move(*this), ec, 0));
|
||||
return;
|
||||
}
|
||||
if(used > 0)
|
||||
d.started = true;
|
||||
d.sb.consume(used);
|
||||
if(d.p.complete())
|
||||
{
|
||||
// call handler
|
||||
d.state = 99;
|
||||
d.m = d.p.release();
|
||||
d.s.get_io_service().post(
|
||||
bind_handler(std::move(*this), ec, 0));
|
||||
return;
|
||||
}
|
||||
d.state = 1;
|
||||
break;
|
||||
}
|
||||
async_parse(d.s, d.sb, d.p, std::move(*this));
|
||||
return;
|
||||
|
||||
case 1:
|
||||
// read
|
||||
d.state = 2;
|
||||
d.s.async_read_some(d.sb.prepare(
|
||||
read_size_helper(d.sb, 65536)),
|
||||
std::move(*this));
|
||||
return;
|
||||
|
||||
// got data
|
||||
case 2:
|
||||
{
|
||||
if(ec == boost::asio::error::eof)
|
||||
{
|
||||
if(! d.started)
|
||||
{
|
||||
// call handler
|
||||
d.state = 99;
|
||||
break;
|
||||
}
|
||||
// Caller will see eof on next read.
|
||||
ec = {};
|
||||
d.p.write_eof(ec);
|
||||
if(! ec)
|
||||
{
|
||||
assert(d.p.complete());
|
||||
d.m = d.p.release();
|
||||
}
|
||||
// call handler
|
||||
d.state = 99;
|
||||
break;
|
||||
}
|
||||
if(ec)
|
||||
{
|
||||
// call handler
|
||||
d.state = 99;
|
||||
break;
|
||||
}
|
||||
d.sb.commit(bytes_transferred);
|
||||
d.sb.consume(d.p.write(d.sb.data(), ec));
|
||||
if(ec)
|
||||
{
|
||||
// call handler
|
||||
d.state = 99;
|
||||
break;
|
||||
}
|
||||
if(d.p.complete())
|
||||
{
|
||||
// call handler
|
||||
d.state = 99;
|
||||
d.m = d.p.release();
|
||||
break;
|
||||
}
|
||||
d.state = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
d.h(ec);
|
||||
}
|
||||
@@ -212,6 +318,97 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class SyncReadStream, class Streambuf, class Parser>
|
||||
void
|
||||
parse(SyncReadStream& stream,
|
||||
Streambuf& streambuf, Parser& parser)
|
||||
{
|
||||
error_code ec;
|
||||
parse(stream, streambuf, parser, ec);
|
||||
if(ec)
|
||||
throw boost::system::system_error{ec};
|
||||
}
|
||||
|
||||
template<class SyncReadStream, class Streambuf, class Parser>
|
||||
void
|
||||
parse(SyncReadStream& stream, Streambuf& streambuf,
|
||||
Parser& parser, error_code& ec)
|
||||
{
|
||||
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
||||
"SyncReadStream requirements not met");
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
static_assert(is_Parser<Parser>::value,
|
||||
"Parser requirements not met");
|
||||
bool started = false;
|
||||
for(;;)
|
||||
{
|
||||
auto used =
|
||||
parser.write(streambuf.data(), ec);
|
||||
if(ec)
|
||||
return;
|
||||
streambuf.consume(used);
|
||||
if(used > 0)
|
||||
started = true;
|
||||
if(parser.complete())
|
||||
break;
|
||||
streambuf.commit(stream.read_some(
|
||||
streambuf.prepare(read_size_helper(
|
||||
streambuf, 65536)), ec));
|
||||
if(ec && ec != boost::asio::error::eof)
|
||||
return;
|
||||
if(ec == boost::asio::error::eof)
|
||||
{
|
||||
if(! started)
|
||||
return;
|
||||
// Caller will see eof on next read.
|
||||
ec = {};
|
||||
parser.write_eof(ec);
|
||||
if(ec)
|
||||
return;
|
||||
assert(parser.complete());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class AsyncReadStream,
|
||||
class Streambuf, class Parser, class ReadHandler>
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
async_parse(AsyncReadStream& stream,
|
||||
Streambuf& streambuf, Parser& parser, ReadHandler&& handler)
|
||||
{
|
||||
static_assert(is_AsyncReadStream<AsyncReadStream>::value,
|
||||
"AsyncReadStream requirements not met");
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
static_assert(is_Parser<Parser>::value,
|
||||
"Parser requirements not met");
|
||||
beast::async_completion<ReadHandler,
|
||||
void(error_code)> completion(handler);
|
||||
detail::parse_op<AsyncReadStream, Streambuf,
|
||||
Parser, decltype(completion.handler)>{
|
||||
completion.handler, stream, streambuf, parser};
|
||||
return completion.result.get();
|
||||
}
|
||||
|
||||
template<class SyncReadStream, class Streambuf,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
message_v1<isRequest, Body, Headers>& msg)
|
||||
{
|
||||
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
||||
"SyncReadStream requirements not met");
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
error_code ec;
|
||||
read(stream, streambuf, msg, ec);
|
||||
if(ec)
|
||||
throw system_error{ec};
|
||||
}
|
||||
|
||||
template<class SyncReadStream, class Streambuf,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
@@ -224,40 +421,11 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
parser_v1<isRequest, Body, Headers> p;
|
||||
bool started = false;
|
||||
for(;;)
|
||||
{
|
||||
auto used =
|
||||
p.write(streambuf.data(), ec);
|
||||
if(ec)
|
||||
return;
|
||||
streambuf.consume(used);
|
||||
if(used > 0)
|
||||
started = true;
|
||||
if(p.complete())
|
||||
{
|
||||
m = p.release();
|
||||
break;
|
||||
}
|
||||
streambuf.commit(stream.read_some(
|
||||
streambuf.prepare(read_size_helper(
|
||||
streambuf, 65536)), ec));
|
||||
if(ec && ec != boost::asio::error::eof)
|
||||
return;
|
||||
if(ec == boost::asio::error::eof)
|
||||
{
|
||||
if(! started)
|
||||
return;
|
||||
// Caller will see eof on next read.
|
||||
ec = {};
|
||||
p.write_eof(ec);
|
||||
parse(stream, streambuf, p, ec);
|
||||
if(ec)
|
||||
return;
|
||||
assert(p.complete());
|
||||
m = p.release();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class AsyncReadStream, class Streambuf,
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
#include <beast/http/resume_context.hpp>
|
||||
#include <beast/http/detail/chunk_encode.hpp>
|
||||
#include <beast/http/detail/has_content_length.hpp>
|
||||
#include <beast/buffer_cat.hpp>
|
||||
#include <beast/bind_handler.hpp>
|
||||
#include <beast/buffer_concepts.hpp>
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <beast/stream_concepts.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <beast/write_streambuf.hpp>
|
||||
#include <beast/core/buffer_cat.hpp>
|
||||
#include <beast/core/bind_handler.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
#include <beast/core/streambuf.hpp>
|
||||
#include <beast/core/write_streambuf.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
#include <boost/logic/tribool.hpp>
|
||||
#include <condition_variable>
|
||||
@@ -39,22 +39,11 @@ write_firstline(Streambuf& streambuf,
|
||||
write(streambuf, msg.method);
|
||||
write(streambuf, " ");
|
||||
write(streambuf, msg.url);
|
||||
switch(msg.version)
|
||||
{
|
||||
case 10:
|
||||
write(streambuf, " HTTP/1.0\r\n");
|
||||
break;
|
||||
case 11:
|
||||
write(streambuf, " HTTP/1.1\r\n");
|
||||
break;
|
||||
default:
|
||||
write(streambuf, " HTTP/");
|
||||
write(streambuf, msg.version / 10);
|
||||
write(streambuf, ".");
|
||||
write(streambuf, msg.version % 10);
|
||||
write(streambuf, "\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<class Streambuf, class Body, class Headers>
|
||||
@@ -62,22 +51,11 @@ void
|
||||
write_firstline(Streambuf& streambuf,
|
||||
message_v1<false, Body, Headers> const& msg)
|
||||
{
|
||||
switch(msg.version)
|
||||
{
|
||||
case 10:
|
||||
write(streambuf, "HTTP/1.0 ");
|
||||
break;
|
||||
case 11:
|
||||
write(streambuf, "HTTP/1.1 ");
|
||||
break;
|
||||
default:
|
||||
write(streambuf, " HTTP/");
|
||||
write(streambuf, "HTTP/");
|
||||
write(streambuf, msg.version / 10);
|
||||
write(streambuf, ".");
|
||||
write(streambuf, msg.version % 10);
|
||||
write(streambuf, " ");
|
||||
break;
|
||||
}
|
||||
write(streambuf, msg.status);
|
||||
write(streambuf, " ");
|
||||
write(streambuf, msg.reason);
|
||||
@@ -170,13 +148,13 @@ class write_op
|
||||
}
|
||||
};
|
||||
|
||||
class writef0
|
||||
class writef0_lambda
|
||||
{
|
||||
write_op& self_;
|
||||
|
||||
public:
|
||||
explicit
|
||||
writef0(write_op& self)
|
||||
writef0_lambda(write_op& self)
|
||||
: self_(self)
|
||||
{
|
||||
}
|
||||
@@ -198,13 +176,13 @@ class write_op
|
||||
}
|
||||
};
|
||||
|
||||
class writef
|
||||
class writef_lambda
|
||||
{
|
||||
write_op& self_;
|
||||
|
||||
public:
|
||||
explicit
|
||||
writef(write_op& self)
|
||||
writef_lambda(write_op& self)
|
||||
: self_(self)
|
||||
{
|
||||
}
|
||||
@@ -322,7 +300,7 @@ operator()(error_code ec, std::size_t, bool again)
|
||||
case 1:
|
||||
{
|
||||
auto const result = d.wp.w(
|
||||
std::move(d.copy), ec, writef0{*this});
|
||||
std::move(d.copy), ec, writef0_lambda{*this});
|
||||
if(ec)
|
||||
{
|
||||
// call handler
|
||||
@@ -353,7 +331,7 @@ operator()(error_code ec, std::size_t, bool again)
|
||||
case 3:
|
||||
{
|
||||
auto const result = d.wp.w(
|
||||
std::move(d.copy), ec, writef{*this});
|
||||
std::move(d.copy), ec, writef_lambda{*this});
|
||||
if(ec)
|
||||
{
|
||||
// call handler
|
||||
@@ -400,7 +378,7 @@ operator()(error_code ec, std::size_t, bool again)
|
||||
}
|
||||
|
||||
template<class SyncWriteStream, class Streambuf>
|
||||
class writef0_write
|
||||
class writef0_lambda
|
||||
{
|
||||
Streambuf const& sb_;
|
||||
SyncWriteStream& stream_;
|
||||
@@ -408,7 +386,7 @@ class writef0_write
|
||||
error_code& ec_;
|
||||
|
||||
public:
|
||||
writef0_write(SyncWriteStream& stream,
|
||||
writef0_lambda(SyncWriteStream& stream,
|
||||
Streambuf const& sb, bool chunked, error_code& ec)
|
||||
: sb_(sb)
|
||||
, stream_(stream)
|
||||
@@ -431,14 +409,14 @@ public:
|
||||
};
|
||||
|
||||
template<class SyncWriteStream>
|
||||
class writef_write
|
||||
class writef_lambda
|
||||
{
|
||||
SyncWriteStream& stream_;
|
||||
bool chunked_;
|
||||
error_code& ec_;
|
||||
|
||||
public:
|
||||
writef_write(SyncWriteStream& stream,
|
||||
writef_lambda(SyncWriteStream& stream,
|
||||
bool chunked, error_code& ec)
|
||||
: stream_(stream)
|
||||
, chunked_(chunked)
|
||||
@@ -473,7 +451,7 @@ write(SyncWriteStream& stream,
|
||||
error_code ec;
|
||||
write(stream, msg, ec);
|
||||
if(ec)
|
||||
throw boost::system::system_error{ec};
|
||||
throw system_error{ec};
|
||||
}
|
||||
|
||||
template<class SyncWriteStream,
|
||||
@@ -500,47 +478,44 @@ write(SyncWriteStream& stream,
|
||||
cv.notify_one();
|
||||
}};
|
||||
auto copy = resume;
|
||||
for(;;)
|
||||
{
|
||||
{
|
||||
auto result = wp.w(std::move(copy), ec,
|
||||
detail::writef0_write<SyncWriteStream, decltype(wp.sb)>{
|
||||
stream, wp.sb, wp.chunked, ec});
|
||||
boost::tribool result = wp.w(std::move(copy),
|
||||
ec, detail::writef0_lambda<SyncWriteStream,
|
||||
decltype(wp.sb)>{stream, wp.sb, wp.chunked, ec});
|
||||
if(ec)
|
||||
return;
|
||||
if(result)
|
||||
break;
|
||||
if(boost::indeterminate(result))
|
||||
{
|
||||
boost::asio::write(stream, wp.sb.data(), ec);
|
||||
if(ec)
|
||||
return;
|
||||
wp.sb.consume(wp.sb.size());
|
||||
copy = resume;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m);
|
||||
cv.wait(lock, [&]{ return ready; });
|
||||
ready = false;
|
||||
}
|
||||
boost::asio::write(stream, wp.sb.data(), ec);
|
||||
if(ec)
|
||||
return;
|
||||
result = false;
|
||||
}
|
||||
wp.sb.consume(wp.sb.size());
|
||||
if(! result)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
auto result = wp.w(std::move(copy), ec,
|
||||
detail::writef_write<SyncWriteStream>{
|
||||
result = wp.w(std::move(copy), ec,
|
||||
detail::writef_lambda<SyncWriteStream>{
|
||||
stream, wp.chunked, ec});
|
||||
if(ec)
|
||||
return;
|
||||
if(result)
|
||||
break;
|
||||
if(boost::indeterminate(result))
|
||||
{
|
||||
if(! result)
|
||||
continue;
|
||||
copy = resume;
|
||||
std::unique_lock<std::mutex> lock(m);
|
||||
cv.wait(lock, [&]{ return ready; });
|
||||
ready = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(wp.chunked)
|
||||
{
|
||||
// VFALCO Unfortunately the current interface to the
|
||||
@@ -597,7 +572,7 @@ public:
|
||||
error_code ec;
|
||||
auto const n = write_some(buffers, ec);
|
||||
if(ec)
|
||||
throw boost::system::system_error{ec};
|
||||
throw system_error{ec};
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -636,7 +611,7 @@ operator<<(std::ostream& os,
|
||||
error_code ec;
|
||||
write(oss, msg, ec);
|
||||
if(ec && ec != boost::asio::error::eof)
|
||||
throw boost::system::system_error{ec};
|
||||
throw system_error{ec};
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,11 @@
|
||||
#define BEAST_HTTP_MESSAGE_HPP
|
||||
|
||||
#include <beast/http/basic_headers.hpp>
|
||||
#include <beast/core/detail/integer_sequence.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
@@ -69,6 +72,77 @@ struct message
|
||||
|
||||
/// A container representing the body.
|
||||
typename Body::value_type body;
|
||||
|
||||
/// Default constructor
|
||||
message() = default;
|
||||
|
||||
/** Construct a message.
|
||||
|
||||
@param u An argument forwarded to the body constructor.
|
||||
*/
|
||||
template<class U>
|
||||
explicit
|
||||
message(U&& u)
|
||||
: body(std::forward<U>(u))
|
||||
{
|
||||
}
|
||||
|
||||
/** Construct a message.
|
||||
|
||||
@param u An argument forwarded to the body constructor.
|
||||
@param v An argument forwarded to the headers constructor.
|
||||
*/
|
||||
template<class U, class V>
|
||||
message(U&& u, V&& v)
|
||||
: headers(std::forward<V>(v))
|
||||
, body(std::forward<U>(u))
|
||||
{
|
||||
}
|
||||
|
||||
/** Construct a message.
|
||||
|
||||
@param un A tuple forwarded as a parameter pack to the body constructor.
|
||||
*/
|
||||
template<class... Un>
|
||||
message(std::piecewise_construct_t, std::tuple<Un...> un)
|
||||
: message(std::piecewise_construct, un,
|
||||
beast::detail::make_index_sequence<sizeof...(Un)>{})
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** Construct a message.
|
||||
|
||||
@param un A tuple forwarded as a parameter pack to the body constructor.
|
||||
@param vn A tuple forwarded as a parameter pack to the headers constructor.
|
||||
*/
|
||||
template<class... Un, class... Vn>
|
||||
message(std::piecewise_construct_t,
|
||||
std::tuple<Un...>&& un, std::tuple<Vn...>&& vn)
|
||||
: message(std::piecewise_construct, un, vn,
|
||||
beast::detail::make_index_sequence<sizeof...(Un)>{},
|
||||
beast::detail::make_index_sequence<sizeof...(Vn)>{})
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
template<class... Un, size_t... IUn>
|
||||
message(std::piecewise_construct_t,
|
||||
std::tuple<Un...>& tu, beast::detail::index_sequence<IUn...>)
|
||||
: body(std::forward<Un>(std::get<IUn>(tu))...)
|
||||
{
|
||||
}
|
||||
|
||||
template<class... Un, class... Vn,
|
||||
std::size_t... IUn, std::size_t... IVn>
|
||||
message(std::piecewise_construct_t,
|
||||
std::tuple<Un...>& tu, std::tuple<Vn...>& tv,
|
||||
beast::detail::index_sequence<IUn...>,
|
||||
beast::detail::index_sequence<IVn...>)
|
||||
: headers(std::forward<Vn>(std::get<IVn>(tv))...)
|
||||
, body(std::forward<Un>(std::get<IUn>(tu))...)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#if ! GENERATING_DOCS
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user