diff options
Diffstat (limited to 'boost/beast/websocket/detail')
-rw-r--r-- | boost/beast/websocket/detail/error.hpp | 78 | ||||
-rw-r--r-- | boost/beast/websocket/detail/frame.hpp | 25 | ||||
-rw-r--r-- | boost/beast/websocket/detail/mask.hpp | 177 | ||||
-rw-r--r-- | boost/beast/websocket/detail/pausation.hpp | 203 | ||||
-rw-r--r-- | boost/beast/websocket/detail/pmd_extension.hpp | 80 | ||||
-rw-r--r-- | boost/beast/websocket/detail/stream_base.hpp | 221 | ||||
-rw-r--r-- | boost/beast/websocket/detail/type_traits.hpp | 4 | ||||
-rw-r--r-- | boost/beast/websocket/detail/utf8_checker.hpp | 6 |
8 files changed, 417 insertions, 377 deletions
diff --git a/boost/beast/websocket/detail/error.hpp b/boost/beast/websocket/detail/error.hpp new file mode 100644 index 0000000000..57b837bd4c --- /dev/null +++ b/boost/beast/websocket/detail/error.hpp @@ -0,0 +1,78 @@ +// +// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/beast +// + +#ifndef BOOST_BEAST_WEBSOCKET_DETAIL_ERROR_IPP +#define BOOST_BEAST_WEBSOCKET_DETAIL_ERROR_IPP + +#include <boost/beast/core/error.hpp> +#include <boost/beast/core/string.hpp> + +namespace boost { + +namespace beast { +namespace websocket { +enum class error; +enum class condition; +} // websocket +} // beast + +namespace system { +template<> +struct is_error_code_enum<beast::websocket::error> +{ + static bool const value = true; +}; +template<> +struct is_error_condition_enum<beast::websocket::condition> +{ + static bool const value = true; +}; +} // system + +namespace beast { +namespace websocket { +namespace detail { + +class error_codes : public error_category +{ +public: + const char* + name() const noexcept override; + + std::string + message(int ev) const override; + + error_condition + default_error_condition(int ev) const noexcept override; +}; + +class error_conditions : public error_category +{ +public: + const char* + name() const noexcept override; + + std::string + message(int cv) const override; +}; + +} // detail + +error_code +make_error_code(error e); + +error_condition +make_error_condition(condition c); + +} // websocket +} // beast + +} // boost + +#endif diff --git a/boost/beast/websocket/detail/frame.hpp b/boost/beast/websocket/detail/frame.hpp index 95080aeefc..c3bd1690a9 100644 --- a/boost/beast/websocket/detail/frame.hpp +++ b/boost/beast/websocket/detail/frame.hpp @@ -10,6 +10,7 @@ #ifndef BOOST_BEAST_WEBSOCKET_DETAIL_FRAME_HPP #define BOOST_BEAST_WEBSOCKET_DETAIL_FRAME_HPP +#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> @@ -75,7 +76,7 @@ native_to_little_uint32(std::uint32_t v, void* buf) p[3] = (v >> 24) & 0xff; } -/** WebSocket frame header opcodes. */ +// frame header opcodes enum class opcode : std::uint8_t { cont = 0, @@ -110,8 +111,7 @@ struct frame_header }; // holds the largest possible frame header -using fh_buffer = - flat_static_buffer<14>; +using fh_buffer = flat_static_buffer<14>; // holds the largest possible control frame using frame_buffer = @@ -245,8 +245,10 @@ read_ping(ping_data& data, Buffers const& bs) // template<class Buffers> void -read_close(close_reason& cr, - Buffers const& bs, close_code& code) +read_close( + close_reason& cr, + Buffers const& bs, + error_code& ec) { using boost::asio::buffer; using boost::asio::buffer_copy; @@ -257,12 +259,13 @@ read_close(close_reason& cr, if(n == 0) { cr = close_reason{}; - code = close_code::none; + ec.assign(0, ec.category()); return; } if(n == 1) { - code = close_code::protocol_error; + // invalid payload size == 1 + ec = error::bad_close_size; return; } buffers_suffix<Buffers> cb(bs); @@ -274,7 +277,8 @@ read_close(close_reason& cr, n -= 2; if(! is_valid_close_code(cr.code)) { - code = close_code::protocol_error; + // invalid close code + ec = error::bad_close_code; return; } } @@ -285,7 +289,8 @@ read_close(close_reason& cr, if(! check_utf8( cr.reason.data(), cr.reason.size())) { - code = close_code::protocol_error; + // not valid utf-8 + ec = error::bad_close_payload; return; } } @@ -293,7 +298,7 @@ read_close(close_reason& cr, { cr.reason = ""; } - code = close_code::none; + ec.assign(0, ec.category()); } } // detail diff --git a/boost/beast/websocket/detail/mask.hpp b/boost/beast/websocket/detail/mask.hpp index 92ea0a4238..8958d793b8 100644 --- a/boost/beast/websocket/detail/mask.hpp +++ b/boost/beast/websocket/detail/mask.hpp @@ -11,6 +11,7 @@ #define BOOST_BEAST_WEBSOCKET_DETAIL_MASK_HPP #include <boost/beast/core/detail/config.hpp> +#include <boost/beast/core/detail/type_traits.hpp> #include <boost/asio/buffer.hpp> #include <array> #include <climits> @@ -83,179 +84,59 @@ using maskgen = maskgen_t<std::minstd_rand>; //------------------------------------------------------------------------------ -using prepared_key = - std::conditional<sizeof(void*) == 8, - std::uint64_t, std::uint32_t>::type; +using prepared_key = std::array<unsigned char, 4>; inline void -prepare_key(std::uint32_t& prepared, std::uint32_t key) +prepare_key(prepared_key& prepared, std::uint32_t key) { - prepared = key; + prepared[0] = (key >> 0) & 0xff; + prepared[1] = (key >> 8) & 0xff; + prepared[2] = (key >> 16) & 0xff; + prepared[3] = (key >> 24) & 0xff; } -inline +template<std::size_t N> void -prepare_key(std::uint64_t& prepared, std::uint32_t key) -{ - prepared = - (static_cast<std::uint64_t>(key) << 32) | key; -} - -template<class T> -inline -typename std::enable_if<std::is_integral<T>::value, T>::type -ror(T t, unsigned n = 1) +rol(std::array<unsigned char, N>& v, std::size_t n) { - auto constexpr bits = - static_cast<unsigned>( - sizeof(T) * CHAR_BIT); - n &= bits-1; - return static_cast<T>((t << (bits - n)) | ( - static_cast<typename std::make_unsigned<T>::type>(t) >> n)); + auto v0 = v; + for(std::size_t i = 0; i < v.size(); ++i ) + v[i] = v0[(i + n) % v.size()]; } -// 32-bit optimized -// -template<class = void> -void -mask_inplace_fast( - boost::asio::mutable_buffer const& b, - std::uint32_t& key) -{ - auto n = b.size(); - auto p = reinterpret_cast<std::uint8_t*>(b.data()); - if(n >= sizeof(key)) - { - // Bring p to 4-byte alignment - auto const i = reinterpret_cast< - std::uintptr_t>(p) & (sizeof(key)-1); - switch(i) - { - case 1: p[2] ^= static_cast<std::uint8_t>(key >> 16); BOOST_BEAST_FALLTHROUGH; - case 2: p[1] ^= static_cast<std::uint8_t>(key >> 8); BOOST_BEAST_FALLTHROUGH; - case 3: p[0] ^= static_cast<std::uint8_t>(key); - { - auto const d = static_cast<unsigned>(sizeof(key) - i); - key = ror(key, 8*d); - n -= d; - p += d; - BOOST_BEAST_FALLTHROUGH; - } - default: - break; - } - } - - // Mask 4 bytes at a time - for(auto i = n / sizeof(key); i; --i) - { - *reinterpret_cast< - std::uint32_t*>(p) ^= key; - p += sizeof(key); - } - - // Leftovers - n &= sizeof(key)-1; - switch(n) - { - case 3: p[2] ^= static_cast<std::uint8_t>(key >> 16); BOOST_BEAST_FALLTHROUGH; - case 2: p[1] ^= static_cast<std::uint8_t>(key >> 8); BOOST_BEAST_FALLTHROUGH; - case 1: p[0] ^= static_cast<std::uint8_t>(key); - key = ror(key, static_cast<unsigned>(8*n)); - BOOST_BEAST_FALLTHROUGH; - default: - break; - } -} - -// 64-bit optimized +// Apply mask in place // -template<class = void> +inline void -mask_inplace_fast( - boost::asio::mutable_buffer const& b, - std::uint64_t& key) +mask_inplace(boost::asio::mutable_buffer& b, prepared_key& key) { auto n = b.size(); - auto p = reinterpret_cast<std::uint8_t*>(b.data()); - if(n >= sizeof(key)) + auto mask = key; // avoid aliasing + auto p = reinterpret_cast<unsigned char*>(b.data()); + while(n >= 4) { - // Bring p to 8-byte alignment - auto const i = reinterpret_cast< - std::uintptr_t>(p) & (sizeof(key)-1); - switch(i) - { - case 1: p[6] ^= static_cast<std::uint8_t>(key >> 48); - case 2: p[5] ^= static_cast<std::uint8_t>(key >> 40); - case 3: p[4] ^= static_cast<std::uint8_t>(key >> 32); - case 4: p[3] ^= static_cast<std::uint8_t>(key >> 24); - case 5: p[2] ^= static_cast<std::uint8_t>(key >> 16); - case 6: p[1] ^= static_cast<std::uint8_t>(key >> 8); - case 7: p[0] ^= static_cast<std::uint8_t>(key); - { - auto const d = static_cast< - unsigned>(sizeof(key) - i); - key = ror(key, 8*d); - n -= d; - p += d; - } - default: - break; - } + for(int i = 0; i < 4; ++i) + p[i] ^= mask[i]; + p += 4; + n -= 4; } - - // Mask 8 bytes at a time - for(auto i = n / sizeof(key); i; --i) + if(n > 0) { - *reinterpret_cast< - std::uint64_t*>(p) ^= key; - p += sizeof(key); + for(std::size_t i = 0; i < n; ++i) + p[i] ^= mask[i]; + rol(key, n); } - - // Leftovers - n &= sizeof(key)-1; - switch(n) - { - case 7: p[6] ^= static_cast<std::uint8_t>(key >> 48); - case 6: p[5] ^= static_cast<std::uint8_t>(key >> 40); - case 5: p[4] ^= static_cast<std::uint8_t>(key >> 32); - case 4: p[3] ^= static_cast<std::uint8_t>(key >> 24); - case 3: p[2] ^= static_cast<std::uint8_t>(key >> 16); - case 2: p[1] ^= static_cast<std::uint8_t>(key >> 8); - case 1: p[0] ^= static_cast<std::uint8_t>(key); - key = ror(key, static_cast<unsigned>(8*n)); - default: - break; - } -} - -inline -void -mask_inplace( - boost::asio::mutable_buffer const& b, - std::uint32_t& key) -{ - mask_inplace_fast(b, key); -} - -inline -void -mask_inplace( - boost::asio::mutable_buffer const& b, - std::uint64_t& key) -{ - mask_inplace_fast(b, key); } // Apply mask in place // template<class MutableBuffers, class KeyType> void -mask_inplace( - MutableBuffers const& bs, KeyType& key) +mask_inplace(MutableBuffers const& bs, KeyType& key) { - for(boost::asio::mutable_buffer b : bs) + for(boost::asio::mutable_buffer b : + beast::detail::buffers_range(bs)) mask_inplace(b, key); } diff --git a/boost/beast/websocket/detail/pausation.hpp b/boost/beast/websocket/detail/pausation.hpp index f51ee10327..e3870b038a 100644 --- a/boost/beast/websocket/detail/pausation.hpp +++ b/boost/beast/websocket/detail/pausation.hpp @@ -10,13 +10,10 @@ #ifndef BOOST_BEAST_WEBSOCKET_DETAIL_PAUSATION_HPP #define BOOST_BEAST_WEBSOCKET_DETAIL_PAUSATION_HPP -#include <boost/beast/core/handler_ptr.hpp> +#include <boost/beast/core/detail/allocator.hpp> #include <boost/asio/associated_allocator.hpp> -#include <boost/asio/coroutine.hpp> #include <boost/assert.hpp> -#include <array> #include <memory> -#include <new> #include <utility> namespace boost { @@ -30,124 +27,59 @@ namespace detail { // class pausation { - struct base + struct handler { - base() = default; - base(base &&) = delete; - base(base const&) = delete; - virtual ~base() = default; - virtual void operator()() = 0; + handler() = default; + handler(handler &&) = delete; + handler(handler const&) = delete; + virtual ~handler() = default; + virtual void destroy() = 0; + virtual void invoke() = 0; }; - template<class F> - struct holder : base + template<class Handler> + class impl : public handler { - F f; - - holder(holder&&) = default; - - template<class U> - explicit - holder(U&& u) - : f(std::forward<U>(u)) - { - } - - void - operator()() override - { - F f_(std::move(f)); - this->~holder(); - // invocation of f_() can - // assign a new object to *this. - f_(); - } - }; - - struct exemplar : boost::asio::coroutine - { - struct H - { - void operator()(); - }; - - struct T - { - using handler_type = H; - }; - - handler_ptr<T, H> hp; - - void operator()(); - }; - - template<class Op> - class saved_op - { - Op* op_ = nullptr; + Handler h_; public: - ~saved_op() - { - if(op_) - { - Op op(std::move(*op_)); - op_->~Op(); - typename std::allocator_traits< - boost::asio::associated_allocator_t<Op>>:: - template rebind_alloc<Op> alloc{ - boost::asio::get_associated_allocator(op)}; - std::allocator_traits< - decltype(alloc)>::deallocate(alloc, op_, 1); - } - } - - saved_op(saved_op&& other) - : op_(other.op_) + template<class DeducedHandler> + impl(DeducedHandler&& h) + : h_(std::forward<DeducedHandler>(h)) { - other.op_ = nullptr; } - saved_op& operator=(saved_op&& other) - { - BOOST_ASSERT(! op_); - op_ = other.op_; - other.op_ = 0; - return *this; - } - - explicit - saved_op(Op&& op) + void + destroy() override { - typename std::allocator_traits< - boost::asio::associated_allocator_t<Op>>:: - template rebind_alloc<Op> alloc{ - boost::asio::get_associated_allocator(op)}; - auto const p = std::allocator_traits< - decltype(alloc)>::allocate(alloc, 1); - op_ = new(p) Op{std::move(op)}; + Handler h(std::move(h_)); + typename beast::detail::allocator_traits< + boost::asio::associated_allocator_t< + Handler>>::template rebind_alloc<impl> alloc{ + boost::asio::get_associated_allocator(h)}; + beast::detail::allocator_traits< + decltype(alloc)>::destroy(alloc, this); + beast::detail::allocator_traits< + decltype(alloc)>::deallocate(alloc, this, 1); } void - operator()() + invoke() override { - BOOST_ASSERT(op_); - Op op{std::move(*op_)}; - typename std::allocator_traits< - boost::asio::associated_allocator_t<Op>>:: - template rebind_alloc<Op> alloc{ - boost::asio::get_associated_allocator(op)}; - std::allocator_traits< - decltype(alloc)>::deallocate(alloc, op_, 1); - op_ = nullptr; - op(); + Handler h(std::move(h_)); + typename beast::detail::allocator_traits< + boost::asio::associated_allocator_t< + Handler>>::template rebind_alloc<impl> alloc{ + boost::asio::get_associated_allocator(h)}; + beast::detail::allocator_traits< + decltype(alloc)>::destroy(alloc, this); + beast::detail::allocator_traits< + decltype(alloc)>::deallocate(alloc, this, 1); + h(); } }; - using buf_type = char[sizeof(holder<exemplar>)]; - - base* base_ = nullptr; - alignas(holder<exemplar>) buf_type buf_; + handler* h_ = nullptr; public: pausation() = default; @@ -156,69 +88,70 @@ public: ~pausation() { - if(base_) - base_->~base(); + if(h_) + h_->destroy(); } pausation(pausation&& other) { boost::ignore_unused(other); - BOOST_ASSERT(! other.base_); + BOOST_ASSERT(! other.h_); } pausation& operator=(pausation&& other) { boost::ignore_unused(other); - BOOST_ASSERT(! base_); - BOOST_ASSERT(! other.base_); + BOOST_ASSERT(! h_); + BOOST_ASSERT(! other.h_); return *this; } - template<class F> - void - emplace(F&& f); - - template<class F> + template<class CompletionHandler> void - save(F&& f); + emplace(CompletionHandler&& handler); explicit operator bool() const { - return base_ != nullptr; + return h_ != nullptr; } bool maybe_invoke() { - if(base_) + if(h_) { - auto const basep = base_; - base_ = nullptr; - (*basep)(); + auto const h = h_; + h_ = nullptr; + h->invoke(); return true; } return false; } }; -template<class F> +template<class CompletionHandler> void -pausation::emplace(F&& f) +pausation::emplace(CompletionHandler&& handler) { - using type = holder<typename std::decay<F>::type>; - static_assert(sizeof(buf_type) >= sizeof(type), - "buffer too small"); - BOOST_ASSERT(! base_); - base_ = ::new(buf_) type{std::forward<F>(f)}; -} - -template<class F> -void -pausation::save(F&& f) -{ - emplace(saved_op<F>{std::move(f)}); + BOOST_ASSERT(! h_); + typename beast::detail::allocator_traits< + boost::asio::associated_allocator_t< + CompletionHandler>>::template rebind_alloc< + impl<CompletionHandler>> alloc{ + boost::asio::get_associated_allocator(handler)}; + using A = decltype(alloc); + auto const d = + [&alloc](impl<CompletionHandler>* p) + { + beast::detail::allocator_traits<A>::deallocate(alloc, p, 1); + }; + std::unique_ptr<impl<CompletionHandler>, decltype(d)> p{ + beast::detail::allocator_traits<A>::allocate(alloc, 1), d}; + beast::detail::allocator_traits<A>::construct( + alloc, p.get(), std::forward<CompletionHandler>(handler)); + h_ = p.release(); } } // detail diff --git a/boost/beast/websocket/detail/pmd_extension.hpp b/boost/beast/websocket/detail/pmd_extension.hpp index a28b844cd7..ce4f2425cf 100644 --- a/boost/beast/websocket/detail/pmd_extension.hpp +++ b/boost/beast/websocket/detail/pmd_extension.hpp @@ -19,6 +19,7 @@ #include <boost/beast/http/rfc7230.hpp> #include <boost/asio/buffer.hpp> #include <utility> +#include <type_traits> namespace boost { namespace beast { @@ -355,85 +356,6 @@ pmd_normalize(pmd_offer& offer) } } -//-------------------------------------------------------------------- - -// Compress a buffer sequence -// Returns: `true` if more calls are needed -// -template<class DeflateStream, class ConstBufferSequence> -bool -deflate( - DeflateStream& zo, - boost::asio::mutable_buffer& out, - buffers_suffix<ConstBufferSequence>& cb, - bool fin, - std::size_t& total_in, - error_code& ec) -{ - using boost::asio::buffer; - BOOST_ASSERT(out.size() >= 6); - zlib::z_params zs; - zs.avail_in = 0; - zs.next_in = nullptr; - zs.avail_out = out.size(); - zs.next_out = out.data(); - for(auto in : beast::detail::buffers_range(cb)) - { - zs.avail_in = in.size(); - if(zs.avail_in == 0) - continue; - zs.next_in = in.data(); - zo.write(zs, zlib::Flush::none, ec); - if(ec) - { - if(ec != zlib::error::need_buffers) - return false; - BOOST_ASSERT(zs.avail_out == 0); - BOOST_ASSERT(zs.total_out == out.size()); - ec.assign(0, ec.category()); - break; - } - if(zs.avail_out == 0) - { - BOOST_ASSERT(zs.total_out == out.size()); - break; - } - BOOST_ASSERT(zs.avail_in == 0); - } - total_in = zs.total_in; - cb.consume(zs.total_in); - if(zs.avail_out > 0 && fin) - { - auto const remain = boost::asio::buffer_size(cb); - if(remain == 0) - { - // Inspired by Mark Adler - // https://github.com/madler/zlib/issues/149 - // - // VFALCO We could do this flush twice depending - // on how much space is in the output. - zo.write(zs, zlib::Flush::block, ec); - BOOST_ASSERT(! ec || ec == zlib::error::need_buffers); - if(ec == zlib::error::need_buffers) - ec.assign(0, ec.category()); - if(ec) - return false; - if(zs.avail_out >= 6) - { - zo.write(zs, zlib::Flush::full, ec); - BOOST_ASSERT(! ec); - // remove flush marker - zs.total_out -= 4; - out = buffer(out.data(), zs.total_out); - return false; - } - } - } - ec.assign(0, ec.category()); - out = buffer(out.data(), zs.total_out); - return true; -} - } // detail } // websocket } // beast diff --git a/boost/beast/websocket/detail/stream_base.hpp b/boost/beast/websocket/detail/stream_base.hpp new file mode 100644 index 0000000000..2e93cce3d4 --- /dev/null +++ b/boost/beast/websocket/detail/stream_base.hpp @@ -0,0 +1,221 @@ +// +// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/beast +// + +#ifndef BOOST_BEAST_WEBSOCKET_STREAM_BASE_HPP +#define BOOST_BEAST_WEBSOCKET_STREAM_BASE_HPP + +#include <boost/beast/websocket/option.hpp> +#include <boost/beast/websocket/detail/pmd_extension.hpp> +#include <boost/beast/zlib/deflate_stream.hpp> +#include <boost/beast/zlib/inflate_stream.hpp> +#include <boost/beast/core/buffers_suffix.hpp> +#include <boost/beast/core/error.hpp> +#include <boost/asio/buffer.hpp> +#include <cstdint> +#include <memory> + +namespace boost { +namespace beast { +namespace websocket { +namespace detail { + +// used to order reads and writes +class soft_mutex +{ + int id_ = 0; + +public: + soft_mutex() = default; + soft_mutex(soft_mutex const&) = delete; + soft_mutex& operator=(soft_mutex const&) = delete; + + soft_mutex(soft_mutex&& other) noexcept + : id_(other.id_) + { + other.id_ = 0; + } + + soft_mutex& operator=(soft_mutex&& other) noexcept + { + id_ = other.id_; + other.id_ = 0; + return *this; + } + + // VFALCO I'm not too happy that this function is needed + void reset() + { + id_ = 0; + } + + bool is_locked() const + { + return id_ != 0; + } + + template<class T> + bool is_locked(T const*) const + { + return id_ == T::id; + } + + template<class T> + void lock(T const*) + { + BOOST_ASSERT(id_ == 0); + id_ = T::id; + } + + template<class T> + void unlock(T const*) + { + BOOST_ASSERT(id_ == T::id); + id_ = 0; + } + + template<class T> + bool try_lock(T const*) + { + // If this assert goes off it means you are attempting to + // simultaneously initiate more than one of same asynchronous + // operation, which is not allowed. For example, you must wait + // for an async_read to complete before performing another + // async_read. + // + BOOST_ASSERT(id_ != T::id); + if(id_ != 0) + return false; + id_ = T::id; + return true; + } + + template<class T> + bool try_unlock(T const*) + { + if(id_ != T::id) + return false; + id_ = 0; + return true; + } +}; + +template<bool deflateSupported> +struct stream_base +{ + // State information for the permessage-deflate extension + struct pmd_type + { + // `true` if current read message is compressed + bool rd_set = false; + + zlib::deflate_stream zo; + zlib::inflate_stream zi; + }; + + std::unique_ptr<pmd_type> pmd_; // pmd settings or nullptr + permessage_deflate pmd_opts_; // local pmd options + detail::pmd_offer pmd_config_; // offer (client) or negotiation (server) + + // return `true` if current message is deflated + bool + rd_deflated() const + { + return pmd_ && pmd_->rd_set; + } + + // set whether current message is deflated + // returns `false` on protocol violation + bool + rd_deflated(bool rsv1) + { + if(pmd_) + { + pmd_->rd_set = rsv1; + return true; + } + return ! rsv1; // pmd not negotiated + } + + template<class ConstBufferSequence> + bool + deflate( + boost::asio::mutable_buffer& out, + buffers_suffix<ConstBufferSequence>& cb, + bool fin, + std::size_t& total_in, + error_code& ec); + + void + do_context_takeover_write(role_type role); + + void + inflate( + zlib::z_params& zs, + zlib::Flush flush, + error_code& ec); + + void + do_context_takeover_read(role_type role); +}; + +template<> +struct stream_base<false> +{ + // These stubs are for avoiding linking in the zlib + // code when permessage-deflate is not enabled. + + bool + rd_deflated() const + { + return false; + } + + bool + rd_deflated(bool rsv1) + { + return ! rsv1; + } + + template<class ConstBufferSequence> + bool + deflate( + boost::asio::mutable_buffer&, + buffers_suffix<ConstBufferSequence>&, + bool, + std::size_t&, + error_code&) + { + return false; + } + + void + do_context_takeover_write(role_type) + { + } + + void + inflate( + zlib::z_params&, + zlib::Flush, + error_code&) + { + } + + void + do_context_takeover_read(role_type) + { + } +}; + +} // detail +} // websocket +} // beast +} // boost + +#endif diff --git a/boost/beast/websocket/detail/type_traits.hpp b/boost/beast/websocket/detail/type_traits.hpp index 6c2806146c..6913174fd0 100644 --- a/boost/beast/websocket/detail/type_traits.hpp +++ b/boost/beast/websocket/detail/type_traits.hpp @@ -19,12 +19,12 @@ namespace websocket { namespace detail { template<class F> -using is_RequestDecorator = +using is_request_decorator = typename beast::detail::is_invocable<F, void(request_type&)>::type; template<class F> -using is_ResponseDecorator = +using is_response_decorator = typename beast::detail::is_invocable<F, void(response_type&)>::type; diff --git a/boost/beast/websocket/detail/utf8_checker.hpp b/boost/beast/websocket/detail/utf8_checker.hpp index e86310f051..61c241bc19 100644 --- a/boost/beast/websocket/detail/utf8_checker.hpp +++ b/boost/beast/websocket/detail/utf8_checker.hpp @@ -151,13 +151,13 @@ write(std::uint8_t const* in, std::size_t size) { default: BOOST_ASSERT(false); - BOOST_BEAST_FALLTHROUGH; + BOOST_FALLTHROUGH; case 1: cp_[1] = 0x81; - BOOST_BEAST_FALLTHROUGH; + BOOST_FALLTHROUGH; case 2: cp_[2] = 0x81; - BOOST_BEAST_FALLTHROUGH; + BOOST_FALLTHROUGH; case 3: cp_[3] = 0x81; break; |