summaryrefslogtreecommitdiff
path: root/boost/beast/http/impl
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:22:41 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:22:41 +0900
commit3c1df2168531ad5580076ae08d529054689aeedd (patch)
tree941aff6f86393eecacddfec252a8508c7e8351c9 /boost/beast/http/impl
parentd6a306e745acfee00e81ccaf3324a2a03516db41 (diff)
downloadboost-3c1df2168531ad5580076ae08d529054689aeedd.tar.gz
boost-3c1df2168531ad5580076ae08d529054689aeedd.tar.bz2
boost-3c1df2168531ad5580076ae08d529054689aeedd.zip
Imported Upstream version 1.70.0upstream/1.70.0
Diffstat (limited to 'boost/beast/http/impl')
-rw-r--r--boost/beast/http/impl/basic_parser.hpp78
-rw-r--r--boost/beast/http/impl/basic_parser.ipp234
-rw-r--r--boost/beast/http/impl/chunk_encode.hpp (renamed from boost/beast/http/impl/chunk_encode.ipp)27
-rw-r--r--boost/beast/http/impl/error.hpp37
-rw-r--r--boost/beast/http/impl/error.ipp14
-rw-r--r--boost/beast/http/impl/field.ipp174
-rw-r--r--boost/beast/http/impl/fields.hpp (renamed from boost/beast/http/impl/fields.ipp)46
-rw-r--r--boost/beast/http/impl/file_body_win32.hpp (renamed from boost/beast/http/impl/file_body_win32.ipp)324
-rw-r--r--boost/beast/http/impl/message.hpp (renamed from boost/beast/http/impl/message.ipp)20
-rw-r--r--boost/beast/http/impl/parser.hpp (renamed from boost/beast/http/impl/parser.ipp)8
-rw-r--r--boost/beast/http/impl/read.hpp559
-rw-r--r--boost/beast/http/impl/read.ipp857
-rw-r--r--boost/beast/http/impl/rfc7230.hpp423
-rw-r--r--boost/beast/http/impl/rfc7230.ipp408
-rw-r--r--boost/beast/http/impl/serializer.hpp (renamed from boost/beast/http/impl/serializer.ipp)67
-rw-r--r--boost/beast/http/impl/status.ipp80
-rw-r--r--boost/beast/http/impl/verb.ipp27
-rw-r--r--boost/beast/http/impl/write.hpp (renamed from boost/beast/http/impl/write.ipp)721
18 files changed, 1869 insertions, 2235 deletions
diff --git a/boost/beast/http/impl/basic_parser.hpp b/boost/beast/http/impl/basic_parser.hpp
new file mode 100644
index 0000000000..e25be7ce08
--- /dev/null
+++ b/boost/beast/http/impl/basic_parser.hpp
@@ -0,0 +1,78 @@
+//
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/beast
+//
+
+#ifndef BOOST_BEAST_HTTP_IMPL_BASIC_PARSER_HPP
+#define BOOST_BEAST_HTTP_IMPL_BASIC_PARSER_HPP
+
+#include <boost/beast/core/buffer_traits.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/make_unique.hpp>
+
+namespace boost {
+namespace beast {
+namespace http {
+
+template<bool isRequest>
+template<class ConstBufferSequence>
+std::size_t
+basic_parser<isRequest>::
+put(ConstBufferSequence const& buffers,
+ error_code& ec)
+{
+ static_assert(net::is_const_buffer_sequence<
+ ConstBufferSequence>::value,
+ "ConstBufferSequence type requirements not met");
+ auto const p = net::buffer_sequence_begin(buffers);
+ auto const last = net::buffer_sequence_end(buffers);
+ if(p == last)
+ {
+ ec = {};
+ return 0;
+ }
+ if(std::next(p) == last)
+ {
+ // single buffer
+ return put(net::const_buffer(*p), ec);
+ }
+ auto const size = buffer_bytes(buffers);
+ if(size <= max_stack_buffer)
+ return put_from_stack(size, buffers, ec);
+ if(size > buf_len_)
+ {
+ // reallocate
+ buf_ = boost::make_unique_noinit<char[]>(size);
+ buf_len_ = size;
+ }
+ // flatten
+ net::buffer_copy(net::buffer(
+ buf_.get(), buf_len_), buffers);
+ return put(net::const_buffer{
+ buf_.get(), buf_len_}, ec);
+}
+
+template<bool isRequest>
+template<class ConstBufferSequence>
+std::size_t
+basic_parser<isRequest>::
+put_from_stack(std::size_t size,
+ ConstBufferSequence const& buffers,
+ error_code& ec)
+{
+ char buf[max_stack_buffer];
+ net::buffer_copy(net::mutable_buffer(
+ buf, sizeof(buf)), buffers);
+ return put(net::const_buffer{
+ buf, size}, ec);
+}
+
+} // http
+} // beast
+} // boost
+
+#endif
diff --git a/boost/beast/http/impl/basic_parser.ipp b/boost/beast/http/impl/basic_parser.ipp
index 7a46092861..99947ae1f2 100644
--- a/boost/beast/http/impl/basic_parser.ipp
+++ b/boost/beast/http/impl/basic_parser.ipp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,14 +10,14 @@
#ifndef BOOST_BEAST_HTTP_IMPL_BASIC_PARSER_IPP
#define BOOST_BEAST_HTTP_IMPL_BASIC_PARSER_IPP
+#include <boost/beast/http/basic_parser.hpp>
+#include <boost/beast/http/error.hpp>
+#include <boost/beast/http/rfc7230.hpp>
+#include <boost/beast/core/buffer_traits.hpp>
#include <boost/beast/core/static_string.hpp>
-#include <boost/beast/core/type_traits.hpp>
#include <boost/beast/core/detail/clamp.hpp>
#include <boost/beast/core/detail/config.hpp>
-#include <boost/beast/http/error.hpp>
-#include <boost/beast/http/rfc7230.hpp>
#include <boost/asio/buffer.hpp>
-#include <boost/make_unique.hpp>
#include <algorithm>
#include <utility>
@@ -25,26 +25,9 @@ namespace boost {
namespace beast {
namespace http {
-template<bool isRequest, class Derived>
-template<class OtherDerived>
-basic_parser<isRequest, Derived>::
-basic_parser(basic_parser<
- isRequest, OtherDerived>&& other)
- : body_limit_(other.body_limit_)
- , len_(other.len_)
- , buf_(std::move(other.buf_))
- , buf_len_(other.buf_len_)
- , skip_(other.skip_)
- , header_limit_(other.header_limit_)
- , status_(other.status_)
- , state_(other.state_)
- , f_(other.f_)
-{
-}
-
-template<bool isRequest, class Derived>
+template<bool isRequest>
bool
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
keep_alive() const
{
BOOST_ASSERT(is_header_done());
@@ -61,20 +44,31 @@ keep_alive() const
return (f_ & flagNeedEOF) == 0;
}
-template<bool isRequest, class Derived>
+template<bool isRequest>
boost::optional<std::uint64_t>
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
content_length() const
{
BOOST_ASSERT(is_header_done());
if(! (f_ & flagContentLength))
return boost::none;
+ return len0_;
+}
+
+template<bool isRequest>
+boost::optional<std::uint64_t>
+basic_parser<isRequest>::
+content_length_remaining() const
+{
+ BOOST_ASSERT(is_header_done());
+ if(! (f_ & flagContentLength))
+ return boost::none;
return len_;
}
-template<bool isRequest, class Derived>
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
skip(bool v)
{
BOOST_ASSERT(! got_some());
@@ -84,59 +78,18 @@ skip(bool v)
f_ &= ~flagSkipBody;
}
-template<bool isRequest, class Derived>
-template<class ConstBufferSequence>
+template<bool isRequest>
std::size_t
-basic_parser<isRequest, Derived>::
-put(ConstBufferSequence const& buffers,
- error_code& ec)
-{
- static_assert(boost::asio::is_const_buffer_sequence<
- ConstBufferSequence>::value,
- "ConstBufferSequence requirements not met");
- using boost::asio::buffer_copy;
- using boost::asio::buffer_size;
- auto const p = boost::asio::buffer_sequence_begin(buffers);
- auto const last = boost::asio::buffer_sequence_end(buffers);
- if(p == last)
- {
- ec.assign(0, ec.category());
- return 0;
- }
- if(std::next(p) == last)
- {
- // single buffer
- return put(boost::asio::const_buffer(*p), ec);
- }
- auto const size = buffer_size(buffers);
- if(size <= max_stack_buffer)
- return put_from_stack(size, buffers, ec);
- if(size > buf_len_)
- {
- // reallocate
- buf_ = boost::make_unique_noinit<char[]>(size);
- buf_len_ = size;
- }
- // flatten
- buffer_copy(boost::asio::buffer(
- buf_.get(), buf_len_), buffers);
- return put(boost::asio::const_buffer{
- buf_.get(), buf_len_}, ec);
-}
-
-template<bool isRequest, class Derived>
-std::size_t
-basic_parser<isRequest, Derived>::
-put(boost::asio::const_buffer const& buffer,
+basic_parser<isRequest>::
+put(net::const_buffer buffer,
error_code& ec)
{
BOOST_ASSERT(state_ != state::complete);
- using boost::asio::buffer_size;
auto p = static_cast<char const*>(buffer.data());
auto n = buffer.size();
auto const p0 = p;
auto const p1 = p0 + n;
- ec.assign(0, ec.category());
+ ec = {};
loop:
switch(state_)
{
@@ -207,7 +160,7 @@ loop:
case state::body0:
BOOST_ASSERT(! skip_);
- impl().on_body_init_impl(content_length(), ec);
+ this->on_body_init_impl(content_length(), ec);
if(ec)
goto done;
state_ = state::body;
@@ -222,7 +175,7 @@ loop:
case state::body_to_eof0:
BOOST_ASSERT(! skip_);
- impl().on_body_init_impl(content_length(), ec);
+ this->on_body_init_impl(content_length(), ec);
if(ec)
goto done;
state_ = state::body_to_eof;
@@ -236,7 +189,7 @@ loop:
break;
case state::chunk_header0:
- impl().on_body_init_impl(content_length(), ec);
+ this->on_body_init_impl(content_length(), ec);
if(ec)
goto done;
state_ = state::chunk_header;
@@ -255,7 +208,7 @@ loop:
break;
case state::complete:
- ec.assign(0, ec.category());
+ ec = {};
goto done;
}
if(p < p1 && ! is_done() && eager())
@@ -267,9 +220,9 @@ done:
return static_cast<std::size_t>(p - p0);
}
-template<bool isRequest, class Derived>
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
put_eof(error_code& ec)
{
BOOST_ASSERT(got_some());
@@ -286,35 +239,19 @@ put_eof(error_code& ec)
ec = error::partial_message;
return;
}
- ec.assign(0, ec.category());
+ ec = {};
return;
}
- impl().on_finish_impl(ec);
+ ec = {};
+ this->on_finish_impl(ec);
if(ec)
return;
state_ = state::complete;
}
-template<bool isRequest, class Derived>
-template<class ConstBufferSequence>
-std::size_t
-basic_parser<isRequest, Derived>::
-put_from_stack(std::size_t size,
- ConstBufferSequence const& buffers,
- error_code& ec)
-{
- char buf[max_stack_buffer];
- using boost::asio::buffer;
- using boost::asio::buffer_copy;
- buffer_copy(buffer(buf, sizeof(buf)), buffers);
- return put(boost::asio::const_buffer{
- buf, size}, ec);
-}
-
-template<bool isRequest, class Derived>
-inline
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
maybe_need_more(
char const* p, std::size_t n,
error_code& ec)
@@ -344,10 +281,9 @@ maybe_need_more(
skip_ = 0;
}
-template<bool isRequest, class Derived>
-inline
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
parse_start_line(
char const*& in, char const* last,
error_code& ec, std::true_type)
@@ -393,7 +329,7 @@ parse_start_line(
if(version >= 11)
f_ |= flagHTTP11;
- impl().on_request_impl(string_to_verb(method),
+ this->on_request_impl(string_to_verb(method),
method, target, version, ec);
if(ec)
return;
@@ -402,10 +338,9 @@ parse_start_line(
state_ = state::fields;
}
-template<bool isRequest, class Derived>
-inline
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
parse_start_line(
char const*& in, char const* last,
error_code& ec, std::false_type)
@@ -452,7 +387,7 @@ parse_start_line(
if(version >= 11)
f_ |= flagHTTP11;
- impl().on_response_impl(
+ this->on_response_impl(
status_, reason, version, ec);
if(ec)
return;
@@ -461,9 +396,9 @@ parse_start_line(
state_ = state::fields;
}
-template<bool isRequest, class Derived>
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
parse_fields(char const*& in,
char const* last, error_code& ec)
{
@@ -493,17 +428,16 @@ parse_fields(char const*& in,
do_field(f, value, ec);
if(ec)
return;
- impl().on_field_impl(f, name, value, ec);
+ this->on_field_impl(f, name, value, ec);
if(ec)
return;
in = p;
}
}
-template<bool isRequest, class Derived>
-inline
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
finish_header(error_code& ec, std::true_type)
{
// RFC 7230 section 3.3
@@ -538,24 +472,25 @@ finish_header(error_code& ec, std::true_type)
else
{
len_ = 0;
+ len0_ = 0;
state_ = state::complete;
}
- impl().on_header_impl(ec);
+ ec = {};
+ this->on_header_impl(ec);
if(ec)
return;
if(state_ == state::complete)
{
- impl().on_finish_impl(ec);
+ this->on_finish_impl(ec);
if(ec)
return;
}
}
-template<bool isRequest, class Derived>
-inline
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
finish_header(error_code& ec, std::false_type)
{
// RFC 7230 section 3.3
@@ -600,25 +535,26 @@ finish_header(error_code& ec, std::false_type)
state_ = state::body_to_eof0;
}
- impl().on_header_impl(ec);
+ ec = {};
+ this->on_header_impl(ec);
if(ec)
return;
if(state_ == state::complete)
{
- impl().on_finish_impl(ec);
+ this->on_finish_impl(ec);
if(ec)
return;
}
}
-template<bool isRequest, class Derived>
-inline
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
parse_body(char const*& p,
std::size_t n, error_code& ec)
{
- n = impl().on_body_impl(string_view{p,
+ ec = {};
+ n = this->on_body_impl(string_view{p,
beast::detail::clamp(len_, n)}, ec);
p += n;
len_ -= n;
@@ -626,16 +562,15 @@ parse_body(char const*& p,
return;
if(len_ > 0)
return;
- impl().on_finish_impl(ec);
+ this->on_finish_impl(ec);
if(ec)
return;
state_ = state::complete;
}
-template<bool isRequest, class Derived>
-inline
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
parse_body_to_eof(char const*& p,
std::size_t n, error_code& ec)
{
@@ -645,15 +580,16 @@ parse_body_to_eof(char const*& p,
return;
}
body_limit_ = body_limit_ - n;
- n = impl().on_body_impl(string_view{p, n}, ec);
+ ec = {};
+ n = this->on_body_impl(string_view{p, n}, ec);
p += n;
if(ec)
return;
}
-template<bool isRequest, class Derived>
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
parse_chunk_header(char const*& p0,
std::size_t n, error_code& ec)
{
@@ -729,7 +665,7 @@ parse_chunk_header(char const*& p0,
return;
}
auto const ext = make_string(start, p);
- impl().on_chunk_header_impl(size, ext, ec);
+ this->on_chunk_header_impl(size, ext, ec);
if(ec)
return;
len_ = size;
@@ -772,7 +708,7 @@ parse_chunk_header(char const*& p0,
return;
}
auto const ext = make_string(start, p);
- impl().on_chunk_header_impl(0, ext, ec);
+ this->on_chunk_header_impl(0, ext, ec);
if(ec)
return;
p = eol;
@@ -782,20 +718,20 @@ parse_chunk_header(char const*& p0,
BOOST_ASSERT(p == eom);
p0 = eom;
- impl().on_finish_impl(ec);
+ this->on_finish_impl(ec);
if(ec)
return;
state_ = state::complete;
}
-template<bool isRequest, class Derived>
-inline
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
parse_chunk_body(char const*& p,
std::size_t n, error_code& ec)
{
- n = impl().on_chunk_body_impl(
+ ec = {};
+ n = this->on_chunk_body_impl(
len_, string_view{p,
beast::detail::clamp(len_, n)}, ec);
p += n;
@@ -804,9 +740,9 @@ parse_chunk_body(char const*& p,
state_ = state::chunk_header;
}
-template<bool isRequest, class Derived>
+template<bool isRequest>
void
-basic_parser<isRequest, Derived>::
+basic_parser<isRequest>::
do_field(field f,
string_view value, error_code& ec)
{
@@ -841,7 +777,7 @@ do_field(field f,
continue;
}
}
- ec.assign(0, ec.category());
+ ec = {};
return;
}
@@ -870,8 +806,9 @@ do_field(field f,
return;
}
- ec.assign(0, ec.category());
+ ec = {};
len_ = v;
+ len0_ = v;
f_ |= flagContentLength;
return;
}
@@ -893,7 +830,7 @@ do_field(field f,
return;
}
- ec.assign(0, ec.category());
+ ec = {};
auto const v = token_list{value};
auto const p = std::find_if(v.begin(), v.end(),
[&](typename token_list::value_type const& s)
@@ -912,14 +849,19 @@ do_field(field f,
// Upgrade
if(f == field::upgrade)
{
- ec.assign(0, ec.category());
+ ec = {};
f_ |= flagUpgrade;
return;
}
- ec.assign(0, ec.category());
+ ec = {};
}
+#ifdef BOOST_BEAST_SOURCE
+template class http::basic_parser<true>;
+template class http::basic_parser<false>;
+#endif
+
} // http
} // beast
} // boost
diff --git a/boost/beast/http/impl/chunk_encode.ipp b/boost/beast/http/impl/chunk_encode.hpp
index 51296041f7..0272e3abb3 100644
--- a/boost/beast/http/impl/chunk_encode.ipp
+++ b/boost/beast/http/impl/chunk_encode.hpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,9 +7,10 @@
// Official repository: https://github.com/boostorg/beast
//
-#ifndef BOOST_BEAST_HTTP_IMPL_CHUNK_ENCODE_IPP
-#define BOOST_BEAST_HTTP_IMPL_CHUNK_ENCODE_IPP
+#ifndef BOOST_BEAST_HTTP_IMPL_CHUNK_ENCODE_HPP
+#define BOOST_BEAST_HTTP_IMPL_CHUNK_ENCODE_HPP
+#include <boost/beast/core/buffer_traits.hpp>
#include <boost/beast/core/detail/varint.hpp>
#include <boost/beast/http/error.hpp>
#include <boost/beast/http/detail/rfc7230.hpp>
@@ -24,7 +25,7 @@ chunk_header::
chunk_header(std::size_t size)
: view_(
size,
- boost::asio::const_buffer{nullptr, 0},
+ net::const_buffer{nullptr, 0},
chunk_crlf{})
{
BOOST_ASSERT(size > 0);
@@ -37,7 +38,7 @@ chunk_header(
string_view extensions)
: view_(
size,
- boost::asio::const_buffer{
+ net::const_buffer{
extensions.data(), extensions.size()},
chunk_crlf{})
{
@@ -89,8 +90,8 @@ template<class ConstBufferSequence>
chunk_body<ConstBufferSequence>::
chunk_body(ConstBufferSequence const& buffers)
: view_(
- boost::asio::buffer_size(buffers),
- boost::asio::const_buffer{nullptr, 0},
+ buffer_bytes(buffers),
+ net::const_buffer{nullptr, 0},
chunk_crlf{},
buffers,
chunk_crlf{})
@@ -103,8 +104,8 @@ chunk_body(
ConstBufferSequence const& buffers,
string_view extensions)
: view_(
- boost::asio::buffer_size(buffers),
- boost::asio::const_buffer{
+ buffer_bytes(buffers),
+ net::const_buffer{
extensions.data(), extensions.size()},
chunk_crlf{},
buffers,
@@ -122,7 +123,7 @@ chunk_body(
typename std::decay<ChunkExtensions>::type>>(
std::forward<ChunkExtensions>(extensions)))
, view_(
- boost::asio::buffer_size(buffers),
+ buffer_bytes(buffers),
exts_->str(),
chunk_crlf{},
buffers,
@@ -141,7 +142,7 @@ chunk_body(
typename std::decay<ChunkExtensions>::type>>(allocator,
std::forward<ChunkExtensions>(extensions)))
, view_(
- boost::asio::buffer_size(buffers),
+ buffer_bytes(buffers),
exts_->str(),
chunk_crlf{},
buffers,
@@ -387,7 +388,7 @@ do_parse(FwdIt it, FwdIt last, error_code& ec)
loop:
if(it == last)
{
- ec.assign(0, ec.category());
+ ec = {};
return it;
}
// BWS
@@ -680,7 +681,6 @@ insert(string_view name, string_view value)
}
template<class Allocator>
-inline
auto
basic_chunk_extensions<Allocator>::
begin() const ->
@@ -690,7 +690,6 @@ begin() const ->
}
template<class Allocator>
-inline
auto
basic_chunk_extensions<Allocator>::
end() const ->
diff --git a/boost/beast/http/impl/error.hpp b/boost/beast/http/impl/error.hpp
new file mode 100644
index 0000000000..b4efaa05ca
--- /dev/null
+++ b/boost/beast/http/impl/error.hpp
@@ -0,0 +1,37 @@
+//
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/beast
+//
+
+#ifndef BOOST_BEAST_HTTP_IMPL_ERROR_HPP
+#define BOOST_BEAST_HTTP_IMPL_ERROR_HPP
+
+#include <type_traits>
+
+namespace boost {
+namespace system {
+template<>
+struct is_error_code_enum<::boost::beast::http::error>
+{
+ static bool const value = true;
+};
+} // system
+} // boost
+
+namespace boost {
+namespace beast {
+namespace http {
+
+BOOST_BEAST_DECL
+error_code
+make_error_code(error ev);
+
+} // http
+} // beast
+} // boost
+
+#endif
diff --git a/boost/beast/http/impl/error.ipp b/boost/beast/http/impl/error.ipp
index b6320cf4c9..e0167b308e 100644
--- a/boost/beast/http/impl/error.ipp
+++ b/boost/beast/http/impl/error.ipp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,18 +10,10 @@
#ifndef BOOST_BEAST_HTTP_IMPL_ERROR_IPP
#define BOOST_BEAST_HTTP_IMPL_ERROR_IPP
+#include <boost/beast/http/error.hpp>
#include <type_traits>
namespace boost {
-
-namespace system {
-template<>
-struct is_error_code_enum<beast::http::error>
-{
- static bool const value = true;
-};
-} // system
-
namespace beast {
namespace http {
namespace detail {
@@ -63,6 +55,7 @@ public:
case error::bad_chunk: return "bad chunk";
case error::bad_chunk_extension: return "bad chunk extension";
case error::bad_obs_fold: return "bad obs-fold";
+ case error::stale_parser: return "stale parser";
default:
return "beast.http error";
@@ -96,7 +89,6 @@ public:
} // detail
-inline
error_code
make_error_code(error ev)
{
diff --git a/boost/beast/http/impl/field.ipp b/boost/beast/http/impl/field.ipp
index b61a0ba8a2..46af6f8552 100644
--- a/boost/beast/http/impl/field.ipp
+++ b/boost/beast/http/impl/field.ipp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,11 +10,10 @@
#ifndef BOOST_BEAST_HTTP_IMPL_FIELD_IPP
#define BOOST_BEAST_HTTP_IMPL_FIELD_IPP
-#include <boost/beast/core/string.hpp>
+#include <boost/beast/http/field.hpp>
#include <algorithm>
#include <array>
-#include <unordered_map>
-#include <vector>
+#include <cstring>
#include <boost/assert.hpp>
namespace boost {
@@ -28,58 +27,66 @@ struct field_table
using array_type =
std::array<string_view, 353>;
- struct hash
+ // Strings are converted to lowercase
+ static
+ std::uint32_t
+ digest(string_view s)
{
- std::size_t
- operator()(string_view s) const
+ std::uint32_t r = 0;
+ std::size_t n = s.size();
+ unsigned char const* p =reinterpret_cast<
+ unsigned char const*>(s.data());
+ while(n >= 4)
{
- auto const n = s.size();
- return
- beast::detail::ascii_tolower(s[0]) *
- beast::detail::ascii_tolower(s[n/2]) ^
- beast::detail::ascii_tolower(s[n-1]); // hist[] = 331, 10, max_load_factor = 0.15f
+ std::uint32_t v;
+ std::memcpy(&v, p, 4);
+ r = r * 5 + ( v | 0x20202020 );
+ p += 4;
+ n -= 4;
}
- };
+ while( n > 0 )
+ {
+ r = r * 5 + ( *p | 0x20 );
+ ++p;
+ --n;
+ }
+ return r;
+ }
- struct iequal
+ // This comparison is case-insensitive, and the
+ // strings must contain only valid http field characters.
+ static
+ bool
+ equals(string_view lhs, string_view rhs)
{
- // assumes inputs have equal length
- bool
- operator()(
- string_view lhs,
- string_view rhs) const
+ using Int = std::uint32_t; // or std::size_t
+ auto n = lhs.size();
+ if(n != rhs.size())
+ return false;
+ auto p1 = lhs.data();
+ auto p2 = rhs.data();
+ auto constexpr S = sizeof(Int);
+ auto constexpr Mask = static_cast<Int>(
+ 0xDFDFDFDFDFDFDFDF & ~Int{0});
+ for(; n >= S; p1 += S, p2 += S, n -= S)
{
- auto p1 = lhs.data();
- auto p2 = rhs.data();
- auto pend = p1 + lhs.size();
- char a, b;
- while(p1 < pend)
- {
- a = *p1++;
- b = *p2++;
- if(a != b)
- goto slow;
- }
- return true;
-
- while(p1 < pend)
- {
- slow:
- if( beast::detail::ascii_tolower(a) !=
- beast::detail::ascii_tolower(b))
- return false;
- a = *p1++;
- b = *p2++;
- }
- return true;
+ Int v1, v2;
+ std::memcpy( &v1, p1, S );
+ std::memcpy( &v2, p2, S );
+ if((v1 ^ v2) & Mask)
+ return false;
}
- };
-
- using map_type = std::unordered_map<
- string_view, field, hash, iequal>;
+ for(; n; ++p1, ++p2, --n)
+ if(( *p1 ^ *p2) & 0xDF)
+ return false;
+ return true;
+ }
array_type by_name_;
- std::vector<map_type> by_size_;
+
+ enum { N = 5155 };
+ unsigned char map_[ N ][ 2 ] = {};
+
/*
From:
@@ -442,58 +449,43 @@ struct field_table
"Xref"
}})
{
- // find the longest field length
- std::size_t high = 0;
- for(auto const& s : by_name_)
- if(high < s.size())
- high = s.size();
- // build by_size map
- // skip field::unknown
- by_size_.resize(high + 1);
- for(auto& map : by_size_)
- map.max_load_factor(.15f);
- for(std::size_t i = 1;
- i < by_name_.size(); ++i)
+ for(std::size_t i = 1, n = 256; i < n; ++i)
{
- auto const& s = by_name_[i];
- by_size_[s.size()].emplace(
- s, static_cast<field>(i));
+ auto sv = by_name_[ i ];
+ auto h = digest(sv);
+ auto j = h % N;
+ BOOST_ASSERT(map_[j][0] == 0);
+ map_[j][0] = static_cast<unsigned char>(i);
}
-#if 0
- // This snippet calculates the performance
- // of the hash function and map settings
+ for(std::size_t i = 256, n = by_name_.size(); i < n; ++i)
{
- std::vector<std::size_t> hist;
- for(auto const& map : by_size_)
- {
- for(std::size_t i = 0; i < map.bucket_count(); ++i)
- {
- auto const n = map.bucket_size(i);
- if(n > 0)
- {
- if(hist.size() < n)
- hist.resize(n);
- ++hist[n-1];
- }
- }
- }
+ auto sv = by_name_[i];
+ auto h = digest(sv);
+ auto j = h % N;
+ BOOST_ASSERT(map_[j][1] == 0);
+ map_[j][1] = static_cast<unsigned char>(i - 255);
}
-#endif
}
field
string_to_field(string_view s) const
{
- if(s.size() >= by_size_.size())
+ auto h = digest(s);
+ auto j = h % N;
+ int i = map_[j][0];
+ string_view s2 = by_name_[i];
+ if(i != 0 && equals(s, s2))
+ return static_cast<field>(i);
+ i = map_[j][1];
+ if(i == 0)
return field::unknown;
- auto const& map = by_size_[s.size()];
- if(map.empty())
- return field::unknown;
- auto it = map.find(s);
- if(it == map.end())
- return field::unknown;
- return it->second;
+ i += 255;
+ s2 = by_name_[i];
+
+ if(equals(s, s2))
+ return static_cast<field>(i);
+ return field::unknown;
}
//
@@ -522,7 +514,7 @@ struct field_table
}
};
-inline
+BOOST_BEAST_DECL
field_table const&
get_field_table()
{
@@ -530,7 +522,7 @@ get_field_table()
return tab;
}
-template<class = void>
+BOOST_BEAST_DECL
string_view
to_string(field f)
{
@@ -541,14 +533,12 @@ to_string(field f)
} // detail
-inline
string_view
to_string(field f)
{
return detail::to_string(f);
}
-inline
field
string_to_field(string_view s)
{
diff --git a/boost/beast/http/impl/fields.ipp b/boost/beast/http/impl/fields.hpp
index f34a8e7471..9616af829c 100644
--- a/boost/beast/http/impl/fields.ipp
+++ b/boost/beast/http/impl/fields.hpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,13 +7,14 @@
// Official repository: https://github.com/boostorg/beast
//
-#ifndef BOOST_BEAST_HTTP_IMPL_FIELDS_IPP
-#define BOOST_BEAST_HTTP_IMPL_FIELDS_IPP
+#ifndef BOOST_BEAST_HTTP_IMPL_FIELDS_HPP
+#define BOOST_BEAST_HTTP_IMPL_FIELDS_HPP
#include <boost/beast/core/buffers_cat.hpp>
#include <boost/beast/core/string.hpp>
#include <boost/beast/core/static_string.hpp>
#include <boost/beast/core/detail/buffers_ref.hpp>
+#include <boost/beast/core/detail/clamp.hpp>
#include <boost/beast/http/verb.hpp>
#include <boost/beast/http/rfc7230.hpp>
#include <boost/beast/http/status.hpp>
@@ -44,7 +45,7 @@ public:
{
iter_type it_;
- using value_type = boost::asio::const_buffer;
+ using value_type = net::const_buffer;
using pointer = value_type const*;
using reference = value_type const;
using difference_type = std::ptrdiff_t;
@@ -144,9 +145,9 @@ public:
};
using view_type = buffers_cat_view<
- boost::asio::const_buffer,
- boost::asio::const_buffer,
- boost::asio::const_buffer,
+ net::const_buffer,
+ net::const_buffer,
+ net::const_buffer,
field_range,
chunk_crlf>;
@@ -179,9 +180,9 @@ writer(basic_fields const& f)
: f_(f)
{
view_.emplace(
- boost::asio::const_buffer{nullptr, 0},
- boost::asio::const_buffer{nullptr, 0},
- boost::asio::const_buffer{nullptr, 0},
+ net::const_buffer{nullptr, 0},
+ net::const_buffer{nullptr, 0},
+ net::const_buffer{nullptr, 0},
field_range(f_.list_.begin(), f_.list_.end()),
chunk_crlf());
}
@@ -219,11 +220,11 @@ writer(basic_fields const& f,
buf_[10]= '\n';
view_.emplace(
- boost::asio::const_buffer{sv.data(), sv.size()},
- boost::asio::const_buffer{
+ net::const_buffer{sv.data(), sv.size()},
+ net::const_buffer{
f_.target_or_reason_.data(),
f_.target_or_reason_.size()},
- boost::asio::const_buffer{buf_, 11},
+ net::const_buffer{buf_, 11},
field_range(f_.list_.begin(), f_.list_.end()),
chunk_crlf());
}
@@ -261,9 +262,9 @@ writer(basic_fields const& f,
sv = obsolete_reason(static_cast<status>(code));
view_.emplace(
- boost::asio::const_buffer{buf_, 13},
- boost::asio::const_buffer{sv.data(), sv.size()},
- boost::asio::const_buffer{"\r\n", 2},
+ net::const_buffer{buf_, 13},
+ net::const_buffer{sv.data(), sv.size()},
+ net::const_buffer{"\r\n", 2},
field_range(f_.list_.begin(), f_.list_.end()),
chunk_crlf{});
}
@@ -282,12 +283,12 @@ data() const
}
template<class Allocator>
-boost::asio::const_buffer
+net::const_buffer
basic_fields<Allocator>::
value_type::
buffer() const
{
- return boost::asio::const_buffer{data(),
+ return net::const_buffer{data(),
static_cast<std::size_t>(off_) + len_ + 2};
}
@@ -1018,7 +1019,8 @@ set_chunked_impl(bool value)
itt = next;
}
static_string<max_static_buffer> buf;
- if(it->value().size() <= buf.size() + 9)
+ if(! beast::detail::sum_exceeds(
+ it->value().size(), 9u, buf.max_size()))
{
buf.append(it->value().data(), it->value().size());
buf.append(", chunked", 9);
@@ -1048,6 +1050,7 @@ set_chunked_impl(bool value)
// filter "chunked"
if(it == end())
return;
+#ifndef BOOST_NO_EXCEPTIONS
try
{
static_string<max_static_buffer> buf;
@@ -1062,6 +1065,7 @@ set_chunked_impl(bool value)
erase(field::transfer_encoding);
}
catch(std::length_error const&)
+#endif
{
#ifdef BOOST_BEAST_HTTP_NO_FIELDS_BASIC_STRING_ALLOCATOR
// Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56437
@@ -1108,6 +1112,7 @@ set_keep_alive_impl(
{
// VFALCO What about Proxy-Connection ?
auto const value = (*this)[field::connection];
+#ifndef BOOST_NO_EXCEPTIONS
try
{
static_string<max_static_buffer> buf;
@@ -1119,6 +1124,7 @@ set_keep_alive_impl(
set(field::connection, buf);
}
catch(std::length_error const&)
+#endif
{
#ifdef BOOST_BEAST_HTTP_NO_FIELDS_BASIC_STRING_ALLOCATOR
// Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56437
@@ -1168,7 +1174,7 @@ new_element(field name,
auto const p = alloc_traits::allocate(a,
(sizeof(element) + off + len + 2 + sizeof(align_type) - 1) /
sizeof(align_type));
- return *(new(p) element(name, sname, value));
+ return *(::new(p) element(name, sname, value));
}
template<class Allocator>
diff --git a/boost/beast/http/impl/file_body_win32.ipp b/boost/beast/http/impl/file_body_win32.hpp
index 6357cf4983..fc74c49772 100644
--- a/boost/beast/http/impl/file_body_win32.ipp
+++ b/boost/beast/http/impl/file_body_win32.hpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,22 +7,18 @@
// Official repository: https://github.com/boostorg/beast
//
-#ifndef BOOST_BEAST_HTTP_IMPL_FILE_BODY_WIN32_IPP
-#define BOOST_BEAST_HTTP_IMPL_FILE_BODY_WIN32_IPP
+#ifndef BOOST_BEAST_HTTP_IMPL_FILE_BODY_WIN32_HPP
+#define BOOST_BEAST_HTTP_IMPL_FILE_BODY_WIN32_HPP
#if BOOST_BEAST_USE_WIN32_FILE
+#include <boost/beast/core/async_base.hpp>
#include <boost/beast/core/bind_handler.hpp>
-#include <boost/beast/core/type_traits.hpp>
+#include <boost/beast/core/buffers_range.hpp>
#include <boost/beast/core/detail/clamp.hpp>
#include <boost/beast/http/serializer.hpp>
-#include <boost/asio/associated_allocator.hpp>
-#include <boost/asio/associated_executor.hpp>
#include <boost/asio/async_result.hpp>
#include <boost/asio/basic_stream_socket.hpp>
-#include <boost/asio/executor_work_guard.hpp>
-#include <boost/asio/handler_continuation_hook.hpp>
-#include <boost/asio/handler_invoke_hook.hpp>
#include <boost/asio/windows/overlapped_ptr.hpp>
#include <boost/make_unique.hpp>
#include <boost/smart_ptr/make_shared_array.hpp>
@@ -36,7 +32,7 @@ namespace beast {
namespace http {
namespace detail {
-template<class, class, bool, class>
+template<class, class, bool, class, class>
class write_some_win32_op;
} // detail
@@ -56,14 +52,15 @@ struct basic_file_body<file_win32>
friend class reader;
friend struct basic_file_body<file_win32>;
- template<class, class, bool, class>
+ template<class, class, bool, class, class>
friend class detail::write_some_win32_op;
template<
- class Protocol, bool isRequest, class Fields>
+ class Protocol, class Executor,
+ bool isRequest, class Fields>
friend
std::size_t
write_some(
- boost::asio::basic_stream_socket<Protocol>& sock,
+ net::basic_stream_socket<Protocol, Executor>& sock,
serializer<isRequest,
basic_file_body<file_win32>, Fields>& sr,
error_code& ec);
@@ -105,14 +102,15 @@ struct basic_file_body<file_win32>
class writer
{
- template<class, class, bool, class>
+ template<class, class, bool, class, class>
friend class detail::write_some_win32_op;
template<
- class Protocol, bool isRequest, class Fields>
+ class Protocol, class Executor,
+ bool isRequest, class Fields>
friend
std::size_t
write_some(
- boost::asio::basic_stream_socket<Protocol>& sock,
+ net::basic_stream_socket<Protocol, Executor>& sock,
serializer<isRequest,
basic_file_body<file_win32>, Fields>& sr,
error_code& ec);
@@ -123,7 +121,7 @@ struct basic_file_body<file_win32>
public:
using const_buffers_type =
- boost::asio::const_buffer;
+ net::const_buffer;
template<bool isRequest, class Fields>
writer(header<isRequest, Fields>&, value_type& b)
@@ -145,7 +143,7 @@ struct basic_file_body<file_win32>
beast::detail::clamp(body_.last_ - pos_));
if(n == 0)
{
- ec.assign(0, ec.category());
+ ec = {};
return boost::none;
}
auto const nread = body_.file_.read(buf_, n, ec);
@@ -153,7 +151,7 @@ struct basic_file_body<file_win32>
return boost::none;
BOOST_ASSERT(nread != 0);
pos_ += nread;
- ec.assign(0, ec.category());
+ ec = {};
return {{
{buf_, nread}, // buffer to return.
pos_ < body_.last_}}; // `true` if there are more buffers.
@@ -182,7 +180,7 @@ struct basic_file_body<file_win32>
// VFALCO We could reserve space in the file
boost::ignore_unused(content_length);
BOOST_ASSERT(body_.file_.is_open());
- ec.assign(0, ec.category());
+ ec = {};
}
template<class ConstBufferSequence>
@@ -191,21 +189,21 @@ struct basic_file_body<file_win32>
error_code& ec)
{
std::size_t nwritten = 0;
- for(auto buffer : beast::detail::buffers_range(buffers))
+ for(auto buffer : beast::buffers_range_ref(buffers))
{
nwritten += body_.file_.write(
buffer.data(), buffer.size(), ec);
if(ec)
return nwritten;
}
- ec.assign(0, ec.category());
+ ec = {};
return nwritten;
}
void
finish(error_code& ec)
{
- ec.assign(0, ec.category());
+ ec = {};
}
};
@@ -280,7 +278,6 @@ reset(file_win32&& file, error_code& ec)
namespace detail {
template<class Unsigned>
-inline
boost::winapi::DWORD_
lowPart(Unsigned n)
{
@@ -290,7 +287,6 @@ lowPart(Unsigned n)
}
template<class Unsigned>
-inline
boost::winapi::DWORD_
highPart(Unsigned n, std::true_type)
{
@@ -300,7 +296,6 @@ highPart(Unsigned n, std::true_type)
}
template<class Unsigned>
-inline
boost::winapi::DWORD_
highPart(Unsigned, std::false_type)
{
@@ -308,7 +303,6 @@ highPart(Unsigned, std::false_type)
}
template<class Unsigned>
-inline
boost::winapi::DWORD_
highPart(Unsigned n)
{
@@ -333,165 +327,144 @@ public:
#if BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR
template<
- class Protocol, class Handler,
- bool isRequest, class Fields>
+ class Protocol, class Executor,
+ bool isRequest, class Fields,
+ class Handler>
class write_some_win32_op
+ : public beast::async_base<Handler, Executor>
{
- boost::asio::basic_stream_socket<Protocol>& sock_;
- boost::asio::executor_work_guard<decltype(std::declval<
- boost::asio::basic_stream_socket<Protocol>&>().get_executor())> wg_;
+ net::basic_stream_socket<
+ Protocol, Executor>& sock_;
serializer<isRequest,
basic_file_body<file_win32>, Fields>& sr_;
std::size_t bytes_transferred_ = 0;
- Handler h_;
bool header_ = false;
public:
- write_some_win32_op(write_some_win32_op&&) = default;
- write_some_win32_op(write_some_win32_op const&) = delete;
-
- template<class DeducedHandler>
+ template<class Handler_>
write_some_win32_op(
- DeducedHandler&& h,
- boost::asio::basic_stream_socket<Protocol>& s,
+ Handler_&& h,
+ net::basic_stream_socket<
+ Protocol, Executor>& s,
serializer<isRequest,
basic_file_body<file_win32>,Fields>& sr)
- : sock_(s)
- , wg_(sock_.get_executor())
+ : async_base<
+ Handler, Executor>(
+ std::forward<Handler_>(h),
+ s.get_executor())
+ , sock_(s)
, sr_(sr)
- , h_(std::forward<DeducedHandler>(h))
- {
- }
-
- using allocator_type =
- boost::asio::associated_allocator_t<Handler>;
-
- allocator_type
- get_allocator() const noexcept
{
- return (boost::asio::get_associated_allocator)(h_);
+ (*this)();
}
- using executor_type =
- boost::asio::associated_executor_t<Handler, decltype(std::declval<
- boost::asio::basic_stream_socket<Protocol>&>().get_executor())>;
-
- executor_type
- get_executor() const noexcept
+ void
+ operator()()
{
- return (boost::asio::get_associated_executor)(
- h_, sock_.get_executor());
+ if(! sr_.is_header_done())
+ {
+ header_ = true;
+ sr_.split(true);
+ return detail::async_write_some_impl(
+ sock_, sr_, std::move(*this));
+ }
+ if(sr_.get().chunked())
+ {
+ return detail::async_write_some_impl(
+ sock_, sr_, std::move(*this));
+ }
+ auto& w = sr_.writer_impl();
+ boost::winapi::DWORD_ const nNumberOfBytesToWrite =
+ static_cast<boost::winapi::DWORD_>(
+ (std::min<std::uint64_t>)(
+ (std::min<std::uint64_t>)(w.body_.last_ - w.pos_, sr_.limit()),
+ (std::numeric_limits<boost::winapi::DWORD_>::max)()));
+ net::windows::overlapped_ptr overlapped{
+ sock_.get_executor(), std::move(*this)};
+ // Note that we have moved *this, so we cannot access
+ // the handler since it is now moved-from. We can still
+ // access simple things like references and built-in types.
+ auto& ov = *overlapped.get();
+ ov.Offset = lowPart(w.pos_);
+ ov.OffsetHigh = highPart(w.pos_);
+ auto const bSuccess = ::TransmitFile(
+ sock_.native_handle(),
+ sr_.get().body().file_.native_handle(),
+ nNumberOfBytesToWrite,
+ 0,
+ overlapped.get(),
+ nullptr,
+ 0);
+ auto const dwError = boost::winapi::GetLastError();
+ if(! bSuccess && dwError !=
+ boost::winapi::ERROR_IO_PENDING_)
+ {
+ // VFALCO This needs review, is 0 the right number?
+ // completed immediately (with error?)
+ overlapped.complete(error_code{static_cast<int>(dwError),
+ system_category()}, 0);
+ return;
+ }
+ overlapped.release();
}
void
- operator()();
-
- void
operator()(
error_code ec,
- std::size_t bytes_transferred = 0);
-
- friend
- bool asio_handler_is_continuation(write_some_win32_op* op)
- {
- using boost::asio::asio_handler_is_continuation;
- return asio_handler_is_continuation(
- std::addressof(op->h_));
- }
-
- template<class Function>
- friend
- void asio_handler_invoke(Function&& f, write_some_win32_op* op)
+ std::size_t bytes_transferred = 0)
{
- using boost::asio::asio_handler_invoke;
- asio_handler_invoke(f, std::addressof(op->h_));
+ bytes_transferred_ += bytes_transferred;
+ if(! ec)
+ {
+ if(header_)
+ {
+ header_ = false;
+ return (*this)();
+ }
+ auto& w = sr_.writer_impl();
+ w.pos_ += bytes_transferred;
+ BOOST_ASSERT(w.pos_ <= w.body_.last_);
+ if(w.pos_ >= w.body_.last_)
+ {
+ sr_.next(ec, null_lambda{});
+ BOOST_ASSERT(! ec);
+ BOOST_ASSERT(sr_.is_done());
+ }
+ }
+ this->complete_now(ec, bytes_transferred_);
}
};
-template<
- class Protocol, class Handler,
- bool isRequest, class Fields>
-void
-write_some_win32_op<
- Protocol, Handler, isRequest, Fields>::
-operator()()
+struct run_write_some_win32_op
{
- if(! sr_.is_header_done())
- {
- header_ = true;
- sr_.split(true);
- return detail::async_write_some_impl(
- sock_, sr_, std::move(*this));
- }
- if(sr_.get().chunked())
- {
- return detail::async_write_some_impl(
- sock_, sr_, std::move(*this));
- }
- auto& w = sr_.writer_impl();
- boost::winapi::DWORD_ const nNumberOfBytesToWrite =
- static_cast<boost::winapi::DWORD_>(
- (std::min<std::uint64_t>)(
- (std::min<std::uint64_t>)(w.body_.last_ - w.pos_, sr_.limit()),
- (std::numeric_limits<boost::winapi::DWORD_>::max)()));
- boost::asio::windows::overlapped_ptr overlapped{
- sock_.get_executor().context(), std::move(*this)};
- // Note that we have moved *this, so we cannot access
- // the handler since it is now moved-from. We can still
- // access simple things like references and built-in types.
- auto& ov = *overlapped.get();
- ov.Offset = lowPart(w.pos_);
- ov.OffsetHigh = highPart(w.pos_);
- auto const bSuccess = ::TransmitFile(
- sock_.native_handle(),
- sr_.get().body().file_.native_handle(),
- nNumberOfBytesToWrite,
- 0,
- overlapped.get(),
- nullptr,
- 0);
- auto const dwError = boost::winapi::GetLastError();
- if(! bSuccess && dwError !=
- boost::winapi::ERROR_IO_PENDING_)
- {
- // VFALCO This needs review, is 0 the right number?
- // completed immediately (with error?)
- overlapped.complete(error_code{static_cast<int>(dwError),
- system_category()}, 0);
- return;
- }
- overlapped.release();
-}
-
-template<
- class Protocol, class Handler,
- bool isRequest, class Fields>
-void
-write_some_win32_op<
- Protocol, Handler, isRequest, Fields>::
-operator()(
- error_code ec, std::size_t bytes_transferred)
-{
- bytes_transferred_ += bytes_transferred;
- if(! ec)
+ template<
+ class Protocol, class Executor,
+ bool isRequest, class Fields,
+ class WriteHandler>
+ void
+ operator()(
+ WriteHandler&& h,
+ net::basic_stream_socket<
+ Protocol, Executor>* s,
+ serializer<isRequest,
+ basic_file_body<file_win32>, Fields>* sr)
{
- if(header_)
- {
- header_ = false;
- return (*this)();
- }
- auto& w = sr_.writer_impl();
- w.pos_ += bytes_transferred;
- BOOST_ASSERT(w.pos_ <= w.body_.last_);
- if(w.pos_ >= w.body_.last_)
- {
- sr_.next(ec, null_lambda{});
- BOOST_ASSERT(! ec);
- BOOST_ASSERT(sr_.is_done());
- }
+ // If you get an error on the following line it means
+ // that your handler does not meet the documented type
+ // requirements for the handler.
+
+ static_assert(
+ beast::detail::is_invocable<WriteHandler,
+ void(error_code, std::size_t)>::value,
+ "WriteHandler type requirements not met");
+
+ write_some_win32_op<
+ Protocol, Executor,
+ isRequest, Fields,
+ typename std::decay<WriteHandler>::type>(
+ std::forward<WriteHandler>(h), *s, *sr);
}
- h_(ec, bytes_transferred_);
-}
+};
#endif
@@ -499,10 +472,13 @@ operator()(
//------------------------------------------------------------------------------
-template<class Protocol, bool isRequest, class Fields>
+template<
+ class Protocol, class Executor,
+ bool isRequest, class Fields>
std::size_t
write_some(
- boost::asio::basic_stream_socket<Protocol>& sock,
+ net::basic_stream_socket<
+ Protocol, Executor>& sock,
serializer<isRequest,
basic_file_body<file_win32>, Fields>& sr,
error_code& ec)
@@ -552,7 +528,7 @@ write_some(
BOOST_ASSERT(w.pos_ <= w.body_.last_);
if(w.pos_ < w.body_.last_)
{
- ec.assign(0, ec.category());
+ ec = {};
}
else
{
@@ -566,26 +542,24 @@ write_some(
#if BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR
template<
- class Protocol,
+ class Protocol, class Executor,
bool isRequest, class Fields,
class WriteHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(
- WriteHandler, void(error_code, std::size_t))
+BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
async_write_some(
- boost::asio::basic_stream_socket<Protocol>& sock,
+ net::basic_stream_socket<
+ Protocol, Executor>& sock,
serializer<isRequest,
basic_file_body<file_win32>, Fields>& sr,
WriteHandler&& handler)
-{
- BOOST_BEAST_HANDLER_INIT(
- WriteHandler, void(error_code, std::size_t));
- detail::write_some_win32_op<
- Protocol,
- BOOST_ASIO_HANDLER_TYPE(WriteHandler,
- void(error_code, std::size_t)),
- isRequest, Fields>{
- std::move(init.completion_handler), sock, sr}();
- return init.result.get();
+{
+ return net::async_initiate<
+ WriteHandler,
+ void(error_code, std::size_t)>(
+ detail::run_write_some_win32_op{},
+ handler,
+ &sock,
+ &sr);
}
#endif
diff --git a/boost/beast/http/impl/message.ipp b/boost/beast/http/impl/message.hpp
index a2a10402f9..805d01f09a 100644
--- a/boost/beast/http/impl/message.ipp
+++ b/boost/beast/http/impl/message.hpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,8 +7,8 @@
// Official repository: https://github.com/boostorg/beast
//
-#ifndef BOOST_BEAST_HTTP_IMPL_MESSAGE_IPP
-#define BOOST_BEAST_HTTP_IMPL_MESSAGE_IPP
+#ifndef BOOST_BEAST_HTTP_IMPL_MESSAGE_HPP
+#define BOOST_BEAST_HTTP_IMPL_MESSAGE_HPP
#include <boost/beast/core/error.hpp>
#include <boost/beast/core/detail/type_traits.hpp>
@@ -30,7 +30,6 @@ header(Arg1&& arg1, ArgN&&... argn)
}
template<class Fields>
-inline
verb
header<true, Fields>::
method() const
@@ -73,7 +72,6 @@ method_string(string_view s)
}
template<class Fields>
-inline
string_view
header<true, Fields>::
target() const
@@ -82,7 +80,6 @@ target() const
}
template<class Fields>
-inline
void
header<true, Fields>::
target(string_view s)
@@ -116,7 +113,6 @@ header(Arg1&& arg1, ArgN&&... argn)
}
template<class Fields>
-inline
status
header<false, Fields>::
result() const
@@ -126,7 +122,6 @@ result() const
}
template<class Fields>
-inline
void
header<false, Fields>::
result(status v)
@@ -135,7 +130,6 @@ result(status v)
}
template<class Fields>
-inline
void
header<false, Fields>::
result(unsigned v)
@@ -148,7 +142,6 @@ result(unsigned v)
}
template<class Fields>
-inline
unsigned
header<false, Fields>::
result_int() const
@@ -168,7 +161,6 @@ reason() const
}
template<class Fields>
-inline
void
header<false, Fields>::
reason(string_view s)
@@ -295,7 +287,7 @@ message(std::piecewise_construct_t,
std::tuple<BodyArgs...> body_args)
: message(std::piecewise_construct,
body_args,
- beast::detail::make_index_sequence<
+ mp11::make_index_sequence<
sizeof...(BodyArgs)>{})
{
}
@@ -309,9 +301,9 @@ message(std::piecewise_construct_t,
: message(std::piecewise_construct,
body_args,
fields_args,
- beast::detail::make_index_sequence<
+ mp11::make_index_sequence<
sizeof...(BodyArgs)>{},
- beast::detail::make_index_sequence<
+ mp11::make_index_sequence<
sizeof...(FieldsArgs)>{})
{
}
diff --git a/boost/beast/http/impl/parser.ipp b/boost/beast/http/impl/parser.hpp
index 45bef1c6ac..066ac5fea1 100644
--- a/boost/beast/http/impl/parser.ipp
+++ b/boost/beast/http/impl/parser.hpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,8 +7,8 @@
// Official repository: https://github.com/boostorg/beast
//
-#ifndef BOOST_BEAST_HTTP_IMPL_PARSER_IPP
-#define BOOST_BEAST_HTTP_IMPL_PARSER_IPP
+#ifndef BOOST_BEAST_HTTP_IMPL_PARSER_HPP
+#define BOOST_BEAST_HTTP_IMPL_PARSER_HPP
#include <boost/throw_exception.hpp>
#include <stdexcept>
@@ -42,7 +42,7 @@ parser<isRequest, Body, Allocator>::
parser(
parser<isRequest, OtherBody, Allocator>&& other,
Args&&... args)
- : base_type(std::move(other))
+ : basic_parser<isRequest>(std::move(other))
, m_(other.release(), std::forward<Args>(args)...)
, rd_(m_.base(), m_.body())
{
diff --git a/boost/beast/http/impl/read.hpp b/boost/beast/http/impl/read.hpp
new file mode 100644
index 0000000000..faea67eb25
--- /dev/null
+++ b/boost/beast/http/impl/read.hpp
@@ -0,0 +1,559 @@
+//
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/beast
+//
+
+#ifndef BOOST_BEAST_HTTP_IMPL_READ_HPP
+#define BOOST_BEAST_HTTP_IMPL_READ_HPP
+
+#include <boost/beast/http/type_traits.hpp>
+#include <boost/beast/http/error.hpp>
+#include <boost/beast/http/parser.hpp>
+#include <boost/beast/http/read.hpp>
+#include <boost/beast/core/async_base.hpp>
+#include <boost/beast/core/stream_traits.hpp>
+#include <boost/beast/core/detail/read.hpp>
+#include <boost/asio/error.hpp>
+
+namespace boost {
+namespace beast {
+namespace http {
+
+namespace detail {
+
+// The default maximum number of bytes to transfer in a single operation.
+std::size_t constexpr default_max_transfer_size = 65536;
+
+template<
+ class DynamicBuffer,
+ bool isRequest,
+ class Condition>
+std::size_t
+parse_until(
+ DynamicBuffer& buffer,
+ basic_parser<isRequest>& parser,
+ error_code& ec,
+ Condition cond)
+{
+ if(ec == net::error::eof)
+ {
+ if(parser.got_some())
+ {
+ // Caller sees EOF on next read
+ ec = {};
+ parser.put_eof(ec);
+ BOOST_ASSERT(ec || parser.is_done());
+ }
+ else
+ {
+ ec = error::end_of_stream;
+ }
+ return 0;
+ }
+ if(ec)
+ {
+ // Upgrade the error if we have a partial message.
+ // This causes SSL short reads (and every other error)
+ // to be converted into something else, allowing the
+ // caller to distinguish an SSL short read which
+ // represents a safe connection closure, versus
+ // a closure with data loss.
+ if(parser.got_some() && ! parser.is_done())
+ ec = error::partial_message;
+ return 0;
+ }
+ if(parser.is_done())
+ return 0;
+ if(buffer.size() > 0)
+ {
+ auto const bytes_used =
+ parser.put(buffer.data(), ec);
+ // total = total + bytes_used; // VFALCO Can't do this in a condition
+ buffer.consume(bytes_used);
+ if(ec == http::error::need_more)
+ {
+ if(buffer.size() >= buffer.max_size())
+ {
+ ec = http::error::buffer_overflow;
+ return 0;
+ }
+ ec = {};
+ }
+ else if(ec || cond())
+ {
+ return 0;
+ }
+ }
+ return default_max_transfer_size;
+}
+
+// predicate is true on any forward parser progress
+template<bool isRequest>
+struct read_some_condition
+{
+ basic_parser<isRequest>& parser;
+
+ template<class DynamicBuffer>
+ std::size_t
+ operator()(error_code& ec, std::size_t,
+ DynamicBuffer& buffer)
+ {
+ return detail::parse_until(
+ buffer, parser, ec,
+ []
+ {
+ return true;
+ });
+ }
+};
+
+// predicate is true when parser header is complete
+template<bool isRequest>
+struct read_header_condition
+{
+ basic_parser<isRequest>& parser;
+
+ template<class DynamicBuffer>
+ std::size_t
+ operator()(error_code& ec, std::size_t,
+ DynamicBuffer& buffer)
+ {
+ return detail::parse_until(
+ buffer, parser, ec,
+ [this]
+ {
+ return parser.is_header_done();
+ });
+ }
+};
+
+// predicate is true when parser message is complete
+template<bool isRequest>
+struct read_all_condition
+{
+ basic_parser<isRequest>& parser;
+
+ template<class DynamicBuffer>
+ std::size_t
+ operator()(error_code& ec, std::size_t,
+ DynamicBuffer& buffer)
+ {
+ return detail::parse_until(
+ buffer, parser, ec,
+ [this]
+ {
+ return parser.is_done();
+ });
+ }
+};
+
+//------------------------------------------------------------------------------
+
+template<
+ class Stream, class DynamicBuffer,
+ bool isRequest, class Body, class Allocator,
+ class Handler>
+class read_msg_op
+ : public beast::stable_async_base<
+ Handler, beast::executor_type<Stream>>
+ , public net::coroutine
+{
+ using parser_type =
+ parser<isRequest, Body, Allocator>;
+
+ using message_type =
+ typename parser_type::value_type;
+
+ struct data
+ {
+ Stream& s;
+ message_type& m;
+ parser_type p;
+
+ data(
+ Stream& s_,
+ message_type& m_)
+ : s(s_)
+ , m(m_)
+ , p(std::move(m))
+ {
+ }
+ };
+
+ data& d_;
+
+public:
+ template<class Handler_>
+ read_msg_op(
+ Handler_&& h,
+ Stream& s,
+ DynamicBuffer& b,
+ message_type& m)
+ : stable_async_base<
+ Handler, beast::executor_type<Stream>>(
+ std::forward<Handler_>(h), s.get_executor())
+ , d_(beast::allocate_stable<data>(
+ *this, s, m))
+ {
+ http::async_read(d_.s, b, d_.p, std::move(*this));
+ }
+
+ void
+ operator()(
+ error_code ec,
+ std::size_t bytes_transferred)
+ {
+ if(! ec)
+ d_.m = d_.p.release();
+ this->complete_now(ec, bytes_transferred);
+ }
+};
+
+struct run_read_msg_op
+{
+ template<
+ class ReadHandler,
+ class AsyncReadStream,
+ class DynamicBuffer,
+ bool isRequest, class Body, class Allocator>
+ void
+ operator()(
+ ReadHandler&& h,
+ AsyncReadStream* s,
+ DynamicBuffer* b,
+ message<isRequest, Body,
+ basic_fields<Allocator>>* m)
+ {
+ // If you get an error on the following line it means
+ // that your handler does not meet the documented type
+ // requirements for the handler.
+
+ static_assert(
+ beast::detail::is_invocable<ReadHandler,
+ void(error_code, std::size_t)>::value,
+ "ReadHandler type requirements not met");
+
+ read_msg_op<
+ AsyncReadStream,
+ DynamicBuffer,
+ isRequest, Body, Allocator,
+ typename std::decay<ReadHandler>::type>(
+ std::forward<ReadHandler>(h), *s, *b, *m);
+ }
+};
+
+} // detail
+
+//------------------------------------------------------------------------------
+
+template<
+ class SyncReadStream,
+ class DynamicBuffer,
+ bool isRequest>
+std::size_t
+read_some(
+ SyncReadStream& stream,
+ DynamicBuffer& buffer,
+ basic_parser<isRequest>& parser)
+{
+ static_assert(
+ is_sync_read_stream<SyncReadStream>::value,
+ "SyncReadStream type requirements not met");
+ static_assert(
+ net::is_dynamic_buffer<DynamicBuffer>::value,
+ "DynamicBuffer type requirements not met");
+ error_code ec;
+ auto const bytes_transferred =
+ http::read_some(stream, buffer, parser, ec);
+ if(ec)
+ BOOST_THROW_EXCEPTION(system_error{ec});
+ return bytes_transferred;
+}
+
+template<
+ class SyncReadStream,
+ class DynamicBuffer,
+ bool isRequest>
+std::size_t
+read_some(
+ SyncReadStream& stream,
+ DynamicBuffer& buffer,
+ basic_parser<isRequest>& parser,
+ error_code& ec)
+{
+ static_assert(
+ is_sync_read_stream<SyncReadStream>::value,
+ "SyncReadStream type requirements not met");
+ static_assert(
+ net::is_dynamic_buffer<DynamicBuffer>::value,
+ "DynamicBuffer type requirements not met");
+ return beast::detail::read(stream, buffer,
+ detail::read_some_condition<
+ isRequest>{parser}, ec);
+}
+
+template<
+ class AsyncReadStream,
+ class DynamicBuffer,
+ bool isRequest,
+ class ReadHandler>
+BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
+async_read_some(
+ AsyncReadStream& stream,
+ DynamicBuffer& buffer,
+ basic_parser<isRequest>& parser,
+ ReadHandler&& handler)
+{
+ return beast::detail::async_read(
+ stream,
+ buffer,
+ detail::read_some_condition<
+ isRequest>{parser},
+ std::forward<ReadHandler>(handler));
+}
+
+//------------------------------------------------------------------------------
+
+template<
+ class SyncReadStream,
+ class DynamicBuffer,
+ bool isRequest>
+std::size_t
+read_header(
+ SyncReadStream& stream,
+ DynamicBuffer& buffer,
+ basic_parser<isRequest>& parser)
+{
+ static_assert(
+ is_sync_read_stream<SyncReadStream>::value,
+ "SyncReadStream type requirements not met");
+ static_assert(
+ net::is_dynamic_buffer<DynamicBuffer>::value,
+ "DynamicBuffer type requirements not met");
+ error_code ec;
+ auto const bytes_transferred =
+ http::read_header(stream, buffer, parser, ec);
+ if(ec)
+ BOOST_THROW_EXCEPTION(system_error{ec});
+ return bytes_transferred;
+}
+
+template<
+ class SyncReadStream,
+ class DynamicBuffer,
+ bool isRequest>
+std::size_t
+read_header(
+ SyncReadStream& stream,
+ DynamicBuffer& buffer,
+ basic_parser<isRequest>& parser,
+ error_code& ec)
+{
+ static_assert(
+ is_sync_read_stream<SyncReadStream>::value,
+ "SyncReadStream type requirements not met");
+ static_assert(
+ net::is_dynamic_buffer<DynamicBuffer>::value,
+ "DynamicBuffer type requirements not met");
+ parser.eager(false);
+ return beast::detail::read(stream, buffer,
+ detail::read_header_condition<
+ isRequest>{parser}, ec);
+}
+
+template<
+ class AsyncReadStream,
+ class DynamicBuffer,
+ bool isRequest,
+ class ReadHandler>
+BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
+async_read_header(
+ AsyncReadStream& stream,
+ DynamicBuffer& buffer,
+ basic_parser<isRequest>& parser,
+ ReadHandler&& handler)
+{
+ parser.eager(false);
+ return beast::detail::async_read(
+ stream,
+ buffer,
+ detail::read_header_condition<
+ isRequest>{parser},
+ std::forward<ReadHandler>(handler));
+}
+
+//------------------------------------------------------------------------------
+
+template<
+ class SyncReadStream,
+ class DynamicBuffer,
+ bool isRequest>
+std::size_t
+read(
+ SyncReadStream& stream,
+ DynamicBuffer& buffer,
+ basic_parser<isRequest>& parser)
+{
+ static_assert(
+ is_sync_read_stream<SyncReadStream>::value,
+ "SyncReadStream type requirements not met");
+ static_assert(
+ net::is_dynamic_buffer<DynamicBuffer>::value,
+ "DynamicBuffer type requirements not met");
+ error_code ec;
+ auto const bytes_transferred =
+ http::read(stream, buffer, parser, ec);
+ if(ec)
+ BOOST_THROW_EXCEPTION(system_error{ec});
+ return bytes_transferred;
+}
+
+template<
+ class SyncReadStream,
+ class DynamicBuffer,
+ bool isRequest>
+std::size_t
+read(
+ SyncReadStream& stream,
+ DynamicBuffer& buffer,
+ basic_parser<isRequest>& parser,
+ error_code& ec)
+{
+ static_assert(
+ is_sync_read_stream<SyncReadStream>::value,
+ "SyncReadStream type requirements not met");
+ static_assert(
+ net::is_dynamic_buffer<DynamicBuffer>::value,
+ "DynamicBuffer type requirements not met");
+ parser.eager(true);
+ return beast::detail::read(stream, buffer,
+ detail::read_all_condition<
+ isRequest>{parser}, ec);
+}
+
+template<
+ class AsyncReadStream,
+ class DynamicBuffer,
+ bool isRequest,
+ class ReadHandler>
+BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
+async_read(
+ AsyncReadStream& stream,
+ DynamicBuffer& buffer,
+ basic_parser<isRequest>& parser,
+ ReadHandler&& handler)
+{
+ static_assert(
+ is_async_read_stream<AsyncReadStream>::value,
+ "AsyncReadStream type requirements not met");
+ static_assert(
+ net::is_dynamic_buffer<DynamicBuffer>::value,
+ "DynamicBuffer type requirements not met");
+ parser.eager(true);
+ return beast::detail::async_read(
+ stream,
+ buffer,
+ detail::read_all_condition<
+ isRequest>{parser},
+ std::forward<ReadHandler>(handler));
+}
+
+//------------------------------------------------------------------------------
+
+template<
+ class SyncReadStream,
+ class DynamicBuffer,
+ bool isRequest, class Body, class Allocator>
+std::size_t
+read(
+ SyncReadStream& stream,
+ DynamicBuffer& buffer,
+ message<isRequest, Body, basic_fields<Allocator>>& msg)
+{
+ static_assert(
+ is_sync_read_stream<SyncReadStream>::value,
+ "SyncReadStream type requirements not met");
+ static_assert(
+ net::is_dynamic_buffer<DynamicBuffer>::value,
+ "DynamicBuffer type requirements not met");
+ static_assert(is_body<Body>::value,
+ "Body type requirements not met");
+ static_assert(is_body_reader<Body>::value,
+ "BodyReader type requirements not met");
+ error_code ec;
+ auto const bytes_transferred =
+ http::read(stream, buffer, msg, ec);
+ if(ec)
+ BOOST_THROW_EXCEPTION(system_error{ec});
+ return bytes_transferred;
+}
+
+template<
+ class SyncReadStream,
+ class DynamicBuffer,
+ bool isRequest, class Body, class Allocator>
+std::size_t
+read(
+ SyncReadStream& stream,
+ DynamicBuffer& buffer,
+ message<isRequest, Body, basic_fields<Allocator>>& msg,
+ error_code& ec)
+{
+ static_assert(
+ is_sync_read_stream<SyncReadStream>::value,
+ "SyncReadStream type requirements not met");
+ static_assert(
+ net::is_dynamic_buffer<DynamicBuffer>::value,
+ "DynamicBuffer type requirements not met");
+ static_assert(is_body<Body>::value,
+ "Body type requirements not met");
+ static_assert(is_body_reader<Body>::value,
+ "BodyReader type requirements not met");
+ parser<isRequest, Body, Allocator> p(std::move(msg));
+ p.eager(true);
+ auto const bytes_transferred =
+ http::read(stream, buffer, p, ec);
+ if(ec)
+ return bytes_transferred;
+ msg = p.release();
+ return bytes_transferred;
+}
+
+template<
+ class AsyncReadStream,
+ class DynamicBuffer,
+ bool isRequest, class Body, class Allocator,
+ class ReadHandler>
+BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
+async_read(
+ AsyncReadStream& stream,
+ DynamicBuffer& buffer,
+ message<isRequest, Body, basic_fields<Allocator>>& msg,
+ ReadHandler&& handler)
+{
+ static_assert(
+ is_async_read_stream<AsyncReadStream>::value,
+ "AsyncReadStream type requirements not met");
+ static_assert(
+ net::is_dynamic_buffer<DynamicBuffer>::value,
+ "DynamicBuffer type requirements not met");
+ static_assert(is_body<Body>::value,
+ "Body type requirements not met");
+ static_assert(is_body_reader<Body>::value,
+ "BodyReader type requirements not met");
+ return net::async_initiate<
+ ReadHandler,
+ void(error_code, std::size_t)>(
+ detail::run_read_msg_op{},
+ handler, &stream, &buffer, &msg);
+}
+
+} // http
+} // beast
+} // boost
+
+#endif
diff --git a/boost/beast/http/impl/read.ipp b/boost/beast/http/impl/read.ipp
deleted file mode 100644
index 42ce175d8c..0000000000
--- a/boost/beast/http/impl/read.ipp
+++ /dev/null
@@ -1,857 +0,0 @@
-//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// Official repository: https://github.com/boostorg/beast
-//
-
-#ifndef BOOST_BEAST_HTTP_IMPL_READ_IPP_HPP
-#define BOOST_BEAST_HTTP_IMPL_READ_IPP_HPP
-
-#include <boost/beast/http/type_traits.hpp>
-#include <boost/beast/http/error.hpp>
-#include <boost/beast/http/parser.hpp>
-#include <boost/beast/http/read.hpp>
-#include <boost/beast/core/bind_handler.hpp>
-#include <boost/beast/core/handler_ptr.hpp>
-#include <boost/beast/core/read_size.hpp>
-#include <boost/beast/core/type_traits.hpp>
-#include <boost/beast/core/detail/buffer.hpp>
-#include <boost/asio/associated_allocator.hpp>
-#include <boost/asio/associated_executor.hpp>
-#include <boost/asio/coroutine.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/executor_work_guard.hpp>
-#include <boost/asio/handler_continuation_hook.hpp>
-#include <boost/asio/handler_invoke_hook.hpp>
-#include <boost/asio/post.hpp>
-#include <boost/assert.hpp>
-#include <boost/config.hpp>
-#include <boost/optional.hpp>
-#include <boost/throw_exception.hpp>
-
-namespace boost {
-namespace beast {
-namespace http {
-
-namespace detail {
-
-//------------------------------------------------------------------------------
-
-template<class Stream, class DynamicBuffer,
- bool isRequest, class Derived, class Handler>
-class read_some_op
- : public boost::asio::coroutine
-{
- Stream& s_;
- boost::asio::executor_work_guard<decltype(
- std::declval<Stream&>().get_executor())> wg_;
- DynamicBuffer& b_;
- basic_parser<isRequest, Derived>& p_;
- std::size_t bytes_transferred_ = 0;
- Handler h_;
- bool cont_ = false;
-
-public:
- read_some_op(read_some_op&&) = default;
- read_some_op(read_some_op const&) = delete;
-
- template<class DeducedHandler>
- read_some_op(DeducedHandler&& h, Stream& s,
- DynamicBuffer& b, basic_parser<isRequest, Derived>& p)
- : s_(s)
- , wg_(s_.get_executor())
- , b_(b)
- , p_(p)
- , h_(std::forward<DeducedHandler>(h))
- {
- }
-
- using allocator_type =
- boost::asio::associated_allocator_t<Handler>;
-
- allocator_type
- get_allocator() const noexcept
- {
- return (boost::asio::get_associated_allocator)(h_);
- }
-
- using executor_type = boost::asio::associated_executor_t<
- Handler, decltype(std::declval<Stream&>().get_executor())>;
-
- executor_type
- get_executor() const noexcept
- {
- return (boost::asio::get_associated_executor)(
- h_, s_.get_executor());
- }
-
- void
- operator()(
- error_code ec,
- std::size_t bytes_transferred = 0,
- bool cont = true);
-
- friend
- bool asio_handler_is_continuation(read_some_op* op)
- {
- using boost::asio::asio_handler_is_continuation;
- return op->cont_ ? true :
- asio_handler_is_continuation(
- std::addressof(op->h_));
- }
-
- template<class Function>
- friend
- void asio_handler_invoke(Function&& f, read_some_op* op)
- {
- using boost::asio::asio_handler_invoke;
- asio_handler_invoke(f, std::addressof(op->h_));
- }
-};
-
-template<class Stream, class DynamicBuffer,
- bool isRequest, class Derived, class Handler>
-void
-read_some_op<Stream, DynamicBuffer,
- isRequest, Derived, Handler>::
-operator()(
- error_code ec,
- std::size_t bytes_transferred,
- bool cont)
-{
- cont_ = cont;
- BOOST_ASIO_CORO_REENTER(*this)
- {
- if(b_.size() == 0)
- goto do_read;
- for(;;)
- {
- // parse
- {
- auto const used = p_.put(b_.data(), ec);
- bytes_transferred_ += used;
- b_.consume(used);
- }
- if(ec != http::error::need_more)
- break;
-
- do_read:
- BOOST_ASIO_CORO_YIELD
- {
- // VFALCO This was read_size_or_throw
- auto const size = read_size(b_, 65536);
- if(size == 0)
- {
- ec = error::buffer_overflow;
- goto upcall;
- }
- auto const mb =
- beast::detail::dynamic_buffer_prepare(
- b_, size, ec, error::buffer_overflow);
- if(ec)
- goto upcall;
- s_.async_read_some(*mb, std::move(*this));
- }
- if(ec == boost::asio::error::eof)
- {
- BOOST_ASSERT(bytes_transferred == 0);
- if(p_.got_some())
- {
- // caller sees EOF on next read
- ec.assign(0, ec.category());
- p_.put_eof(ec);
- if(ec)
- goto upcall;
- BOOST_ASSERT(p_.is_done());
- goto upcall;
- }
- ec = error::end_of_stream;
- break;
- }
- if(ec)
- break;
- b_.commit(bytes_transferred);
- }
-
- upcall:
- if(! cont_)
- {
- BOOST_ASIO_CORO_YIELD
- boost::asio::post(
- s_.get_executor(),
- bind_handler(std::move(*this),
- ec, bytes_transferred_));
- }
- h_(ec, bytes_transferred_);
- }
-}
-
-//------------------------------------------------------------------------------
-
-struct parser_is_done
-{
- template<bool isRequest, class Derived>
- bool
- operator()(basic_parser<
- isRequest, Derived> const& p) const
- {
- return p.is_done();
- }
-};
-
-struct parser_is_header_done
-{
- template<bool isRequest, class Derived>
- bool
- operator()(basic_parser<
- isRequest, Derived> const& p) const
- {
- return p.is_header_done();
- }
-};
-
-template<class Stream, class DynamicBuffer,
- bool isRequest, class Derived, class Condition,
- class Handler>
-class read_op
- : public boost::asio::coroutine
-{
- Stream& s_;
- boost::asio::executor_work_guard<decltype(
- std::declval<Stream&>().get_executor())> wg_;
- DynamicBuffer& b_;
- basic_parser<isRequest, Derived>& p_;
- std::size_t bytes_transferred_ = 0;
- Handler h_;
- bool cont_ = false;
-
-public:
- read_op(read_op&&) = default;
- read_op(read_op const&) = delete;
-
- template<class DeducedHandler>
- read_op(DeducedHandler&& h, Stream& s,
- DynamicBuffer& b, basic_parser<isRequest,
- Derived>& p)
- : s_(s)
- , wg_(s_.get_executor())
- , b_(b)
- , p_(p)
- , h_(std::forward<DeducedHandler>(h))
- {
- }
-
- using allocator_type =
- boost::asio::associated_allocator_t<Handler>;
-
- allocator_type
- get_allocator() const noexcept
- {
- return (boost::asio::get_associated_allocator)(h_);
- }
-
- using executor_type = boost::asio::associated_executor_t<
- Handler, decltype(std::declval<Stream&>().get_executor())>;
-
- executor_type
- get_executor() const noexcept
- {
- return (boost::asio::get_associated_executor)(
- h_, s_.get_executor());
- }
-
- void
- operator()(
- error_code ec,
- std::size_t bytes_transferred = 0,
- bool cont = true);
-
- friend
- bool asio_handler_is_continuation(read_op* op)
- {
- using boost::asio::asio_handler_is_continuation;
- return op->cont_ ? true :
- asio_handler_is_continuation(
- std::addressof(op->h_));
- }
-
- template<class Function>
- friend
- void asio_handler_invoke(Function&& f, read_op* op)
- {
- using boost::asio::asio_handler_invoke;
- asio_handler_invoke(f, std::addressof(op->h_));
- }
-};
-
-template<class Stream, class DynamicBuffer,
- bool isRequest, class Derived, class Condition,
- class Handler>
-void
-read_op<Stream, DynamicBuffer,
- isRequest, Derived, Condition, Handler>::
-operator()(
- error_code ec,
- std::size_t bytes_transferred,
- bool cont)
-{
- cont_ = cont;
- BOOST_ASIO_CORO_REENTER(*this)
- {
- if(Condition{}(p_))
- {
- BOOST_ASIO_CORO_YIELD
- boost::asio::post(s_.get_executor(),
- bind_handler(std::move(*this), ec));
- goto upcall;
- }
- for(;;)
- {
- BOOST_ASIO_CORO_YIELD
- async_read_some(
- s_, b_, p_, std::move(*this));
- if(ec)
- goto upcall;
- bytes_transferred_ += bytes_transferred;
- if(Condition{}(p_))
- goto upcall;
- }
- upcall:
- h_(ec, bytes_transferred_);
- }
-}
-
-//------------------------------------------------------------------------------
-
-template<class Stream, class DynamicBuffer,
- bool isRequest, class Body, class Allocator,
- class Handler>
-class read_msg_op
- : public boost::asio::coroutine
-{
- using parser_type =
- parser<isRequest, Body, Allocator>;
-
- using message_type =
- typename parser_type::value_type;
-
- struct data
- {
- Stream& s;
- boost::asio::executor_work_guard<decltype(
- std::declval<Stream&>().get_executor())> wg;
- DynamicBuffer& b;
- message_type& m;
- parser_type p;
- std::size_t bytes_transferred = 0;
- bool cont = false;
-
- data(Handler const&, Stream& s_,
- DynamicBuffer& b_, message_type& m_)
- : s(s_)
- , wg(s.get_executor())
- , b(b_)
- , m(m_)
- , p(std::move(m))
- {
- p.eager(true);
- }
- };
-
- handler_ptr<data, Handler> d_;
-
-public:
- read_msg_op(read_msg_op&&) = default;
- read_msg_op(read_msg_op const&) = delete;
-
- template<class DeducedHandler, class... Args>
- read_msg_op(DeducedHandler&& h, Stream& s, Args&&... args)
- : d_(std::forward<DeducedHandler>(h),
- s, std::forward<Args>(args)...)
- {
- }
-
- using allocator_type =
- boost::asio::associated_allocator_t<Handler>;
-
- allocator_type
- get_allocator() const noexcept
- {
- return (boost::asio::get_associated_allocator)(d_.handler());
- }
-
- using executor_type = boost::asio::associated_executor_t<
- Handler, decltype(std::declval<Stream&>().get_executor())>;
-
- executor_type
- get_executor() const noexcept
- {
- return (boost::asio::get_associated_executor)(
- d_.handler(), d_->s.get_executor());
- }
-
- void
- operator()(
- error_code ec,
- std::size_t bytes_transferred = 0,
- bool cont = true);
-
- friend
- bool asio_handler_is_continuation(read_msg_op* op)
- {
- using boost::asio::asio_handler_is_continuation;
- return op->d_->cont ? true :
- asio_handler_is_continuation(
- std::addressof(op->d_.handler()));
- }
-
- template<class Function>
- friend
- void asio_handler_invoke(Function&& f, read_msg_op* op)
- {
- using boost::asio::asio_handler_invoke;
- asio_handler_invoke(f, std::addressof(op->d_.handler()));
- }
-};
-
-template<class Stream, class DynamicBuffer,
- bool isRequest, class Body, class Allocator,
- class Handler>
-void
-read_msg_op<Stream, DynamicBuffer,
- isRequest, Body, Allocator, Handler>::
-operator()(
- error_code ec,
- std::size_t bytes_transferred,
- bool cont)
-{
- auto& d = *d_;
- d.cont = cont;
- BOOST_ASIO_CORO_REENTER(*this)
- {
- for(;;)
- {
- BOOST_ASIO_CORO_YIELD
- async_read_some(
- d.s, d.b, d.p, std::move(*this));
- if(ec)
- goto upcall;
- d.bytes_transferred +=
- bytes_transferred;
- if(d.p.is_done())
- {
- d.m = d.p.release();
- goto upcall;
- }
- }
- upcall:
- bytes_transferred = d.bytes_transferred;
- {
- auto wg = std::move(d.wg);
- d_.invoke(ec, bytes_transferred);
- }
- }
-}
-
-} // detail
-
-//------------------------------------------------------------------------------
-
-template<
- class SyncReadStream,
- class DynamicBuffer,
- bool isRequest, class Derived>
-std::size_t
-read_some(
- SyncReadStream& stream,
- DynamicBuffer& buffer,
- basic_parser<isRequest, Derived>& parser)
-{
- static_assert(is_sync_read_stream<SyncReadStream>::value,
- "SyncReadStream requirements not met");
- static_assert(
- boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
- "DynamicBuffer requirements not met");
- BOOST_ASSERT(! parser.is_done());
- error_code ec;
- auto const bytes_transferred =
- read_some(stream, buffer, parser, ec);
- if(ec)
- BOOST_THROW_EXCEPTION(system_error{ec});
- return bytes_transferred;
-}
-
-template<
- class SyncReadStream,
- class DynamicBuffer,
- bool isRequest, class Derived>
-std::size_t
-read_some(
- SyncReadStream& stream,
- DynamicBuffer& buffer,
- basic_parser<isRequest, Derived>& parser,
- error_code& ec)
-{
- static_assert(is_sync_read_stream<SyncReadStream>::value,
- "SyncReadStream requirements not met");
- static_assert(
- boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
- "DynamicBuffer requirements not met");
- BOOST_ASSERT(! parser.is_done());
- std::size_t bytes_transferred = 0;
- if(buffer.size() == 0)
- goto do_read;
- for(;;)
- {
- // invoke parser
- {
- auto const n = parser.put(buffer.data(), ec);
- bytes_transferred += n;
- buffer.consume(n);
- if(! ec)
- break;
- if(ec != http::error::need_more)
- break;
- }
- do_read:
- auto const size = read_size(buffer, 65536);
- if(size == 0)
- {
- ec = error::buffer_overflow;
- break;
- }
- auto const mb =
- beast::detail::dynamic_buffer_prepare(
- buffer, size, ec, error::buffer_overflow);
- if(ec)
- break;
- auto const n = stream.read_some(*mb, ec);
- if(ec == boost::asio::error::eof)
- {
- BOOST_ASSERT(n == 0);
- if(parser.got_some())
- {
- // caller sees EOF on next read
- parser.put_eof(ec);
- if(ec)
- break;
- BOOST_ASSERT(parser.is_done());
- break;
- }
- ec = error::end_of_stream;
- break;
- }
- if(ec)
- break;
- buffer.commit(n);
- }
- return bytes_transferred;
-}
-
-template<
- class AsyncReadStream,
- class DynamicBuffer,
- bool isRequest, class Derived,
- class ReadHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(
- ReadHandler, void(error_code, std::size_t))
-async_read_some(
- AsyncReadStream& stream,
- DynamicBuffer& buffer,
- basic_parser<isRequest, Derived>& parser,
- ReadHandler&& handler)
-{
- static_assert(is_async_read_stream<AsyncReadStream>::value,
- "AsyncReadStream requirements not met");
- static_assert(
- boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
- "DynamicBuffer requirements not met");
- BOOST_ASSERT(! parser.is_done());
- BOOST_BEAST_HANDLER_INIT(
- ReadHandler, void(error_code, std::size_t));
- detail::read_some_op<AsyncReadStream,
- DynamicBuffer, isRequest, Derived, BOOST_ASIO_HANDLER_TYPE(
- ReadHandler, void(error_code, std::size_t))>{
- std::move(init.completion_handler), stream, buffer, parser}(
- {}, 0, false);
- return init.result.get();
-}
-
-//------------------------------------------------------------------------------
-
-template<
- class SyncReadStream,
- class DynamicBuffer,
- bool isRequest, class Derived>
-std::size_t
-read_header(
- SyncReadStream& stream,
- DynamicBuffer& buffer,
- basic_parser<isRequest, Derived>& parser)
-{
- static_assert(is_sync_read_stream<SyncReadStream>::value,
- "SyncReadStream requirements not met");
- static_assert(
- boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
- "DynamicBuffer requirements not met");
- error_code ec;
- auto const bytes_transferred =
- read_header(stream, buffer, parser, ec);
- if(ec)
- BOOST_THROW_EXCEPTION(system_error{ec});
- return bytes_transferred;
-}
-
-template<
- class SyncReadStream,
- class DynamicBuffer,
- bool isRequest, class Derived>
-std::size_t
-read_header(
- SyncReadStream& stream,
- DynamicBuffer& buffer,
- basic_parser<isRequest, Derived>& parser,
- error_code& ec)
-{
- static_assert(is_sync_read_stream<SyncReadStream>::value,
- "SyncReadStream requirements not met");
- static_assert(
- boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
- "DynamicBuffer requirements not met");
- parser.eager(false);
- if(parser.is_header_done())
- {
- ec.assign(0, ec.category());
- return 0;
- }
- std::size_t bytes_transferred = 0;
- do
- {
- bytes_transferred += read_some(
- stream, buffer, parser, ec);
- if(ec)
- return bytes_transferred;
- }
- while(! parser.is_header_done());
- return bytes_transferred;
-}
-
-template<
- class AsyncReadStream,
- class DynamicBuffer,
- bool isRequest, class Derived,
- class ReadHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(
- ReadHandler, void(error_code, std::size_t))
-async_read_header(
- AsyncReadStream& stream,
- DynamicBuffer& buffer,
- basic_parser<isRequest, Derived>& parser,
- ReadHandler&& handler)
-{
- static_assert(is_async_read_stream<AsyncReadStream>::value,
- "AsyncReadStream requirements not met");
- static_assert(
- boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
- "DynamicBuffer requirements not met");
- parser.eager(false);
- BOOST_BEAST_HANDLER_INIT(
- ReadHandler, void(error_code, std::size_t));
- detail::read_op<AsyncReadStream, DynamicBuffer,
- isRequest, Derived, detail::parser_is_header_done,
- BOOST_ASIO_HANDLER_TYPE(ReadHandler, void(error_code, std::size_t))>{
- std::move(init.completion_handler), stream,
- buffer, parser}({}, 0, false);
- return init.result.get();
-}
-
-//------------------------------------------------------------------------------
-
-template<
- class SyncReadStream,
- class DynamicBuffer,
- bool isRequest, class Derived>
-std::size_t
-read(
- SyncReadStream& stream,
- DynamicBuffer& buffer,
- basic_parser<isRequest, Derived>& parser)
-{
- static_assert(is_sync_read_stream<SyncReadStream>::value,
- "SyncReadStream requirements not met");
- static_assert(
- boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
- "DynamicBuffer requirements not met");
- error_code ec;
- auto const bytes_transferred =
- read(stream, buffer, parser, ec);
- if(ec)
- BOOST_THROW_EXCEPTION(system_error{ec});
- return bytes_transferred;
-}
-
-template<
- class SyncReadStream,
- class DynamicBuffer,
- bool isRequest, class Derived>
-std::size_t
-read(
- SyncReadStream& stream,
- DynamicBuffer& buffer,
- basic_parser<isRequest, Derived>& parser,
- error_code& ec)
-{
- static_assert(is_sync_read_stream<SyncReadStream>::value,
- "SyncReadStream requirements not met");
- static_assert(
- boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
- "DynamicBuffer requirements not met");
- parser.eager(true);
- if(parser.is_done())
- {
- ec.assign(0, ec.category());
- return 0;
- }
- std::size_t bytes_transferred = 0;
- do
- {
- bytes_transferred += read_some(
- stream, buffer, parser, ec);
- if(ec)
- return bytes_transferred;
- }
- while(! parser.is_done());
- return bytes_transferred;
-}
-
-template<
- class AsyncReadStream,
- class DynamicBuffer,
- bool isRequest, class Derived,
- class ReadHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(
- ReadHandler, void(error_code, std::size_t))
-async_read(
- AsyncReadStream& stream,
- DynamicBuffer& buffer,
- basic_parser<isRequest, Derived>& parser,
- ReadHandler&& handler)
-{
- static_assert(is_async_read_stream<AsyncReadStream>::value,
- "AsyncReadStream requirements not met");
- static_assert(
- boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
- "DynamicBuffer requirements not met");
- parser.eager(true);
- BOOST_BEAST_HANDLER_INIT(
- ReadHandler, void(error_code, std::size_t));
- detail::read_op<AsyncReadStream, DynamicBuffer,
- isRequest, Derived, detail::parser_is_done,
- BOOST_ASIO_HANDLER_TYPE(ReadHandler, void(error_code, std::size_t))>{
- std::move(init.completion_handler), stream, buffer, parser}(
- {}, 0, false);
- return init.result.get();
-}
-
-//------------------------------------------------------------------------------
-
-template<
- class SyncReadStream,
- class DynamicBuffer,
- bool isRequest, class Body, class Allocator>
-std::size_t
-read(
- SyncReadStream& stream,
- DynamicBuffer& buffer,
- message<isRequest, Body, basic_fields<Allocator>>& msg)
-{
- static_assert(is_sync_read_stream<SyncReadStream>::value,
- "SyncReadStream requirements not met");
- static_assert(
- boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
- "DynamicBuffer requirements not met");
- static_assert(is_body<Body>::value,
- "Body requirements not met");
- static_assert(is_body_reader<Body>::value,
- "BodyReader requirements not met");
- error_code ec;
- auto const bytes_transferred =
- read(stream, buffer, msg, ec);
- if(ec)
- BOOST_THROW_EXCEPTION(system_error{ec});
- return bytes_transferred;
-}
-
-template<
- class SyncReadStream,
- class DynamicBuffer,
- bool isRequest, class Body, class Allocator>
-std::size_t
-read(
- SyncReadStream& stream,
- DynamicBuffer& buffer,
- message<isRequest, Body, basic_fields<Allocator>>& msg,
- error_code& ec)
-{
- static_assert(is_sync_read_stream<SyncReadStream>::value,
- "SyncReadStream requirements not met");
- static_assert(
- boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
- "DynamicBuffer requirements not met");
- static_assert(is_body<Body>::value,
- "Body requirements not met");
- static_assert(is_body_reader<Body>::value,
- "BodyReader requirements not met");
- parser<isRequest, Body, Allocator> p{std::move(msg)};
- p.eager(true);
- auto const bytes_transferred =
- read(stream, buffer, p.base(), ec);
- if(ec)
- return bytes_transferred;
- msg = p.release();
- return bytes_transferred;
-}
-
-template<
- class AsyncReadStream,
- class DynamicBuffer,
- bool isRequest, class Body, class Allocator,
- class ReadHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(
- ReadHandler, void(error_code, std::size_t))
-async_read(
- AsyncReadStream& stream,
- DynamicBuffer& buffer,
- message<isRequest, Body, basic_fields<Allocator>>& msg,
- ReadHandler&& handler)
-{
- static_assert(is_async_read_stream<AsyncReadStream>::value,
- "AsyncReadStream requirements not met");
- static_assert(
- boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
- "DynamicBuffer requirements not met");
- static_assert(is_body<Body>::value,
- "Body requirements not met");
- static_assert(is_body_reader<Body>::value,
- "BodyReader requirements not met");
- BOOST_BEAST_HANDLER_INIT(
- ReadHandler, void(error_code, std::size_t));
- detail::read_msg_op<
- AsyncReadStream,
- DynamicBuffer,
- isRequest, Body, Allocator,
- BOOST_ASIO_HANDLER_TYPE(
- ReadHandler, void(error_code, std::size_t))>{
- std::move(init.completion_handler), stream, buffer, msg}(
- {}, 0, false);
- return init.result.get();
-}
-
-} // http
-} // beast
-} // boost
-
-#endif
diff --git a/boost/beast/http/impl/rfc7230.hpp b/boost/beast/http/impl/rfc7230.hpp
new file mode 100644
index 0000000000..11e424b4d1
--- /dev/null
+++ b/boost/beast/http/impl/rfc7230.hpp
@@ -0,0 +1,423 @@
+//
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/beast
+//
+
+#ifndef BOOST_BEAST_HTTP_IMPL_RFC7230_HPP
+#define BOOST_BEAST_HTTP_IMPL_RFC7230_HPP
+
+#include <boost/beast/http/detail/rfc7230.hpp>
+#include <iterator>
+
+namespace boost {
+namespace beast {
+namespace http {
+
+class param_list::const_iterator
+{
+ using iter_type = string_view::const_iterator;
+
+ std::string s_;
+ detail::param_iter pi_;
+
+public:
+ using value_type = param_list::value_type;
+ using pointer = value_type const*;
+ using reference = value_type const&;
+ using difference_type = std::ptrdiff_t;
+ using iterator_category = std::input_iterator_tag;
+
+ const_iterator() = default;
+
+ bool
+ operator==(const_iterator const& other) const
+ {
+ return
+ other.pi_.it == pi_.it &&
+ other.pi_.last == pi_.last &&
+ other.pi_.first == pi_.first;
+ }
+
+ bool
+ operator!=(const_iterator const& other) const
+ {
+ return !(*this == other);
+ }
+
+ reference
+ operator*() const
+ {
+ return pi_.v;
+ }
+
+ pointer
+ operator->() const
+ {
+ return &*(*this);
+ }
+
+ const_iterator&
+ operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ const_iterator
+ operator++(int)
+ {
+ auto temp = *this;
+ ++(*this);
+ return temp;
+ }
+
+private:
+ friend class param_list;
+
+ const_iterator(iter_type first, iter_type last)
+ {
+ pi_.it = first;
+ pi_.first = first;
+ pi_.last = last;
+ increment();
+ }
+
+ BOOST_BEAST_DECL
+ static
+ std::string
+ unquote(string_view sr);
+
+ BOOST_BEAST_DECL
+ void
+ increment();
+};
+
+inline
+auto
+param_list::
+begin() const ->
+ const_iterator
+{
+ return const_iterator{s_.begin(), s_.end()};
+}
+
+inline
+auto
+param_list::
+end() const ->
+ const_iterator
+{
+ return const_iterator{s_.end(), s_.end()};
+}
+
+inline
+auto
+param_list::
+cbegin() const ->
+ const_iterator
+{
+ return const_iterator{s_.begin(), s_.end()};
+}
+
+inline
+auto
+param_list::
+cend() const ->
+ const_iterator
+{
+ return const_iterator{s_.end(), s_.end()};
+}
+
+//------------------------------------------------------------------------------
+
+class ext_list::const_iterator
+{
+ ext_list::value_type v_;
+ iter_type it_;
+ iter_type first_;
+ iter_type last_;
+
+public:
+ using value_type = ext_list::value_type;
+ using pointer = value_type const*;
+ using reference = value_type const&;
+ using difference_type = std::ptrdiff_t;
+ using iterator_category = std::forward_iterator_tag;
+
+ const_iterator() = default;
+
+ bool
+ operator==(const_iterator const& other) const
+ {
+ return
+ other.it_ == it_ &&
+ other.first_ == first_ &&
+ other.last_ == last_;
+ }
+
+ bool
+ operator!=(const_iterator const& other) const
+ {
+ return !(*this == other);
+ }
+
+ reference
+ operator*() const
+ {
+ return v_;
+ }
+
+ pointer
+ operator->() const
+ {
+ return &*(*this);
+ }
+
+ const_iterator&
+ operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ const_iterator
+ operator++(int)
+ {
+ auto temp = *this;
+ ++(*this);
+ return temp;
+ }
+
+private:
+ friend class ext_list;
+
+ const_iterator(iter_type begin, iter_type end)
+ {
+ it_ = begin;
+ first_ = begin;
+ last_ = end;
+ increment();
+ }
+
+ BOOST_BEAST_DECL
+ void
+ increment();
+};
+
+inline
+auto
+ext_list::
+begin() const ->
+ const_iterator
+{
+ return const_iterator{s_.begin(), s_.end()};
+}
+
+inline
+auto
+ext_list::
+end() const ->
+ const_iterator
+{
+ return const_iterator{s_.end(), s_.end()};
+}
+
+inline
+auto
+ext_list::
+cbegin() const ->
+ const_iterator
+{
+ return const_iterator{s_.begin(), s_.end()};
+}
+
+inline
+auto
+ext_list::
+cend() const ->
+ const_iterator
+{
+ return const_iterator{s_.end(), s_.end()};
+}
+
+template<class T>
+auto
+ext_list::
+find(T const& s) ->
+ const_iterator
+{
+ return std::find_if(begin(), end(),
+ [&s](value_type const& v)
+ {
+ return iequals(s, v.first);
+ });
+}
+
+template<class T>
+bool
+ext_list::
+exists(T const& s)
+{
+ return find(s) != end();
+}
+
+
+//------------------------------------------------------------------------------
+
+class token_list::const_iterator
+{
+ token_list::value_type v_;
+ iter_type it_;
+ iter_type first_;
+ iter_type last_;
+
+public:
+ using value_type = token_list::value_type;
+ using pointer = value_type const*;
+ using reference = value_type const&;
+ using difference_type = std::ptrdiff_t;
+ using iterator_category = std::forward_iterator_tag;
+
+ const_iterator() = default;
+
+ bool
+ operator==(const_iterator const& other) const
+ {
+ return
+ other.it_ == it_ &&
+ other.first_ == first_ &&
+ other.last_ == last_;
+ }
+
+ bool
+ operator!=(const_iterator const& other) const
+ {
+ return !(*this == other);
+ }
+
+ reference
+ operator*() const
+ {
+ return v_;
+ }
+
+ pointer
+ operator->() const
+ {
+ return &*(*this);
+ }
+
+ const_iterator&
+ operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ const_iterator
+ operator++(int)
+ {
+ auto temp = *this;
+ ++(*this);
+ return temp;
+ }
+
+private:
+ friend class token_list;
+
+ const_iterator(iter_type begin, iter_type end)
+ {
+ it_ = begin;
+ first_ = begin;
+ last_ = end;
+ increment();
+ }
+
+ BOOST_BEAST_DECL
+ void
+ increment();
+};
+
+inline
+auto
+token_list::
+begin() const ->
+ const_iterator
+{
+ return const_iterator{s_.begin(), s_.end()};
+}
+
+inline
+auto
+token_list::
+end() const ->
+ const_iterator
+{
+ return const_iterator{s_.end(), s_.end()};
+}
+
+inline
+auto
+token_list::
+cbegin() const ->
+ const_iterator
+{
+ return const_iterator{s_.begin(), s_.end()};
+}
+
+inline
+auto
+token_list::
+cend() const ->
+ const_iterator
+{
+ return const_iterator{s_.end(), s_.end()};
+}
+
+template<class T>
+bool
+token_list::
+exists(T const& s)
+{
+ return std::find_if(begin(), end(),
+ [&s](value_type const& v)
+ {
+ return iequals(s, v);
+ }
+ ) != end();
+}
+
+template<class Policy>
+bool
+validate_list(detail::basic_parsed_list<
+ Policy> const& list)
+{
+ auto const last = list.end();
+ auto it = list.begin();
+ if(it.error())
+ return false;
+ while(it != last)
+ {
+ ++it;
+ if(it.error())
+ return false;
+ if(it == last)
+ break;
+ }
+ return true;
+}
+
+} // http
+} // beast
+} // boost
+
+#ifdef BOOST_BEAST_HEADER_ONLY
+#include <boost/beast/http/impl/rfc7230.ipp>
+#endif
+
+#endif
+
diff --git a/boost/beast/http/impl/rfc7230.ipp b/boost/beast/http/impl/rfc7230.ipp
index 96ec902ceb..cf60cefa36 100644
--- a/boost/beast/http/impl/rfc7230.ipp
+++ b/boost/beast/http/impl/rfc7230.ipp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,129 +10,13 @@
#ifndef BOOST_BEAST_HTTP_IMPL_RFC7230_IPP
#define BOOST_BEAST_HTTP_IMPL_RFC7230_IPP
-#include <boost/beast/http/detail/rfc7230.hpp>
-#include <iterator>
+#include <boost/beast/http/rfc7230.hpp>
namespace boost {
namespace beast {
namespace http {
-class param_list::const_iterator
-{
- using iter_type = string_view::const_iterator;
-
- std::string s_;
- detail::param_iter pi_;
-
-public:
- using value_type = param_list::value_type;
- using pointer = value_type const*;
- using reference = value_type const&;
- using difference_type = std::ptrdiff_t;
- using iterator_category = std::input_iterator_tag;
-
- const_iterator() = default;
-
- bool
- operator==(const_iterator const& other) const
- {
- return
- other.pi_.it == pi_.it &&
- other.pi_.last == pi_.last &&
- other.pi_.first == pi_.first;
- }
-
- bool
- operator!=(const_iterator const& other) const
- {
- return !(*this == other);
- }
-
- reference
- operator*() const
- {
- return pi_.v;
- }
-
- pointer
- operator->() const
- {
- return &*(*this);
- }
-
- const_iterator&
- operator++()
- {
- increment();
- return *this;
- }
-
- const_iterator
- operator++(int)
- {
- auto temp = *this;
- ++(*this);
- return temp;
- }
-
-private:
- friend class param_list;
-
- const_iterator(iter_type first, iter_type last)
- {
- pi_.it = first;
- pi_.first = first;
- pi_.last = last;
- increment();
- }
-
- template<class = void>
- static
- std::string
- unquote(string_view sr);
-
- template<class = void>
- void
- increment();
-};
-
-inline
-auto
-param_list::
-begin() const ->
- const_iterator
-{
- return const_iterator{s_.begin(), s_.end()};
-}
-
-inline
-auto
-param_list::
-end() const ->
- const_iterator
-{
- return const_iterator{s_.end(), s_.end()};
-}
-
-inline
-auto
-param_list::
-cbegin() const ->
- const_iterator
-{
- return const_iterator{s_.begin(), s_.end()};
-}
-
-inline
-auto
-param_list::
-cend() const ->
- const_iterator
-{
- return const_iterator{s_.end(), s_.end()};
-}
-template<class>
std::string
param_list::const_iterator::
unquote(string_view sr)
@@ -151,7 +35,6 @@ unquote(string_view sr)
return s;
}
-template<class>
void
param_list::const_iterator::
increment()
@@ -172,140 +55,6 @@ increment()
}
}
-//------------------------------------------------------------------------------
-
-class ext_list::const_iterator
-{
- ext_list::value_type v_;
- iter_type it_;
- iter_type first_;
- iter_type last_;
-
-public:
- using value_type = ext_list::value_type;
- using pointer = value_type const*;
- using reference = value_type const&;
- using difference_type = std::ptrdiff_t;
- using iterator_category = std::forward_iterator_tag;
-
- const_iterator() = default;
-
- bool
- operator==(const_iterator const& other) const
- {
- return
- other.it_ == it_ &&
- other.first_ == first_ &&
- other.last_ == last_;
- }
-
- bool
- operator!=(const_iterator const& other) const
- {
- return !(*this == other);
- }
-
- reference
- operator*() const
- {
- return v_;
- }
-
- pointer
- operator->() const
- {
- return &*(*this);
- }
-
- const_iterator&
- operator++()
- {
- increment();
- return *this;
- }
-
- const_iterator
- operator++(int)
- {
- auto temp = *this;
- ++(*this);
- return temp;
- }
-
-private:
- friend class ext_list;
-
- const_iterator(iter_type begin, iter_type end)
- {
- it_ = begin;
- first_ = begin;
- last_ = end;
- increment();
- }
-
- template<class = void>
- void
- increment();
-};
-
-inline
-auto
-ext_list::
-begin() const ->
- const_iterator
-{
- return const_iterator{s_.begin(), s_.end()};
-}
-
-inline
-auto
-ext_list::
-end() const ->
- const_iterator
-{
- return const_iterator{s_.end(), s_.end()};
-}
-
-inline
-auto
-ext_list::
-cbegin() const ->
- const_iterator
-{
- return const_iterator{s_.begin(), s_.end()};
-}
-
-inline
-auto
-ext_list::
-cend() const ->
- const_iterator
-{
- return const_iterator{s_.end(), s_.end()};
-}
-
-template<class T>
-auto
-ext_list::
-find(T const& s) ->
- const_iterator
-{
- return std::find_if(begin(), end(),
- [&s](value_type const& v)
- {
- return iequals(s, v.first);
- });
-}
-
-template<class T>
-bool
-ext_list::
-exists(T const& s)
-{
- return find(s) != end();
-}
-
-template<class>
void
ext_list::const_iterator::
increment()
@@ -316,7 +65,7 @@ increment()
param-list = *( OWS ";" OWS param )
param = token OWS "=" OWS ( token / quoted-string )
- chunked;a=b;i=j,gzip;windowBits=12
+ chunked;a=b;i=j;gzip;windowBits=12
x,y
,,,,,chameleon
*/
@@ -350,6 +99,8 @@ increment()
}
v_.first = string_view{&*p0,
static_cast<std::size_t>(it_ - p0)};
+ if (it_ == last_)
+ return;
detail::param_iter pi;
pi.it = it_;
pi.first = it_;
@@ -372,119 +123,6 @@ increment()
}
}
-//------------------------------------------------------------------------------
-
-class token_list::const_iterator
-{
- token_list::value_type v_;
- iter_type it_;
- iter_type first_;
- iter_type last_;
-
-public:
- using value_type = token_list::value_type;
- using pointer = value_type const*;
- using reference = value_type const&;
- using difference_type = std::ptrdiff_t;
- using iterator_category = std::forward_iterator_tag;
-
- const_iterator() = default;
-
- bool
- operator==(const_iterator const& other) const
- {
- return
- other.it_ == it_ &&
- other.first_ == first_ &&
- other.last_ == last_;
- }
-
- bool
- operator!=(const_iterator const& other) const
- {
- return !(*this == other);
- }
-
- reference
- operator*() const
- {
- return v_;
- }
-
- pointer
- operator->() const
- {
- return &*(*this);
- }
-
- const_iterator&
- operator++()
- {
- increment();
- return *this;
- }
-
- const_iterator
- operator++(int)
- {
- auto temp = *this;
- ++(*this);
- return temp;
- }
-
-private:
- friend class token_list;
-
- const_iterator(iter_type begin, iter_type end)
- {
- it_ = begin;
- first_ = begin;
- last_ = end;
- increment();
- }
-
- template<class = void>
- void
- increment();
-};
-
-inline
-auto
-token_list::
-begin() const ->
- const_iterator
-{
- return const_iterator{s_.begin(), s_.end()};
-}
-
-inline
-auto
-token_list::
-end() const ->
- const_iterator
-{
- return const_iterator{s_.end(), s_.end()};
-}
-
-inline
-auto
-token_list::
-cbegin() const ->
- const_iterator
-{
- return const_iterator{s_.begin(), s_.end()};
-}
-
-inline
-auto
-token_list::
-cend() const ->
- const_iterator
-{
- return const_iterator{s_.end(), s_.end()};
-}
-
-template<class>
void
token_list::const_iterator::
increment()
@@ -531,42 +169,8 @@ increment()
}
}
-template<class T>
-bool
-token_list::
-exists(T const& s)
-{
- return std::find_if(begin(), end(),
- [&s](value_type const& v)
- {
- return iequals(s, v);
- }
- ) != end();
-}
-
-template<class Policy>
-bool
-validate_list(detail::basic_parsed_list<
- Policy> const& list)
-{
- auto const last = list.end();
- auto it = list.begin();
- if(it.error())
- return false;
- while(it != last)
- {
- ++it;
- if(it.error())
- return false;
- if(it == last)
- break;
- }
- return true;
-}
-
} // http
} // beast
} // boost
-#endif
-
+#endif // BOOST_BEAST_HTTP_IMPL_RFC7230_IPP
diff --git a/boost/beast/http/impl/serializer.ipp b/boost/beast/http/impl/serializer.hpp
index b9e7d26bdb..39efb482d0 100644
--- a/boost/beast/http/impl/serializer.ipp
+++ b/boost/beast/http/impl/serializer.hpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,9 +7,10 @@
// Official repository: https://github.com/boostorg/beast
//
-#ifndef BOOST_BEAST_HTTP_IMPL_SERIALIZER_IPP
-#define BOOST_BEAST_HTTP_IMPL_SERIALIZER_IPP
+#ifndef BOOST_BEAST_HTTP_IMPL_SERIALIZER_HPP
+#define BOOST_BEAST_HTTP_IMPL_SERIALIZER_HPP
+#include <boost/beast/core/buffer_traits.hpp>
#include <boost/beast/core/detail/buffers_ref.hpp>
#include <boost/beast/http/error.hpp>
#include <boost/beast/http/status.hpp>
@@ -70,7 +71,6 @@ void
serializer<isRequest, Body, Fields>::
next(error_code& ec, Visit&& visit)
{
- using boost::asio::buffer_size;
switch(s_)
{
case do_construct:
@@ -165,21 +165,21 @@ next(error_code& ec, Visit&& visit)
v_.template emplace<7>(
boost::in_place_init,
fwr_->get(),
- buffer_size(result->first),
- boost::asio::const_buffer{nullptr, 0},
+ buffer_bytes(result->first),
+ net::const_buffer{nullptr, 0},
chunk_crlf{},
result->first,
chunk_crlf{},
detail::chunk_last(),
- boost::asio::const_buffer{nullptr, 0},
+ net::const_buffer{nullptr, 0},
chunk_crlf{});
goto go_all_c;
}
v_.template emplace<4>(
boost::in_place_init,
fwr_->get(),
- buffer_size(result->first),
- boost::asio::const_buffer{nullptr, 0},
+ buffer_bytes(result->first),
+ net::const_buffer{nullptr, 0},
chunk_crlf{},
result->first,
chunk_crlf{});
@@ -217,20 +217,20 @@ next(error_code& ec, Visit&& visit)
// do it all in one buffer
v_.template emplace<6>(
boost::in_place_init,
- buffer_size(result->first),
- boost::asio::const_buffer{nullptr, 0},
+ buffer_bytes(result->first),
+ net::const_buffer{nullptr, 0},
chunk_crlf{},
result->first,
chunk_crlf{},
detail::chunk_last(),
- boost::asio::const_buffer{nullptr, 0},
+ net::const_buffer{nullptr, 0},
chunk_crlf{});
goto go_body_final_c;
}
v_.template emplace<5>(
boost::in_place_init,
- buffer_size(result->first),
- boost::asio::const_buffer{nullptr, 0},
+ buffer_bytes(result->first),
+ net::const_buffer{nullptr, 0},
chunk_crlf{},
result->first,
chunk_crlf{});
@@ -261,7 +261,7 @@ next(error_code& ec, Visit&& visit)
v_.template emplace<8>(
boost::in_place_init,
detail::chunk_last(),
- boost::asio::const_buffer{nullptr, 0},
+ net::const_buffer{nullptr, 0},
chunk_crlf{});
s_ = do_final_c + 1;
BOOST_FALLTHROUGH;
@@ -289,14 +289,13 @@ void
serializer<isRequest, Body, Fields>::
consume(std::size_t n)
{
- using boost::asio::buffer_size;
switch(s_)
{
case do_header:
BOOST_ASSERT(
- n <= buffer_size(v_.template get<2>()));
+ n <= buffer_bytes(v_.template get<2>()));
v_.template get<2>().consume(n);
- if(buffer_size(v_.template get<2>()) > 0)
+ if(buffer_bytes(v_.template get<2>()) > 0)
break;
header_done_ = true;
v_.reset();
@@ -307,9 +306,9 @@ consume(std::size_t n)
case do_header_only:
BOOST_ASSERT(
- n <= buffer_size(v_.template get<1>()));
+ n <= buffer_bytes(v_.template get<1>()));
v_.template get<1>().consume(n);
- if(buffer_size(v_.template get<1>()) > 0)
+ if(buffer_bytes(v_.template get<1>()) > 0)
break;
fwr_ = boost::none;
header_done_ = true;
@@ -321,9 +320,9 @@ consume(std::size_t n)
case do_body + 2:
{
BOOST_ASSERT(
- n <= buffer_size(v_.template get<3>()));
+ n <= buffer_bytes(v_.template get<3>()));
v_.template get<3>().consume(n);
- if(buffer_size(v_.template get<3>()) > 0)
+ if(buffer_bytes(v_.template get<3>()) > 0)
break;
v_.reset();
if(! more_)
@@ -336,9 +335,9 @@ consume(std::size_t n)
case do_header_c:
BOOST_ASSERT(
- n <= buffer_size(v_.template get<4>()));
+ n <= buffer_bytes(v_.template get<4>()));
v_.template get<4>().consume(n);
- if(buffer_size(v_.template get<4>()) > 0)
+ if(buffer_bytes(v_.template get<4>()) > 0)
break;
header_done_ = true;
v_.reset();
@@ -351,9 +350,9 @@ consume(std::size_t n)
case do_header_only_c:
{
BOOST_ASSERT(
- n <= buffer_size(v_.template get<1>()));
+ n <= buffer_bytes(v_.template get<1>()));
v_.template get<1>().consume(n);
- if(buffer_size(v_.template get<1>()) > 0)
+ if(buffer_bytes(v_.template get<1>()) > 0)
break;
fwr_ = boost::none;
header_done_ = true;
@@ -368,9 +367,9 @@ consume(std::size_t n)
case do_body_c + 2:
BOOST_ASSERT(
- n <= buffer_size(v_.template get<5>()));
+ n <= buffer_bytes(v_.template get<5>()));
v_.template get<5>().consume(n);
- if(buffer_size(v_.template get<5>()) > 0)
+ if(buffer_bytes(v_.template get<5>()) > 0)
break;
v_.reset();
if(more_)
@@ -382,9 +381,9 @@ consume(std::size_t n)
case do_body_final_c:
{
BOOST_ASSERT(
- n <= buffer_size(v_.template get<6>()));
+ n <= buffer_bytes(v_.template get<6>()));
v_.template get<6>().consume(n);
- if(buffer_size(v_.template get<6>()) > 0)
+ if(buffer_bytes(v_.template get<6>()) > 0)
break;
v_.reset();
s_ = do_complete;
@@ -394,9 +393,9 @@ consume(std::size_t n)
case do_all_c:
{
BOOST_ASSERT(
- n <= buffer_size(v_.template get<7>()));
+ n <= buffer_bytes(v_.template get<7>()));
v_.template get<7>().consume(n);
- if(buffer_size(v_.template get<7>()) > 0)
+ if(buffer_bytes(v_.template get<7>()) > 0)
break;
header_done_ = true;
v_.reset();
@@ -405,9 +404,9 @@ consume(std::size_t n)
}
case do_final_c + 1:
- BOOST_ASSERT(buffer_size(v_.template get<8>()));
+ BOOST_ASSERT(buffer_bytes(v_.template get<8>()));
v_.template get<8>().consume(n);
- if(buffer_size(v_.template get<8>()) > 0)
+ if(buffer_bytes(v_.template get<8>()) > 0)
break;
v_.reset();
goto go_complete;
diff --git a/boost/beast/http/impl/status.ipp b/boost/beast/http/impl/status.ipp
index 7d37919423..2a61acd5c9 100644
--- a/boost/beast/http/impl/status.ipp
+++ b/boost/beast/http/impl/status.ipp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,15 +10,13 @@
#ifndef BOOST_BEAST_HTTP_IMPL_STATUS_IPP
#define BOOST_BEAST_HTTP_IMPL_STATUS_IPP
-#include <boost/beast/core/detail/config.hpp>
+#include <boost/beast/http/status.hpp>
#include <boost/throw_exception.hpp>
namespace boost {
namespace beast {
namespace http {
-namespace detail {
-template<class = void>
status
int_to_status(unsigned v)
{
@@ -107,9 +105,30 @@ int_to_status(unsigned v)
return status::unknown;
}
-template<class = void>
+status_class
+to_status_class(unsigned v)
+{
+ switch(v / 100)
+ {
+ case 1: return status_class::informational;
+ case 2: return status_class::successful;
+ case 3: return status_class::redirection;
+ case 4: return status_class::client_error;
+ case 5: return status_class::server_error;
+ default:
+ break;
+ }
+ return status_class::unknown;
+}
+
+status_class
+to_status_class(status v)
+{
+ return to_status_class(static_cast<int>(v));
+}
+
string_view
-status_to_string(unsigned v)
+obsolete_reason(status v)
{
switch(static_cast<status>(v))
{
@@ -190,55 +209,6 @@ status_to_string(unsigned v)
return "<unknown-status>";
}
-template<class = void>
-status_class
-to_status_class(unsigned v)
-{
- switch(v / 100)
- {
- case 1: return status_class::informational;
- case 2: return status_class::successful;
- case 3: return status_class::redirection;
- case 4: return status_class::client_error;
- case 5: return status_class::server_error;
- default:
- break;
- }
- return status_class::unknown;
-}
-
-} // detail
-
-inline
-status
-int_to_status(unsigned v)
-{
- return detail::int_to_status(v);
-}
-
-inline
-status_class
-to_status_class(unsigned v)
-{
- return detail::to_status_class(v);
-}
-
-inline
-status_class
-to_status_class(status v)
-{
- return to_status_class(static_cast<int>(v));
-}
-
-inline
-string_view
-obsolete_reason(status v)
-{
- return detail::status_to_string(
- static_cast<unsigned>(v));
-}
-
-inline
std::ostream&
operator<<(std::ostream& os, status v)
{
diff --git a/boost/beast/http/impl/verb.ipp b/boost/beast/http/impl/verb.ipp
index 36a1734c33..20ef47c551 100644
--- a/boost/beast/http/impl/verb.ipp
+++ b/boost/beast/http/impl/verb.ipp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,7 +10,7 @@
#ifndef BOOST_BEAST_HTTP_IMPL_VERB_IPP
#define BOOST_BEAST_HTTP_IMPL_VERB_IPP
-#include <boost/beast/core/detail/config.hpp>
+#include <boost/beast/http/verb.hpp>
#include <boost/throw_exception.hpp>
#include <stdexcept>
@@ -18,12 +18,8 @@ namespace boost {
namespace beast {
namespace http {
-namespace detail {
-
-template<class = void>
-inline
string_view
-verb_to_string(verb v)
+to_string(verb v)
{
switch(v)
{
@@ -74,7 +70,6 @@ verb_to_string(verb v)
BOOST_THROW_EXCEPTION(std::invalid_argument{"unknown verb"});
}
-template<class = void>
verb
string_to_verb(string_view v)
{
@@ -314,22 +309,6 @@ string_to_verb(string_view v)
return verb::unknown;
}
-} // detail
-
-inline
-string_view
-to_string(verb v)
-{
- return detail::verb_to_string(v);
-}
-
-inline
-verb
-string_to_verb(string_view s)
-{
- return detail::string_to_verb(s);
-}
-
} // http
} // beast
} // boost
diff --git a/boost/beast/http/impl/write.ipp b/boost/beast/http/impl/write.hpp
index bbada07024..5636ce92f8 100644
--- a/boost/beast/http/impl/write.ipp
+++ b/boost/beast/http/impl/write.hpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,21 +7,16 @@
// Official repository: https://github.com/boostorg/beast
//
-#ifndef BOOST_BEAST_HTTP_IMPL_WRITE_IPP
-#define BOOST_BEAST_HTTP_IMPL_WRITE_IPP
+#ifndef BOOST_BEAST_HTTP_IMPL_WRITE_HPP
+#define BOOST_BEAST_HTTP_IMPL_WRITE_HPP
#include <boost/beast/http/type_traits.hpp>
+#include <boost/beast/core/async_base.hpp>
#include <boost/beast/core/bind_handler.hpp>
+#include <boost/beast/core/buffers_range.hpp>
#include <boost/beast/core/ostream.hpp>
-#include <boost/beast/core/handler_ptr.hpp>
-#include <boost/beast/core/type_traits.hpp>
-#include <boost/beast/core/detail/config.hpp>
-#include <boost/asio/associated_allocator.hpp>
-#include <boost/asio/associated_executor.hpp>
+#include <boost/beast/core/stream_traits.hpp>
#include <boost/asio/coroutine.hpp>
-#include <boost/asio/executor_work_guard.hpp>
-#include <boost/asio/handler_continuation_hook.hpp>
-#include <boost/asio/handler_invoke_hook.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/write.hpp>
#include <boost/optional.hpp>
@@ -35,15 +30,15 @@ namespace http {
namespace detail {
template<
- class Stream, class Handler,
+ class Handler,
+ class Stream,
bool isRequest, class Body, class Fields>
class write_some_op
+ : public beast::async_base<
+ Handler, beast::executor_type<Stream>>
{
Stream& s_;
- boost::asio::executor_work_guard<decltype(
- std::declval<Stream&>().get_executor())> wg_;
serializer<isRequest,Body, Fields>& sr_;
- Handler h_;
class lambda
{
@@ -60,122 +55,74 @@ class write_some_op
template<class ConstBufferSequence>
void
- operator()(error_code& ec,
+ operator()(
+ error_code& ec,
ConstBufferSequence const& buffers)
{
invoked = true;
- ec.assign(0, ec.category());
- return op_.s_.async_write_some(
+ ec = {};
+ op_.s_.async_write_some(
buffers, std::move(op_));
}
};
public:
- write_some_op(write_some_op&&) = default;
- write_some_op(write_some_op const&) = delete;
-
- template<class DeducedHandler>
- write_some_op(DeducedHandler&& h, Stream& s,
- serializer<isRequest, Body, Fields>& sr)
- : s_(s)
- , wg_(s_.get_executor())
+ template<class Handler_>
+ write_some_op(
+ Handler_&& h,
+ Stream& s,
+ serializer<isRequest, Body, Fields>& sr)
+ : async_base<
+ Handler, beast::executor_type<Stream>>(
+ std::forward<Handler_>(h), s.get_executor())
+ , s_(s)
, sr_(sr)
- , h_(std::forward<DeducedHandler>(h))
{
+ (*this)();
}
- using allocator_type =
- boost::asio::associated_allocator_t<Handler>;
-
- allocator_type
- get_allocator() const noexcept
+ void
+ operator()()
{
- return (boost::asio::get_associated_allocator)(h_);
- }
-
- using executor_type = boost::asio::associated_executor_t<
- Handler, decltype(std::declval<Stream&>().get_executor())>;
+ error_code ec;
+ if(! sr_.is_done())
+ {
+ lambda f{*this};
+ sr_.next(ec, f);
+ if(ec)
+ {
+ BOOST_ASSERT(! f.invoked);
+ return net::post(
+ s_.get_executor(),
+ beast::bind_front_handler(
+ std::move(*this), ec, 0));
+ }
+ if(f.invoked)
+ {
+ // *this is now moved-from,
+ return;
+ }
+ // What else could it be?
+ BOOST_ASSERT(sr_.is_done());
+ }
- executor_type
- get_executor() const noexcept
- {
- return (boost::asio::get_associated_executor)(
- h_, s_.get_executor());
+ return net::post(
+ s_.get_executor(),
+ beast::bind_front_handler(
+ std::move(*this), ec, 0));
}
void
- operator()();
-
- void
operator()(
error_code ec,
- std::size_t bytes_transferred);
-
- friend
- bool asio_handler_is_continuation(write_some_op* op)
+ std::size_t bytes_transferred)
{
- using boost::asio::asio_handler_is_continuation;
- return asio_handler_is_continuation(
- std::addressof(op->h_));
- }
-
- template<class Function>
- friend
- void asio_handler_invoke(Function&& f, write_some_op* op)
- {
- using boost::asio::asio_handler_invoke;
- asio_handler_invoke(f, std::addressof(op->h_));
+ if(! ec)
+ sr_.consume(bytes_transferred);
+ this->complete_now(ec, bytes_transferred);
}
};
-template<
- class Stream, class Handler,
- bool isRequest, class Body, class Fields>
-void
-write_some_op<
- Stream, Handler, isRequest, Body, Fields>::
-operator()()
-{
- error_code ec;
- if(! sr_.is_done())
- {
- lambda f{*this};
- sr_.next(ec, f);
- if(ec)
- {
- BOOST_ASSERT(! f.invoked);
- return boost::asio::post(
- s_.get_executor(),
- bind_handler(std::move(*this), ec, 0));
- }
- if(f.invoked)
- {
- // *this has been moved from,
- // cannot access members here.
- return;
- }
- // What else could it be?
- BOOST_ASSERT(sr_.is_done());
- }
- return boost::asio::post(
- s_.get_executor(),
- bind_handler(std::move(*this), ec, 0));
-}
-
-template<
- class Stream, class Handler,
- bool isRequest, class Body, class Fields>
-void
-write_some_op<
- Stream, Handler, isRequest, Body, Fields>::
-operator()(
- error_code ec, std::size_t bytes_transferred)
-{
- if(! ec)
- sr_.consume(bytes_transferred);
- h_(ec, bytes_transferred);
-}
-
//------------------------------------------------------------------------------
struct serializer_is_header_done
@@ -205,221 +152,235 @@ struct serializer_is_done
//------------------------------------------------------------------------------
template<
- class Stream, class Handler, class Predicate,
+ class Handler,
+ class Stream,
+ class Predicate,
bool isRequest, class Body, class Fields>
-class write_op : public boost::asio::coroutine
+class write_op
+ : public beast::async_base<
+ Handler, beast::executor_type<Stream>>
+ , public net::coroutine
{
Stream& s_;
- boost::asio::executor_work_guard<decltype(
- std::declval<Stream&>().get_executor())> wg_;
serializer<isRequest, Body, Fields>& sr_;
std::size_t bytes_transferred_ = 0;
- Handler h_;
- bool cont_;
public:
- write_op(write_op&&) = default;
- write_op(write_op const&) = delete;
-
- template<class DeducedHandler>
- write_op(DeducedHandler&& h, Stream& s,
- serializer<isRequest, Body, Fields>& sr)
- : s_(s)
- , wg_(s_.get_executor())
+ template<class Handler_>
+ write_op(
+ Handler_&& h,
+ Stream& s,
+ serializer<isRequest, Body, Fields>& sr)
+ : async_base<
+ Handler, beast::executor_type<Stream>>(
+ std::forward<Handler_>(h), s.get_executor())
+ , s_(s)
, sr_(sr)
- , h_(std::forward<DeducedHandler>(h))
- , cont_([&]
- {
- using boost::asio::asio_handler_is_continuation;
- return asio_handler_is_continuation(
- std::addressof(h_));
- }())
{
- }
-
- using allocator_type =
- boost::asio::associated_allocator_t<Handler>;
-
- allocator_type
- get_allocator() const noexcept
- {
- return (boost::asio::get_associated_allocator)(h_);
- }
-
- using executor_type = boost::asio::associated_executor_t<
- Handler, decltype(std::declval<Stream&>().get_executor())>;
-
- executor_type
- get_executor() const noexcept
- {
- return (boost::asio::get_associated_executor)(
- h_, s_.get_executor());
+ (*this)();
}
void
operator()(
error_code ec = {},
- std::size_t bytes_transferred = 0);
-
- friend
- bool asio_handler_is_continuation(write_op* op)
- {
- return op->cont_;
- }
-
- template<class Function>
- friend
- void asio_handler_invoke(Function&& f, write_op* op)
- {
- using boost::asio::asio_handler_invoke;
- asio_handler_invoke(f, std::addressof(op->h_));
- }
-};
-
-template<
- class Stream, class Handler, class Predicate,
- bool isRequest, class Body, class Fields>
-void
-write_op<Stream, Handler, Predicate,
- isRequest, Body, Fields>::
-operator()(
- error_code ec,
- std::size_t bytes_transferred)
-{
- BOOST_ASIO_CORO_REENTER(*this)
+ std::size_t bytes_transferred = 0)
{
- if(Predicate{}(sr_))
+ BOOST_ASIO_CORO_REENTER(*this)
{
- BOOST_ASIO_CORO_YIELD
- boost::asio::post(
- s_.get_executor(),
- bind_handler(std::move(*this)));
- goto upcall;
- }
- for(;;)
- {
- BOOST_ASIO_CORO_YIELD
- beast::http::async_write_some(
- s_, sr_, std::move(*this));
- bytes_transferred_ += bytes_transferred;
- if(ec)
- goto upcall;
if(Predicate{}(sr_))
- break;
- cont_ = true;
+ {
+ BOOST_ASIO_CORO_YIELD
+ net::post(
+ s_.get_executor(),
+ std::move(*this));
+ goto upcall;
+ }
+ for(;;)
+ {
+ BOOST_ASIO_CORO_YIELD
+ beast::http::async_write_some(
+ s_, sr_, std::move(*this));
+ bytes_transferred_ += bytes_transferred;
+ if(ec)
+ goto upcall;
+ if(Predicate{}(sr_))
+ break;
+ }
+ upcall:
+ this->complete_now(ec, bytes_transferred_);
}
- upcall:
- h_(ec, bytes_transferred_);
}
-}
+};
//------------------------------------------------------------------------------
-template<class Stream, class Handler,
+template<
+ class Handler,
+ class Stream,
bool isRequest, class Body, class Fields>
class write_msg_op
+ : public beast::stable_async_base<
+ Handler, beast::executor_type<Stream>>
{
- struct data
- {
- Stream& s;
- boost::asio::executor_work_guard<decltype(
- std::declval<Stream&>().get_executor())> wg;
- serializer<isRequest, Body, Fields> sr;
-
- data(Handler const&, Stream& s_, message<
- isRequest, Body, Fields>& m_)
- : s(s_)
- , wg(s.get_executor())
- , sr(m_)
- {
- }
-
- data(Handler const&, Stream& s_, message<
- isRequest, Body, Fields> const& m_)
- : s(s_)
- , wg(s.get_executor())
- , sr(m_)
- {
- }
- };
-
- handler_ptr<data, Handler> d_;
+ Stream& s_;
+ serializer<isRequest, Body, Fields>& sr_;
public:
- write_msg_op(write_msg_op&&) = default;
- write_msg_op(write_msg_op const&) = delete;
-
- template<class DeducedHandler, class... Args>
- write_msg_op(DeducedHandler&& h, Stream& s, Args&&... args)
- : d_(std::forward<DeducedHandler>(h),
- s, std::forward<Args>(args)...)
- {
+ template<
+ class Handler_,
+ class... Args>
+ write_msg_op(
+ Handler_&& h,
+ Stream& s,
+ Args&&... args)
+ : stable_async_base<
+ Handler, beast::executor_type<Stream>>(
+ std::forward<Handler_>(h), s.get_executor())
+ , s_(s)
+ , sr_(beast::allocate_stable<
+ serializer<isRequest, Body, Fields>>(
+ *this, std::forward<Args>(args)...))
+ {
+ (*this)();
}
- using allocator_type =
- boost::asio::associated_allocator_t<Handler>;
-
- allocator_type
- get_allocator() const noexcept
+ void
+ operator()()
{
- return (boost::asio::get_associated_allocator)(d_.handler());
+ async_write(s_, sr_, std::move(*this));
}
- using executor_type = boost::asio::associated_executor_t<
- Handler, decltype(std::declval<Stream&>().get_executor())>;
-
- executor_type
- get_executor() const noexcept
+ void
+ operator()(
+ error_code ec, std::size_t bytes_transferred)
{
- return (boost::asio::get_associated_executor)(
- d_.handler(), d_->s.get_executor());
+ this->complete_now(ec, bytes_transferred);
}
+};
- void
- operator()();
-
+struct run_write_some_op
+{
+ template<
+ class WriteHandler,
+ class Stream,
+ bool isRequest, class Body, class Fields>
void
operator()(
- error_code ec, std::size_t bytes_transferred);
-
- friend
- bool asio_handler_is_continuation(write_msg_op* op)
- {
- using boost::asio::asio_handler_is_continuation;
- return asio_handler_is_continuation(
- std::addressof(op->d_.handler()));
+ WriteHandler&& h,
+ Stream* s,
+ serializer<isRequest, Body, Fields>* sr)
+ {
+ // If you get an error on the following line it means
+ // that your handler does not meet the documented type
+ // requirements for the handler.
+
+ static_assert(
+ beast::detail::is_invocable<WriteHandler,
+ void(error_code, std::size_t)>::value,
+ "WriteHandler type requirements not met");
+
+ write_some_op<
+ typename std::decay<WriteHandler>::type,
+ Stream,
+ isRequest, Body, Fields>(
+ std::forward<WriteHandler>(h), *s, *sr);
}
+};
- template<class Function>
- friend
- void asio_handler_invoke(Function&& f, write_msg_op* op)
- {
- using boost::asio::asio_handler_invoke;
- asio_handler_invoke(f, std::addressof(op->d_.handler()));
+struct run_write_op
+{
+ template<
+ class WriteHandler,
+ class Stream,
+ class Predicate,
+ bool isRequest, class Body, class Fields>
+ void
+ operator()(
+ WriteHandler&& h,
+ Stream* s,
+ Predicate const&,
+ serializer<isRequest, Body, Fields>* sr)
+ {
+ // If you get an error on the following line it means
+ // that your handler does not meet the documented type
+ // requirements for the handler.
+
+ static_assert(
+ beast::detail::is_invocable<WriteHandler,
+ void(error_code, std::size_t)>::value,
+ "WriteHandler type requirements not met");
+
+ write_op<
+ typename std::decay<WriteHandler>::type,
+ Stream,
+ Predicate,
+ isRequest, Body, Fields>(
+ std::forward<WriteHandler>(h), *s, *sr);
}
};
-template<class Stream, class Handler,
- bool isRequest, class Body, class Fields>
-void
-write_msg_op<
- Stream, Handler, isRequest, Body, Fields>::
-operator()()
+struct run_write_msg_op
{
- auto& d = *d_;
- return async_write(d.s, d.sr, std::move(*this));
-}
+ template<
+ class WriteHandler,
+ class Stream,
+ bool isRequest, class Body, class Fields,
+ class... Args>
+ void
+ operator()(
+ WriteHandler&& h,
+ Stream* s,
+ message<isRequest, Body, Fields>* m,
+ std::false_type,
+ Args&&... args)
+ {
+ // If you get an error on the following line it means
+ // that your handler does not meet the documented type
+ // requirements for the handler.
+
+ static_assert(
+ beast::detail::is_invocable<WriteHandler,
+ void(error_code, std::size_t)>::value,
+ "WriteHandler type requirements not met");
+
+ write_msg_op<
+ typename std::decay<WriteHandler>::type,
+ Stream,
+ isRequest, Body, Fields>(
+ std::forward<WriteHandler>(h), *s, *m,
+ std::forward<Args>(args)...);
+ }
-template<class Stream, class Handler,
- bool isRequest, class Body, class Fields>
-void
-write_msg_op<
- Stream, Handler, isRequest, Body, Fields>::
-operator()(error_code ec, std::size_t bytes_transferred)
-{
- auto wg = std::move(d_->wg);
- d_.invoke(ec, bytes_transferred);
-}
+ template<
+ class WriteHandler,
+ class Stream,
+ bool isRequest, class Body, class Fields,
+ class... Args>
+ void
+ operator()(
+ WriteHandler&& h,
+ Stream* s,
+ message<isRequest, Body, Fields> const* m,
+ std::true_type,
+ Args&&... args)
+ {
+ // If you get an error on the following line it means
+ // that your handler does not meet the documented type
+ // requirements for the handler.
+
+ static_assert(
+ beast::detail::is_invocable<WriteHandler,
+ void(error_code, std::size_t)>::value,
+ "WriteHandler type requirements not met");
+
+ write_msg_op<
+ typename std::decay<WriteHandler>::type,
+ Stream,
+ isRequest, Body, Fields>(
+ std::forward<WriteHandler>(h), *s, *m,
+ std::forward<Args>(args)...);
+ }
+};
//------------------------------------------------------------------------------
@@ -470,7 +431,7 @@ public:
ConstBufferSequence const& buffers)
{
invoked = true;
- bytes_transferred = boost::asio::write(
+ bytes_transferred = net::write(
stream_, buffers, ec);
}
};
@@ -494,7 +455,7 @@ write_some_impl(
sr.consume(f.bytes_transferred);
return f.bytes_transferred;
}
- ec.assign(0, ec.category());
+ ec = {};
return 0;
}
@@ -502,22 +463,19 @@ template<
class AsyncWriteStream,
bool isRequest, class Body, class Fields,
class WriteHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(
- WriteHandler, void(error_code, std::size_t))
+BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
async_write_some_impl(
AsyncWriteStream& stream,
serializer<isRequest, Body, Fields>& sr,
WriteHandler&& handler)
{
- BOOST_BEAST_HANDLER_INIT(
- WriteHandler, void(error_code, std::size_t));
- detail::write_some_op<
- AsyncWriteStream,
- BOOST_ASIO_HANDLER_TYPE(WriteHandler,
- void(error_code, std::size_t)),
- isRequest, Body, Fields>{
- std::move(init.completion_handler), stream, sr}();
- return init.result.get();
+ return net::async_initiate<
+ WriteHandler,
+ void(error_code, std::size_t)>(
+ run_write_some_op{},
+ handler,
+ &stream,
+ &sr);
}
} // detail
@@ -533,11 +491,11 @@ write_some(
serializer<isRequest, Body, Fields>& sr)
{
static_assert(is_sync_write_stream<SyncWriteStream>::value,
- "SyncWriteStream requirements not met");
+ "SyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
+ "BodyWriter type requirements not met");
error_code ec;
auto const bytes_transferred =
write_some(stream, sr, ec);
@@ -556,11 +514,11 @@ write_some(
error_code& ec)
{
static_assert(is_sync_write_stream<SyncWriteStream>::value,
- "SyncWriteStream requirements not met");
+ "SyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
+ "BodyWriter type requirements not met");
return detail::write_some_impl(stream, sr, ec);
}
@@ -568,8 +526,7 @@ template<
class AsyncWriteStream,
bool isRequest, class Body, class Fields,
class WriteHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(
- WriteHandler, void(error_code, std::size_t))
+BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
async_write_some(
AsyncWriteStream& stream,
serializer<isRequest, Body, Fields>& sr,
@@ -577,11 +534,11 @@ async_write_some(
{
static_assert(is_async_write_stream<
AsyncWriteStream>::value,
- "AsyncWriteStream requirements not met");
+ "AsyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
+ "BodyWriter type requirements not met");
return detail::async_write_some_impl(stream, sr,
std::forward<WriteHandler>(handler));
}
@@ -596,11 +553,11 @@ write_header(SyncWriteStream& stream,
serializer<isRequest, Body, Fields>& sr)
{
static_assert(is_sync_write_stream<SyncWriteStream>::value,
- "SyncWriteStream requirements not met");
+ "SyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
+ "BodyWriter type requirements not met");
error_code ec;
auto const bytes_transferred =
write_header(stream, sr, ec);
@@ -619,11 +576,11 @@ write_header(
error_code& ec)
{
static_assert(is_sync_write_stream<SyncWriteStream>::value,
- "SyncWriteStream requirements not met");
+ "SyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
+ "BodyWriter type requirements not met");
sr.split(true);
std::size_t bytes_transferred = 0;
if(! sr.is_header_done())
@@ -642,7 +599,7 @@ write_header(
}
else
{
- ec.assign(0, ec.category());
+ ec = {};
}
return bytes_transferred;
}
@@ -651,8 +608,7 @@ template<
class AsyncWriteStream,
bool isRequest, class Body, class Fields,
class WriteHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(
- WriteHandler, void(error_code, std::size_t))
+BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
async_write_header(
AsyncWriteStream& stream,
serializer<isRequest, Body, Fields>& sr,
@@ -660,22 +616,20 @@ async_write_header(
{
static_assert(is_async_write_stream<
AsyncWriteStream>::value,
- "AsyncWriteStream requirements not met");
+ "AsyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
+ "BodyWriter type requirements not met");
sr.split(true);
- BOOST_BEAST_HANDLER_INIT(
- WriteHandler, void(error_code, std::size_t));
- detail::write_op<
- AsyncWriteStream,
- BOOST_ASIO_HANDLER_TYPE(WriteHandler,
- void(error_code, std::size_t)),
- detail::serializer_is_header_done,
- isRequest, Body, Fields>{
- std::move(init.completion_handler), stream, sr}();
- return init.result.get();
+ return net::async_initiate<
+ WriteHandler,
+ void(error_code, std::size_t)>(
+ detail::run_write_op{},
+ handler,
+ &stream,
+ detail::serializer_is_header_done{},
+ &sr);
}
//------------------------------------------------------------------------------
@@ -689,7 +643,7 @@ write(
serializer<isRequest, Body, Fields>& sr)
{
static_assert(is_sync_write_stream<SyncWriteStream>::value,
- "SyncWriteStream requirements not met");
+ "SyncWriteStream type requirements not met");
error_code ec;
auto const bytes_transferred =
write(stream, sr, ec);
@@ -708,7 +662,7 @@ write(
error_code& ec)
{
static_assert(is_sync_write_stream<SyncWriteStream>::value,
- "SyncWriteStream requirements not met");
+ "SyncWriteStream type requirements not met");
std::size_t bytes_transferred = 0;
sr.split(false);
for(;;)
@@ -727,8 +681,7 @@ template<
class AsyncWriteStream,
bool isRequest, class Body, class Fields,
class WriteHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(
- WriteHandler, void(error_code, std::size_t))
+BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
async_write(
AsyncWriteStream& stream,
serializer<isRequest, Body, Fields>& sr,
@@ -736,22 +689,20 @@ async_write(
{
static_assert(is_async_write_stream<
AsyncWriteStream>::value,
- "AsyncWriteStream requirements not met");
+ "AsyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
+ "BodyWriter type requirements not met");
sr.split(false);
- BOOST_BEAST_HANDLER_INIT(
- WriteHandler, void(error_code, std::size_t));
- detail::write_op<
- AsyncWriteStream,
- BOOST_ASIO_HANDLER_TYPE(WriteHandler,
- void(error_code, std::size_t)),
- detail::serializer_is_done,
- isRequest, Body, Fields>{
- std::move(init.completion_handler), stream, sr}();
- return init.result.get();
+ return net::async_initiate<
+ WriteHandler,
+ void(error_code, std::size_t)>(
+ detail::run_write_op{},
+ handler,
+ &stream,
+ detail::serializer_is_done{},
+ &sr);
}
//------------------------------------------------------------------------------
@@ -767,11 +718,11 @@ write(
message<isRequest, Body, Fields>& msg)
{
static_assert(is_sync_write_stream<SyncWriteStream>::value,
- "SyncWriteStream requirements not met");
+ "SyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
+ "BodyWriter type requirements not met");
error_code ec;
auto const bytes_transferred =
write(stream, msg, ec);
@@ -791,11 +742,11 @@ write(
message<isRequest, Body, Fields> const& msg)
{
static_assert(is_sync_write_stream<SyncWriteStream>::value,
- "SyncWriteStream requirements not met");
+ "SyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
+ "BodyWriter type requirements not met");
error_code ec;
auto const bytes_transferred =
write(stream, msg, ec);
@@ -816,11 +767,11 @@ write(
error_code& ec)
{
static_assert(is_sync_write_stream<SyncWriteStream>::value,
- "SyncWriteStream requirements not met");
+ "SyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
+ "BodyWriter type requirements not met");
serializer<isRequest, Body, Fields> sr{msg};
return write(stream, sr, ec);
}
@@ -837,11 +788,11 @@ write(
error_code& ec)
{
static_assert(is_sync_write_stream<SyncWriteStream>::value,
- "SyncWriteStream requirements not met");
+ "SyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
+ "BodyWriter type requirements not met");
serializer<isRequest, Body, Fields> sr{msg};
return write(stream, sr, ec);
}
@@ -852,8 +803,7 @@ template<
class WriteHandler>
typename std::enable_if<
is_mutable_body_writer<Body>::value,
- BOOST_ASIO_INITFN_RESULT_TYPE(
- WriteHandler, void(error_code, std::size_t))>::type
+ BOOST_BEAST_ASYNC_RESULT2(WriteHandler)>::type
async_write(
AsyncWriteStream& stream,
message<isRequest, Body, Fields>& msg,
@@ -861,20 +811,19 @@ async_write(
{
static_assert(
is_async_write_stream<AsyncWriteStream>::value,
- "AsyncWriteStream requirements not met");
+ "AsyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
- BOOST_BEAST_HANDLER_INIT(
- WriteHandler, void(error_code, std::size_t));
- detail::write_msg_op<
- AsyncWriteStream,
- BOOST_ASIO_HANDLER_TYPE(WriteHandler,
- void(error_code, std::size_t)),
- isRequest, Body, Fields>{
- std::move(init.completion_handler), stream, msg}();
- return init.result.get();
+ "BodyWriter type requirements not met");
+ return net::async_initiate<
+ WriteHandler,
+ void(error_code, std::size_t)>(
+ detail::run_write_msg_op{},
+ handler,
+ &stream,
+ &msg,
+ std::false_type{});
}
template<
@@ -883,8 +832,7 @@ template<
class WriteHandler>
typename std::enable_if<
! is_mutable_body_writer<Body>::value,
- BOOST_ASIO_INITFN_RESULT_TYPE(
- WriteHandler, void(error_code, std::size_t))>::type
+ BOOST_BEAST_ASYNC_RESULT2(WriteHandler)>::type
async_write(
AsyncWriteStream& stream,
message<isRequest, Body, Fields> const& msg,
@@ -892,20 +840,19 @@ async_write(
{
static_assert(
is_async_write_stream<AsyncWriteStream>::value,
- "AsyncWriteStream requirements not met");
+ "AsyncWriteStream type requirements not met");
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
- BOOST_BEAST_HANDLER_INIT(
- WriteHandler, void(error_code, std::size_t));
- detail::write_msg_op<
- AsyncWriteStream,
- BOOST_ASIO_HANDLER_TYPE(WriteHandler,
- void(error_code, std::size_t)),
- isRequest, Body, Fields>{
- std::move(init.completion_handler), stream, msg}();
- return init.result.get();
+ "BodyWriter type requirements not met");
+ return net::async_initiate<
+ WriteHandler,
+ void(error_code, std::size_t)>(
+ detail::run_write_msg_op{},
+ handler,
+ &stream,
+ &msg,
+ std::true_type{});
}
//------------------------------------------------------------------------------
@@ -931,11 +878,11 @@ public:
operator()(error_code& ec,
ConstBufferSequence const& buffers) const
{
- ec.assign(0, ec.category());
+ ec = {};
if(os_.fail())
return;
std::size_t bytes_transferred = 0;
- for(auto b : buffers_range(buffers))
+ for(auto b : beast::buffers_range_ref(buffers))
{
os_.write(static_cast<char const*>(
b.data()), b.size());
@@ -975,9 +922,9 @@ operator<<(std::ostream& os,
message<isRequest, Body, Fields> const& msg)
{
static_assert(is_body<Body>::value,
- "Body requirements not met");
+ "Body type requirements not met");
static_assert(is_body_writer<Body>::value,
- "BodyWriter requirements not met");
+ "BodyWriter type requirements not met");
serializer<isRequest, Body, Fields> sr{msg};
error_code ec;
detail::write_ostream_lambda<decltype(sr)> f{os, sr};
@@ -990,7 +937,7 @@ operator<<(std::ostream& os,
{
os.setstate(std::ios::failbit);
break;
- }
+ }
}
while(! sr.is_done());
return os;