summaryrefslogtreecommitdiff
path: root/boost/beast/websocket
diff options
context:
space:
mode:
Diffstat (limited to 'boost/beast/websocket')
-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
19 files changed, 245 insertions, 549 deletions
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