2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// 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_IMPL_READ_HPP
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define BOOST_BEAST_WEBSOCKET_IMPL_READ_HPP
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-02 20:44:04 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/core/buffer_size.hpp>
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/websocket/teardown.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/websocket/detail/mask.hpp>
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/websocket/impl/stream_impl.hpp>
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/core/async_op_base.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/core/bind_handler.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/core/buffers_prefix.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/core/buffers_suffix.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/core/flat_static_buffer.hpp>
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-04 21:52:54 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/core/stream_traits.hpp>
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/core/detail/bind_continuation.hpp>
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/core/detail/buffer.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/core/detail/clamp.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/beast/core/detail/config.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/asio/coroutine.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/asio/post.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/assert.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/config.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/optional.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/throw_exception.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <algorithm>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <limits>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <memory>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								namespace boost {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								namespace beast {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								namespace websocket {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								/*  Read some message data into a buffer sequence.
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Also reads and handles control frames.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								*/
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class NextLayer, bool deflateSupported>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    class MutableBufferSequence,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    class Handler>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								class stream<NextLayer, deflateSupported>::read_some_op
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    : public beast::async_op_base<
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-04 21:52:54 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        Handler, beast::executor_type<stream>>
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    , public net::coroutine
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    boost::weak_ptr<impl_type> wp_;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    MutableBufferSequence bs_;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    buffers_suffix<MutableBufferSequence> cb_;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    std::size_t bytes_written_ = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    error_code result_;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    close_code code_;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    bool did_read_ = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								public:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static constexpr int id = 1; // for soft_mutex
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    template<class Handler_>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    read_some_op(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        Handler_&& h,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        boost::shared_ptr<impl_type> const& sp,
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        MutableBufferSequence const& bs)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        : async_op_base<
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-04 21:52:54 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            Handler, beast::executor_type<stream>>(
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                std::forward<Handler_>(h),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    sp->stream.get_executor())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        , wp_(sp)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        , bs_(bs)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        , cb_(bs)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        , code_(close_code::none)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        (*this)({}, 0, false);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    void operator()(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        error_code ec = {},
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        std::size_t bytes_transferred = 0,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        bool cont = true)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        using beast::detail::clamp;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        auto sp = wp_.lock();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if(! sp)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return this->invoke(cont,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                net::error::operation_aborted, 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        auto& impl = *sp;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        BOOST_ASIO_CORO_REENTER(*this)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            impl.update_timer(this->get_executor());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        acquire_read_lock:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // Acquire the read lock
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if(! impl.rd_block.try_lock(this))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            do_suspend:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.op_r_rd.emplace(std::move(*this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                impl.rd_block.lock(this);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                net::post(std::move(*this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(impl.rd_block.is_locked(this));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                // VFALCO Is this check correct here?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(! ec && impl.check_stop_now(ec));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.check_stop_now(ec))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    BOOST_ASSERT(ec == net::error::operation_aborted);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    goto upcall;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // VFALCO Should never get here
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // The only way to get read blocked is if
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // a `close_op` wrote a close frame
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(impl.wr_close);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(impl.status_ != status::open);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                ec = net::error::operation_aborted;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                goto upcall;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // Make sure the stream is not closed
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if( impl.status_ == status::closed ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.status_ == status::failed)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    ec = net::error::operation_aborted;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    goto upcall;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // if status_ == status::closing, we want to suspend
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // the read operation until the close completes,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // then finish the read with operation_aborted.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        loop:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            BOOST_ASSERT(impl.rd_block.is_locked(this));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // See if we need to read a frame header. This
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // condition is structured to give the decompressor
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // a chance to emit the final empty deflate block
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if(impl.rd_remain == 0 &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                (! impl.rd_fh.fin || impl.rd_done))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // Read frame header
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                while(! impl.parse_fh(
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_fh, impl.rd_buf, result_))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if(result_)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // _Fail the WebSocket Connection_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(result_ == error::message_too_big)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            code_ = close_code::too_big;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            code_ = close_code::protocol_error;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        goto close;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    BOOST_ASSERT(impl.rd_block.is_locked(this));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.stream.async_read_some(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_buf.prepare(read_size(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_buf, impl.rd_buf.max_size())),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                std::move(*this));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    BOOST_ASSERT(impl.rd_block.is_locked(this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_buf.commit(bytes_transferred);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        goto upcall;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    impl.reset_idle();
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // Allow a close operation
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // to acquire the read block
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_block.unlock(this);
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    if( impl.op_r_close.maybe_invoke())
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // Suspend
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASSERT(impl.rd_block.is_locked());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        goto do_suspend;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // Acquire read block
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_block.lock(this);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // Immediately apply the mask to the portion
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // of the buffer holding payload data.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.rd_fh.len > 0 && impl.rd_fh.mask)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    detail::mask_inplace(buffers_prefix(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        clamp(impl.rd_fh.len),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_buf.data()),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                impl.rd_key);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(detail::is_control(impl.rd_fh.op))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // Clear this otherwise the next
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // frame will be considered final.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_fh.fin = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // Handle ping frame
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if(impl.rd_fh.op == detail::opcode::ping)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(impl.ctrl_cb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        {
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            if(! cont)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                net::post(std::move(*this));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                BOOST_ASSERT(cont);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                // VFALCO call check_stop_now() here?
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            auto const b = buffers_prefix(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                clamp(impl.rd_fh.len),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    impl.rd_buf.data());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            auto const len = buffer_size(b);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            BOOST_ASSERT(len == impl.rd_fh.len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            ping_data payload;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            detail::read_ping(payload, b);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_buf.consume(len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            // Ignore ping when closing
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            if(impl.status_ == status::closing)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                goto loop;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            if(impl.ctrl_cb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                impl.ctrl_cb(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    frame_type::ping, payload);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_fb.clear();
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            impl.template write_ping<
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                flat_static_buffer_base>(impl.rd_fb,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    detail::opcode::pong, payload);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // Allow a close operation
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // to acquire the read block
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_block.unlock(this);
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        impl.op_r_close.maybe_invoke();
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        // Acquire the write lock
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(! impl.wr_block.try_lock(this))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            impl.op_rd.emplace(std::move(*this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.wr_block.lock(this);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            net::post(std::move(*this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            BOOST_ASSERT(impl.wr_block.is_locked(this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                goto upcall;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // Send pong
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASSERT(impl.wr_block.is_locked(this));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        net::async_write(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.stream, impl.rd_fb.data(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            beast::detail::bind_continuation(std::move(*this)));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASSERT(impl.wr_block.is_locked(this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            goto upcall;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.wr_block.unlock(this);
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        impl.op_close.maybe_invoke()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            || impl.op_idle_ping.maybe_invoke()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            || impl.op_ping.maybe_invoke()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            || impl.op_wr.maybe_invoke();
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        goto acquire_read_lock;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // Handle pong frame
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if(impl.rd_fh.op == detail::opcode::pong)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // Ignore pong when closing
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(! impl.wr_close && impl.ctrl_cb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        {
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            if(! cont)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                net::post(std::move(*this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                BOOST_ASSERT(cont);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        auto const cb = buffers_prefix(clamp(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_fh.len), impl.rd_buf.data());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        auto const len = buffer_size(cb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASSERT(len == impl.rd_fh.len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        ping_data payload;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        detail::read_ping(payload, cb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_buf.consume(len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // Ignore pong when closing
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(! impl.wr_close && impl.ctrl_cb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.ctrl_cb(frame_type::pong, payload);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        goto loop;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // Handle close frame
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    BOOST_ASSERT(impl.rd_fh.op == detail::opcode::close);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(impl.ctrl_cb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        {
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            if(! cont)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                net::post(std::move(*this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                BOOST_ASSERT(cont);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        auto const cb = buffers_prefix(clamp(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_fh.len), impl.rd_buf.data());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        auto const len = buffer_size(cb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASSERT(len == impl.rd_fh.len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASSERT(! impl.rd_close);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_close = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        close_reason cr;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        detail::read_close(cr, cb, result_);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(result_)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            // _Fail the WebSocket Connection_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            code_ = close_code::protocol_error;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            goto close;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.cr = cr;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_buf.consume(len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(impl.ctrl_cb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.ctrl_cb(frame_type::close,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                impl.cr.reason);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // See if we are already closing
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(impl.status_ == status::closing)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            // _Close the WebSocket Connection_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            BOOST_ASSERT(impl.wr_close);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            code_ = close_code::none;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            result_ = error::closed;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            goto close;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // _Start the WebSocket Closing Handshake_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        code_ = cr.code == close_code::none ?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            close_code::normal :
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            static_cast<close_code>(cr.code);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        result_ = error::closed;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        goto close;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.rd_fh.len == 0 && ! impl.rd_fh.fin)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // Empty non-final frame
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    goto loop;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                impl.rd_done = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if(! impl.rd_deflated())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.rd_remain > 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if(impl.rd_buf.size() == 0 && impl.rd_buf.max_size() >
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        (std::min)(clamp(impl.rd_remain),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            buffer_size(cb_)))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // Fill the read buffer first, otherwise we
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // get fewer bytes at the cost of one I/O.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.stream.async_read_some(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_buf.prepare(read_size(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                impl.rd_buf, impl.rd_buf.max_size())),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    std::move(*this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_buf.commit(bytes_transferred);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            goto upcall;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        impl.reset_idle();
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(impl.rd_fh.mask)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            detail::mask_inplace(buffers_prefix(clamp(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                impl.rd_remain), impl.rd_buf.data()),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    impl.rd_key);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if(impl.rd_buf.size() > 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // Copy from the read buffer.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // The mask was already applied.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        bytes_transferred = net::buffer_copy(cb_,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_buf.data(), clamp(impl.rd_remain));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        auto const mb = buffers_prefix(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            bytes_transferred, cb_);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_remain -= bytes_transferred;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(impl.rd_op == detail::opcode::text)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            if(! impl.rd_utf8.write(mb) ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                (impl.rd_remain == 0 && impl.rd_fh.fin &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    ! impl.rd_utf8.finish()))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                // _Fail the WebSocket Connection_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                code_ = close_code::bad_payload;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                result_ = error::bad_frame_payload;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                goto close;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        bytes_written_ += bytes_transferred;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_size += bytes_transferred;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_buf.consume(bytes_transferred);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // Read into caller's buffer
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASSERT(impl.rd_remain > 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASSERT(buffer_size(cb_) > 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASSERT(buffer_size(buffers_prefix(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            clamp(impl.rd_remain), cb_)) > 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.stream.async_read_some(buffers_prefix(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            clamp(impl.rd_remain), cb_), std::move(*this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            goto upcall;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        impl.reset_idle();
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASSERT(bytes_transferred > 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        auto const mb = buffers_prefix(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            bytes_transferred, cb_);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_remain -= bytes_transferred;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(impl.rd_fh.mask)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            detail::mask_inplace(mb, impl.rd_key);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(impl.rd_op == detail::opcode::text)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            if(! impl.rd_utf8.write(mb) ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                (impl.rd_remain == 0 && impl.rd_fh.fin &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    ! impl.rd_utf8.finish()))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                // _Fail the WebSocket Connection_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                code_ = close_code::bad_payload;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                result_ = error::bad_frame_payload;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                goto close;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        bytes_written_ += bytes_transferred;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_size += bytes_transferred;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                impl.rd_done = impl.rd_remain == 0 && impl.rd_fh.fin;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // Read compressed message frame payload:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // inflate even if rd_fh_.len == 0, otherwise we
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // never emit the end-of-stream deflate block.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                while(buffer_size(cb_) > 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if( impl.rd_remain > 0 &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_buf.size() == 0 &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        ! did_read_)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // read new
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.stream.async_read_some(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_buf.prepare(read_size(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                impl.rd_buf, impl.rd_buf.max_size())),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    std::move(*this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            goto upcall;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        impl.reset_idle();
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASSERT(bytes_transferred > 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_buf.commit(bytes_transferred);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(impl.rd_fh.mask)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            detail::mask_inplace(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                buffers_prefix(clamp(impl.rd_remain),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    impl.rd_buf.data()), impl.rd_key);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        did_read_ = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    zlib::z_params zs;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        auto const out = buffers_front(cb_);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        zs.next_out = out.data();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        zs.avail_out = out.size();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        BOOST_ASSERT(zs.avail_out > 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if(impl.rd_remain > 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(impl.rd_buf.size() > 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            // use what's there
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            auto const in = buffers_prefix(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                clamp(impl.rd_remain), buffers_front(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    impl.rd_buf.data()));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            zs.avail_in = in.size();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            zs.next_in = in.data();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    else if(impl.rd_fh.fin)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // append the empty block codes
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        std::uint8_t constexpr
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            empty_block[4] = { 0x00, 0x00, 0xff, 0xff };
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        zs.next_in = empty_block;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        zs.avail_in = sizeof(empty_block);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.inflate(zs, zlib::Flush::sync, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if(! ec)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            // https://github.com/madler/zlib/issues/280
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            if(zs.total_out > 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                ec = error::partial_deflate_block;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            goto upcall;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.do_context_takeover_read(impl.role);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_done = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.inflate(zs, zlib::Flush::sync, ec);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        goto upcall;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if(impl.rd_msg_max && beast::detail::sum_exceeds(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_size, zs.total_out, impl.rd_msg_max))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // _Fail the WebSocket Connection_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        code_ = close_code::too_big;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        result_ = error::message_too_big;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        goto close;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    cb_.consume(zs.total_out);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_size += zs.total_out;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_remain -= zs.total_in;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_buf.consume(zs.total_in);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    bytes_written_ += zs.total_out;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.rd_op == detail::opcode::text)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // check utf8
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if(! impl.rd_utf8.write(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        buffers_prefix(bytes_written_, bs_)) || (
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_done && ! impl.rd_utf8.finish()))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // _Fail the WebSocket Connection_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        code_ = close_code::bad_payload;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        result_ = error::bad_frame_payload;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        goto close;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            goto upcall;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        close:
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            // Acquire the write lock
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if(! impl.wr_block.try_lock(this))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.op_rd.emplace(std::move(*this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                impl.wr_block.lock(this);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                net::post(std::move(*this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(impl.wr_block.is_locked(this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    goto upcall;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            impl.change_status(status::closing);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if(! impl.wr_close)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                impl.wr_close = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // Serialize close frame
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                impl.rd_fb.clear();
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.template write_close<
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    flat_static_buffer_base>(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_fb, code_);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // Send close frame
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(impl.wr_block.is_locked(this));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                net::async_write(impl.stream, impl.rd_fb.data(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    beast::detail::bind_continuation(std::move(*this)));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(impl.wr_block.is_locked(this));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    goto upcall;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // Teardown
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            using beast::websocket::async_teardown;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            BOOST_ASSERT(impl.wr_block.is_locked(this));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            async_teardown(impl.role, impl.stream,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                beast::detail::bind_continuation(std::move(*this)));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            BOOST_ASSERT(impl.wr_block.is_locked(this));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if(ec == net::error::eof)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // Rationale:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // http://stackoverflow.com/questions/25587403/boost-asio-ssl-async-shutdown-always-finishes-with-an-error
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                ec = {};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if(! ec)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                ec = result_;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if(ec && ec != error::closed)
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.change_status(status::failed);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            else
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.change_status(status::closed);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            impl.close();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        upcall:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            impl.rd_block.try_unlock(this);
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            impl.op_r_close.maybe_invoke();
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if(impl.wr_block.try_unlock(this))
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.op_close.maybe_invoke()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    || impl.op_idle_ping.maybe_invoke()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    || impl.op_ping.maybe_invoke()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    || impl.op_wr.maybe_invoke();
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            this->invoke(cont, ec, bytes_written_);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//------------------------------------------------------------------------------
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class NextLayer, bool deflateSupported>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    class DynamicBuffer,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    class Handler>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								class stream<NextLayer, deflateSupported>::read_op
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    : public beast::async_op_base<
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-04 21:52:54 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        Handler, beast::executor_type<stream>>
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    , public net::coroutine
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    boost::weak_ptr<impl_type> wp_;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    DynamicBuffer& b_;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    std::size_t limit_;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    std::size_t bytes_written_ = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    bool some_;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								public:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    template<class Handler_>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    read_op(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        Handler_&& h,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        boost::shared_ptr<impl_type> const& sp,
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        DynamicBuffer& b,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        std::size_t limit,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        bool some)
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        : async_op_base<Handler,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            beast::executor_type<stream>>(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                std::forward<Handler_>(h),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    sp->stream.get_executor())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        , wp_(sp)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        , b_(b)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        , limit_(limit ? limit : (
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            std::numeric_limits<std::size_t>::max)())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        , some_(some)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        (*this)({}, 0, false);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    void operator()(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        error_code ec = {},
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        std::size_t bytes_transferred = 0,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        bool cont = true)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        using beast::detail::clamp;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        auto sp = wp_.lock();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if(! sp)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return this->invoke(cont,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                net::error::operation_aborted, 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        auto& impl = *sp;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        using mutable_buffers_type = typename
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            DynamicBuffer::mutable_buffers_type;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        boost::optional<mutable_buffers_type> mb;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        BOOST_ASIO_CORO_REENTER(*this)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            do
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                mb = beast::detail::dynamic_buffer_prepare(b_,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    clamp(impl.read_size_hint_db(b_), limit_),
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        ec, error::buffer_overflow);
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    goto upcall;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // VFALCO TODO use boost::beast::bind_continuation
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASIO_CORO_YIELD
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                read_some_op<mutable_buffers_type, read_op>(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    std::move(*this), sp, *mb);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                b_.commit(bytes_transferred);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                bytes_written_ += bytes_transferred;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if(ec)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    goto upcall;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            while(! some_ && ! impl.rd_done);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        upcall:
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            this->invoke(cont, ec, bytes_written_);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//------------------------------------------------------------------------------
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class NextLayer, bool deflateSupported>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class DynamicBuffer>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								std::size_t
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								stream<NextLayer, deflateSupported>::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								read(DynamicBuffer& buffer)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(is_sync_stream<next_layer_type>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "SyncStream type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        net::is_dynamic_buffer<DynamicBuffer>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "DynamicBuffer type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    error_code ec;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto const bytes_written = read(buffer, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if(ec)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        BOOST_THROW_EXCEPTION(system_error{ec});
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class NextLayer, bool deflateSupported>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class DynamicBuffer>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								std::size_t
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								stream<NextLayer, deflateSupported>::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								read(DynamicBuffer& buffer, error_code& ec)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(is_sync_stream<next_layer_type>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "SyncStream type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        net::is_dynamic_buffer<DynamicBuffer>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "DynamicBuffer type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    std::size_t bytes_written = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    do
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        bytes_written += read_some(buffer, 0, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if(ec)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    while(! is_message_done());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class NextLayer, bool deflateSupported>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class DynamicBuffer, class ReadHandler>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								BOOST_ASIO_INITFN_RESULT_TYPE(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ReadHandler, void(error_code, std::size_t))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								stream<NextLayer, deflateSupported>::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								async_read(DynamicBuffer& buffer, ReadHandler&& handler)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(is_async_stream<next_layer_type>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "AsyncStream type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        net::is_dynamic_buffer<DynamicBuffer>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "DynamicBuffer type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    BOOST_BEAST_HANDLER_INIT(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ReadHandler, void(error_code, std::size_t));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    read_op<DynamicBuffer, BOOST_ASIO_HANDLER_TYPE(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ReadHandler, void(error_code, std::size_t))>(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            std::move(init.completion_handler),
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl_, buffer, 0, false);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return init.result.get();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//------------------------------------------------------------------------------
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class NextLayer, bool deflateSupported>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class DynamicBuffer>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								std::size_t
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								stream<NextLayer, deflateSupported>::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								read_some(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    DynamicBuffer& buffer,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    std::size_t limit)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(is_sync_stream<next_layer_type>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "SyncStream type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        net::is_dynamic_buffer<DynamicBuffer>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "DynamicBuffer type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    error_code ec;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto const bytes_written =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        read_some(buffer, limit, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if(ec)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        BOOST_THROW_EXCEPTION(system_error{ec});
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class NextLayer, bool deflateSupported>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class DynamicBuffer>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								std::size_t
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								stream<NextLayer, deflateSupported>::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								read_some(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    DynamicBuffer& buffer,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    std::size_t limit,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    error_code& ec)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(is_sync_stream<next_layer_type>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "SyncStream type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        net::is_dynamic_buffer<DynamicBuffer>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "DynamicBuffer type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    using beast::detail::clamp;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if(! limit)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        limit = (std::numeric_limits<std::size_t>::max)();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto const size =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        clamp(read_size_hint(buffer), limit);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    BOOST_ASSERT(size > 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto mb = beast::detail::dynamic_buffer_prepare(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        buffer, size, ec, error::buffer_overflow);
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if(impl_->check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto const bytes_written = read_some(*mb, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    buffer.commit(bytes_written);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class NextLayer, bool deflateSupported>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class DynamicBuffer, class ReadHandler>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								BOOST_ASIO_INITFN_RESULT_TYPE(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ReadHandler, void(error_code, std::size_t))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								stream<NextLayer, deflateSupported>::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								async_read_some(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    DynamicBuffer& buffer,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    std::size_t limit,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ReadHandler&& handler)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(is_async_stream<next_layer_type>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "AsyncStream type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        net::is_dynamic_buffer<DynamicBuffer>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "DynamicBuffer type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    BOOST_BEAST_HANDLER_INIT(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ReadHandler, void(error_code, std::size_t));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    read_op<DynamicBuffer, BOOST_ASIO_HANDLER_TYPE(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ReadHandler, void(error_code, std::size_t))>(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            std::move(init.completion_handler),
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl_, buffer, limit, true);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return init.result.get();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//------------------------------------------------------------------------------
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class NextLayer, bool deflateSupported>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class MutableBufferSequence>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								std::size_t
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								stream<NextLayer, deflateSupported>::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								read_some(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    MutableBufferSequence const& buffers)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(is_sync_stream<next_layer_type>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "SyncStream type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(net::is_mutable_buffer_sequence<
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            MutableBufferSequence>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "MutableBufferSequence type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    error_code ec;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto const bytes_written = read_some(buffers, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if(ec)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        BOOST_THROW_EXCEPTION(system_error{ec});
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class NextLayer, bool deflateSupported>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class MutableBufferSequence>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								std::size_t
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								stream<NextLayer, deflateSupported>::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								read_some(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    MutableBufferSequence const& buffers,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    error_code& ec)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(is_sync_stream<next_layer_type>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "SyncStream type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(net::is_mutable_buffer_sequence<
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            MutableBufferSequence>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "MutableBufferSequence type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    using beast::detail::clamp;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    auto& impl = *impl_;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    close_code code{};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    std::size_t bytes_written = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ec = {};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // Make sure the stream is open
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if(impl.check_stop_now(ec))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return bytes_written;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								loop:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // See if we need to read a frame header. This
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // condition is structured to give the decompressor
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // a chance to emit the final empty deflate block
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    //
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if(impl.rd_remain == 0 && (
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ! impl.rd_fh.fin || impl.rd_done))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        // Read frame header
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        error_code result;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        while(! impl.parse_fh(impl.rd_fh, impl.rd_buf, result))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if(result)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // _Fail the WebSocket Connection_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(result == error::message_too_big)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    code = close_code::too_big;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    code = close_code::protocol_error;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                do_fail(code, result, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            auto const bytes_transferred =
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.stream.read_some(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_buf.prepare(read_size(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_buf, impl.rd_buf.max_size())),
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    ec);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            impl.rd_buf.commit(bytes_transferred);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        // Immediately apply the mask to the portion
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        // of the buffer holding payload data.
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if(impl.rd_fh.len > 0 && impl.rd_fh.mask)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            detail::mask_inplace(buffers_prefix(
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                clamp(impl.rd_fh.len), impl.rd_buf.data()),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_key);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if(detail::is_control(impl.rd_fh.op))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // Get control frame payload
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            auto const b = buffers_prefix(
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                clamp(impl.rd_fh.len), impl.rd_buf.data());
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            auto const len = buffer_size(b);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            BOOST_ASSERT(len == impl.rd_fh.len);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // Clear this otherwise the next
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // frame will be considered final.
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            impl.rd_fh.fin = false;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // Handle ping frame
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if(impl.rd_fh.op == detail::opcode::ping)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                ping_data payload;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                detail::read_ping(payload, b);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.rd_buf.consume(len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.wr_close)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // Ignore ping when closing
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    goto loop;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if(impl.ctrl_cb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.ctrl_cb(frame_type::ping, payload);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                detail::frame_buffer fb;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.template write_ping<flat_static_buffer_base>(fb,
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    detail::opcode::pong, payload);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                net::write(impl.stream, fb.data(), ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                goto loop;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // Handle pong frame
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if(impl.rd_fh.op == detail::opcode::pong)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                ping_data payload;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                detail::read_ping(payload, b);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.rd_buf.consume(len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.ctrl_cb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.ctrl_cb(frame_type::pong, payload);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                goto loop;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // Handle close frame
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            BOOST_ASSERT(impl.rd_fh.op == detail::opcode::close);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(! impl.rd_close);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                impl.rd_close = true;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                close_reason cr;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                detail::read_close(cr, b, result);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(result)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // _Fail the WebSocket Connection_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    do_fail(close_code::protocol_error,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        result, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.cr = cr;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                impl.rd_buf.consume(len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.ctrl_cb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.ctrl_cb(frame_type::close, impl.cr.reason);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(! impl.wr_close);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // _Start the WebSocket Closing Handshake_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                do_fail(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    cr.code == close_code::none ?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        close_code::normal :
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        static_cast<close_code>(cr.code),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    error::closed, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if(impl.rd_fh.len == 0 && ! impl.rd_fh.fin)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // Empty non-final frame
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            goto loop;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        impl.rd_done = false;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ec = {};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if(! impl.rd_deflated())
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if(impl.rd_remain > 0)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if(impl.rd_buf.size() == 0 && impl.rd_buf.max_size() >
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                (std::min)(clamp(impl.rd_remain),
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    buffer_size(buffers)))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // Fill the read buffer first, otherwise we
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // get fewer bytes at the cost of one I/O.
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.rd_buf.commit(impl.stream.read_some(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_buf.prepare(read_size(impl.rd_buf,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        impl.rd_buf.max_size())), ec));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    return bytes_written;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if(impl.rd_fh.mask)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    detail::mask_inplace(
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        buffers_prefix(clamp(impl.rd_remain),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_buf.data()), impl.rd_key);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if(impl.rd_buf.size() > 0)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // Copy from the read buffer.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // The mask was already applied.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                auto const bytes_transferred = net::buffer_copy(
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    buffers, impl.rd_buf.data(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        clamp(impl.rd_remain));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                auto const mb = buffers_prefix(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    bytes_transferred, buffers);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.rd_remain -= bytes_transferred;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.rd_op == detail::opcode::text)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    if(! impl.rd_utf8.write(mb) ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        (impl.rd_remain == 0 && impl.rd_fh.fin &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            ! impl.rd_utf8.finish()))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // _Fail the WebSocket Connection_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        do_fail(close_code::bad_payload,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            error::bad_frame_payload, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                bytes_written += bytes_transferred;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.rd_size += bytes_transferred;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                impl.rd_buf.consume(bytes_transferred);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // Read into caller's buffer
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(impl.rd_remain > 0);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(buffer_size(buffers) > 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(buffer_size(buffers_prefix(
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    clamp(impl.rd_remain), buffers)) > 0);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                auto const bytes_transferred =
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    impl.stream.read_some(buffers_prefix(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        clamp(impl.rd_remain), buffers), ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // VFALCO What if some bytes were written?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(bytes_transferred > 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                auto const mb = buffers_prefix(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    bytes_transferred, buffers);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.rd_remain -= bytes_transferred;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.rd_fh.mask)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    detail::mask_inplace(mb, impl.rd_key);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(impl.rd_op == detail::opcode::text)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    if(! impl.rd_utf8.write(mb) ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        (impl.rd_remain == 0 && impl.rd_fh.fin &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            ! impl.rd_utf8.finish()))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        // _Fail the WebSocket Connection_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        do_fail(close_code::bad_payload,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            error::bad_frame_payload, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                bytes_written += bytes_transferred;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.rd_size += bytes_transferred;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        impl.rd_done = impl.rd_remain == 0 && impl.rd_fh.fin;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        // Read compressed message frame payload:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        // inflate even if rd_fh_.len == 0, otherwise we
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        // never emit the end-of-stream deflate block.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        bool did_read = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        buffers_suffix<MutableBufferSequence> cb(buffers);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        while(buffer_size(cb) > 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            zlib::z_params zs;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                auto const out = beast::buffers_front(cb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                zs.next_out = out.data();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                zs.avail_out = out.size();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                BOOST_ASSERT(zs.avail_out > 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if(impl.rd_remain > 0)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if(impl.rd_buf.size() > 0)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // use what's there
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    auto const in = buffers_prefix(
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        clamp(impl.rd_remain), beast::buffers_front(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_buf.data()));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    zs.avail_in = in.size();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    zs.next_in = in.data();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                else if(! did_read)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // read new
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    auto const bytes_transferred =
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        impl.stream.read_some(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_buf.prepare(read_size(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                impl.rd_buf, impl.rd_buf.max_size())),
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            ec);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    BOOST_ASSERT(bytes_transferred > 0);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_buf.commit(bytes_transferred);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if(impl.rd_fh.mask)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        detail::mask_inplace(
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            buffers_prefix(clamp(impl.rd_remain),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                impl.rd_buf.data()), impl.rd_key);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    auto const in = buffers_prefix(
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        clamp(impl.rd_remain), buffers_front(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            impl.rd_buf.data()));
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    zs.avail_in = in.size();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    zs.next_in = in.data();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    did_read = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            else if(impl.rd_fh.fin)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // append the empty block codes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                static std::uint8_t constexpr
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    empty_block[4] = {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        0x00, 0x00, 0xff, 0xff };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                zs.next_in = empty_block;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                zs.avail_in = sizeof(empty_block);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.inflate(zs, zlib::Flush::sync, ec);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if(! ec)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // https://github.com/madler/zlib/issues/280
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if(zs.total_out > 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        ec = error::partial_deflate_block;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    return bytes_written;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                impl.do_context_takeover_read(impl.role);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                impl.rd_done = true;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            impl.inflate(zs, zlib::Flush::sync, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if(impl.check_stop_now(ec))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                return bytes_written;
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if(impl.rd_msg_max && beast::detail::sum_exceeds(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                impl.rd_size, zs.total_out, impl.rd_msg_max))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                do_fail(close_code::too_big,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    error::message_too_big, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            cb.consume(zs.total_out);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            impl.rd_size += zs.total_out;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            impl.rd_remain -= zs.total_in;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            impl.rd_buf.consume(zs.total_in);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            bytes_written += zs.total_out;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if(impl.rd_op == detail::opcode::text)
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // check utf8
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if(! impl.rd_utf8.write(beast::buffers_prefix(
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                bytes_written, buffers)) || (
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    impl.rd_done && ! impl.rd_utf8.finish()))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // _Fail the WebSocket Connection_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                do_fail(close_code::bad_payload,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    error::bad_frame_payload, ec);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return bytes_written;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class NextLayer, bool deflateSupported>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								template<class MutableBufferSequence, class ReadHandler>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								BOOST_ASIO_INITFN_RESULT_TYPE(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ReadHandler, void(error_code, std::size_t))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								stream<NextLayer, deflateSupported>::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								async_read_some(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    MutableBufferSequence const& buffers,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ReadHandler&& handler)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(is_async_stream<next_layer_type>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "AsyncStream type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    static_assert(net::is_mutable_buffer_sequence<
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            MutableBufferSequence>::value,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-20 19:19:59 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        "MutableBufferSequence type requirements not met");
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    BOOST_BEAST_HANDLER_INIT(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ReadHandler, void(error_code, std::size_t));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    read_some_op<MutableBufferSequence, BOOST_ASIO_HANDLER_TYPE(
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-20 12:25:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        ReadHandler, void(error_code, std::size_t))>(
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-13 08:00:07 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            std::move(init.completion_handler), impl_, buffers);
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-19 07:24:00 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return init.result.get();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								} // websocket
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								} // beast
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								} // boost
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 |