summaryrefslogtreecommitdiff
path: root/boost/beast
diff options
context:
space:
mode:
Diffstat (limited to 'boost/beast')
-rw-r--r--boost/beast/_experimental/http/impl/icy_stream.hpp4
-rw-r--r--boost/beast/_experimental/test/impl/stream.hpp7
-rw-r--r--boost/beast/_experimental/test/impl/stream.ipp6
-rw-r--r--boost/beast/_experimental/test/stream.hpp16
-rw-r--r--boost/beast/_experimental/unit_test/thread.hpp128
-rw-r--r--boost/beast/core/basic_stream.hpp157
-rw-r--r--boost/beast/core/buffers_cat.hpp20
-rw-r--r--boost/beast/core/detail/base64.hpp21
-rw-r--r--boost/beast/core/detail/base64.ipp18
-rw-r--r--boost/beast/core/detail/buffers_range_adaptor.hpp17
-rw-r--r--boost/beast/core/detail/char_buffer.hpp78
-rw-r--r--boost/beast/core/detail/impl/read.hpp19
-rw-r--r--boost/beast/core/detail/impl/temporary_buffer.ipp69
-rw-r--r--boost/beast/core/detail/ostream.hpp1
-rw-r--r--boost/beast/core/detail/remap_post_to_defer.hpp1
-rw-r--r--boost/beast/core/detail/service_base.hpp9
-rw-r--r--boost/beast/core/detail/sha1.hpp3
-rw-r--r--boost/beast/core/detail/string.hpp44
-rw-r--r--boost/beast/core/detail/temporary_buffer.hpp83
-rw-r--r--boost/beast/core/detail/type_traits.hpp42
-rw-r--r--boost/beast/core/detail/variant.hpp20
-rw-r--r--boost/beast/core/detect_ssl.hpp3
-rw-r--r--boost/beast/core/impl/async_base.hpp24
-rw-r--r--boost/beast/core/impl/basic_stream.hpp116
-rw-r--r--boost/beast/core/impl/buffered_read_stream.hpp2
-rw-r--r--boost/beast/core/impl/buffers_adaptor.hpp1
-rw-r--r--boost/beast/core/impl/buffers_cat.hpp29
-rw-r--r--boost/beast/core/impl/flat_buffer.hpp2
-rw-r--r--boost/beast/core/impl/flat_stream.hpp2
-rw-r--r--boost/beast/core/impl/multi_buffer.hpp81
-rw-r--r--boost/beast/core/impl/read_size.hpp1
-rw-r--r--boost/beast/core/impl/static_buffer.hpp5
-rw-r--r--boost/beast/core/impl/static_buffer.ipp4
-rw-r--r--boost/beast/core/impl/static_string.hpp59
-rw-r--r--boost/beast/core/impl/string.ipp73
-rw-r--r--boost/beast/core/multi_buffer.hpp66
-rw-r--r--boost/beast/core/rate_policy.hpp2
-rw-r--r--boost/beast/core/span.hpp6
-rw-r--r--boost/beast/core/static_buffer.hpp8
-rw-r--r--boost/beast/core/static_string.hpp3
-rw-r--r--boost/beast/core/string.hpp98
-rw-r--r--boost/beast/core/string_param.hpp1
-rw-r--r--boost/beast/core/string_type.hpp45
-rw-r--r--boost/beast/http/basic_dynamic_body.hpp3
-rw-r--r--boost/beast/http/detail/basic_parser.hpp6
-rw-r--r--boost/beast/http/detail/basic_parser.ipp93
-rw-r--r--boost/beast/http/detail/rfc7230.hpp8
-rw-r--r--boost/beast/http/detail/rfc7230.ipp6
-rw-r--r--boost/beast/http/fields.hpp6
-rw-r--r--boost/beast/http/impl/basic_parser.ipp29
-rw-r--r--boost/beast/http/impl/fields.hpp277
-rw-r--r--boost/beast/http/impl/fields.ipp138
-rw-r--r--boost/beast/http/impl/file_body_win32.hpp1
-rw-r--r--boost/beast/http/impl/message.hpp1
-rw-r--r--boost/beast/http/impl/read.hpp8
-rw-r--r--boost/beast/http/impl/rfc7230.hpp34
-rw-r--r--boost/beast/http/impl/rfc7230.ipp31
-rw-r--r--boost/beast/http/impl/verb.ipp167
-rw-r--r--boost/beast/http/impl/write.hpp11
-rw-r--r--boost/beast/http/rfc7230.hpp12
-rw-r--r--boost/beast/http/string_body.hpp1
-rw-r--r--boost/beast/http/vector_body.hpp4
-rw-r--r--boost/beast/src.hpp4
-rw-r--r--boost/beast/ssl/ssl_stream.hpp42
-rw-r--r--boost/beast/version.hpp2
-rw-r--r--boost/beast/websocket/detail/decorator.hpp9
-rw-r--r--boost/beast/websocket/detail/frame.hpp126
-rw-r--r--boost/beast/websocket/detail/hybi13.ipp21
-rw-r--r--boost/beast/websocket/detail/mask.hpp55
-rw-r--r--boost/beast/websocket/detail/mask.ipp66
-rw-r--r--boost/beast/websocket/detail/pmd_extension.ipp10
-rw-r--r--boost/beast/websocket/detail/prng.hpp79
-rw-r--r--boost/beast/websocket/detail/prng.ipp294
-rw-r--r--boost/beast/websocket/impl/accept.hpp14
-rw-r--r--boost/beast/websocket/impl/close.hpp2
-rw-r--r--boost/beast/websocket/impl/handshake.hpp2
-rw-r--r--boost/beast/websocket/impl/ping.hpp7
-rw-r--r--boost/beast/websocket/impl/read.hpp23
-rw-r--r--boost/beast/websocket/impl/stream.hpp12
-rw-r--r--boost/beast/websocket/impl/stream_impl.hpp56
-rw-r--r--boost/beast/websocket/impl/teardown.hpp4
-rw-r--r--boost/beast/websocket/impl/write.hpp2
-rw-r--r--boost/beast/websocket/option.hpp9
-rw-r--r--boost/beast/websocket/stream.hpp3
-rw-r--r--boost/beast/zlib/detail/deflate_stream.hpp1
-rw-r--r--boost/beast/zlib/detail/deflate_stream.ipp2
86 files changed, 1380 insertions, 1695 deletions
diff --git a/boost/beast/_experimental/http/impl/icy_stream.hpp b/boost/beast/_experimental/http/impl/icy_stream.hpp
index f7329180ee..9b6e66ab92 100644
--- a/boost/beast/_experimental/http/impl/icy_stream.hpp
+++ b/boost/beast/_experimental/http/impl/icy_stream.hpp
@@ -35,7 +35,7 @@ is_icy(ConstBufferSequence const& buffers)
char buf[3];
auto const n = net::buffer_copy(
net::mutable_buffer(buf, 3),
- buffers);
+ buffers);
if(n >= 1 && buf[0] != 'I')
return false;
if(n >= 2 && buf[1] != 'C')
@@ -57,7 +57,7 @@ template<class Buffers, class Handler>
class read_op
: public beast::async_base<Handler,
beast::executor_type<icy_stream>>
- , public net::coroutine
+ , public asio::coroutine
{
icy_stream& s_;
Buffers b_;
diff --git a/boost/beast/_experimental/test/impl/stream.hpp b/boost/beast/_experimental/test/impl/stream.hpp
index 53bd4db7c8..3925d7421f 100644
--- a/boost/beast/_experimental/test/impl/stream.hpp
+++ b/boost/beast/_experimental/test/impl/stream.hpp
@@ -12,9 +12,8 @@
#include <boost/beast/core/bind_handler.hpp>
#include <boost/beast/core/buffer_traits.hpp>
-#include <boost/beast/core/buffers_prefix.hpp>
#include <boost/beast/core/detail/service_base.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
+#include <boost/beast/core/detail/is_invocable.hpp>
#include <mutex>
#include <stdexcept>
#include <vector>
@@ -108,6 +107,7 @@ class stream::read_op : public stream::read_op_base
net::buffer_copy(
b_, sp->b.data(), sp->read_max);
sp->b.consume(bytes_transferred);
+ sp->nread_bytes += bytes_transferred;
}
else if (buffer_bytes(b_) > 0)
{
@@ -232,6 +232,7 @@ struct stream::run_write_op
std::lock_guard<std::mutex> lock(out->m);
n = net::buffer_copy(out->b.prepare(n), buffers);
out->b.commit(n);
+ out->nwrite_bytes += n;
out->notify_read();
}
BOOST_ASSERT(! ec);
@@ -295,6 +296,7 @@ read_some(MutableBufferSequence const& buffers,
auto const n = net::buffer_copy(
buffers, in_->b.data(), in_->read_max);
in_->b.consume(n);
+ in_->nread_bytes += n;
return n;
}
@@ -378,6 +380,7 @@ write_some(
std::lock_guard<std::mutex> lock(out->m);
n = net::buffer_copy(out->b.prepare(n), buffers);
out->b.commit(n);
+ out->nwrite_bytes += n;
out->notify_read();
}
return n;
diff --git a/boost/beast/_experimental/test/impl/stream.ipp b/boost/beast/_experimental/test/impl/stream.ipp
index 38b8a8b2a4..1570ccaac0 100644
--- a/boost/beast/_experimental/test/impl/stream.ipp
+++ b/boost/beast/_experimental/test/impl/stream.ipp
@@ -13,7 +13,6 @@
#include <boost/beast/_experimental/test/stream.hpp>
#include <boost/beast/core/bind_handler.hpp>
#include <boost/beast/core/buffer_traits.hpp>
-#include <boost/beast/core/buffers_prefix.hpp>
#include <boost/make_shared.hpp>
#include <stdexcept>
#include <vector>
@@ -262,6 +261,9 @@ connect(stream& remote)
{
BOOST_ASSERT(! out_.lock());
BOOST_ASSERT(! remote.out_.lock());
+ std::lock(in_->m, remote.in_->m);
+ std::lock_guard<std::mutex> guard1{in_->m, std::adopt_lock};
+ std::lock_guard<std::mutex> guard2{remote.in_->m, std::adopt_lock};
out_ = remote.in_;
remote.out_ = in_;
in_->code = status::ok;
@@ -275,7 +277,7 @@ str() const
auto const bs = in_->b.data();
if(buffer_bytes(bs) == 0)
return {};
- auto const b = beast::buffers_front(bs);
+ net::const_buffer const b = *net::buffer_sequence_begin(bs);
return {static_cast<char const*>(b.data()), b.size()};
}
diff --git a/boost/beast/_experimental/test/stream.hpp b/boost/beast/_experimental/test/stream.hpp
index 181acec9aa..eb12e8d840 100644
--- a/boost/beast/_experimental/test/stream.hpp
+++ b/boost/beast/_experimental/test/stream.hpp
@@ -141,7 +141,9 @@ class stream
status code = status::ok;
fail_count* fc = nullptr;
std::size_t nread = 0;
+ std::size_t nread_bytes = 0;
std::size_t nwrite = 0;
+ std::size_t nwrite_bytes = 0;
std::size_t read_max =
(std::numeric_limits<std::size_t>::max)();
std::size_t write_max =
@@ -361,6 +363,13 @@ public:
return in_->nread;
}
+ /// Return the number of bytes read
+ std::size_t
+ nread_bytes() const noexcept
+ {
+ return in_->nread_bytes;
+ }
+
/// Return the number of writes
std::size_t
nwrite() const noexcept
@@ -368,6 +377,13 @@ public:
return in_->nwrite;
}
+ /// Return the number of bytes written
+ std::size_t
+ nwrite_bytes() const noexcept
+ {
+ return in_->nwrite_bytes;
+ }
+
/** Close the stream.
The other end of the connection will see
diff --git a/boost/beast/_experimental/unit_test/thread.hpp b/boost/beast/_experimental/unit_test/thread.hpp
deleted file mode 100644
index ed06cb3731..0000000000
--- a/boost/beast/_experimental/unit_test/thread.hpp
+++ /dev/null
@@ -1,128 +0,0 @@
-//
-// 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_UNIT_TEST_THREAD_HPP
-#define BOOST_BEAST_UNIT_TEST_THREAD_HPP
-
-#include <boost/beast/_experimental/unit_test/suite.hpp>
-#include <functional>
-#include <thread>
-#include <utility>
-
-namespace boost {
-namespace beast {
-namespace unit_test {
-
-/** Replacement for std::thread that handles exceptions in unit tests. */
-class thread
-{
-private:
- suite* s_ = nullptr;
- std::thread t_;
-
-public:
- using id = std::thread::id;
- using native_handle_type = std::thread::native_handle_type;
-
- thread() = default;
- thread(thread const&) = delete;
- thread& operator=(thread const&) = delete;
-
- thread(thread&& other)
- : s_(other.s_)
- , t_(std::move(other.t_))
- {
- }
-
- thread& operator=(thread&& other)
- {
- s_ = other.s_;
- t_ = std::move(other.t_);
- return *this;
- }
-
- template<class F, class... Args>
- explicit
- thread(suite& s, F&& f, Args&&... args)
- : s_(&s)
- {
- std::function<void(void)> b =
- std::bind(std::forward<F>(f),
- std::forward<Args>(args)...);
- t_ = std::thread(&thread::run, this,
- std::move(b));
- }
-
- bool
- joinable() const
- {
- return t_.joinable();
- }
-
- std::thread::id
- get_id() const
- {
- return t_.get_id();
- }
-
- static
- unsigned
- hardware_concurrency() noexcept
- {
- return std::thread::hardware_concurrency();
- }
-
- void
- join()
- {
- t_.join();
- s_->propagate_abort();
- }
-
- void
- detach()
- {
- t_.detach();
- }
-
- void
- swap(thread& other)
- {
- std::swap(s_, other.s_);
- std::swap(t_, other.t_);
- }
-
-private:
- void
- run(std::function <void(void)> f)
- {
- try
- {
- f();
- }
- catch(suite::abort_exception const&)
- {
- }
- catch(std::exception const& e)
- {
- s_->fail("unhandled exception: " +
- std::string(e.what()));
- }
- catch(...)
- {
- s_->fail("unhandled exception");
- }
- }
-};
-
-} // unit_test
-} // beast
-} // boost
-
-#endif
diff --git a/boost/beast/core/basic_stream.hpp b/boost/beast/core/basic_stream.hpp
index 057ab07ffd..25076059e2 100644
--- a/boost/beast/core/basic_stream.hpp
+++ b/boost/beast/core/basic_stream.hpp
@@ -73,7 +73,7 @@ namespace beast {
be invoked by the executor associated with the stream upon construction.
The type of executor used with this stream must meet the following
requirements:
-
+
@li Function objects submitted to the executor shall never run
concurrently with each other.
@@ -284,6 +284,7 @@ private:
// but the implementation is still waiting on a timer.
boost::shared_ptr<impl_type> impl_;
+ template<class Executor2>
struct timeout_handler;
struct ops;
@@ -367,7 +368,7 @@ public:
/** Move constructor
- @param other The other object from which the move will occur.
+ @param other The other object from which the move will occur.
@note Following the move, the moved-from object is in the
same state as if newly constructed.
@@ -490,7 +491,7 @@ public:
//--------------------------------------------------------------------------
/** Get the executor associated with the object.
-
+
This function may be used to obtain the executor object that the
stream uses to dispatch completion handlers without an assocaited
executor.
@@ -498,7 +499,7 @@ public:
@return A copy of the executor that stream will use to dispatch handlers.
*/
executor_type
- get_executor() const noexcept
+ get_executor() noexcept
{
return impl_->ex();
}
@@ -525,7 +526,7 @@ public:
}
/** Connect the stream to the specified endpoint.
-
+
This function is used to connect the underlying socket to the
specified remote endpoint. The function call will block until
the connection is successfully made or an error occurs.
@@ -534,7 +535,7 @@ public:
closed state upon failure.
@param ep The remote endpoint to connect to.
-
+
@param ec Set to indicate what error occurred, if any.
@see connect
@@ -546,7 +547,7 @@ public:
}
/** Establishes a connection by trying each endpoint in a sequence.
-
+
This function attempts to connect the stream to one of a sequence of
endpoints by trying each endpoint until a connection is successfully
established.
@@ -556,11 +557,11 @@ public:
The algorithm, known as a <em>composed operation</em>, is implemented
in terms of calls to the underlying socket's `connect` function.
-
+
@param endpoints A sequence of endpoints.
-
+
@returns The successfully connected endpoint.
-
+
@throws system_error Thrown on failure. If the sequence is
empty, the associated error code is `net::error::not_found`.
Otherwise, contains the error from the last connection attempt.
@@ -579,7 +580,7 @@ public:
}
/** Establishes a connection by trying each endpoint in a sequence.
-
+
This function attempts to connect the stream to one of a sequence of
endpoints by trying each endpoint until a connection is successfully
established.
@@ -589,16 +590,16 @@ public:
The algorithm, known as a <em>composed operation</em>, is implemented
in terms of calls to the underlying socket's `connect` function.
-
+
@param endpoints A sequence of endpoints.
-
+
@param ec Set to indicate what error occurred, if any. If the sequence is
empty, set to `net::error::not_found`. Otherwise, contains the error
from the last connection attempt.
-
+
@returns On success, the successfully connected endpoint. Otherwise, a
default-constructed endpoint.
- */
+ */
template<class EndpointSequence
#if ! BOOST_BEAST_DOXYGEN
,class = typename std::enable_if<
@@ -616,27 +617,27 @@ public:
}
/** Establishes a connection by trying each endpoint in a sequence.
-
+
This function attempts to connect the stream to one of a sequence of
endpoints by trying each endpoint until a connection is successfully
established.
The underlying socket is automatically opened if needed.
An automatically opened socket is not returned to the
closed state upon failure.
-
+
The algorithm, known as a <em>composed operation</em>, is implemented
in terms of calls to the underlying socket's `connect` function.
-
+
@param begin An iterator pointing to the start of a sequence of endpoints.
-
+
@param end An iterator pointing to the end of a sequence of endpoints.
-
+
@returns An iterator denoting the successfully connected endpoint.
-
+
@throws system_error Thrown on failure. If the sequence is
empty, the associated error code is `net::error::not_found`.
Otherwise, contains the error from the last connection attempt.
- */
+ */
template<class Iterator>
Iterator
connect(
@@ -646,25 +647,25 @@ public:
}
/** Establishes a connection by trying each endpoint in a sequence.
-
+
This function attempts to connect the stream to one of a sequence of
endpoints by trying each endpoint until a connection is successfully
established.
The underlying socket is automatically opened if needed.
An automatically opened socket is not returned to the
closed state upon failure.
-
+
The algorithm, known as a <em>composed operation</em>, is implemented
in terms of calls to the underlying socket's `connect` function.
-
+
@param begin An iterator pointing to the start of a sequence of endpoints.
-
+
@param end An iterator pointing to the end of a sequence of endpoints.
-
+
@param ec Set to indicate what error occurred, if any. If the sequence is
empty, set to boost::asio::error::not_found. Otherwise, contains the error
from the last connection attempt.
-
+
@returns On success, an iterator denoting the successfully connected
endpoint. Otherwise, the end iterator.
*/
@@ -678,7 +679,7 @@ public:
}
/** Establishes a connection by trying each endpoint in a sequence.
-
+
This function attempts to connect the stream to one of a sequence of
endpoints by trying each endpoint until a connection is successfully
established.
@@ -688,9 +689,9 @@ public:
The algorithm, known as a <em>composed operation</em>, is implemented
in terms of calls to the underlying socket's `connect` function.
-
+
@param endpoints A sequence of endpoints.
-
+
@param connect_condition A function object that is called prior to each
connection attempt. The signature of the function object must be:
@code
@@ -703,9 +704,9 @@ public:
indicate success. The @c next parameter is the next endpoint to be tried.
The function object should return true if the next endpoint should be tried,
and false if it should be skipped.
-
+
@returns The successfully connected endpoint.
-
+
@throws boost::system::system_error Thrown on failure. If the sequence is
empty, the associated error code is `net::error::not_found`.
Otherwise, contains the error from the last connection attempt.
@@ -779,7 +780,7 @@ public:
}
/** Establishes a connection by trying each endpoint in a sequence.
-
+
This function attempts to connect the stream to one of a sequence of
endpoints by trying each endpoint until a connection is successfully
established.
@@ -789,11 +790,11 @@ public:
The algorithm, known as a <em>composed operation</em>, is implemented
in terms of calls to the underlying socket's `connect` function.
-
+
@param begin An iterator pointing to the start of a sequence of endpoints.
-
+
@param end An iterator pointing to the end of a sequence of endpoints.
-
+
@param connect_condition A function object that is called prior to each
connection attempt. The signature of the function object must be:
@code
@@ -806,13 +807,13 @@ public:
indicate success. The @c next parameter is the next endpoint to be tried.
The function object should return true if the next endpoint should be tried,
and false if it should be skipped.
-
+
@returns An iterator denoting the successfully connected endpoint.
-
+
@throws boost::system::system_error Thrown on failure. If the sequence is
empty, the associated @c error_code is `net::error::not_found`.
Otherwise, contains the error from the last connection attempt.
- */
+ */
template<
class Iterator, class ConnectCondition>
Iterator
@@ -824,7 +825,7 @@ public:
}
/** Establishes a connection by trying each endpoint in a sequence.
-
+
This function attempts to connect the stream to one of a sequence of
endpoints by trying each endpoint until a connection is successfully
established.
@@ -834,11 +835,11 @@ public:
The algorithm, known as a <em>composed operation</em>, is implemented
in terms of calls to the underlying socket's `connect` function.
-
+
@param begin An iterator pointing to the start of a sequence of endpoints.
-
+
@param end An iterator pointing to the end of a sequence of endpoints.
-
+
@param connect_condition A function object that is called prior to each
connection attempt. The signature of the function object must be:
@code
@@ -851,11 +852,11 @@ public:
indicate success. The @c next parameter is the next endpoint to be tried.
The function object should return true if the next endpoint should be tried,
and false if it should be skipped.
-
+
@param ec Set to indicate what error occurred, if any. If the sequence is
empty, set to `net::error::not_found`. Otherwise, contains the error
from the last connection attempt.
-
+
@returns On success, an iterator denoting the successfully connected
endpoint. Otherwise, the end iterator.
*/
@@ -885,7 +886,7 @@ public:
@param ep The remote endpoint to which the underlying socket will be
connected. Copies will be made of the endpoint object as required.
-
+
@param handler The completion handler to invoke when the operation
completes. The implementation takes ownership of the handler by
performing a decay-copy. The equivalent function signature of
@@ -909,7 +910,7 @@ public:
ConnectHandler&& handler);
/** Establishes a connection by trying each endpoint in a sequence asynchronously.
-
+
This function attempts to connect the stream to one of a sequence of
endpoints by trying each endpoint until a connection is successfully
established.
@@ -924,10 +925,10 @@ public:
If the timeout timer expires while the operation is outstanding,
the current connection attempt will be canceled and the completion
handler will be invoked with the error @ref error::timeout.
-
+
@param endpoints A sequence of endpoints. This this object must meet
the requirements of <em>EndpointSequence</em>.
-
+
@param handler The completion handler to invoke when the operation
completes. The implementation takes ownership of the handler by
performing a decay-copy. The equivalent function signature of
@@ -938,7 +939,7 @@ public:
// net::error::not_found. Otherwise, contains the
// error from the last connection attempt.
error_code const& error,
-
+
// On success, the successfully connected endpoint.
// Otherwise, a default-constructed endpoint.
typename Protocol::endpoint const& endpoint
@@ -964,7 +965,7 @@ public:
RangeConnectHandler&& handler);
/** Establishes a connection by trying each endpoint in a sequence asynchronously.
-
+
This function attempts to connect the stream to one of a sequence of
endpoints by trying each endpoint until a connection is successfully
established.
@@ -982,7 +983,7 @@ public:
@param endpoints A sequence of endpoints. This this object must meet
the requirements of <em>EndpointSequence</em>.
-
+
@param connect_condition A function object that is called prior to each
connection attempt. The signature of the function object must be:
@code
@@ -1006,7 +1007,7 @@ public:
// net::error::not_found. Otherwise, contains the
// error from the last connection attempt.
error_code const& error,
-
+
// On success, the successfully connected endpoint.
// Otherwise, a default-constructed endpoint.
typename Protocol::endpoint const& endpoint
@@ -1052,7 +1053,7 @@ public:
RangeConnectHandler&& handler);
/** Establishes a connection by trying each endpoint in a sequence asynchronously.
-
+
This function attempts to connect the stream to one of a sequence of
endpoints by trying each endpoint until a connection is successfully
established.
@@ -1067,9 +1068,9 @@ public:
If the timeout timer expires while the operation is outstanding,
the current connection attempt will be canceled and the completion
handler will be invoked with the error @ref error::timeout.
-
+
@param begin An iterator pointing to the start of a sequence of endpoints.
-
+
@param end An iterator pointing to the end of a sequence of endpoints.
@param handler The completion handler to invoke when the operation
@@ -1082,7 +1083,7 @@ public:
// net::error::not_found. Otherwise, contains the
// error from the last connection attempt.
error_code const& error,
-
+
// On success, an iterator denoting the successfully
// connected endpoint. Otherwise, the end iterator.
Iterator iterator
@@ -1102,7 +1103,7 @@ public:
IteratorConnectHandler&& handler);
/** Establishes a connection by trying each endpoint in a sequence asynchronously.
-
+
This function attempts to connect the stream to one of a sequence of
endpoints by trying each endpoint until a connection is successfully
established.
@@ -1113,11 +1114,11 @@ public:
If the timeout timer expires while the operation is outstanding,
the current connection attempt will be canceled and the completion
handler will be invoked with the error @ref error::timeout.
-
+
@param begin An iterator pointing to the start of a sequence of endpoints.
@param end An iterator pointing to the end of a sequence of endpoints.
-
+
@param connect_condition A function object that is called prior to each
connection attempt. The signature of the function object must be:
@code
@@ -1136,7 +1137,7 @@ public:
// net::error::not_found. Otherwise, contains the
// error from the last connection attempt.
error_code const& error,
-
+
// On success, an iterator denoting the successfully
// connected endpoint. Otherwise, the end iterator.
Iterator iterator
@@ -1162,7 +1163,7 @@ public:
/** Read some data.
This function is used to read some data from the stream.
-
+
The call blocks until one of the following is true:
@li One or more bytes are read from the stream.
@@ -1172,11 +1173,11 @@ public:
@param buffers The buffers into which the data will be read. If the
size of the buffers is zero bytes, the call always returns
immediately with no error.
-
+
@returns The number of bytes read.
-
+
@throws system_error Thrown on failure.
-
+
@note The `read_some` operation may not receive all of the requested
number of bytes. Consider using the function `net::read` if you need
to ensure that the requested amount of data is read before the
@@ -1202,11 +1203,11 @@ public:
@param buffers The buffers into which the data will be read. If the
size of the buffers is zero bytes, the call always returns
immediately with no error.
-
+
@param ec Set to indicate what error occurred, if any.
@returns The number of bytes read.
-
+
@note The `read_some` operation may not receive all of the requested
number of bytes. Consider using the function `net::read` if you need
to ensure that the requested amount of data is read before the
@@ -1224,7 +1225,7 @@ public:
/** Read some data asynchronously.
This function is used to asynchronously read data from the stream.
-
+
This call always returns immediately. The asynchronous operation
will continue until one of the following conditions is true:
@@ -1247,7 +1248,7 @@ public:
Although the buffers object may be copied as necessary, ownership of the
underlying memory blocks is retained by the caller, which must guarantee
that they remain valid until the handler is called.
-
+
@param handler The completion handler to invoke when the operation
completes. The implementation takes ownership of the handler by
performing a decay-copy. The equivalent function signature of
@@ -1277,7 +1278,7 @@ public:
/** Write some data.
This function is used to write some data to the stream.
-
+
The call blocks until one of the following is true:
@li One or more bytes are written to the stream.
@@ -1289,9 +1290,9 @@ public:
with no error.
@returns The number of bytes written.
-
+
@throws system_error Thrown on failure.
-
+
@note The `write_some` operation may not transmit all of the requested
number of bytes. Consider using the function `net::write` if you need
to ensure that the requested amount of data is written before the
@@ -1307,7 +1308,7 @@ public:
/** Write some data.
This function is used to write some data to the stream.
-
+
The call blocks until one of the following is true:
@li One or more bytes are written to the stream.
@@ -1321,9 +1322,9 @@ public:
@param ec Set to indicate what error occurred, if any.
@returns The number of bytes written.
-
+
@throws system_error Thrown on failure.
-
+
@note The `write_some` operation may not transmit all of the requested
number of bytes. Consider using the function `net::write` if you need
to ensure that the requested amount of data is written before the
@@ -1341,7 +1342,7 @@ public:
/** Write some data asynchronously.
This function is used to asynchronously write data to the underlying socket.
-
+
This call always returns immediately. The asynchronous operation
will continue until one of the following conditions is true:
@@ -1364,7 +1365,7 @@ public:
Although the buffers object may be copied as necessary, ownership of the
underlying memory blocks is retained by the caller, which must guarantee
that they remain valid until the handler is called.
-
+
@param handler The completion handler to invoke when the operation
completes. The implementation takes ownership of the handler by
performing a decay-copy. The equivalent function signature of
diff --git a/boost/beast/core/buffers_cat.hpp b/boost/beast/core/buffers_cat.hpp
index 532ea32eef..f13732916b 100644
--- a/boost/beast/core/buffers_cat.hpp
+++ b/boost/beast/core/buffers_cat.hpp
@@ -19,7 +19,6 @@ namespace boost {
namespace beast {
/** A buffer sequence representing a concatenation of buffer sequences.
-
@see buffers_cat
*/
template<class... Buffers>
@@ -29,7 +28,6 @@ class buffers_cat_view
public:
/** The type of buffer returned when dereferencing an iterator.
-
If every buffer sequence in the view is a <em>MutableBufferSequence</em>,
then `value_type` will be `net::mutable_buffer`.
Otherwise, `value_type` will be `net::const_buffer`.
@@ -50,7 +48,6 @@ public:
buffers_cat_view& operator=(buffers_cat_view const&) = default;
/** Constructor
-
@param buffers The list of buffer sequences to concatenate.
Copies of the arguments will be maintained for the lifetime
of the concatenated sequence; however, the ownership of the
@@ -63,12 +60,12 @@ public:
const_iterator
begin() const;
- /// Returns an iterator to one past the last buffer in the sequence
+ /// Returns an iterator to one past the last buffer in the sequence
const_iterator
end() const;
};
-/** Concatenate 2 or more buffer sequences.
+/** Concatenate 1 or more buffer sequences.
This function returns a constant or mutable buffer sequence which,
when iterated, efficiently concatenates the input buffer sequences.
@@ -76,15 +73,12 @@ public:
object does not take ownership of the underlying memory. The
application is still responsible for managing the lifetime of the
referenced memory.
-
@param buffers The list of buffer sequences to concatenate.
-
@return A new buffer sequence that represents the concatenation of
the input buffer sequences. This buffer sequence will be a
<em>MutableBufferSequence</em> if each of the passed buffer sequences is
also a <em>MutableBufferSequence</em>; otherwise the returned buffer
sequence will be a <em>ConstBufferSequence</em>.
-
@see buffers_cat_view
*/
#if BOOST_BEAST_DOXYGEN
@@ -92,15 +86,15 @@ template<class... BufferSequence>
buffers_cat_view<BufferSequence...>
buffers_cat(BufferSequence const&... buffers)
#else
-template<class B1, class B2, class... Bn>
-buffers_cat_view<B1, B2, Bn...>
-buffers_cat(B1 const& b1, B2 const& b2, Bn const&... bn)
+template<class B1, class... Bn>
+buffers_cat_view<B1, Bn...>
+buffers_cat(B1 const& b1, Bn const&... bn)
#endif
{
static_assert(
- is_const_buffer_sequence<B1, B2, Bn...>::value,
+ is_const_buffer_sequence<B1, Bn...>::value,
"BufferSequence type requirements not met");
- return buffers_cat_view<B1, B2, Bn...>{b1, b2, bn...};
+ return buffers_cat_view<B1, Bn...>{b1, bn...};
}
} // beast
diff --git a/boost/beast/core/detail/base64.hpp b/boost/beast/core/detail/base64.hpp
index 7f91c04777..477fecf2a6 100644
--- a/boost/beast/core/detail/base64.hpp
+++ b/boost/beast/core/detail/base64.hpp
@@ -12,7 +12,6 @@
#include <boost/beast/core/string.hpp>
#include <cctype>
-#include <string>
#include <utility>
namespace boost {
@@ -78,26 +77,6 @@ decode(void* dest, char const* src, std::size_t len);
} // base64
-BOOST_BEAST_DECL
-std::string
-base64_encode(std::uint8_t const* data, std::size_t len);
-
-BOOST_BEAST_DECL
-std::string
-base64_encode(string_view s);
-
-template<class = void>
-std::string
-base64_decode(string_view data)
-{
- std::string dest;
- dest.resize(base64::decoded_size(data.size()));
- auto const result = base64::decode(
- &dest[0], data.data(), data.size());
- dest.resize(result.first);
- return dest;
-}
-
} // detail
} // beast
} // boost
diff --git a/boost/beast/core/detail/base64.ipp b/boost/beast/core/detail/base64.ipp
index 7e11d188b6..4fc3c6771f 100644
--- a/boost/beast/core/detail/base64.ipp
+++ b/boost/beast/core/detail/base64.ipp
@@ -195,24 +195,6 @@ decode(void* dest, char const* src, std::size_t len)
} // base64
-std::string
-base64_encode(
- std::uint8_t const* data,
- std::size_t len)
-{
- std::string dest;
- dest.resize(base64::encoded_size(len));
- dest.resize(base64::encode(&dest[0], data, len));
- return dest;
-}
-
-std::string
-base64_encode(string_view s)
-{
- return base64_encode (reinterpret_cast <
- std::uint8_t const*> (s.data()), s.size());
-}
-
} // detail
} // beast
} // boost
diff --git a/boost/beast/core/detail/buffers_range_adaptor.hpp b/boost/beast/core/detail/buffers_range_adaptor.hpp
index 2e04d14f6d..e8e5147433 100644
--- a/boost/beast/core/detail/buffers_range_adaptor.hpp
+++ b/boost/beast/core/detail/buffers_range_adaptor.hpp
@@ -38,13 +38,9 @@ public:
buffers_iterator_type<BufferSequence>;
iter_type it_{};
- buffers_range_adaptor const* b_ = nullptr;
- const_iterator(
- buffers_range_adaptor const& b,
- iter_type const& it)
+ const_iterator(iter_type const& it)
: it_(it)
- , b_(&b)
{
}
@@ -62,7 +58,7 @@ public:
bool
operator==(const_iterator const& other) const
{
- return b_ == other.b_ && it_ == other.it_;
+ return it_ == other.it_;
}
bool
@@ -111,11 +107,6 @@ public:
}
};
- buffers_range_adaptor(
- buffers_range_adaptor const&) = default;
- buffers_range_adaptor& operator=(
- buffers_range_adaptor const&) = default;
-
explicit
buffers_range_adaptor(BufferSequence const& b)
: b_(b)
@@ -125,13 +116,13 @@ public:
const_iterator
begin() const noexcept
{
- return {*this, net::buffer_sequence_begin(b_)};
+ return {net::buffer_sequence_begin(b_)};
}
const_iterator
end() const noexcept
{
- return {*this, net::buffer_sequence_end(b_)};
+ return {net::buffer_sequence_end(b_)};
}
};
diff --git a/boost/beast/core/detail/char_buffer.hpp b/boost/beast/core/detail/char_buffer.hpp
new file mode 100644
index 0000000000..b1970ebc0a
--- /dev/null
+++ b/boost/beast/core/detail/char_buffer.hpp
@@ -0,0 +1,78 @@
+//
+// Copyright (c) 2019 Damian Jarek(damian.jarek93@gmail.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_CORE_DETAIL_CHAR_BUFFER_HPP
+#define BOOST_BEAST_CORE_DETAIL_CHAR_BUFFER_HPP
+
+#include <boost/config.hpp>
+#include <cstddef>
+#include <cstring>
+#include <cstdint>
+
+namespace boost {
+namespace beast {
+namespace detail {
+
+template <std::size_t N>
+class char_buffer
+{
+public:
+ bool try_push_back(char c)
+ {
+ if (size_ == N)
+ return false;
+ buf_[size_++] = c;
+ return true;
+ }
+
+ bool try_append(char const* first, char const* last)
+ {
+ std::size_t const n = last - first;
+ if (n > N - size_)
+ return false;
+ std::memmove(&buf_[size_], first, n);
+ size_ += n;
+ return true;
+ }
+
+ void clear() noexcept
+ {
+ size_ = 0;
+ }
+
+ char* data() noexcept
+ {
+ return buf_;
+ }
+
+ char const* data() const noexcept
+ {
+ return buf_;
+ }
+
+ std::size_t size() const noexcept
+ {
+ return size_;
+ }
+
+ bool empty() const noexcept
+ {
+ return size_ == 0;
+ }
+
+private:
+ std::size_t size_= 0;
+ char buf_[N];
+};
+
+} // detail
+} // beast
+} // boost
+
+#endif
diff --git a/boost/beast/core/detail/impl/read.hpp b/boost/beast/core/detail/impl/read.hpp
index 137384aa40..3724979272 100644
--- a/boost/beast/core/detail/impl/read.hpp
+++ b/boost/beast/core/detail/impl/read.hpp
@@ -13,6 +13,7 @@
#include <boost/beast/core/bind_handler.hpp>
#include <boost/beast/core/async_base.hpp>
#include <boost/beast/core/flat_static_buffer.hpp>
+#include <boost/beast/core/read_size.hpp>
#include <boost/asio/basic_stream_socket.hpp>
#include <boost/asio/coroutine.hpp>
#include <boost/throw_exception.hpp>
@@ -37,7 +38,7 @@ template<
class Condition,
class Handler>
class read_op
- : public net::coroutine
+ : public asio::coroutine
, public async_base<
Handler, beast::executor_type<Stream>>
{
@@ -73,18 +74,12 @@ public:
std::size_t bytes_transferred,
bool cont = true)
{
- std::size_t max_size;
std::size_t max_prepare;
BOOST_ASIO_CORO_REENTER(*this)
{
for(;;)
{
- max_size = cond_(ec, total_, b_);
- max_prepare = std::min<std::size_t>(
- std::max<std::size_t>(
- 512, b_.capacity() - b_.size()),
- std::min<std::size_t>(
- max_size, b_.max_size() - b_.size()));
+ max_prepare = beast::read_size(b_, cond_(ec, total_, b_));
if(max_prepare == 0)
break;
BOOST_ASIO_CORO_YIELD
@@ -201,16 +196,10 @@ read(
"CompletionCondition type requirements not met");
ec = {};
std::size_t total = 0;
- std::size_t max_size;
std::size_t max_prepare;
for(;;)
{
- max_size = cond(ec, total, buffer);
- max_prepare = std::min<std::size_t>(
- std::max<std::size_t>(
- 512, buffer.capacity() - buffer.size()),
- std::min<std::size_t>(
- max_size, buffer.max_size() - buffer.size()));
+ max_prepare = beast::read_size(buffer, cond(ec, total, buffer));
if(max_prepare == 0)
break;
std::size_t const bytes_transferred =
diff --git a/boost/beast/core/detail/impl/temporary_buffer.ipp b/boost/beast/core/detail/impl/temporary_buffer.ipp
new file mode 100644
index 0000000000..932e847371
--- /dev/null
+++ b/boost/beast/core/detail/impl/temporary_buffer.ipp
@@ -0,0 +1,69 @@
+//
+// Copyright (c) 2019 Damian Jarek(damian.jarek93@gmail.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_DETAIL_IMPL_TEMPORARY_BUFFER_IPP
+#define BOOST_BEAST_DETAIL_IMPL_TEMPORARY_BUFFER_IPP
+
+#include <boost/beast/core/detail/temporary_buffer.hpp>
+#include <boost/beast/core/detail/clamp.hpp>
+#include <boost/core/exchange.hpp>
+#include <boost/assert.hpp>
+#include <memory>
+#include <cstring>
+
+namespace boost {
+namespace beast {
+namespace detail {
+
+void
+temporary_buffer::
+append(string_view s)
+{
+ grow(s.size());
+ unchecked_append(s);
+}
+
+void
+temporary_buffer::
+append(string_view s1, string_view s2)
+{
+ grow(s1.size() + s2.size());
+ unchecked_append(s1);
+ unchecked_append(s2);
+}
+
+void
+temporary_buffer::
+unchecked_append(string_view s)
+{
+ auto n = s.size();
+ std::memcpy(&data_[size_], s.data(), n);
+ size_ += n;
+}
+
+void
+temporary_buffer::
+grow(std::size_t n)
+{
+ if (capacity_ - size_ >= n)
+ return;
+
+ auto const capacity = (n + size_) * 2u;
+ BOOST_ASSERT(! detail::sum_exceeds(
+ n, size_, capacity));
+ char* const p = new char[capacity];
+ std::memcpy(p, data_, size_);
+ deallocate(boost::exchange(data_, p));
+ capacity_ = capacity;
+}
+} // detail
+} // beast
+} // boost
+
+#endif
diff --git a/boost/beast/core/detail/ostream.hpp b/boost/beast/core/detail/ostream.hpp
index 65da560179..8785c2e6d8 100644
--- a/boost/beast/core/detail/ostream.hpp
+++ b/boost/beast/core/detail/ostream.hpp
@@ -12,7 +12,6 @@
#include <boost/beast/core/buffers_prefix.hpp>
#include <boost/beast/core/buffers_range.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/throw_exception.hpp>
#include <boost/asio/buffer.hpp>
#include <memory>
diff --git a/boost/beast/core/detail/remap_post_to_defer.hpp b/boost/beast/core/detail/remap_post_to_defer.hpp
index 77f7d8ab20..850a833b52 100644
--- a/boost/beast/core/detail/remap_post_to_defer.hpp
+++ b/boost/beast/core/detail/remap_post_to_defer.hpp
@@ -10,7 +10,6 @@
#ifndef BOOST_BEAST_DETAIL_REMAP_POST_TO_DEFER_HPP
#define BOOST_BEAST_DETAIL_REMAP_POST_TO_DEFER_HPP
-#include <boost/asio/bind_executor.hpp>
#include <boost/asio/is_executor.hpp>
#include <boost/core/empty_value.hpp>
#include <type_traits>
diff --git a/boost/beast/core/detail/service_base.hpp b/boost/beast/core/detail/service_base.hpp
index adec09bbf1..1efe121516 100644
--- a/boost/beast/core/detail/service_base.hpp
+++ b/boost/beast/core/detail/service_base.hpp
@@ -17,14 +17,9 @@ namespace beast {
namespace detail {
template<class T>
-struct service_id : net::execution_context::id
-{
-};
-
-template<class T>
struct service_base : net::execution_context::service
{
- static service_id<T> id;
+ static net::execution_context::id const id;
explicit
service_base(net::execution_context& ctx)
@@ -34,7 +29,7 @@ struct service_base : net::execution_context::service
};
template<class T>
-service_id<T> service_base<T>::id;
+net::execution_context::id const service_base<T>::id;
} // detail
} // beast
diff --git a/boost/beast/core/detail/sha1.hpp b/boost/beast/core/detail/sha1.hpp
index abcc307407..c4c8d5e3fd 100644
--- a/boost/beast/core/detail/sha1.hpp
+++ b/boost/beast/core/detail/sha1.hpp
@@ -11,10 +11,7 @@
#define BOOST_BEAST_DETAIL_SHA1_HPP
#include <boost/beast/core/detail/config.hpp>
-
-#include <algorithm>
#include <cstdint>
-#include <cstring>
// Based on https://github.com/vog/sha1
/*
diff --git a/boost/beast/core/detail/string.hpp b/boost/beast/core/detail/string.hpp
new file mode 100644
index 0000000000..b553c60439
--- /dev/null
+++ b/boost/beast/core/detail/string.hpp
@@ -0,0 +1,44 @@
+//
+// 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_DETAIL_STRING_HPP
+#define BOOST_BEAST_DETAIL_STRING_HPP
+
+#include <boost/beast/core/string_type.hpp>
+
+namespace boost {
+namespace beast {
+
+namespace detail {
+
+// Pulling in the UDL directly breaks in some places on MSVC,
+// so introduce a namespace for this purprose.
+namespace string_literals {
+
+inline
+string_view
+operator"" _sv(char const* p, std::size_t n)
+{
+ return string_view{p, n};
+}
+
+} // string_literals
+
+inline
+char
+ascii_tolower(char c)
+{
+ return ((static_cast<unsigned>(c) - 65U) < 26) ?
+ c + 'a' - 'A' : c;
+}
+} // detail
+} // beast
+} // boost
+
+#endif
diff --git a/boost/beast/core/detail/temporary_buffer.hpp b/boost/beast/core/detail/temporary_buffer.hpp
new file mode 100644
index 0000000000..8285b8f7eb
--- /dev/null
+++ b/boost/beast/core/detail/temporary_buffer.hpp
@@ -0,0 +1,83 @@
+//
+// Copyright (c) 2019 Damian Jarek(damian.jarek93@gmail.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_DETAIL_TEMPORARY_BUFFER_HPP
+#define BOOST_BEAST_DETAIL_TEMPORARY_BUFFER_HPP
+
+#include <boost/beast/core/detail/config.hpp>
+#include <boost/beast/core/string.hpp>
+
+#include <memory>
+
+namespace boost {
+namespace beast {
+namespace detail {
+
+struct temporary_buffer
+{
+ temporary_buffer() = default;
+ temporary_buffer(temporary_buffer const&) = delete;
+ temporary_buffer& operator=(temporary_buffer const&) = delete;
+
+ ~temporary_buffer() noexcept
+ {
+ deallocate(data_);
+ }
+
+ BOOST_BEAST_DECL
+ void
+ append(string_view s);
+
+ BOOST_BEAST_DECL
+ void
+ append(string_view s1, string_view s2);
+
+ string_view
+ view() const noexcept
+ {
+ return {data_, size_};
+ }
+
+ bool
+ empty() const noexcept
+ {
+ return size_ == 0;
+ }
+
+private:
+ BOOST_BEAST_DECL
+ void
+ unchecked_append(string_view s);
+
+ BOOST_BEAST_DECL
+ void
+ grow(std::size_t n);
+
+ void
+ deallocate(char* data) noexcept
+ {
+ if (data != buffer_)
+ delete[] data;
+ }
+
+ char buffer_[4096];
+ char* data_ = buffer_;
+ std::size_t capacity_ = sizeof(buffer_);
+ std::size_t size_ = 0;
+};
+
+} // detail
+} // beast
+} // boost
+
+#ifdef BOOST_BEAST_HEADER_ONLY
+#include <boost/beast/core/detail/impl/temporary_buffer.ipp>
+#endif
+
+#endif
diff --git a/boost/beast/core/detail/type_traits.hpp b/boost/beast/core/detail/type_traits.hpp
index 3d895403b3..e94abbb179 100644
--- a/boost/beast/core/detail/type_traits.hpp
+++ b/boost/beast/core/detail/type_traits.hpp
@@ -10,36 +10,14 @@
#ifndef BOOST_BEAST_DETAIL_TYPE_TRAITS_HPP
#define BOOST_BEAST_DETAIL_TYPE_TRAITS_HPP
-#include <boost/beast/core/error.hpp>
-#include <boost/beast/core/detail/is_invocable.hpp>
-#include <boost/asio/buffer.hpp>
-#include <boost/mp11/function.hpp>
#include <boost/type_traits/make_void.hpp>
-#include <iterator>
-#include <tuple>
#include <type_traits>
-#include <string>
-#include <utility>
+#include <new>
namespace boost {
namespace beast {
namespace detail {
-// variadic min
-template<class T>
-T constexpr min(T t)
-{
- return t;
-}
-
-template<class T, class...Tn>
-T constexpr min(T t0, T t1, Tn... tn)
-{
- return (t0 < t1) ?
- (detail::min)(t0, tn...) :
- (detail::min)(t1, tn...);
-}
-
template<class U>
std::size_t constexpr
max_sizeof()
@@ -97,12 +75,6 @@ using aligned_union_t =
//------------------------------------------------------------------------------
-template<class T>
-void
-accept_rv(T){}
-
-//------------------------------------------------------------------------------
-
// for span
template<class T, class E, class = void>
struct is_contiguous_container: std::false_type {};
@@ -124,6 +96,18 @@ struct is_contiguous_container<T, E, void_t<
>::type>>: std::true_type
{};
+template <class T, class U>
+T launder_cast(U* u)
+{
+#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
+ return std::launder(reinterpret_cast<T>(u));
+#elif defined(BOOST_GCC) && BOOST_GCC_VERSION > 80000
+ return __builtin_launder(reinterpret_cast<T>(u));
+#else
+ return reinterpret_cast<T>(u);
+#endif
+}
+
} // detail
} // beast
} // boost
diff --git a/boost/beast/core/detail/variant.hpp b/boost/beast/core/detail/variant.hpp
index 94bd4c040c..f6f5b3c60b 100644
--- a/boost/beast/core/detail/variant.hpp
+++ b/boost/beast/core/detail/variant.hpp
@@ -45,7 +45,7 @@ class variant
{
using T =
mp11::mp_at_c<variant, I::value - 1>;
- reinterpret_cast<T&>(self.buf_).~T();
+ detail::launder_cast<T*>(&self.buf_)->~T();
}
};
@@ -64,7 +64,7 @@ class variant
using T =
mp11::mp_at_c<variant, I::value - 1>;
::new(&self.buf_) T(
- reinterpret_cast<T const&>(other.buf_));
+ *detail::launder_cast<T const*>(&other.buf_));
self.i_ = I::value;
}
};
@@ -83,9 +83,9 @@ class variant
{
using T =
mp11::mp_at_c<variant, I::value - 1>;
- ::new(&self.buf_) T(
- reinterpret_cast<T&&>(other.buf_));
- reinterpret_cast<T&>(other.buf_).~T();
+ ::new(&self.buf_) T(std::move(
+ *detail::launder_cast<T*>(&other.buf_)));
+ detail::launder_cast<T*>(&other.buf_)->~T();
self.i_ = I::value;
}
};
@@ -106,8 +106,8 @@ class variant
using T =
mp11::mp_at_c<variant, I::value - 1>;
return
- reinterpret_cast<T const&>(self.buf_) ==
- reinterpret_cast<T const&>(other.buf_);
+ *detail::launder_cast<T const*>(&self.buf_) ==
+ *detail::launder_cast<T const*>(&other.buf_);
}
};
@@ -181,7 +181,7 @@ public:
}
return *this;
}
-
+
variant& operator=(variant const& other)
{
if(this != &other)
@@ -208,7 +208,7 @@ public:
get()
{
BOOST_ASSERT(i_ == I);
- return *reinterpret_cast<
+ return *detail::launder_cast<
mp11::mp_at_c<variant, I - 1>*>(&buf_);
}
@@ -217,7 +217,7 @@ public:
get() const
{
BOOST_ASSERT(i_ == I);
- return *reinterpret_cast<
+ return *detail::launder_cast<
mp11::mp_at_c<variant, I - 1> const*>(&buf_);
}
diff --git a/boost/beast/core/detect_ssl.hpp b/boost/beast/core/detect_ssl.hpp
index b7b0550175..9281156819 100644
--- a/boost/beast/core/detect_ssl.hpp
+++ b/boost/beast/core/detect_ssl.hpp
@@ -430,7 +430,6 @@ async_detect_ssl(
// Non-const references need to be passed as pointers,
// since we don't want a decay-copy.
-
return net::async_initiate<
CompletionToken,
void(error_code, bool)>(
@@ -505,7 +504,7 @@ public:
AsyncReadStream& stream,
DynamicBuffer& buffer)
: beast::async_base<
- DetectHandler_,
+ DetectHandler,
beast::executor_type<AsyncReadStream>>(
std::forward<DetectHandler_>(handler),
stream.get_executor())
diff --git a/boost/beast/core/impl/async_base.hpp b/boost/beast/core/impl/async_base.hpp
index ec17b1cc1e..8dc8cb29a9 100644
--- a/boost/beast/core/impl/async_base.hpp
+++ b/boost/beast/core/impl/async_base.hpp
@@ -42,8 +42,9 @@ struct allocate_stable_state final
allocate_stable_state>;
A a(this->get());
- detail::allocator_traits<A>::destroy(a, this);
- detail::allocator_traits<A>::deallocate(a, this, 1);
+ auto* p = this;
+ p->~allocate_stable_state();
+ a.deallocate(p, 1);
}
};
@@ -118,33 +119,30 @@ allocate_stable(
{
using allocator_type = typename stable_async_base<
Handler, Executor1, Allocator>::allocator_type;
-
+ using state = detail::allocate_stable_state<
+ State, allocator_type>;
using A = typename detail::allocator_traits<
- allocator_type>::template rebind_alloc<
- detail::allocate_stable_state<
- State, allocator_type>>;
+ allocator_type>::template rebind_alloc<state>;
struct deleter
{
allocator_type alloc;
- detail::allocate_stable_state<
- State, allocator_type>* ptr;
+ state* ptr;
~deleter()
{
if(ptr)
{
A a(alloc);
- detail::allocator_traits<A>::deallocate(a, ptr, 1);
+ a.deallocate(ptr, 1);
}
}
};
A a(base.get_allocator());
- deleter d{base.get_allocator(), nullptr};
- d.ptr = detail::allocator_traits<A>::allocate(a, 1);
- detail::allocator_traits<A>::construct(a, d.ptr,
- d.alloc, std::forward<Args>(args)...);
+ deleter d{base.get_allocator(), a.allocate(1)};
+ ::new(static_cast<void*>(d.ptr))
+ state(d.alloc, std::forward<Args>(args)...);
d.ptr->next_ = base.list_;
base.list_ = d.ptr;
return boost::exchange(d.ptr, nullptr)->value;
diff --git a/boost/beast/core/impl/basic_stream.hpp b/boost/beast/core/impl/basic_stream.hpp
index c871944552..336c09f227 100644
--- a/boost/beast/core/impl/basic_stream.hpp
+++ b/boost/beast/core/impl/basic_stream.hpp
@@ -13,9 +13,7 @@
#include <boost/beast/core/async_base.hpp>
#include <boost/beast/core/buffer_traits.hpp>
#include <boost/beast/core/buffers_prefix.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/beast/websocket/teardown.hpp>
-#include <boost/asio/bind_executor.hpp>
#include <boost/asio/coroutine.hpp>
#include <boost/assert.hpp>
#include <boost/make_shared.hpp>
@@ -161,12 +159,21 @@ close()
//------------------------------------------------------------------------------
template<class Protocol, class Executor, class RatePolicy>
+template<class Executor2>
struct basic_stream<Protocol, Executor, RatePolicy>::
timeout_handler
{
+ using executor_type = Executor2;
+
op_state& state;
boost::weak_ptr<impl_type> wp;
tick_type tick;
+ executor_type ex;
+
+ executor_type get_executor() const noexcept
+ {
+ return ex;
+ }
void
operator()(error_code ec)
@@ -212,62 +219,34 @@ class transfer_op
using is_read = std::integral_constant<bool, isRead>;
op_state&
- state(std::true_type)
- {
- return impl_->read;
- }
-
- op_state&
- state(std::false_type)
- {
- return impl_->write;
- }
-
- op_state&
state()
{
- return state(
- std::integral_constant<bool, isRead>{});
- }
-
- std::size_t
- available_bytes(std::true_type)
- {
- return rate_policy_access::
- available_read_bytes(impl_->policy());
- }
-
- std::size_t
- available_bytes(std::false_type)
- {
- return rate_policy_access::
- available_write_bytes(impl_->policy());
+ if (isRead)
+ return impl_->read;
+ else
+ return impl_->write;
}
std::size_t
available_bytes()
{
- return available_bytes(is_read{});
- }
-
- void
- transfer_bytes(std::size_t n, std::true_type)
- {
- rate_policy_access::
- transfer_read_bytes(impl_->policy(), n);
- }
-
- void
- transfer_bytes(std::size_t n, std::false_type)
- {
- rate_policy_access::
- transfer_write_bytes(impl_->policy(), n);
+ if (isRead)
+ return rate_policy_access::
+ available_read_bytes(impl_->policy());
+ else
+ return rate_policy_access::
+ available_write_bytes(impl_->policy());
}
void
transfer_bytes(std::size_t n)
{
- transfer_bytes(n, is_read{});
+ if (isRead)
+ rate_policy_access::
+ transfer_read_bytes(impl_->policy(), n);
+ else
+ rate_policy_access::
+ transfer_write_bytes(impl_->policy(), n);
}
void
@@ -329,13 +308,11 @@ public:
// if a timeout is active, wait on the timer
if(state().timer.expiry() != never())
state().timer.async_wait(
- net::bind_executor(
- this->get_executor(),
- timeout_handler{
- state(),
- impl_,
- state().tick
- }));
+ timeout_handler<decltype(this->get_executor())>{
+ state(),
+ impl_,
+ state().tick,
+ this->get_executor()});
// check rate limit, maybe wait
std::size_t amount;
@@ -430,12 +407,11 @@ public:
{
if(state().timer.expiry() != stream_base::never())
impl_->write.timer.async_wait(
- net::bind_executor(
- this->get_executor(),
- timeout_handler{
- state(),
- impl_,
- state().tick}));
+ timeout_handler<decltype(this->get_executor())>{
+ state(),
+ impl_,
+ state().tick,
+ this->get_executor()});
impl_->socket.async_connect(
ep, std::move(*this));
@@ -458,12 +434,11 @@ public:
{
if(state().timer.expiry() != stream_base::never())
impl_->write.timer.async_wait(
- net::bind_executor(
- this->get_executor(),
- timeout_handler{
- state(),
- impl_,
- state().tick}));
+ timeout_handler<decltype(this->get_executor())>{
+ state(),
+ impl_,
+ state().tick,
+ this->get_executor()});
net::async_connect(impl_->socket,
eps, cond, std::move(*this));
@@ -486,12 +461,11 @@ public:
{
if(state().timer.expiry() != stream_base::never())
impl_->write.timer.async_wait(
- net::bind_executor(
- this->get_executor(),
- timeout_handler{
- state(),
- impl_,
- state().tick}));
+ timeout_handler<decltype(this->get_executor())>{
+ state(),
+ impl_,
+ state().tick,
+ this->get_executor()});
net::async_connect(impl_->socket,
begin, end, cond, std::move(*this));
diff --git a/boost/beast/core/impl/buffered_read_stream.hpp b/boost/beast/core/impl/buffered_read_stream.hpp
index 184881164f..cea0dcb9fa 100644
--- a/boost/beast/core/impl/buffered_read_stream.hpp
+++ b/boost/beast/core/impl/buffered_read_stream.hpp
@@ -15,7 +15,7 @@
#include <boost/beast/core/error.hpp>
#include <boost/beast/core/read_size.hpp>
#include <boost/beast/core/stream_traits.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
+#include <boost/beast/core/detail/is_invocable.hpp>
#include <boost/asio/post.hpp>
#include <boost/throw_exception.hpp>
diff --git a/boost/beast/core/impl/buffers_adaptor.hpp b/boost/beast/core/impl/buffers_adaptor.hpp
index 91caad5463..3eac32f6e0 100644
--- a/boost/beast/core/impl/buffers_adaptor.hpp
+++ b/boost/beast/core/impl/buffers_adaptor.hpp
@@ -11,7 +11,6 @@
#define BOOST_BEAST_IMPL_BUFFERS_ADAPTOR_HPP
#include <boost/beast/core/buffer_traits.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/config/workaround.hpp>
#include <boost/throw_exception.hpp>
diff --git a/boost/beast/core/impl/buffers_cat.hpp b/boost/beast/core/impl/buffers_cat.hpp
index 255153f2bd..a0506a0b35 100644
--- a/boost/beast/core/impl/buffers_cat.hpp
+++ b/boost/beast/core/impl/buffers_cat.hpp
@@ -11,7 +11,6 @@
#define BOOST_BEAST_IMPL_BUFFERS_CAT_HPP
#include <boost/beast/core/detail/tuple.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/beast/core/detail/variant.hpp>
#include <boost/asio/buffer.hpp>
#include <cstdint>
@@ -23,6 +22,34 @@
namespace boost {
namespace beast {
+template<class Buffer>
+class buffers_cat_view<Buffer>
+{
+ Buffer buffer_;
+public:
+ using value_type = buffers_type<Buffer>;
+
+ using const_iterator = buffers_iterator_type<Buffer>;
+
+ explicit
+ buffers_cat_view(Buffer const& buffer)
+ : buffer_(buffer)
+ {
+ }
+
+ const_iterator
+ begin() const
+ {
+ return net::buffer_sequence_begin(buffer_);
+ }
+
+ const_iterator
+ end() const
+ {
+ return net::buffer_sequence_end(buffer_);
+ }
+};
+
#if defined(_MSC_VER) && ! defined(__clang__)
# define BOOST_BEAST_UNREACHABLE() __assume(false)
# define BOOST_BEAST_UNREACHABLE_RETURN(v) __assume(false)
diff --git a/boost/beast/core/impl/flat_buffer.hpp b/boost/beast/core/impl/flat_buffer.hpp
index f7fd51673d..83d3b4e74b 100644
--- a/boost/beast/core/impl/flat_buffer.hpp
+++ b/boost/beast/core/impl/flat_buffer.hpp
@@ -403,7 +403,7 @@ copy_from(
if(begin_)
{
BOOST_ASSERT(other.begin_);
- std::memcpy(begin_, other.begin_, n);
+ std::memcpy(begin_, other.in_, n);
}
}
diff --git a/boost/beast/core/impl/flat_stream.hpp b/boost/beast/core/impl/flat_stream.hpp
index 2972131198..f99ec02678 100644
--- a/boost/beast/core/impl/flat_stream.hpp
+++ b/boost/beast/core/impl/flat_stream.hpp
@@ -16,7 +16,6 @@
#include <boost/beast/core/stream_traits.hpp>
#include <boost/beast/websocket/teardown.hpp>
#include <boost/asio/buffer.hpp>
-#include <boost/asio/coroutine.hpp>
#include <memory>
namespace boost {
@@ -30,7 +29,6 @@ template<class Handler>
class write_op
: public async_base<Handler,
beast::executor_type<flat_stream>>
- , public net::coroutine
{
public:
template<
diff --git a/boost/beast/core/impl/multi_buffer.hpp b/boost/beast/core/impl/multi_buffer.hpp
index 643f60ce2b..29a10fa17b 100644
--- a/boost/beast/core/impl/multi_buffer.hpp
+++ b/boost/beast/core/impl/multi_buffer.hpp
@@ -11,7 +11,6 @@
#define BOOST_BEAST_IMPL_MULTI_BUFFER_HPP
#include <boost/beast/core/buffer_traits.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/config/workaround.hpp>
#include <boost/core/exchange.hpp>
#include <boost/assert.hpp>
@@ -88,41 +87,6 @@ namespace beast {
in_pos_ out_pos_ == 0
out_end_ == 0
*/
-//------------------------------------------------------------------------------
-
-template<class Allocator>
-class basic_multi_buffer<Allocator>::element
- : public boost::intrusive::list_base_hook<
- boost::intrusive::link_mode<
- boost::intrusive::normal_link>>
-{
- using size_type = typename
- detail::allocator_traits<Allocator>::size_type;
-
- size_type const size_;
-
-public:
- element(element const&) = delete;
-
- explicit
- element(size_type n) noexcept
- : size_(n)
- {
- }
-
- size_type
- size() const noexcept
- {
- return size_;
- }
-
- char*
- data() const noexcept
- {
- return const_cast<char*>(
- reinterpret_cast<char const*>(this + 1));
- }
-};
//------------------------------------------------------------------------------
@@ -487,7 +451,7 @@ template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(
Allocator const& alloc) noexcept
- : boost::empty_value<base_alloc_type>(
+ : boost::empty_value<Allocator>(
boost::empty_init_t(), alloc)
, max_(alloc_traits::max_size(this->get()))
, out_(list_.end())
@@ -499,8 +463,8 @@ basic_multi_buffer<Allocator>::
basic_multi_buffer(
std::size_t limit,
Allocator const& alloc) noexcept
- : boost::empty_value<
- base_alloc_type>(boost::empty_init_t(), alloc)
+ : boost::empty_value<Allocator>(
+ boost::empty_init_t(), alloc)
, max_(limit)
, out_(list_.end())
{
@@ -510,7 +474,7 @@ template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(
basic_multi_buffer&& other) noexcept
- : boost::empty_value<base_alloc_type>(
+ : boost::empty_value<Allocator>(
boost::empty_init_t(), std::move(other.get()))
, max_(other.max_)
, in_size_(boost::exchange(other.in_size_, 0))
@@ -529,9 +493,9 @@ template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(
basic_multi_buffer&& other,
- Allocator const& alloc)
- : boost::empty_value<
- base_alloc_type>(boost::empty_init_t(), alloc)
+ Allocator const& alloc)
+ : boost::empty_value<Allocator>(
+ boost::empty_init_t(), alloc)
, max_(other.max_)
{
if(this->get() != other.get())
@@ -562,7 +526,7 @@ template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(
basic_multi_buffer const& other)
- : boost::empty_value<base_alloc_type>(
+ : boost::empty_value<Allocator>(
boost::empty_init_t(), alloc_traits::
select_on_container_copy_construction(
other.get()))
@@ -577,7 +541,7 @@ basic_multi_buffer<Allocator>::
basic_multi_buffer(
basic_multi_buffer const& other,
Allocator const& alloc)
- : boost::empty_value<base_alloc_type>(
+ : boost::empty_value<Allocator>(
boost::empty_init_t(), alloc)
, max_(other.max_)
, out_(list_.end())
@@ -601,8 +565,8 @@ basic_multi_buffer<Allocator>::
basic_multi_buffer(
basic_multi_buffer<OtherAlloc> const& other,
allocator_type const& alloc)
- : boost::empty_value<
- base_alloc_type>(boost::empty_init_t(), alloc)
+ : boost::empty_value<Allocator>(
+ boost::empty_init_t(), alloc)
, max_(other.max_)
, out_(list_.end())
{
@@ -1012,10 +976,7 @@ consume(size_type n) noexcept
in_pos_ = 0;
auto& e = list_.front();
list_.erase(list_.iterator_to(e));
- auto const len = sizeof(e) + e.size();
- e.~element();
- alloc_traits::deallocate(this->get(),
- reinterpret_cast<char*>(&e), len);
+ destroy(e);
#if BOOST_BEAST_MULTI_BUFFER_DEBUG_CHECK
debug_check();
#endif
@@ -1216,10 +1177,14 @@ void
basic_multi_buffer<Allocator>::
destroy(element& e)
{
- auto const len = sizeof(e) + e.size();
+ auto a = rebind_type{this->get()};
+ auto const n =
+ (sizeof(element) + e.size() +
+ sizeof(align_type) - 1) /
+ sizeof(align_type);
e.~element();
- alloc_traits::deallocate(this->get(),
- reinterpret_cast<char*>(&e), len);
+ alloc_traits::deallocate(a,
+ reinterpret_cast<align_type*>(&e), n);
}
template<class Allocator>
@@ -1231,9 +1196,11 @@ alloc(std::size_t size) ->
if(size > alloc_traits::max_size(this->get()))
BOOST_THROW_EXCEPTION(std::length_error(
"A basic_multi_buffer exceeded the allocator's maximum size"));
- return *::new(alloc_traits::allocate(
- this->get(),
- sizeof(element) + size)) element(size);
+ auto a = rebind_type{this->get()};
+ auto const p = alloc_traits::allocate(a,
+ (sizeof(element) + size + sizeof(align_type) - 1) /
+ sizeof(align_type));
+ return *(::new(p) element(size));
}
template<class Allocator>
diff --git a/boost/beast/core/impl/read_size.hpp b/boost/beast/core/impl/read_size.hpp
index 1896c014b8..babbcaac11 100644
--- a/boost/beast/core/impl/read_size.hpp
+++ b/boost/beast/core/impl/read_size.hpp
@@ -46,7 +46,6 @@ read_size(DynamicBuffer& buffer,
static_assert(
net::is_dynamic_buffer<DynamicBuffer>::value,
"DynamicBuffer type requirements not met");
- BOOST_ASSERT(max_size >= 1);
auto const size = buffer.size();
auto const limit = buffer.max_size() - size;
BOOST_ASSERT(size <= buffer.max_size());
diff --git a/boost/beast/core/impl/static_buffer.hpp b/boost/beast/core/impl/static_buffer.hpp
index dee13bfbe5..ae4f53c1b5 100644
--- a/boost/beast/core/impl/static_buffer.hpp
+++ b/boost/beast/core/impl/static_buffer.hpp
@@ -10,12 +10,7 @@
#ifndef BOOST_BEAST_IMPL_STATIC_BUFFER_HPP
#define BOOST_BEAST_IMPL_STATIC_BUFFER_HPP
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/asio/buffer.hpp>
-#include <boost/throw_exception.hpp>
-#include <algorithm>
-#include <cstring>
-#include <iterator>
#include <stdexcept>
namespace boost {
diff --git a/boost/beast/core/impl/static_buffer.ipp b/boost/beast/core/impl/static_buffer.ipp
index c26ff429b8..b87d704b65 100644
--- a/boost/beast/core/impl/static_buffer.ipp
+++ b/boost/beast/core/impl/static_buffer.ipp
@@ -11,12 +11,8 @@
#define BOOST_BEAST_IMPL_STATIC_BUFFER_IPP
#include <boost/beast/core/static_buffer.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/throw_exception.hpp>
-#include <algorithm>
-#include <cstring>
-#include <iterator>
#include <stdexcept>
namespace boost {
diff --git a/boost/beast/core/impl/static_string.hpp b/boost/beast/core/impl/static_string.hpp
index c668b837fa..2e3e5617ab 100644
--- a/boost/beast/core/impl/static_string.hpp
+++ b/boost/beast/core/impl/static_string.hpp
@@ -11,7 +11,6 @@
#define BOOST_BEAST_IMPL_STATIC_STRING_HPP
#include <boost/beast/core/detail/static_string.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/throw_exception.hpp>
namespace boost {
@@ -559,64 +558,6 @@ assign_char(CharT, std::false_type) ->
"max_size() == 0"});
}
-namespace detail {
-
-template<class Integer>
-static_string<max_digits(sizeof(Integer))>
-to_static_string(Integer x, std::true_type)
-{
- if(x == 0)
- return {'0'};
- static_string<detail::max_digits(
- sizeof(Integer))> s;
- if(x < 0)
- {
- x = -x;
- char buf[max_digits(sizeof(x))];
- char* p = buf;
- for(;x > 0; x /= 10)
- *p++ = "0123456789"[x % 10];
- s.resize(1 + p - buf);
- s[0] = '-';
- auto d = &s[1];
- while(p > buf)
- *d++ = *--p;
- }
- else
- {
- char buf[max_digits(sizeof(x))];
- char* p = buf;
- for(;x > 0; x /= 10)
- *p++ = "0123456789"[x % 10];
- s.resize(p - buf);
- auto d = &s[0];
- while(p > buf)
- *d++ = *--p;
- }
- return s;
-}
-
-template<class Integer>
-static_string<max_digits(sizeof(Integer))>
-to_static_string(Integer x, std::false_type)
-{
- if(x == 0)
- return {'0'};
- char buf[max_digits(sizeof(x))];
- char* p = buf;
- for(;x > 0; x /= 10)
- *p++ = "0123456789"[x % 10];
- static_string<detail::max_digits(
- sizeof(Integer))> s;
- s.resize(p - buf);
- auto d = &s[0];
- while(p > buf)
- *d++ = *--p;
- return s;
-}
-
-} // detail
-
template<class Integer, class>
static_string<detail::max_digits(sizeof(Integer))>
to_static_string(Integer x)
diff --git a/boost/beast/core/impl/string.ipp b/boost/beast/core/impl/string.ipp
new file mode 100644
index 0000000000..b64ce3f6aa
--- /dev/null
+++ b/boost/beast/core/impl/string.ipp
@@ -0,0 +1,73 @@
+//
+// 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_IMPL_STRING_IPP
+#define BOOST_BEAST_IMPL_STRING_IPP
+
+#include <boost/beast/core/string.hpp>
+#include <boost/beast/core/detail/string.hpp>
+
+#include <algorithm>
+
+namespace boost {
+namespace beast {
+
+bool
+iequals(
+ beast::string_view lhs,
+ beast::string_view rhs)
+{
+ auto n = lhs.size();
+ if(rhs.size() != n)
+ return false;
+ auto p1 = lhs.data();
+ auto p2 = rhs.data();
+ char a, b;
+ // fast loop
+ while(n--)
+ {
+ a = *p1++;
+ b = *p2++;
+ if(a != b)
+ goto slow;
+ }
+ return true;
+slow:
+ do
+ {
+ if( detail::ascii_tolower(a) !=
+ detail::ascii_tolower(b))
+ return false;
+ a = *p1++;
+ b = *p2++;
+ }
+ while(n--);
+ return true;
+}
+
+bool
+iless::operator()(
+ string_view lhs,
+ string_view rhs) const
+{
+ using std::begin;
+ using std::end;
+ return std::lexicographical_compare(
+ begin(lhs), end(lhs), begin(rhs), end(rhs),
+ [](char c1, char c2)
+ {
+ return detail::ascii_tolower(c1) < detail::ascii_tolower(c2);
+ }
+ );
+}
+
+} // beast
+} // boost
+
+#endif
diff --git a/boost/beast/core/multi_buffer.hpp b/boost/beast/core/multi_buffer.hpp
index 2cf477a83b..837310c004 100644
--- a/boost/beast/core/multi_buffer.hpp
+++ b/boost/beast/core/multi_buffer.hpp
@@ -15,6 +15,7 @@
#include <boost/asio/buffer.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/intrusive/list.hpp>
+#include <boost/type_traits/type_with_alignment.hpp>
#include <iterator>
#include <limits>
#include <memory>
@@ -62,14 +63,13 @@ namespace beast {
template<class Allocator>
class basic_multi_buffer
#if ! BOOST_BEAST_DOXYGEN
- : private boost::empty_value<
- typename detail::allocator_traits<Allocator>::
- template rebind_alloc<char>>
+ : private boost::empty_value<Allocator>
#endif
{
- using base_alloc_type = typename
- detail::allocator_traits<Allocator>::
- template rebind_alloc<char>;
+ // Fancy pointers are not supported
+ static_assert(std::is_pointer<typename
+ std::allocator_traits<Allocator>::pointer>::value,
+ "Allocator must use regular pointers");
static bool constexpr default_nothrow =
std::is_nothrow_default_constructible<Allocator>::value;
@@ -77,19 +77,61 @@ class basic_multi_buffer
// Storage for the list of buffers representing the input
// and output sequences. The allocation for each element
// contains `element` followed by raw storage bytes.
- class element;
+ class element
+ : public boost::intrusive::list_base_hook<
+ boost::intrusive::link_mode<
+ boost::intrusive::normal_link>>
+ {
+ using size_type = typename
+ detail::allocator_traits<Allocator>::size_type;
+
+ size_type const size_;
+
+ public:
+ element(element const&) = delete;
+
+ explicit
+ element(size_type n) noexcept
+ : size_(n)
+ {
+ }
+
+ size_type
+ size() const noexcept
+ {
+ return size_;
+ }
+
+ char*
+ data() const noexcept
+ {
+ return const_cast<char*>(
+ reinterpret_cast<char const*>(this + 1));
+ }
+ };
template<bool>
class readable_bytes;
+ using size_type = typename
+ detail::allocator_traits<Allocator>::size_type;
+
+ using align_type = typename
+ boost::type_with_alignment<alignof(element)>::type;
+
+ using rebind_type = typename
+ beast::detail::allocator_traits<Allocator>::
+ template rebind_alloc<align_type>;
+
using alloc_traits =
- beast::detail::allocator_traits<base_alloc_type>;
- using list_type = typename boost::intrusive::make_list<element,
- boost::intrusive::constant_time_size<true>>::type;
+ beast::detail::allocator_traits<rebind_type>;
+
+ using list_type = typename boost::intrusive::make_list<
+ element, boost::intrusive::constant_time_size<true>>::type;
+
using iter = typename list_type::iterator;
- using const_iter = typename list_type::const_iterator;
- using size_type = typename alloc_traits::size_type;
+ using const_iter = typename list_type::const_iterator;
using pocma = typename
alloc_traits::propagate_on_container_move_assignment;
diff --git a/boost/beast/core/rate_policy.hpp b/boost/beast/core/rate_policy.hpp
index 1f8abb9b6a..6375b11811 100644
--- a/boost/beast/core/rate_policy.hpp
+++ b/boost/beast/core/rate_policy.hpp
@@ -152,7 +152,7 @@ class simple_rate_policy
friend class rate_policy_access;
static std::size_t constexpr all =
- std::numeric_limits<std::size_t>::max();
+ (std::numeric_limits<std::size_t>::max)();
std::size_t rd_remain_ = all;
std::size_t wr_remain_ = all;
diff --git a/boost/beast/core/span.hpp b/boost/beast/core/span.hpp
index e170729472..55a1454efd 100644
--- a/boost/beast/core/span.hpp
+++ b/boost/beast/core/span.hpp
@@ -186,21 +186,21 @@ public:
{
return data_;
}
-
+
/// Returns an iterator to the beginning of the span
const_iterator
cbegin() const
{
return data_;
}
-
+
/// Returns an iterator to one past the end of the span
const_iterator
end() const
{
return data_ + size_;
}
-
+
/// Returns an iterator to one past the end of the span
const_iterator
cend() const
diff --git a/boost/beast/core/static_buffer.hpp b/boost/beast/core/static_buffer.hpp
index 1e44237164..c4ff534f56 100644
--- a/boost/beast/core/static_buffer.hpp
+++ b/boost/beast/core/static_buffer.hpp
@@ -13,11 +13,7 @@
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/detail/buffers_pair.hpp>
#include <boost/asio/buffer.hpp>
-#include <boost/assert.hpp>
-#include <algorithm>
-#include <array>
#include <cstddef>
-#include <cstring>
namespace boost {
namespace beast {
@@ -134,7 +130,7 @@ public:
BOOST_BEAST_DECL
const_buffers_type
data() const noexcept;
-
+
/// Returns a constant buffer sequence representing the readable bytes
const_buffers_type
cdata() const noexcept
@@ -148,7 +144,7 @@ public:
data() noexcept;
/** Returns a mutable buffer sequence representing writable bytes.
-
+
Returns a mutable buffer sequence representing the writable
bytes containing exactly `n` bytes of storage. Memory may be
reallocated as needed.
diff --git a/boost/beast/core/static_string.hpp b/boost/beast/core/static_string.hpp
index fc60a72e7d..c1cea6c36e 100644
--- a/boost/beast/core/static_string.hpp
+++ b/boost/beast/core/static_string.hpp
@@ -16,8 +16,7 @@
#include <algorithm>
#include <cstdint>
#include <initializer_list>
-#include <iterator>
-#include <ostream>
+#include <iosfwd>
#include <stdexcept>
#include <string>
#include <type_traits>
diff --git a/boost/beast/core/string.hpp b/boost/beast/core/string.hpp
index 976bfca48a..06edca1969 100644
--- a/boost/beast/core/string.hpp
+++ b/boost/beast/core/string.hpp
@@ -11,82 +11,11 @@
#define BOOST_BEAST_STRING_HPP
#include <boost/beast/core/detail/config.hpp>
-#include <boost/version.hpp>
-
-#if defined(BOOST_BEAST_USE_STD_STRING_VIEW)
-#include <string_view>
-#else
-#include <boost/utility/string_view.hpp>
-#endif
-
-#include <algorithm>
+#include <boost/beast/core/string_type.hpp>
namespace boost {
namespace beast {
-#if defined(BOOST_BEAST_USE_STD_STRING_VIEW)
- /// The type of string view used by the library
- using string_view = std::string_view;
-
- /// The type of basic string view used by the library
- template<class CharT, class Traits>
- using basic_string_view =
- std::basic_string_view<CharT, Traits>;
-#else
- /// The type of string view used by the library
- using string_view = boost::string_view;
-
- /// The type of basic string view used by the library
- template<class CharT, class Traits>
- using basic_string_view =
- boost::basic_string_view<CharT, Traits>;
-#endif
-
-namespace detail {
-
-inline
-char
-ascii_tolower(char c)
-{
- return ((static_cast<unsigned>(c) - 65U) < 26) ?
- c + 'a' - 'A' : c;
-}
-
-template<class = void>
-bool
-iequals(
- beast::string_view lhs,
- beast::string_view rhs)
-{
- auto n = lhs.size();
- if(rhs.size() != n)
- return false;
- auto p1 = lhs.data();
- auto p2 = rhs.data();
- char a, b;
- // fast loop
- while(n--)
- {
- a = *p1++;
- b = *p2++;
- if(a != b)
- goto slow;
- }
- return true;
-slow:
- do
- {
- if(ascii_tolower(a) != ascii_tolower(b))
- return false;
- a = *p1++;
- b = *p2++;
- }
- while(n--);
- return true;
-}
-
-} // detail
-
/** Returns `true` if two strings are equal, using a case-insensitive comparison.
The case-comparison operation is defined only for low-ASCII characters.
@@ -95,14 +24,11 @@ slow:
@param rhs The string on the right side of the equality
*/
-inline
+BOOST_BEAST_DECL
bool
iequals(
beast::string_view lhs,
- beast::string_view rhs)
-{
- return detail::iequals(lhs, rhs);
-}
+ beast::string_view rhs);
/** A case-insensitive less predicate for strings.
@@ -110,21 +36,11 @@ iequals(
*/
struct iless
{
+ BOOST_BEAST_DECL
bool
operator()(
string_view lhs,
- string_view rhs) const
- {
- using std::begin;
- using std::end;
- return std::lexicographical_compare(
- begin(lhs), end(lhs), begin(rhs), end(rhs),
- [](char c1, char c2)
- {
- return detail::ascii_tolower(c1) < detail::ascii_tolower(c2);
- }
- );
- }
+ string_view rhs) const;
};
/** A case-insensitive equality predicate for strings.
@@ -145,4 +61,8 @@ struct iequal
} // beast
} // boost
+#ifdef BOOST_BEAST_HEADER_ONLY
+#include <boost/beast/core/impl/string.ipp>
+#endif
+
#endif
diff --git a/boost/beast/core/string_param.hpp b/boost/beast/core/string_param.hpp
index 67ef69469c..cc55bfd170 100644
--- a/boost/beast/core/string_param.hpp
+++ b/boost/beast/core/string_param.hpp
@@ -14,7 +14,6 @@
#include <boost/beast/core/string.hpp>
#include <boost/beast/core/static_string.hpp>
#include <boost/beast/core/detail/static_ostream.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/optional.hpp>
namespace boost {
diff --git a/boost/beast/core/string_type.hpp b/boost/beast/core/string_type.hpp
new file mode 100644
index 0000000000..b6b3f00534
--- /dev/null
+++ b/boost/beast/core/string_type.hpp
@@ -0,0 +1,45 @@
+//
+// 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_STRING_TYPE_HPP
+#define BOOST_BEAST_STRING_TYPE_HPP
+
+#include <boost/beast/core/detail/config.hpp>
+
+#if defined(BOOST_BEAST_USE_STD_STRING_VIEW)
+#include <string_view>
+#else
+#include <boost/utility/string_view.hpp>
+#endif
+
+namespace boost {
+namespace beast {
+
+#if BOOST_BEAST_DOXYGEN || ! defined(BOOST_BEAST_USE_STD_STRING_VIEW)
+/// The type of string view used by the library
+using string_view = boost::string_view;
+
+/// The type of `basic_string_view` used by the library
+template<class CharT, class Traits>
+using basic_string_view =
+ boost::basic_string_view<CharT, Traits>;
+
+#else
+using string_view = std::string_view;
+
+template<class CharT, class Traits>
+using basic_string_view =
+ std::basic_string_view<CharT, Traits>;
+
+#endif
+
+} // beast
+} // boost
+
+#endif
diff --git a/boost/beast/http/basic_dynamic_body.hpp b/boost/beast/http/basic_dynamic_body.hpp
index 3fea37379b..f49c50daf8 100644
--- a/boost/beast/http/basic_dynamic_body.hpp
+++ b/boost/beast/http/basic_dynamic_body.hpp
@@ -13,6 +13,7 @@
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/buffer_traits.hpp>
#include <boost/beast/core/detail/buffer.hpp>
+#include <boost/beast/core/detail/clamp.hpp>
#include <boost/beast/http/error.hpp>
#include <boost/beast/http/message.hpp>
#include <boost/optional.hpp>
@@ -89,7 +90,7 @@ struct basic_dynamic_body
error_code& ec)
{
auto const n = buffer_bytes(buffers);
- if(body_.size() > body_.max_size() - n)
+ if(beast::detail::sum_exceeds(body_.size(), n, body_.max_size()))
{
ec = error::buffer_overflow;
return 0;
diff --git a/boost/beast/http/detail/basic_parser.hpp b/boost/beast/http/detail/basic_parser.hpp
index f4e9083ffa..196d1c0a28 100644
--- a/boost/beast/http/detail/basic_parser.hpp
+++ b/boost/beast/http/detail/basic_parser.hpp
@@ -10,8 +10,8 @@
#ifndef BOOST_BEAST_HTTP_DETAIL_BASIC_PARSER_HPP
#define BOOST_BEAST_HTTP_DETAIL_BASIC_PARSER_HPP
-#include <boost/beast/core/static_string.hpp>
#include <boost/beast/core/string.hpp>
+#include <boost/beast/core/detail/char_buffer.hpp>
#include <boost/beast/http/error.hpp>
#include <boost/beast/http/detail/rfc7230.hpp>
#include <boost/config.hpp>
@@ -127,7 +127,7 @@ struct basic_parser_base
BOOST_BEAST_DECL
static
bool
- parse_dec(char const* it, char const* last, std::uint64_t& v);
+ parse_dec(string_view s, std::uint64_t& v);
BOOST_BEAST_DECL
static
@@ -182,7 +182,7 @@ struct basic_parser_base
char const* last,
string_view& name,
string_view& value,
- static_string<max_obs_fold>& buf,
+ beast::detail::char_buffer<max_obs_fold>& buf,
error_code& ec);
BOOST_BEAST_DECL
diff --git a/boost/beast/http/detail/basic_parser.ipp b/boost/beast/http/detail/basic_parser.ipp
index 934d0dc505..5dd13d4ce1 100644
--- a/boost/beast/http/detail/basic_parser.ipp
+++ b/boost/beast/http/detail/basic_parser.ipp
@@ -154,8 +154,12 @@ find_eol(
bool
basic_parser_base::
-parse_dec(char const* it, char const* last, std::uint64_t& v)
+parse_dec(
+ string_view s,
+ std::uint64_t& v)
{
+ char const* it = s.data();
+ char const* last = it + s.size();
if(it == last)
return false;
std::uint64_t tmp = 0;
@@ -491,7 +495,7 @@ parse_field(
char const* last,
string_view& name,
string_view& value,
- static_string<max_obs_fold>& buf,
+ beast::detail::char_buffer<max_obs_fold>& buf,
error_code& ec)
{
/* header-field = field-name ":" OWS field-value OWS
@@ -607,63 +611,60 @@ parse_field(
if(token_last != first)
break;
}
- buf.resize(0);
- buf.append(first, token_last);
+ buf.clear();
+ if (!buf.try_append(first, token_last))
+ {
+ ec = error::header_limit;
+ return;
+ }
+
BOOST_ASSERT(! buf.empty());
-#ifndef BOOST_NO_EXCEPTIONS
- try
-#endif
+ for(;;)
{
- for(;;)
+ // eat leading ' ' and '\t'
+ for(;;++p)
{
- // eat leading ' ' and '\t'
- for(;;++p)
- {
- if(p + 1 > last)
- {
- ec = error::need_more;
- return;
- }
- if(! (*p == ' ' || *p == '\t'))
- break;
- }
- // parse to CRLF
- first = p;
- p = parse_token_to_eol(p, last, token_last, ec);
- if(ec)
- return;
- if(! p)
- {
- ec = error::bad_value;
- return;
- }
- // Look 1 char past the CRLF to handle obs-fold.
if(p + 1 > last)
{
ec = error::need_more;
return;
}
- token_last = trim_back(token_last, first);
- if(first != token_last)
- {
- buf.push_back(' ');
- buf.append(first, token_last);
- }
- if(*p != ' ' && *p != '\t')
+ if(! (*p == ' ' || *p == '\t'))
+ break;
+ }
+ // parse to CRLF
+ first = p;
+ p = parse_token_to_eol(p, last, token_last, ec);
+ if(ec)
+ return;
+ if(! p)
+ {
+ ec = error::bad_value;
+ return;
+ }
+ // Look 1 char past the CRLF to handle obs-fold.
+ if(p + 1 > last)
+ {
+ ec = error::need_more;
+ return;
+ }
+ token_last = trim_back(token_last, first);
+ if(first != token_last)
+ {
+ if (!buf.try_push_back(' ') ||
+ !buf.try_append(first, token_last))
{
- value = {buf.data(), buf.size()};
+ ec = error::header_limit;
return;
}
- ++p;
}
+ if(*p != ' ' && *p != '\t')
+ {
+ value = {buf.data(), buf.size()};
+ return;
+ }
+ ++p;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(std::length_error const&)
- {
- ec = error::header_limit;
- return;
- }
-#endif
}
diff --git a/boost/beast/http/detail/rfc7230.hpp b/boost/beast/http/detail/rfc7230.hpp
index 99f4af05e1..35bed0ab22 100644
--- a/boost/beast/http/detail/rfc7230.hpp
+++ b/boost/beast/http/detail/rfc7230.hpp
@@ -57,14 +57,6 @@ std::int8_t
unhex(char c);
BOOST_BEAST_DECL
-void
-skip_ows(char const*& it, char const* end);
-
-BOOST_BEAST_DECL
-void
-skip_token(char const*& it, char const* last);
-
-BOOST_BEAST_DECL
string_view
trim(string_view s);
diff --git a/boost/beast/http/detail/rfc7230.ipp b/boost/beast/http/detail/rfc7230.ipp
index 612eaf9a02..4d69e77241 100644
--- a/boost/beast/http/detail/rfc7230.ipp
+++ b/boost/beast/http/detail/rfc7230.ipp
@@ -219,8 +219,9 @@ unhex(char c)
return tab[static_cast<unsigned char>(c)];
}
+template <class ForwardIt>
void
-skip_ows(char const*& it, char const* end)
+skip_ows(ForwardIt& it, ForwardIt end)
{
while(it != end)
{
@@ -230,8 +231,9 @@ skip_ows(char const*& it, char const* end)
}
}
+template <class ForwardIt>
void
-skip_token(char const*& it, char const* last)
+skip_token(ForwardIt& it, ForwardIt last)
{
while(it != last && is_token_char(*it))
++it;
diff --git a/boost/beast/http/fields.hpp b/boost/beast/http/fields.hpp
index 927191d755..24b1a12203 100644
--- a/boost/beast/http/fields.hpp
+++ b/boost/beast/http/fields.hpp
@@ -62,8 +62,6 @@ class basic_fields
friend class fields_test; // for `header`
- static std::size_t constexpr max_static_buffer = 4096;
-
struct element;
using off_t = std::uint16_t;
@@ -72,7 +70,7 @@ public:
/// The type of allocator used.
using allocator_type = Allocator;
- /// The type of element used to represent a field
+ /// The type of element used to represent a field
class value_type
{
friend class basic_fields;
@@ -198,7 +196,7 @@ private:
using rebind_type = typename
beast::detail::allocator_traits<Allocator>::
- template rebind_alloc<element>;
+ template rebind_alloc<align_type>;
using alloc_traits =
beast::detail::allocator_traits<rebind_type>;
diff --git a/boost/beast/http/impl/basic_parser.ipp b/boost/beast/http/impl/basic_parser.ipp
index 99947ae1f2..5cab22a884 100644
--- a/boost/beast/http/impl/basic_parser.ipp
+++ b/boost/beast/http/impl/basic_parser.ipp
@@ -14,9 +14,9 @@
#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/detail/clamp.hpp>
#include <boost/beast/core/detail/config.hpp>
+#include <boost/beast/core/detail/string.hpp>
#include <boost/asio/buffer.hpp>
#include <algorithm>
#include <utility>
@@ -405,7 +405,7 @@ parse_fields(char const*& in,
string_view name;
string_view value;
// https://stackoverflow.com/questions/686217/maximum-on-http-header-values
- static_string<max_obs_fold> buf;
+ beast::detail::char_buffer<max_obs_fold> buf;
auto p = in;
for(;;)
{
@@ -508,15 +508,16 @@ finish_header(error_code& ec, std::false_type)
}
else if(f_ & flagContentLength)
{
- if(len_ > body_limit_)
- {
- ec = error::body_limit;
- return;
- }
if(len_ > 0)
{
f_ |= flagHasBody;
state_ = state::body0;
+
+ if(len_ > body_limit_)
+ {
+ ec = error::body_limit;
+ return;
+ }
}
else
{
@@ -746,6 +747,7 @@ basic_parser<isRequest>::
do_field(field f,
string_view value, error_code& ec)
{
+ using namespace beast::detail::string_literals;
// Connection
if(f == field::connection ||
f == field::proxy_connection)
@@ -759,19 +761,19 @@ do_field(field f,
}
for(auto const& s : list)
{
- if(iequals({"close", 5}, s))
+ if(beast::iequals("close"_sv, s))
{
f_ |= flagConnectionClose;
continue;
}
- if(iequals({"keep-alive", 10}, s))
+ if(beast::iequals("keep-alive"_sv, s))
{
f_ |= flagConnectionKeepAlive;
continue;
}
- if(iequals({"upgrade", 7}, s))
+ if(beast::iequals("upgrade"_sv, s))
{
f_ |= flagConnectionUpgrade;
continue;
@@ -799,8 +801,7 @@ do_field(field f,
}
std::uint64_t v;
- if(! parse_dec(
- value.begin(), value.end(), v))
+ if(! parse_dec(value, v))
{
ec = error::bad_content_length;
return;
@@ -833,9 +834,9 @@ do_field(field f,
ec = {};
auto const v = token_list{value};
auto const p = std::find_if(v.begin(), v.end(),
- [&](typename token_list::value_type const& s)
+ [&](string_view const& s)
{
- return iequals({"chunked", 7}, s);
+ return beast::iequals("chunked"_sv, s);
});
if(p == v.end())
return;
diff --git a/boost/beast/http/impl/fields.hpp b/boost/beast/http/impl/fields.hpp
index 9616af829c..2711df38b4 100644
--- a/boost/beast/http/impl/fields.hpp
+++ b/boost/beast/http/impl/fields.hpp
@@ -12,9 +12,9 @@
#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/core/detail/temporary_buffer.hpp>
#include <boost/beast/http/verb.hpp>
#include <boost/beast/http/rfc7230.hpp>
#include <boost/beast/http/status.hpp>
@@ -24,13 +24,6 @@
#include <stdexcept>
#include <string>
-#if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000
- // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56437
-#ifndef BOOST_BEAST_HTTP_NO_FIELDS_BASIC_STRING_ALLOCATOR
-#define BOOST_BEAST_HTTP_NO_FIELDS_BASIC_STRING_ALLOCATOR
-#endif
-#endif
-
namespace boost {
namespace beast {
namespace http {
@@ -584,7 +577,7 @@ insert(field name,
}
auto const last = std::prev(before);
// VFALCO is it worth comparing `field name` first?
- if(! iequals(sname, last->name_string()))
+ if(! beast::iequals(sname, last->name_string()))
{
BOOST_ASSERT(count(sname) == 0);
set_.insert_before(before, e);
@@ -751,136 +744,31 @@ equal_range(string_view name) const ->
namespace detail {
-// Filter a token list
-//
-template<class String, class Pred>
-void
-filter_token_list(
- String& s,
- string_view value,
- Pred&& pred)
+struct iequals_predicate
{
- token_list te{value};
- auto it = te.begin();
- auto last = te.end();
- if(it == last)
- return;
- while(pred(*it))
- if(++it == last)
- return;
- s.append(it->data(), it->size());
- while(++it != last)
+ bool
+ operator()(string_view s) const
{
- if(! pred(*it))
- {
- s.append(", ");
- s.append(it->data(), it->size());
- }
+ return beast::iequals(s, sv1) || beast::iequals(s, sv2);
}
-}
+
+ string_view sv1;
+ string_view sv2;
+};
// Filter the last item in a token list
-template<class String, class Pred>
+BOOST_BEAST_DECL
void
filter_token_list_last(
- String& s,
+ beast::detail::temporary_buffer& s,
string_view value,
- Pred&& pred)
-{
- token_list te{value};
- if(te.begin() != te.end())
- {
- auto it = te.begin();
- auto next = std::next(it);
- if(next == te.end())
- {
- if(! pred(*it))
- s.append(it->data(), it->size());
- return;
- }
- s.append(it->data(), it->size());
- for(;;)
- {
- it = next;
- next = std::next(it);
- if(next == te.end())
- {
- if(! pred(*it))
- {
- s.append(", ");
- s.append(it->data(), it->size());
- }
- return;
- }
- s.append(", ");
- s.append(it->data(), it->size());
- }
- }
-}
+ iequals_predicate const& pred);
-template<class String>
+BOOST_BEAST_DECL
void
keep_alive_impl(
- String& s, string_view value,
- unsigned version, bool keep_alive)
-{
- if(version < 11)
- {
- if(keep_alive)
- {
- // remove close
- filter_token_list(s, value,
- [](string_view s)
- {
- return iequals(s, "close");
- });
- // add keep-alive
- if(s.empty())
- s.append("keep-alive");
- else if(! token_list{value}.exists("keep-alive"))
- s.append(", keep-alive");
- }
- else
- {
- // remove close and keep-alive
- filter_token_list(s, value,
- [](string_view s)
- {
- return
- iequals(s, "close") ||
- iequals(s, "keep-alive");
- });
- }
- }
- else
- {
- if(keep_alive)
- {
- // remove close and keep-alive
- filter_token_list(s, value,
- [](string_view s)
- {
- return
- iequals(s, "close") ||
- iequals(s, "keep-alive");
- });
- }
- else
- {
- // remove keep-alive
- filter_token_list(s, value,
- [](string_view s)
- {
- return iequals(s, "keep-alive");
- });
- // add close
- if(s.empty())
- s.append("close");
- else if(! token_list{value}.exists("close"))
- s.append(", close");
- }
- }
-}
+ beast::detail::temporary_buffer& s, string_view value,
+ unsigned version, bool keep_alive);
} // detail
@@ -930,7 +818,7 @@ get_chunked_impl() const
{
auto const next = std::next(it);
if(next == te.end())
- return iequals(*it, "chunked");
+ return beast::iequals(*it, "chunked");
it = next;
}
return false;
@@ -997,6 +885,7 @@ void
basic_fields<Allocator>::
set_chunked_impl(bool value)
{
+ beast::detail::temporary_buffer buf;
auto it = find(field::transfer_encoding);
if(value)
{
@@ -1012,84 +901,26 @@ set_chunked_impl(bool value)
auto const next = std::next(itt);
if(next == te.end())
{
- if(iequals(*itt, "chunked"))
+ if(beast::iequals(*itt, "chunked"))
return; // already set
break;
}
itt = next;
}
- static_string<max_static_buffer> buf;
- if(! beast::detail::sum_exceeds(
- it->value().size(), 9u, buf.max_size()))
- {
- buf.append(it->value().data(), it->value().size());
- buf.append(", chunked", 9);
- set(field::transfer_encoding, buf);
- }
- else
- {
- #ifdef BOOST_BEAST_HTTP_NO_FIELDS_BASIC_STRING_ALLOCATOR
- // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56437
- std::string s;
- #else
- using A =
- typename beast::detail::allocator_traits<
- Allocator>::template rebind_alloc<char>;
- std::basic_string<
- char,
- std::char_traits<char>,
- A> s{A{this->get()}};
- #endif
- s.reserve(it->value().size() + 9);
- s.append(it->value().data(), it->value().size());
- s.append(", chunked", 9);
- set(field::transfer_encoding, s);
- }
+
+ buf.append(it->value(), ", chunked");
+ set(field::transfer_encoding, buf.view());
return;
}
// filter "chunked"
if(it == end())
return;
-#ifndef BOOST_NO_EXCEPTIONS
- try
- {
- static_string<max_static_buffer> buf;
- detail::filter_token_list_last(buf, it->value(),
- [](string_view s)
- {
- return iequals(s, "chunked");
- });
- if(! buf.empty())
- set(field::transfer_encoding, buf);
- else
- 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
- std::string s;
- #else
- using A =
- typename beast::detail::allocator_traits<
- Allocator>::template rebind_alloc<char>;
- std::basic_string<
- char,
- std::char_traits<char>,
- A> s{A{this->get()}};
- #endif
- s.reserve(it->value().size());
- detail::filter_token_list_last(s, it->value(),
- [](string_view s)
- {
- return iequals(s, "chunked");
- });
- if(! s.empty())
- set(field::transfer_encoding, s);
- else
- erase(field::transfer_encoding);
- }
+
+ detail::filter_token_list_last(buf, it->value(), {"chunked", {}});
+ if(! buf.empty())
+ set(field::transfer_encoding, buf.view());
+ else
+ erase(field::transfer_encoding);
}
template<class Allocator>
@@ -1112,40 +943,12 @@ 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;
- detail::keep_alive_impl(
- buf, value, version, keep_alive);
- if(buf.empty())
- erase(field::connection);
- else
- 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
- std::string s;
- #else
- using A =
- typename beast::detail::allocator_traits<
- Allocator>::template rebind_alloc<char>;
- std::basic_string<
- char,
- std::char_traits<char>,
- A> s{A{this->get()}};
- #endif
- s.reserve(value.size());
- detail::keep_alive_impl(
- s, value, version, keep_alive);
- if(s.empty())
- erase(field::connection);
- else
- set(field::connection, s);
- }
+ beast::detail::temporary_buffer buf;
+ detail::keep_alive_impl(buf, value, version, keep_alive);
+ if(buf.empty())
+ erase(field::connection);
+ else
+ set(field::connection, buf.view());
}
//------------------------------------------------------------------------------
@@ -1187,8 +990,8 @@ delete_element(element& e)
(sizeof(element) + e.off_ + e.len_ + 2 + sizeof(align_type) - 1) /
sizeof(align_type);
e.~element();
- alloc_traits::deallocate(a, &e, n);
- //reinterpret_cast<align_type*>(&e), n);
+ alloc_traits::deallocate(a,
+ reinterpret_cast<align_type*>(&e), n);
}
template<class Allocator>
@@ -1198,7 +1001,7 @@ set_element(element& e)
{
auto it = set_.lower_bound(
e.name_string(), key_compare{});
- if(it == set_.end() || ! iequals(
+ if(it == set_.end() || ! beast::iequals(
e.name_string(), it->name_string()))
{
set_.insert_before(it, e);
@@ -1214,7 +1017,7 @@ set_element(element& e)
delete_element(*it);
it = next;
if(it == set_.end() ||
- ! iequals(e.name_string(), it->name_string()))
+ ! beast::iequals(e.name_string(), it->name_string()))
break;
}
set_.insert_before(it, e);
@@ -1402,4 +1205,8 @@ swap(basic_fields& other, std::false_type)
} // beast
} // boost
+#ifdef BOOST_BEAST_HEADER_ONLY
+#include <boost/beast/http/impl/fields.ipp>
+#endif
+
#endif
diff --git a/boost/beast/http/impl/fields.ipp b/boost/beast/http/impl/fields.ipp
new file mode 100644
index 0000000000..379d0a4d50
--- /dev/null
+++ b/boost/beast/http/impl/fields.ipp
@@ -0,0 +1,138 @@
+//
+// 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_FIELDS_IPP
+#define BOOST_BEAST_HTTP_IMPL_FIELDS_IPP
+
+#include <boost/beast/http/fields.hpp>
+
+namespace boost {
+namespace beast {
+namespace http {
+namespace detail {
+
+// `basic_fields` assumes that `std::size_t` is larger than `uint16_t`, so we
+// verify it explicitly here, so that users that use split compilation don't
+// need to pay the (fairly small) price for this sanity check
+BOOST_STATIC_ASSERT((std::numeric_limits<std::size_t>::max)() >=
+ (std::numeric_limits<std::uint32_t>::max)());
+
+// Filter a token list
+//
+inline
+void
+filter_token_list(
+ beast::detail::temporary_buffer& s,
+ string_view value,
+ iequals_predicate const& pred)
+{
+ token_list te{value};
+ auto it = te.begin();
+ auto last = te.end();
+ if(it == last)
+ return;
+ while(pred(*it))
+ if(++it == last)
+ return;
+ s.append(*it);
+ while(++it != last)
+ {
+ if(! pred(*it))
+ {
+ s.append(", ", *it);
+ }
+ }
+}
+
+void
+filter_token_list_last(
+ beast::detail::temporary_buffer& s,
+ string_view value,
+ iequals_predicate const& pred)
+{
+ token_list te{value};
+ if(te.begin() != te.end())
+ {
+ auto it = te.begin();
+ auto next = std::next(it);
+ if(next == te.end())
+ {
+ if(! pred(*it))
+ s.append(*it);
+ return;
+ }
+ s.append(*it);
+ for(;;)
+ {
+ it = next;
+ next = std::next(it);
+ if(next == te.end())
+ {
+ if(! pred(*it))
+ {
+ s.append(", ", *it);
+ }
+ return;
+ }
+ s.append(", ", *it);
+ }
+ }
+}
+
+void
+keep_alive_impl(
+ beast::detail::temporary_buffer& s, string_view value,
+ unsigned version, bool keep_alive)
+{
+ if(version < 11)
+ {
+ if(keep_alive)
+ {
+ // remove close
+ filter_token_list(s, value, iequals_predicate{"close", {}});
+ // add keep-alive
+ if(s.empty())
+ s.append("keep-alive");
+ else if(! token_list{value}.exists("keep-alive"))
+ s.append(", keep-alive");
+ }
+ else
+ {
+ // remove close and keep-alive
+ filter_token_list(s, value,
+ iequals_predicate{"close", "keep-alive"});
+ }
+ }
+ else
+ {
+ if(keep_alive)
+ {
+ // remove close and keep-alive
+ filter_token_list(s, value,
+ iequals_predicate{"close", "keep-alive"});
+ }
+ else
+ {
+ // remove keep-alive
+ filter_token_list(s, value, iequals_predicate{"keep-alive", {}});
+ // add close
+ if(s.empty())
+ s.append("close");
+ else if(! token_list{value}.exists("close"))
+ s.append(", close");
+ }
+ }
+}
+
+} // detail
+} // http
+} // beast
+} // boost
+
+#endif // BOOST_BEAST_HTTP_IMPL_FIELDS_IPP
diff --git a/boost/beast/http/impl/file_body_win32.hpp b/boost/beast/http/impl/file_body_win32.hpp
index fc74c49772..cfeb5aaefd 100644
--- a/boost/beast/http/impl/file_body_win32.hpp
+++ b/boost/beast/http/impl/file_body_win32.hpp
@@ -16,6 +16,7 @@
#include <boost/beast/core/bind_handler.hpp>
#include <boost/beast/core/buffers_range.hpp>
#include <boost/beast/core/detail/clamp.hpp>
+#include <boost/beast/core/detail/is_invocable.hpp>
#include <boost/beast/http/serializer.hpp>
#include <boost/asio/async_result.hpp>
#include <boost/asio/basic_stream_socket.hpp>
diff --git a/boost/beast/http/impl/message.hpp b/boost/beast/http/impl/message.hpp
index 805d01f09a..4b101ad3b9 100644
--- a/boost/beast/http/impl/message.hpp
+++ b/boost/beast/http/impl/message.hpp
@@ -11,7 +11,6 @@
#define BOOST_BEAST_HTTP_IMPL_MESSAGE_HPP
#include <boost/beast/core/error.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/assert.hpp>
#include <boost/throw_exception.hpp>
#include <stdexcept>
diff --git a/boost/beast/http/impl/read.hpp b/boost/beast/http/impl/read.hpp
index faea67eb25..ba265a57ed 100644
--- a/boost/beast/http/impl/read.hpp
+++ b/boost/beast/http/impl/read.hpp
@@ -62,8 +62,12 @@ parse_until(
// 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())
+ if( ec != net::error::operation_aborted &&
+ parser.got_some() && ! parser.is_done())
+ {
ec = error::partial_message;
+ }
+
return 0;
}
if(parser.is_done())
@@ -160,7 +164,7 @@ template<
class read_msg_op
: public beast::stable_async_base<
Handler, beast::executor_type<Stream>>
- , public net::coroutine
+ , public asio::coroutine
{
using parser_type =
parser<isRequest, Body, Allocator>;
diff --git a/boost/beast/http/impl/rfc7230.hpp b/boost/beast/http/impl/rfc7230.hpp
index 11e424b4d1..40e2fff040 100644
--- a/boost/beast/http/impl/rfc7230.hpp
+++ b/boost/beast/http/impl/rfc7230.hpp
@@ -244,27 +244,6 @@ cend() const ->
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();
-}
-
//------------------------------------------------------------------------------
@@ -378,19 +357,6 @@ cend() const ->
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<
diff --git a/boost/beast/http/impl/rfc7230.ipp b/boost/beast/http/impl/rfc7230.ipp
index cf60cefa36..6b46493ea3 100644
--- a/boost/beast/http/impl/rfc7230.ipp
+++ b/boost/beast/http/impl/rfc7230.ipp
@@ -11,6 +11,7 @@
#define BOOST_BEAST_HTTP_IMPL_RFC7230_IPP
#include <boost/beast/http/rfc7230.hpp>
+#include <algorithm>
namespace boost {
namespace beast {
@@ -123,6 +124,24 @@ increment()
}
}
+auto
+ext_list::
+find(string_view const& s) -> const_iterator
+{
+ return std::find_if(begin(), end(),
+ [&s](value_type const& v)
+ {
+ return beast::iequals(s, v.first);
+ });
+}
+
+bool
+ext_list::
+exists(string_view const& s)
+{
+ return find(s) != end();
+}
+
void
token_list::const_iterator::
increment()
@@ -169,6 +188,18 @@ increment()
}
}
+bool
+token_list::
+exists(string_view const& s)
+{
+ return std::find_if(begin(), end(),
+ [&s](value_type const& v)
+ {
+ return beast::iequals(s, v);
+ }
+ ) != end();
+}
+
} // http
} // beast
} // boost
diff --git a/boost/beast/http/impl/verb.ipp b/boost/beast/http/impl/verb.ipp
index 20ef47c551..988f1b9430 100644
--- a/boost/beast/http/impl/verb.ipp
+++ b/boost/beast/http/impl/verb.ipp
@@ -21,50 +21,51 @@ namespace http {
string_view
to_string(verb v)
{
+ using namespace beast::detail::string_literals;
switch(v)
{
- case verb::delete_: return "DELETE";
- case verb::get: return "GET";
- case verb::head: return "HEAD";
- case verb::post: return "POST";
- case verb::put: return "PUT";
- case verb::connect: return "CONNECT";
- case verb::options: return "OPTIONS";
- case verb::trace: return "TRACE";
-
- case verb::copy: return "COPY";
- case verb::lock: return "LOCK";
- case verb::mkcol: return "MKCOL";
- case verb::move: return "MOVE";
- case verb::propfind: return "PROPFIND";
- case verb::proppatch: return "PROPPATCH";
- case verb::search: return "SEARCH";
- case verb::unlock: return "UNLOCK";
- case verb::bind: return "BIND";
- case verb::rebind: return "REBIND";
- case verb::unbind: return "UNBIND";
- case verb::acl: return "ACL";
-
- case verb::report: return "REPORT";
- case verb::mkactivity: return "MKACTIVITY";
- case verb::checkout: return "CHECKOUT";
- case verb::merge: return "MERGE";
-
- case verb::msearch: return "M-SEARCH";
- case verb::notify: return "NOTIFY";
- case verb::subscribe: return "SUBSCRIBE";
- case verb::unsubscribe: return "UNSUBSCRIBE";
-
- case verb::patch: return "PATCH";
- case verb::purge: return "PURGE";
-
- case verb::mkcalendar: return "MKCALENDAR";
-
- case verb::link: return "LINK";
- case verb::unlink: return "UNLINK";
-
+ case verb::delete_: return "DELETE"_sv;
+ case verb::get: return "GET"_sv;
+ case verb::head: return "HEAD"_sv;
+ case verb::post: return "POST"_sv;
+ case verb::put: return "PUT"_sv;
+ case verb::connect: return "CONNECT"_sv;
+ case verb::options: return "OPTIONS"_sv;
+ case verb::trace: return "TRACE"_sv;
+
+ case verb::copy: return "COPY"_sv;
+ case verb::lock: return "LOCK"_sv;
+ case verb::mkcol: return "MKCOL"_sv;
+ case verb::move: return "MOVE"_sv;
+ case verb::propfind: return "PROPFIND"_sv;
+ case verb::proppatch: return "PROPPATCH"_sv;
+ case verb::search: return "SEARCH"_sv;
+ case verb::unlock: return "UNLOCK"_sv;
+ case verb::bind: return "BIND"_sv;
+ case verb::rebind: return "REBIND"_sv;
+ case verb::unbind: return "UNBIND"_sv;
+ case verb::acl: return "ACL"_sv;
+
+ case verb::report: return "REPORT"_sv;
+ case verb::mkactivity: return "MKACTIVITY"_sv;
+ case verb::checkout: return "CHECKOUT"_sv;
+ case verb::merge: return "MERGE"_sv;
+
+ case verb::msearch: return "M-SEARCH"_sv;
+ case verb::notify: return "NOTIFY"_sv;
+ case verb::subscribe: return "SUBSCRIBE"_sv;
+ case verb::unsubscribe: return "UNSUBSCRIBE"_sv;
+
+ case verb::patch: return "PATCH"_sv;
+ case verb::purge: return "PURGE"_sv;
+
+ case verb::mkcalendar: return "MKCALENDAR"_sv;
+
+ case verb::link: return "LINK"_sv;
+ case verb::unlink: return "UNLINK"_sv;
+
case verb::unknown:
- return "<unknown>";
+ return "<unknown>"_sv;
}
BOOST_THROW_EXCEPTION(std::invalid_argument{"unknown verb"});
@@ -108,34 +109,20 @@ string_to_verb(string_view v)
UNLOCK
UNSUBSCRIBE
*/
+ using namespace beast::detail::string_literals;
if(v.size() < 3)
return verb::unknown;
- // s must be null terminated
- auto const eq =
- [](string_view sv, char const* s)
- {
- auto p = sv.data();
- for(;;)
- {
- if(*s != *p)
- return false;
- ++s;
- ++p;
- if(! *s)
- return p == (sv.data() + sv.size());
- }
- };
auto c = v[0];
v.remove_prefix(1);
switch(c)
{
case 'A':
- if(v == "CL")
+ if(v == "CL"_sv)
return verb::acl;
break;
case 'B':
- if(v == "IND")
+ if(v == "IND"_sv)
return verb::bind;
break;
@@ -145,14 +132,14 @@ string_to_verb(string_view v)
switch(c)
{
case 'H':
- if(eq(v, "ECKOUT"))
+ if(v == "ECKOUT"_sv)
return verb::checkout;
break;
case 'O':
- if(eq(v, "NNECT"))
+ if(v == "NNECT"_sv)
return verb::connect;
- if(eq(v, "PY"))
+ if(v == "PY"_sv)
return verb::copy;
BOOST_FALLTHROUGH;
@@ -162,24 +149,24 @@ string_to_verb(string_view v)
break;
case 'D':
- if(eq(v, "ELETE"))
+ if(v == "ELETE"_sv)
return verb::delete_;
break;
case 'G':
- if(eq(v, "ET"))
+ if(v == "ET"_sv)
return verb::get;
break;
case 'H':
- if(eq(v, "EAD"))
+ if(v == "EAD"_sv)
return verb::head;
break;
case 'L':
- if(eq(v, "INK"))
+ if(v == "INK"_sv)
return verb::link;
- if(eq(v, "OCK"))
+ if(v == "OCK"_sv)
return verb::lock;
break;
@@ -189,31 +176,31 @@ string_to_verb(string_view v)
switch(c)
{
case '-':
- if(eq(v, "SEARCH"))
+ if(v == "SEARCH"_sv)
return verb::msearch;
break;
case 'E':
- if(eq(v, "RGE"))
+ if(v == "RGE"_sv)
return verb::merge;
break;
case 'K':
- if(eq(v, "ACTIVITY"))
+ if(v == "ACTIVITY"_sv)
return verb::mkactivity;
if(v[0] == 'C')
{
v.remove_prefix(1);
- if(eq(v, "ALENDAR"))
+ if(v == "ALENDAR"_sv)
return verb::mkcalendar;
- if(eq(v, "OL"))
+ if(v == "OL"_sv)
return verb::mkcol;
break;
}
break;
-
+
case 'O':
- if(eq(v, "VE"))
+ if(v == "VE"_sv)
return verb::move;
BOOST_FALLTHROUGH;
@@ -223,12 +210,12 @@ string_to_verb(string_view v)
break;
case 'N':
- if(eq(v, "OTIFY"))
+ if(v == "OTIFY"_sv)
return verb::notify;
break;
case 'O':
- if(eq(v, "PTIONS"))
+ if(v == "PTIONS"_sv)
return verb::options;
break;
@@ -238,26 +225,26 @@ string_to_verb(string_view v)
switch(c)
{
case 'A':
- if(eq(v, "TCH"))
+ if(v == "TCH"_sv)
return verb::patch;
break;
case 'O':
- if(eq(v, "ST"))
+ if(v == "ST"_sv)
return verb::post;
break;
case 'R':
- if(eq(v, "OPFIND"))
+ if(v == "OPFIND"_sv)
return verb::propfind;
- if(eq(v, "OPPATCH"))
+ if(v == "OPPATCH"_sv)
return verb::proppatch;
break;
case 'U':
- if(eq(v, "RGE"))
+ if(v == "RGE"_sv)
return verb::purge;
- if(eq(v, "T"))
+ if(v == "T"_sv)
return verb::put;
BOOST_FALLTHROUGH;
@@ -270,21 +257,21 @@ string_to_verb(string_view v)
if(v[0] != 'E')
break;
v.remove_prefix(1);
- if(eq(v, "BIND"))
+ if(v == "BIND"_sv)
return verb::rebind;
- if(eq(v, "PORT"))
+ if(v == "PORT"_sv)
return verb::report;
break;
case 'S':
- if(eq(v, "EARCH"))
+ if(v == "EARCH"_sv)
return verb::search;
- if(eq(v, "UBSCRIBE"))
+ if(v == "UBSCRIBE"_sv)
return verb::subscribe;
break;
case 'T':
- if(eq(v, "RACE"))
+ if(v == "RACE"_sv)
return verb::trace;
break;
@@ -292,13 +279,13 @@ string_to_verb(string_view v)
if(v[0] != 'N')
break;
v.remove_prefix(1);
- if(eq(v, "BIND"))
+ if(v == "BIND"_sv)
return verb::unbind;
- if(eq(v, "LINK"))
+ if(v == "LINK"_sv)
return verb::unlink;
- if(eq(v, "LOCK"))
+ if(v == "LOCK"_sv)
return verb::unlock;
- if(eq(v, "SUBSCRIBE"))
+ if(v == "SUBSCRIBE"_sv)
return verb::unsubscribe;
break;
diff --git a/boost/beast/http/impl/write.hpp b/boost/beast/http/impl/write.hpp
index 5636ce92f8..79b0c83d71 100644
--- a/boost/beast/http/impl/write.hpp
+++ b/boost/beast/http/impl/write.hpp
@@ -14,8 +14,9 @@
#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/make_printable.hpp>
#include <boost/beast/core/stream_traits.hpp>
+#include <boost/beast/core/detail/is_invocable.hpp>
#include <boost/asio/coroutine.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/write.hpp>
@@ -159,7 +160,7 @@ template<
class write_op
: public beast::async_base<
Handler, beast::executor_type<Stream>>
- , public net::coroutine
+ , public asio::coroutine
{
Stream& s_;
serializer<isRequest, Body, Fields>& sr_;
@@ -262,7 +263,7 @@ struct run_write_some_op
{
template<
class WriteHandler,
- class Stream,
+ class Stream,
bool isRequest, class Body, class Fields>
void
operator()(
@@ -903,7 +904,7 @@ operator<<(std::ostream& os,
{
typename Fields::writer fr{
h, h.version(), h.method()};
- return os << buffers(fr.get());
+ return os << beast::make_printable(fr.get());
}
template<class Fields>
@@ -913,7 +914,7 @@ operator<<(std::ostream& os,
{
typename Fields::writer fr{
h, h.version(), h.result_int()};
- return os << buffers(fr.get());
+ return os << beast::make_printable(fr.get());
}
template<bool isRequest, class Body, class Fields>
diff --git a/boost/beast/http/rfc7230.hpp b/boost/beast/http/rfc7230.hpp
index bc2498db52..c83494e666 100644
--- a/boost/beast/http/rfc7230.hpp
+++ b/boost/beast/http/rfc7230.hpp
@@ -190,17 +190,17 @@ public:
@return An iterator to the matching token, or `end()` if no
token exists.
*/
- template<class T>
+ BOOST_BEAST_DECL
const_iterator
- find(T const& s);
+ find(string_view const& s);
/** Return `true` if a token is present in the list.
@param s The token to find. A case-insensitive comparison is used.
*/
- template<class T>
+ BOOST_BEAST_DECL
bool
- exists(T const& s);
+ exists(string_view const& s);
};
//------------------------------------------------------------------------------
@@ -275,9 +275,9 @@ public:
@param s The token to find. A case-insensitive comparison is used.
*/
- template<class T>
+ BOOST_BEAST_DECL
bool
- exists(T const& s);
+ exists(string_view const& s);
};
/** A list of tokens in a comma separated HTTP field value.
diff --git a/boost/beast/http/string_body.hpp b/boost/beast/http/string_body.hpp
index 73a01a41fd..aeeefcc440 100644
--- a/boost/beast/http/string_body.hpp
+++ b/boost/beast/http/string_body.hpp
@@ -16,7 +16,6 @@
#include <boost/beast/http/message.hpp>
#include <boost/beast/core/buffers_range.hpp>
#include <boost/beast/core/detail/clamp.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/optional.hpp>
#include <cstdint>
diff --git a/boost/beast/http/vector_body.hpp b/boost/beast/http/vector_body.hpp
index b44ef0f625..c599e162b9 100644
--- a/boost/beast/http/vector_body.hpp
+++ b/boost/beast/http/vector_body.hpp
@@ -15,7 +15,6 @@
#include <boost/beast/http/error.hpp>
#include <boost/beast/http/message.hpp>
#include <boost/beast/core/detail/clamp.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/optional.hpp>
#include <cstdint>
@@ -39,8 +38,7 @@ template<class T, class Allocator = std::allocator<T>>
struct vector_body
{
private:
- static_assert(sizeof(T) == 1 &&
- std::is_integral<T>::value,
+ static_assert(sizeof(T) == 1,
"T requirements not met");
public:
diff --git a/boost/beast/src.hpp b/boost/beast/src.hpp
index 87b4ab305f..2376c3fcc2 100644
--- a/boost/beast/src.hpp
+++ b/boost/beast/src.hpp
@@ -31,6 +31,7 @@ the program, with the macro BOOST_BEAST_SEPARATE_COMPILATION defined.
#include <boost/beast/core/detail/base64.ipp>
#include <boost/beast/core/detail/sha1.ipp>
+#include <boost/beast/core/detail/impl/temporary_buffer.ipp>
#include <boost/beast/core/impl/error.ipp>
#include <boost/beast/core/impl/file_posix.ipp>
#include <boost/beast/core/impl/file_stdio.ipp>
@@ -38,17 +39,20 @@ the program, with the macro BOOST_BEAST_SEPARATE_COMPILATION defined.
#include <boost/beast/core/impl/flat_static_buffer.ipp>
#include <boost/beast/core/impl/saved_handler.ipp>
#include <boost/beast/core/impl/static_buffer.ipp>
+#include <boost/beast/core/impl/string.ipp>
#include <boost/beast/http/detail/basic_parser.ipp>
#include <boost/beast/http/detail/rfc7230.ipp>
#include <boost/beast/http/impl/basic_parser.ipp>
#include <boost/beast/http/impl/error.ipp>
#include <boost/beast/http/impl/field.ipp>
+#include <boost/beast/http/impl/fields.ipp>
#include <boost/beast/http/impl/rfc7230.ipp>
#include <boost/beast/http/impl/status.ipp>
#include <boost/beast/http/impl/verb.ipp>
#include <boost/beast/websocket/detail/hybi13.ipp>
+#include <boost/beast/websocket/detail/mask.ipp>
#include <boost/beast/websocket/detail/pmd_extension.ipp>
#include <boost/beast/websocket/detail/prng.ipp>
#include <boost/beast/websocket/detail/service.ipp>
diff --git a/boost/beast/ssl/ssl_stream.hpp b/boost/beast/ssl/ssl_stream.hpp
index b96dbdda31..cab2463de2 100644
--- a/boost/beast/ssl/ssl_stream.hpp
+++ b/boost/beast/ssl/ssl_stream.hpp
@@ -655,12 +655,7 @@ public:
teardown(
boost::beast::role_type role,
ssl_stream<SyncStream>& stream,
- boost::system::error_code& ec)
- {
- // Just forward it to the underlying ssl::stream
- using boost::beast::websocket::teardown;
- teardown(role, *stream.p_, ec);
- }
+ boost::system::error_code& ec);
template<class AsyncStream, class TeardownHandler>
friend
@@ -668,16 +663,37 @@ public:
async_teardown(
boost::beast::role_type role,
ssl_stream<AsyncStream>& stream,
- TeardownHandler&& handler)
- {
- // Just forward it to the underlying ssl::stream
- using boost::beast::websocket::async_teardown;
- async_teardown(role, *stream.p_,
- std::forward<TeardownHandler>(handler));
- }
+ TeardownHandler&& handler);
#endif
};
+#if ! BOOST_BEAST_DOXYGEN
+template<class SyncStream>
+void
+teardown(
+ boost::beast::role_type role,
+ ssl_stream<SyncStream>& stream,
+ boost::system::error_code& ec)
+{
+ // Just forward it to the underlying ssl::stream
+ using boost::beast::websocket::teardown;
+ teardown(role, *stream.p_, ec);
+}
+
+template<class AsyncStream, class TeardownHandler>
+void
+async_teardown(
+ boost::beast::role_type role,
+ ssl_stream<AsyncStream>& stream,
+ TeardownHandler&& handler)
+{
+ // Just forward it to the underlying ssl::stream
+ using boost::beast::websocket::async_teardown;
+ async_teardown(role, *stream.p_,
+ std::forward<TeardownHandler>(handler));
+}
+#endif
+
} // beast
} // boost
diff --git a/boost/beast/version.hpp b/boost/beast/version.hpp
index b689881bce..02144712eb 100644
--- a/boost/beast/version.hpp
+++ b/boost/beast/version.hpp
@@ -20,7 +20,7 @@
This is a simple integer that is incremented by one every
time a set of code changes is merged to the develop branch.
*/
-#define BOOST_BEAST_VERSION 248
+#define BOOST_BEAST_VERSION 266
#define BOOST_BEAST_VERSION_STRING "Boost.Beast/" BOOST_STRINGIZE(BOOST_BEAST_VERSION)
diff --git a/boost/beast/websocket/detail/decorator.hpp b/boost/beast/websocket/detail/decorator.hpp
index cab7f9a298..03c1c8f637 100644
--- a/boost/beast/websocket/detail/decorator.hpp
+++ b/boost/beast/websocket/detail/decorator.hpp
@@ -11,7 +11,6 @@
#define BOOST_BEAST_WEBSOCKET_DETAIL_DECORATOR_HPP
#include <boost/beast/websocket/rfc6455.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/core/exchange.hpp>
#include <boost/type_traits/make_void.hpp>
#include <algorithm>
@@ -213,7 +212,7 @@ struct decorator::vtable_impl<F, true>
void
move(storage& dst, storage& src) noexcept
{
- auto& f = *reinterpret_cast<F*>(&src.buf_);
+ auto& f = *beast::detail::launder_cast<F*>(&src.buf_);
::new (&dst.buf_) F(std::move(f));
}
@@ -221,7 +220,7 @@ struct decorator::vtable_impl<F, true>
void
destroy(storage& dst) noexcept
{
- reinterpret_cast<F*>(&dst.buf_)->~F();
+ beast::detail::launder_cast<F*>(&dst.buf_)->~F();
}
static
@@ -229,7 +228,7 @@ struct decorator::vtable_impl<F, true>
invoke_req(storage& dst, request_type& req)
{
maybe_invoke<F, request_type>{}(
- *reinterpret_cast<F*>(&dst.buf_), req);
+ *beast::detail::launder_cast<F*>(&dst.buf_), req);
}
static
@@ -237,7 +236,7 @@ struct decorator::vtable_impl<F, true>
invoke_res(storage& dst, response_type& res)
{
maybe_invoke<F, response_type>{}(
- *reinterpret_cast<F*>(&dst.buf_), res);
+ *beast::detail::launder_cast<F*>(&dst.buf_), res);
}
static
diff --git a/boost/beast/websocket/detail/frame.hpp b/boost/beast/websocket/detail/frame.hpp
index 1603bb556e..f217e04a52 100644
--- a/boost/beast/websocket/detail/frame.hpp
+++ b/boost/beast/websocket/detail/frame.hpp
@@ -14,20 +14,10 @@
#include <boost/beast/websocket/error.hpp>
#include <boost/beast/websocket/rfc6455.hpp>
#include <boost/beast/websocket/detail/utf8_checker.hpp>
-#include <boost/beast/core/buffers_suffix.hpp>
#include <boost/beast/core/flat_static_buffer.hpp>
-#include <boost/beast/core/static_string.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/assert.hpp>
-// This is for <boost/endian/buffers.hpp>
-#if BOOST_WORKAROUND(BOOST_MSVC, > 0)
-# pragma warning (push)
-# pragma warning (disable: 4127) // conditional expression is constant
-#endif
-#include <boost/endian/buffers.hpp>
-#if BOOST_WORKAROUND(BOOST_MSVC, > 0)
-# pragma warning (pop)
-#endif
+#include <boost/endian/conversion.hpp>
#include <cstdint>
namespace boost {
@@ -35,56 +25,6 @@ namespace beast {
namespace websocket {
namespace detail {
-inline
-std::uint16_t
-big_uint16_to_native(void const* buf)
-{
- auto const p = static_cast<
- std::uint8_t const*>(buf);
- return (p[0]<<8) + p[1];
-}
-
-inline
-std::uint64_t
-big_uint64_to_native(void const* buf)
-{
- auto const p = static_cast<
- std::uint8_t const*>(buf);
- return
- (static_cast<std::uint64_t>(p[0])<<56) +
- (static_cast<std::uint64_t>(p[1])<<48) +
- (static_cast<std::uint64_t>(p[2])<<40) +
- (static_cast<std::uint64_t>(p[3])<<32) +
- (static_cast<std::uint64_t>(p[4])<<24) +
- (static_cast<std::uint64_t>(p[5])<<16) +
- (static_cast<std::uint64_t>(p[6])<< 8) +
- p[7];
-}
-
-inline
-std::uint32_t
-little_uint32_to_native(void const* buf)
-{
- auto const p = static_cast<
- std::uint8_t const*>(buf);
- return
- p[0] +
- (static_cast<std::uint32_t>(p[1])<< 8) +
- (static_cast<std::uint32_t>(p[2])<<16) +
- (static_cast<std::uint32_t>(p[3])<<24);
-}
-
-inline
-void
-native_to_little_uint32(std::uint32_t v, void* buf)
-{
- auto p = static_cast<std::uint8_t*>(buf);
- p[0] = v & 0xff;
- p[1] = (v >> 8) & 0xff;
- p[2] = (v >> 16) & 0xff;
- p[3] = (v >> 24) & 0xff;
-}
-
// frame header opcodes
enum class opcode : std::uint8_t
{
@@ -193,7 +133,6 @@ template<class DynamicBuffer>
void
write(DynamicBuffer& db, frame_header const& fh)
{
- using namespace boost::endian;
std::size_t n;
std::uint8_t b[14];
b[0] = (fh.fin ? 0x80 : 0x00) | static_cast<std::uint8_t>(fh.op);
@@ -212,19 +151,24 @@ write(DynamicBuffer& db, frame_header const& fh)
else if(fh.len <= 65535)
{
b[1] |= 126;
- ::new(&b[2]) big_uint16_buf_t{
- (std::uint16_t)fh.len};
+ auto len_be = endian::native_to_big(
+ static_cast<std::uint16_t>(fh.len));
+ std::memcpy(&b[2], &len_be, sizeof(len_be));
n = 4;
}
else
{
b[1] |= 127;
- ::new(&b[2]) big_uint64_buf_t{fh.len};
+ auto len_be = endian::native_to_big(
+ static_cast<std::uint64_t>(fh.len));
+ std::memcpy(&b[2], &len_be, sizeof(len_be));
n = 10;
}
if(fh.mask)
{
- native_to_little_uint32(fh.key, &b[n]);
+ auto key_le = endian::native_to_little(
+ static_cast<std::uint32_t>(fh.key));
+ std::memcpy(&b[n], &key_le, sizeof(key_le));
n += 4;
}
db.commit(net::buffer_copy(
@@ -254,8 +198,7 @@ read_close(
Buffers const& bs,
error_code& ec)
{
- using namespace boost::endian;
- auto n = buffer_bytes(bs);
+ auto const n = buffer_bytes(bs);
BOOST_ASSERT(n <= 125);
if(n == 0)
{
@@ -269,36 +212,29 @@ read_close(
ec = error::bad_close_size;
return;
}
- buffers_suffix<Buffers> cb(bs);
- {
- std::uint8_t b[2];
- net::buffer_copy(net::buffer(b), cb);
- cr.code = big_uint16_to_native(&b[0]);
- cb.consume(2);
- n -= 2;
- if(! is_valid_close_code(cr.code))
- {
- // invalid close code
- ec = error::bad_close_code;
- return;
- }
- }
- if(n > 0)
+
+ std::uint16_t code_be;
+ cr.reason.resize(n - 2);
+ std::array<net::mutable_buffer, 2> out_bufs{{
+ net::mutable_buffer(&code_be, sizeof(code_be)),
+ net::mutable_buffer(&cr.reason[0], n - 2)}};
+
+ net::buffer_copy(out_bufs, bs);
+
+ cr.code = endian::big_to_native(code_be);
+ if(! is_valid_close_code(cr.code))
{
- cr.reason.resize(n);
- net::buffer_copy(
- net::buffer(&cr.reason[0], n), cb);
- if(! check_utf8(
- cr.reason.data(), cr.reason.size()))
- {
- // not valid utf-8
- ec = error::bad_close_payload;
- return;
- }
+ // invalid close code
+ ec = error::bad_close_code;
+ return;
}
- else
+
+ if(n > 2 && !check_utf8(
+ cr.reason.data(), cr.reason.size()))
{
- cr.reason = "";
+ // not valid utf-8
+ ec = error::bad_close_payload;
+ return;
}
ec = {};
}
diff --git a/boost/beast/websocket/detail/hybi13.ipp b/boost/beast/websocket/detail/hybi13.ipp
index b0ed57756b..0cbab15372 100644
--- a/boost/beast/websocket/detail/hybi13.ipp
+++ b/boost/beast/websocket/detail/hybi13.ipp
@@ -27,18 +27,12 @@ void
make_sec_ws_key(sec_ws_key_type& key)
{
auto g = make_prng(true);
- char a[16];
- for(int i = 0; i < 16; i += 4)
- {
- auto const v = g();
- a[i ] = v & 0xff;
- a[i+1] = (v >> 8) & 0xff;
- a[i+2] = (v >> 16) & 0xff;
- a[i+3] = (v >> 24) & 0xff;
- }
+ std::uint32_t a[4];
+ for (auto& v : a)
+ v = g();
key.resize(key.max_size());
key.resize(beast::detail::base64::encode(
- key.data(), &a[0], 16));
+ key.data(), &a[0], sizeof(a)));
}
void
@@ -47,11 +41,12 @@ make_sec_ws_accept(
string_view key)
{
BOOST_ASSERT(key.size() <= sec_ws_key_type::max_size_n);
- static_string<sec_ws_key_type::max_size_n + 36> m(key);
- m.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
+ using namespace beast::detail::string_literals;
+ auto const guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"_sv;
beast::detail::sha1_context ctx;
beast::detail::init(ctx);
- beast::detail::update(ctx, m.data(), m.size());
+ beast::detail::update(ctx, key.data(), key.size());
+ beast::detail::update(ctx, guid.data(), guid.size());
char digest[beast::detail::sha1_context::digest_size];
beast::detail::finish(ctx, &digest[0]);
accept.resize(accept.max_size());
diff --git a/boost/beast/websocket/detail/mask.hpp b/boost/beast/websocket/detail/mask.hpp
index ade89fdae5..58797372e5 100644
--- a/boost/beast/websocket/detail/mask.hpp
+++ b/boost/beast/websocket/detail/mask.hpp
@@ -26,62 +26,27 @@ namespace detail {
using prepared_key = std::array<unsigned char, 4>;
-inline
+BOOST_BEAST_DECL
void
-prepare_key(prepared_key& prepared, std::uint32_t key)
-{
- prepared[0] = (key >> 0) & 0xff;
- prepared[1] = (key >> 8) & 0xff;
- prepared[2] = (key >> 16) & 0xff;
- prepared[3] = (key >> 24) & 0xff;
-}
-
-template<std::size_t N>
-void
-rol(std::array<unsigned char, N>& v, std::size_t n)
-{
- auto v0 = v;
- for(std::size_t i = 0; i < v.size(); ++i )
- v[i] = v0[(i + n) % v.size()];
-}
+prepare_key(prepared_key& prepared, std::uint32_t key);
// Apply mask in place
//
-inline
+BOOST_BEAST_DECL
void
-mask_inplace(net::mutable_buffer& b, prepared_key& key)
-{
- auto n = b.size();
- auto mask = key; // avoid aliasing
- auto p = static_cast<unsigned char*>(b.data());
- while(n >= 4)
- {
- for(int i = 0; i < 4; ++i)
- p[i] ^= mask[i];
- p += 4;
- n -= 4;
- }
- if(n > 0)
- {
- for(std::size_t i = 0; i < n; ++i)
- p[i] ^= mask[i];
- rol(key, n);
- }
-}
+mask_inplace(net::mutable_buffer const& b, prepared_key& key);
// Apply mask in place
//
-template<
- class MutableBufferSequence,
- class KeyType>
+template<class MutableBufferSequence>
void
mask_inplace(
MutableBufferSequence const& buffers,
- KeyType& key)
+ prepared_key& key)
{
for(net::mutable_buffer b :
beast::buffers_range_ref(buffers))
- mask_inplace(b, key);
+ detail::mask_inplace(b, key);
}
} // detail
@@ -89,4 +54,10 @@ mask_inplace(
} // beast
} // boost
+
+#if BOOST_BEAST_HEADER_ONLY
+#include <boost/beast/websocket/detail/mask.ipp>
+#endif
+
+
#endif
diff --git a/boost/beast/websocket/detail/mask.ipp b/boost/beast/websocket/detail/mask.ipp
new file mode 100644
index 0000000000..6c36d56bc1
--- /dev/null
+++ b/boost/beast/websocket/detail/mask.ipp
@@ -0,0 +1,66 @@
+//
+// 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_WEBSOCKET_DETAIL_MASK_IPP
+#define BOOST_BEAST_WEBSOCKET_DETAIL_MASK_IPP
+
+#include <boost/beast/websocket/detail/mask.hpp>
+
+namespace boost {
+namespace beast {
+namespace websocket {
+namespace detail {
+
+void
+prepare_key(prepared_key& prepared, std::uint32_t key)
+{
+ prepared[0] = (key >> 0) & 0xff;
+ prepared[1] = (key >> 8) & 0xff;
+ prepared[2] = (key >> 16) & 0xff;
+ prepared[3] = (key >> 24) & 0xff;
+}
+
+inline
+void
+rol(prepared_key& v, std::size_t n)
+{
+ auto v0 = v;
+ for(std::size_t i = 0; i < v.size(); ++i )
+ v[i] = v0[(i + n) % v.size()];
+}
+
+// Apply mask in place
+//
+void
+mask_inplace(net::mutable_buffer const& b, prepared_key& key)
+{
+ auto n = b.size();
+ auto const mask = key; // avoid aliasing
+ auto p = static_cast<unsigned char*>(b.data());
+ while(n >= 4)
+ {
+ for(int i = 0; i < 4; ++i)
+ p[i] ^= mask[i];
+ p += 4;
+ n -= 4;
+ }
+ if(n > 0)
+ {
+ for(std::size_t i = 0; i < n; ++i)
+ p[i] ^= mask[i];
+ rol(key, n);
+ }
+}
+
+} // detail
+} // websocket
+} // beast
+} // boost
+
+#endif
diff --git a/boost/beast/websocket/detail/pmd_extension.ipp b/boost/beast/websocket/detail/pmd_extension.ipp
index 790998e8ff..005feec19d 100644
--- a/boost/beast/websocket/detail/pmd_extension.ipp
+++ b/boost/beast/websocket/detail/pmd_extension.ipp
@@ -52,11 +52,11 @@ pmd_read_impl(pmd_offer& offer, http::ext_list const& list)
for(auto const& ext : list)
{
- if(iequals(ext.first, "permessage-deflate"))
+ if(beast::iequals(ext.first, "permessage-deflate"))
{
for(auto const& param : ext.second)
{
- if(iequals(param.first,
+ if(beast::iequals(param.first,
"server_max_window_bits"))
{
if(offer.server_max_window_bits != 0)
@@ -84,7 +84,7 @@ pmd_read_impl(pmd_offer& offer, http::ext_list const& list)
return; // MUST decline
}
}
- else if(iequals(param.first,
+ else if(beast::iequals(param.first,
"client_max_window_bits"))
{
if(offer.client_max_window_bits != 0)
@@ -112,7 +112,7 @@ pmd_read_impl(pmd_offer& offer, http::ext_list const& list)
offer.client_max_window_bits = -1;
}
}
- else if(iequals(param.first,
+ else if(beast::iequals(param.first,
"server_no_context_takeover"))
{
if(offer.server_no_context_takeover)
@@ -131,7 +131,7 @@ pmd_read_impl(pmd_offer& offer, http::ext_list const& list)
}
offer.server_no_context_takeover = true;
}
- else if(iequals(param.first,
+ else if(beast::iequals(param.first,
"client_no_context_takeover"))
{
if(offer.client_no_context_takeover)
diff --git a/boost/beast/websocket/detail/prng.hpp b/boost/beast/websocket/detail/prng.hpp
index 35409b5837..6eb474f2f0 100644
--- a/boost/beast/websocket/detail/prng.hpp
+++ b/boost/beast/websocket/detail/prng.hpp
@@ -11,8 +11,8 @@
#define BOOST_BEAST_WEBSOCKET_DETAIL_PRNG_HPP
#include <boost/beast/core/detail/config.hpp>
+#include <boost/config.hpp>
#include <cstdint>
-#include <limits>
#include <random>
namespace boost {
@@ -20,66 +20,7 @@ namespace beast {
namespace websocket {
namespace detail {
-// Type-erased UniformRandomBitGenerator
-// with 32-bit unsigned integer value_type
-//
-class prng
-{
-protected:
- virtual ~prng() = default;
- virtual prng& acquire() noexcept = 0;
- virtual void release() noexcept = 0;
- virtual std::uint32_t operator()() noexcept = 0;
-
-public:
- using value_type = std::uint32_t;
-
- class ref
- {
- prng& p_;
-
- public:
- ref& operator=(ref const&) = delete;
-
- ~ref()
- {
- p_.release();
- }
-
- explicit
- ref(prng& p) noexcept
- : p_(p.acquire())
- {
- }
-
- ref(ref const& other) noexcept
- : p_(other.p_.acquire())
- {
- }
-
- value_type
- operator()() noexcept
- {
- return p_();
- }
-
- static
- value_type constexpr
- min() noexcept
- {
- return (std::numeric_limits<
- value_type>::min)();
- }
-
- static
- value_type constexpr
- max() noexcept
- {
- return (std::numeric_limits<
- value_type>::max)();
- }
- };
-};
+using generator = std::uint32_t(*)();
//------------------------------------------------------------------------------
@@ -90,25 +31,11 @@ BOOST_BEAST_DECL
std::uint32_t const*
prng_seed(std::seed_seq* ss = nullptr);
-// Acquire a PRNG using the no-TLS implementation
-//
-BOOST_BEAST_DECL
-prng::ref
-make_prng_no_tls(bool secure);
-
-// Acquire a PRNG using the TLS implementation
-//
-#ifndef BOOST_NO_CXX11_THREAD_LOCAL
-BOOST_BEAST_DECL
-prng::ref
-make_prng_tls(bool secure);
-#endif
-
// Acquire a PRNG using the TLS implementation if it
// is available, otherwise using the no-TLS implementation.
//
BOOST_BEAST_DECL
-prng::ref
+generator
make_prng(bool secure);
} // detail
diff --git a/boost/beast/websocket/detail/prng.ipp b/boost/beast/websocket/detail/prng.ipp
index 2807ca96e9..2d4e7f2771 100644
--- a/boost/beast/websocket/detail/prng.ipp
+++ b/boost/beast/websocket/detail/prng.ipp
@@ -13,14 +13,10 @@
#include <boost/beast/websocket/detail/prng.hpp>
#include <boost/beast/core/detail/chacha.hpp>
#include <boost/beast/core/detail/pcg.hpp>
-#include <boost/align/aligned_alloc.hpp>
-#include <boost/throw_exception.hpp>
#include <atomic>
#include <cstdlib>
#include <mutex>
-#include <new>
#include <random>
-#include <stdexcept>
namespace boost {
namespace beast {
@@ -59,264 +55,92 @@ prng_seed(std::seed_seq* ss)
//------------------------------------------------------------------------------
-template<class T>
-class prng_pool
+inline
+std::uint32_t
+make_nonce()
{
- std::mutex m_;
- T* head_ = nullptr;
-
-public:
- static
- prng_pool&
- instance()
- {
- static prng_pool p;
- return p;
- }
-
- ~prng_pool()
- {
- for(auto p = head_; p;)
- {
- auto next = p->next;
- p->~T();
- boost::alignment::aligned_free(p);
- p = next;
- }
- }
+ static std::atomic<std::uint32_t> nonce{0};
+ return ++nonce;
+}
- prng::ref
- acquire()
- {
- {
- std::lock_guard<
- std::mutex> g(m_);
- if(head_)
- {
- auto p = head_;
- head_ = head_->next;
- return prng::ref(*p);
- }
- }
- auto p = boost::alignment::aligned_alloc(
- 16, sizeof(T));
- if(! p)
- BOOST_THROW_EXCEPTION(std::bad_alloc{});
- return prng::ref(*(::new(p) T()));
- }
+inline
+beast::detail::pcg make_pcg()
+{
+ auto const pv = prng_seed();
+ return beast::detail::pcg{
+ ((static_cast<std::uint64_t>(pv[0])<<32)+pv[1]) ^
+ ((static_cast<std::uint64_t>(pv[2])<<32)+pv[3]) ^
+ ((static_cast<std::uint64_t>(pv[4])<<32)+pv[5]) ^
+ ((static_cast<std::uint64_t>(pv[6])<<32)+pv[7]), make_nonce()};
+}
- void
- release(T& t)
- {
- std::lock_guard<
- std::mutex> g(m_);
- t.next = head_;
- head_ = &t;
- }
-};
+#ifdef BOOST_NO_CXX11_THREAD_LOCAL
-prng::ref
-make_prng_no_tls(bool secure)
+inline
+std::uint32_t
+secure_generate()
{
- class fast_prng final : public prng
+ struct generator
{
- int refs_ = 0;
- beast::detail::pcg r_;
-
- public:
- fast_prng* next = nullptr;
-
- fast_prng()
- : r_(
- []{
- auto const pv = prng_seed();
- return
- ((static_cast<std::uint64_t>(pv[0])<<32)+pv[1]) ^
- ((static_cast<std::uint64_t>(pv[2])<<32)+pv[3]) ^
- ((static_cast<std::uint64_t>(pv[4])<<32)+pv[5]) ^
- ((static_cast<std::uint64_t>(pv[6])<<32)+pv[7]);
- }(),
- []{
- static std::atomic<
- std::uint32_t> nonce{0};
- return ++nonce;
- }())
- {
- }
-
- protected:
- prng&
- acquire() noexcept override
+ std::uint32_t operator()()
{
- ++refs_;
- return *this;
+ std::lock_guard<std::mutex> guard{mtx};
+ return gen();
}
- void
- release() noexcept override
- {
- if(--refs_ == 0)
- prng_pool<fast_prng>::instance().release(*this);
- }
-
- value_type
- operator()() noexcept override
- {
- return r_();
- }
+ beast::detail::chacha<20> gen;
+ std::mutex mtx;
};
-
- class secure_prng final : public prng
- {
- int refs_ = 0;
- beast::detail::chacha<20> r_;
-
- public:
- secure_prng* next = nullptr;
-
- secure_prng()
- : r_(prng_seed(), []
- {
- static std::atomic<
- std::uint64_t> nonce{0};
- return ++nonce;
- }())
- {
- }
-
- protected:
- prng&
- acquire() noexcept override
- {
- ++refs_;
- return *this;
- }
-
- void
- release() noexcept override
- {
- if(--refs_ == 0)
- prng_pool<secure_prng>::instance().release(*this);
- }
-
- value_type
- operator()() noexcept override
- {
- return r_();
- }
- };
-
- if(secure)
- return prng_pool<secure_prng>::instance().acquire();
-
- return prng_pool<fast_prng>::instance().acquire();
+ static generator gen{beast::detail::chacha<20>{prng_seed(), make_nonce()}};
+ return gen();
}
-//------------------------------------------------------------------------------
-
-#ifndef BOOST_NO_CXX11_THREAD_LOCAL
-
-prng::ref
-make_prng_tls(bool secure)
+inline
+std::uint32_t
+fast_generate()
{
- class fast_prng final : public prng
+ struct generator
{
- beast::detail::pcg r_;
-
- public:
- fast_prng()
- : r_(
- []{
- auto const pv = prng_seed();
- return
- ((static_cast<std::uint64_t>(pv[0])<<32)+pv[1]) ^
- ((static_cast<std::uint64_t>(pv[2])<<32)+pv[3]) ^
- ((static_cast<std::uint64_t>(pv[4])<<32)+pv[5]) ^
- ((static_cast<std::uint64_t>(pv[6])<<32)+pv[7]);
- }(),
- []{
- static std::atomic<
- std::uint32_t> nonce{0};
- return ++nonce;
- }())
- {
- }
-
- protected:
- prng&
- acquire() noexcept override
+ std::uint32_t operator()()
{
- return *this;
+ std::lock_guard<std::mutex> guard{mtx};
+ return gen();
}
- void
- release() noexcept override
- {
- }
-
- value_type
- operator()() noexcept override
- {
- return r_();
- }
+ beast::detail::pcg gen;
+ std::mutex mtx;
};
+ static generator gen{make_pcg()};
+ return gen();
+}
- class secure_prng final : public prng
- {
- beast::detail::chacha<20> r_;
-
- public:
- secure_prng()
- : r_(prng_seed(), []
- {
- static std::atomic<
- std::uint64_t> nonce{0};
- return ++nonce;
- }())
- {
- }
-
- protected:
- prng&
- acquire() noexcept override
- {
- return *this;
- }
-
- void
- release() noexcept override
- {
- }
-
- value_type
- operator()() noexcept override
- {
- return r_();
- }
- };
+#else
- if(secure)
- {
- thread_local secure_prng sp;
- return prng::ref(sp);
- }
+inline
+std::uint32_t
+secure_generate()
+{
+ thread_local static beast::detail::chacha<20> gen{prng_seed(), make_nonce()};
+ return gen();
+}
- thread_local fast_prng fp;
- return prng::ref(fp);
+inline
+std::uint32_t
+fast_generate()
+{
+ thread_local static beast::detail::pcg gen{make_pcg()};
+ return gen();
}
#endif
-//------------------------------------------------------------------------------
-
-prng::ref
+generator
make_prng(bool secure)
{
-#ifdef BOOST_NO_CXX11_THREAD_LOCAL
- return make_prng_no_tls(secure);
-#else
- return make_prng_tls(secure);
-#endif
+ if (secure)
+ return &secure_generate;
+ else
+ return &fast_generate;
}
} // detail
diff --git a/boost/beast/websocket/impl/accept.hpp b/boost/beast/websocket/impl/accept.hpp
index 4b989b56c7..1e33d8b40a 100644
--- a/boost/beast/websocket/impl/accept.hpp
+++ b/boost/beast/websocket/impl/accept.hpp
@@ -21,7 +21,6 @@
#include <boost/beast/core/buffer_traits.hpp>
#include <boost/beast/core/stream_traits.hpp>
#include <boost/beast/core/detail/buffer.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/coroutine.hpp>
#include <boost/asio/post.hpp>
@@ -80,13 +79,8 @@ build_response(
decorator_opt(res);
decorator(res);
if(! res.count(http::field::server))
- {
- // VFALCO this is weird..
- BOOST_STATIC_ASSERT(sizeof(
- BOOST_BEAST_VERSION_STRING) < 20);
- static_string<20> s(BOOST_BEAST_VERSION_STRING);
- res.set(http::field::server, s);
- }
+ res.set(http::field::server,
+ string_view(BOOST_BEAST_VERSION_STRING));
};
auto err =
[&](error e)
@@ -172,7 +166,7 @@ template<class Handler>
class stream<NextLayer, deflateSupported>::response_op
: public beast::stable_async_base<
Handler, beast::executor_type<stream>>
- , public net::coroutine
+ , public asio::coroutine
{
boost::weak_ptr<impl_type> wp_;
error_code result_; // must come before res_
@@ -247,7 +241,7 @@ template<class Handler, class Decorator>
class stream<NextLayer, deflateSupported>::accept_op
: public beast::stable_async_base<
Handler, beast::executor_type<stream>>
- , public net::coroutine
+ , public asio::coroutine
{
boost::weak_ptr<impl_type> wp_;
http::request_parser<http::empty_body>& p_;
diff --git a/boost/beast/websocket/impl/close.hpp b/boost/beast/websocket/impl/close.hpp
index 03078d9232..d59374ccd3 100644
--- a/boost/beast/websocket/impl/close.hpp
+++ b/boost/beast/websocket/impl/close.hpp
@@ -38,7 +38,7 @@ template<class Handler>
class stream<NextLayer, deflateSupported>::close_op
: public beast::stable_async_base<
Handler, beast::executor_type<stream>>
- , public net::coroutine
+ , public asio::coroutine
{
boost::weak_ptr<impl_type> wp_;
error_code ev_;
diff --git a/boost/beast/websocket/impl/handshake.hpp b/boost/beast/websocket/impl/handshake.hpp
index 21fba99738..645b1a3a30 100644
--- a/boost/beast/websocket/impl/handshake.hpp
+++ b/boost/beast/websocket/impl/handshake.hpp
@@ -37,7 +37,7 @@ template<class Handler>
class stream<NextLayer, deflateSupported>::handshake_op
: public beast::stable_async_base<Handler,
beast::executor_type<stream>>
- , public net::coroutine
+ , public asio::coroutine
{
struct data
{
diff --git a/boost/beast/websocket/impl/ping.hpp b/boost/beast/websocket/impl/ping.hpp
index 350505c081..6f92d7c725 100644
--- a/boost/beast/websocket/impl/ping.hpp
+++ b/boost/beast/websocket/impl/ping.hpp
@@ -35,7 +35,7 @@ template<class Handler>
class stream<NextLayer, deflateSupported>::ping_op
: public beast::stable_async_base<
Handler, beast::executor_type<stream>>
- , public net::coroutine
+ , public asio::coroutine
{
boost::weak_ptr<impl_type> wp_;
detail::frame_buffer& fb_;
@@ -115,7 +115,7 @@ public:
template<class NextLayer, bool deflateSupported>
template<class Executor>
class stream<NextLayer, deflateSupported>::idle_ping_op
- : public net::coroutine
+ : public asio::coroutine
, public boost::empty_value<Executor>
{
boost::weak_ptr<impl_type> wp_;
@@ -176,7 +176,8 @@ public:
impl.op_idle_ping.emplace(std::move(*this));
impl.wr_block.lock(this);
BOOST_ASIO_CORO_YIELD
- net::post(this->get(), std::move(*this));
+ net::post(
+ this->get_executor(), std::move(*this));
BOOST_ASSERT(impl.wr_block.is_locked(this));
}
if(impl.check_stop_now(ec))
diff --git a/boost/beast/websocket/impl/read.hpp b/boost/beast/websocket/impl/read.hpp
index 8be18e5975..86c8940fc7 100644
--- a/boost/beast/websocket/impl/read.hpp
+++ b/boost/beast/websocket/impl/read.hpp
@@ -48,7 +48,7 @@ template<class Handler, class MutableBufferSequence>
class stream<NextLayer, deflateSupported>::read_some_op
: public beast::async_base<
Handler, beast::executor_type<stream>>
- , public net::coroutine
+ , public asio::coroutine
{
boost::weak_ptr<impl_type> wp_;
MutableBufferSequence bs_;
@@ -619,7 +619,7 @@ template<class Handler, class DynamicBuffer>
class stream<NextLayer, deflateSupported>::read_op
: public beast::async_base<
Handler, beast::executor_type<stream>>
- , public net::coroutine
+ , public asio::coroutine
{
boost::weak_ptr<impl_type> wp_;
DynamicBuffer& b_;
@@ -664,21 +664,22 @@ public:
auto& impl = *sp;
using mutable_buffers_type = typename
DynamicBuffer::mutable_buffers_type;
- boost::optional<mutable_buffers_type> mb;
BOOST_ASIO_CORO_REENTER(*this)
{
do
{
- mb = beast::detail::dynamic_buffer_prepare(b_,
- clamp(impl.read_size_hint_db(b_), limit_),
- ec, error::buffer_overflow);
- if(impl.check_stop_now(ec))
- goto upcall;
-
// VFALCO TODO use boost::beast::bind_continuation
BOOST_ASIO_CORO_YIELD
- read_some_op<read_op, mutable_buffers_type>(
- std::move(*this), sp, *mb);
+ {
+ auto mb = beast::detail::dynamic_buffer_prepare(b_,
+ clamp(impl.read_size_hint_db(b_), limit_),
+ ec, error::buffer_overflow);
+ if(impl.check_stop_now(ec))
+ goto upcall;
+ read_some_op<read_op, mutable_buffers_type>(
+ std::move(*this), sp, *mb);
+ }
+
b_.commit(bytes_transferred);
bytes_written_ += bytes_transferred;
if(ec)
diff --git a/boost/beast/websocket/impl/stream.hpp b/boost/beast/websocket/impl/stream.hpp
index 150748c453..539e255192 100644
--- a/boost/beast/websocket/impl/stream.hpp
+++ b/boost/beast/websocket/impl/stream.hpp
@@ -25,11 +25,8 @@
#include <boost/beast/core/buffers_suffix.hpp>
#include <boost/beast/core/flat_static_buffer.hpp>
#include <boost/beast/core/detail/clamp.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
-#include <boost/asio/bind_executor.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/assert.hpp>
-#include <boost/endian/buffers.hpp>
#include <boost/make_shared.hpp>
#include <boost/throw_exception.hpp>
#include <algorithm>
@@ -64,7 +61,7 @@ stream(Args&&... args)
template<class NextLayer, bool deflateSupported>
auto
stream<NextLayer, deflateSupported>::
-get_executor() const noexcept ->
+get_executor() noexcept ->
executor_type
{
return impl_->stream().get_executor();
@@ -140,12 +137,7 @@ read_size_hint(DynamicBuffer& buffer) const
static_assert(
net::is_dynamic_buffer<DynamicBuffer>::value,
"DynamicBuffer type requirements not met");
- auto const initial_size = (std::min)(
- +tcp_frame_size,
- buffer.max_size() - buffer.size());
- if(initial_size == 0)
- return 1; // buffer is full
- return read_size_hint(initial_size);
+ return impl_->read_size_hint_db(buffer);
}
//------------------------------------------------------------------------------
diff --git a/boost/beast/websocket/impl/stream_impl.hpp b/boost/beast/websocket/impl/stream_impl.hpp
index ec5557c361..5bcd9c78ab 100644
--- a/boost/beast/websocket/impl/stream_impl.hpp
+++ b/boost/beast/websocket/impl/stream_impl.hpp
@@ -30,9 +30,7 @@
#include <boost/beast/core/static_buffer.hpp>
#include <boost/beast/core/stream_traits.hpp>
#include <boost/beast/core/detail/clamp.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/beast/version.hpp>
-#include <boost/asio/bind_executor.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/enable_shared_from_this.hpp>
@@ -99,7 +97,8 @@ struct stream<NextLayer, deflateSupported>::impl_type
bool wr_cont /* next write is a continuation */ = false;
bool wr_frag /* autofrag the current message */ = false;
bool wr_frag_opt /* autofrag option setting */ = true;
- bool wr_compress /* compress current message */ = false;
+ bool wr_compress; /* compress current message */
+ bool wr_compress_opt /* compress message setting */ = true;
detail::opcode wr_opcode /* message type */ = detail::opcode::text;
std::unique_ptr<
std::uint8_t[]> wr_buf; // write buffer
@@ -211,11 +210,14 @@ struct stream<NextLayer, deflateSupported>::impl_type
timer.cancel();
}
- // Called before each write frame
+ // Called just before sending
+ // the first frame of each message
void
begin_msg()
{
wr_frag = wr_frag_opt;
+ wr_compress =
+ this->pmd_enabled() && wr_compress_opt;
// Maintain the write buffer
if( this->pmd_enabled() ||
@@ -234,6 +236,8 @@ struct stream<NextLayer, deflateSupported>::impl_type
wr_buf_size = wr_buf_opt;
wr_buf.reset();
}
+
+ //
}
//--------------------------------------------------------------------------
@@ -275,13 +279,6 @@ struct stream<NextLayer, deflateSupported>::impl_type
return key;
}
- std::size_t
- read_size_hint(std::size_t initial_size) const
- {
- return this->read_size_hint_pmd(
- initial_size, rd_done, rd_remain, rd_fh);
- }
-
template<class DynamicBuffer>
std::size_t
read_size_hint_db(DynamicBuffer& buffer) const
@@ -291,7 +288,8 @@ struct stream<NextLayer, deflateSupported>::impl_type
buffer.max_size() - buffer.size());
if(initial_size == 0)
return 1; // buffer is full
- return this->read_size_hint(initial_size);
+ return this->read_size_hint_pmd(
+ initial_size, rd_done, rd_remain, rd_fh);
}
template<class DynamicBuffer>
@@ -771,10 +769,12 @@ parse_fh(
{
case 126:
{
- std::uint8_t tmp[2];
- BOOST_ASSERT(buffer_bytes(cb) >= sizeof(tmp));
- cb.consume(net::buffer_copy(net::buffer(tmp), cb));
- fh.len = detail::big_uint16_to_native(&tmp[0]);
+
+ std::uint16_t len_be;
+ BOOST_ASSERT(buffer_bytes(cb) >= sizeof(len_be));
+ cb.consume(net::buffer_copy(
+ net::mutable_buffer(&len_be, sizeof(len_be)), cb));
+ fh.len = endian::big_to_native(len_be);
if(fh.len < 126)
{
// length not canonical
@@ -785,10 +785,11 @@ parse_fh(
}
case 127:
{
- std::uint8_t tmp[8];
- BOOST_ASSERT(buffer_bytes(cb) >= sizeof(tmp));
- cb.consume(net::buffer_copy(net::buffer(tmp), cb));
- fh.len = detail::big_uint64_to_native(&tmp[0]);
+ std::uint64_t len_be;
+ BOOST_ASSERT(buffer_bytes(cb) >= sizeof(len_be));
+ cb.consume(net::buffer_copy(
+ net::mutable_buffer(&len_be, sizeof(len_be)), cb));
+ fh.len = endian::big_to_native(len_be);
if(fh.len < 65536)
{
// length not canonical
@@ -800,10 +801,11 @@ parse_fh(
}
if(fh.mask)
{
- std::uint8_t tmp[4];
- BOOST_ASSERT(buffer_bytes(cb) >= sizeof(tmp));
- cb.consume(net::buffer_copy(net::buffer(tmp), cb));
- fh.key = detail::little_uint32_to_native(&tmp[0]);
+ std::uint32_t key_le;
+ BOOST_ASSERT(buffer_bytes(cb) >= sizeof(key_le));
+ cb.consume(net::buffer_copy(
+ net::mutable_buffer(&key_le, sizeof(key_le)), cb));
+ fh.key = endian::little_to_native(key_le);
detail::prepare_key(rd_key, fh.key);
}
else
@@ -909,12 +911,10 @@ write_close(DynamicBuffer& db, close_reason const& cr)
if(fh.mask)
detail::prepare_key(key, fh.key);
{
- std::uint8_t tmp[2];
- ::new(&tmp[0]) big_uint16_buf_t{
- (std::uint16_t)cr.code};
+ auto code_be = endian::native_to_big<std::uint16_t>(cr.code);
auto mb = db.prepare(2);
net::buffer_copy(mb,
- net::buffer(tmp));
+ net::const_buffer(&code_be, sizeof(code_be)));
if(fh.mask)
detail::mask_inplace(mb, key);
db.commit(2);
diff --git a/boost/beast/websocket/impl/teardown.hpp b/boost/beast/websocket/impl/teardown.hpp
index 8e0913762c..2e2f0ad7e3 100644
--- a/boost/beast/websocket/impl/teardown.hpp
+++ b/boost/beast/websocket/impl/teardown.hpp
@@ -14,7 +14,7 @@
#include <boost/beast/core/bind_handler.hpp>
#include <boost/beast/core/stream_traits.hpp>
#include <boost/beast/core/detail/bind_continuation.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
+#include <boost/beast/core/detail/is_invocable.hpp>
#include <boost/asio/coroutine.hpp>
#include <boost/asio/post.hpp>
#include <memory>
@@ -33,7 +33,7 @@ class teardown_tcp_op
Handler, beast::executor_type<
net::basic_stream_socket<
Protocol, Executor>>>
- , public net::coroutine
+ , public asio::coroutine
{
using socket_type =
net::basic_stream_socket<Protocol, Executor>;
diff --git a/boost/beast/websocket/impl/write.hpp b/boost/beast/websocket/impl/write.hpp
index 318693f512..2a82b677b3 100644
--- a/boost/beast/websocket/impl/write.hpp
+++ b/boost/beast/websocket/impl/write.hpp
@@ -41,7 +41,7 @@ template<class Handler, class Buffers>
class stream<NextLayer, deflateSupported>::write_some_op
: public beast::async_base<
Handler, beast::executor_type<stream>>
- , public net::coroutine
+ , public asio::coroutine
{
enum
{
diff --git a/boost/beast/websocket/option.hpp b/boost/beast/websocket/option.hpp
index 62ebfa4a2b..1133c4e1fa 100644
--- a/boost/beast/websocket/option.hpp
+++ b/boost/beast/websocket/option.hpp
@@ -11,15 +11,6 @@
#define BOOST_BEAST_WEBSOCKET_OPTION_HPP
#include <boost/beast/core/detail/config.hpp>
-#include <boost/beast/websocket/rfc6455.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
-#include <boost/throw_exception.hpp>
-#include <algorithm>
-#include <cstdint>
-#include <functional>
-#include <stdexcept>
-#include <type_traits>
-#include <utility>
namespace boost {
namespace beast {
diff --git a/boost/beast/websocket/stream.hpp b/boost/beast/websocket/stream.hpp
index a9d79d2de4..367a54537c 100644
--- a/boost/beast/websocket/stream.hpp
+++ b/boost/beast/websocket/stream.hpp
@@ -23,7 +23,6 @@
#include <boost/beast/core/role.hpp>
#include <boost/beast/core/stream_traits.hpp>
#include <boost/beast/core/string.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/beast/http/detail/type_traits.hpp>
#include <boost/asio/async_result.hpp>
#include <boost/asio/error.hpp>
@@ -220,7 +219,7 @@ public:
@return A copy of the executor that stream will use to dispatch handlers.
*/
executor_type
- get_executor() const noexcept;
+ get_executor() noexcept;
/** Get a reference to the next layer
diff --git a/boost/beast/zlib/detail/deflate_stream.hpp b/boost/beast/zlib/detail/deflate_stream.hpp
index 74ce6e5a9a..1460dd42dd 100644
--- a/boost/beast/zlib/detail/deflate_stream.hpp
+++ b/boost/beast/zlib/detail/deflate_stream.hpp
@@ -40,7 +40,6 @@
#include <boost/beast/zlib/error.hpp>
#include <boost/beast/zlib/zlib.hpp>
#include <boost/beast/zlib/detail/ranges.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/optional.hpp>
diff --git a/boost/beast/zlib/detail/deflate_stream.ipp b/boost/beast/zlib/detail/deflate_stream.ipp
index 4641697c36..5169843362 100644
--- a/boost/beast/zlib/detail/deflate_stream.ipp
+++ b/boost/beast/zlib/detail/deflate_stream.ipp
@@ -39,7 +39,6 @@
#include <boost/beast/zlib/detail/deflate_stream.hpp>
#include <boost/beast/zlib/detail/ranges.hpp>
-#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/make_unique.hpp>
@@ -623,6 +622,7 @@ init()
window_ = reinterpret_cast<Byte*>(buf_.get());
prev_ = reinterpret_cast<std::uint16_t*>(buf_.get() + nwindow);
+ std::memset(prev_, 0, nprev);
head_ = reinterpret_cast<std::uint16_t*>(buf_.get() + nwindow + nprev);
/* We overlay pending_buf_ and d_buf_ + l_buf_. This works