diff --git a/include/beast/websocket/impl/accept.ipp b/include/beast/websocket/impl/accept.ipp index ca02eddbfa..99b7d2f862 100644 --- a/include/beast/websocket/impl/accept.ipp +++ b/include/beast/websocket/impl/accept.ipp @@ -8,10 +8,11 @@ #ifndef BEAST_WEBSOCKET_IMPL_ACCEPT_IPP #define BEAST_WEBSOCKET_IMPL_ACCEPT_IPP -#include #include #include #include +#include +#include #include #include #include @@ -24,6 +25,124 @@ namespace websocket { //------------------------------------------------------------------------------ +// Respond to an upgrade HTTP request +template +template +class stream::response_op +{ + using alloc_type = + handler_alloc; + + struct data + { + stream& ws; + http::response resp; + Handler h; + error_code final_ec; + bool cont; + int state = 0; + + template + data(DeducedHandler&& h_, stream& ws_, + http::request const& req, + bool cont_) + : ws(ws_) + , resp(ws_.build_response(req)) + , h(std::forward(h_)) + , cont(cont_) + { + // can't call stream::reset() here + // otherwise accept_op will malfunction + // + if(resp.status != 101) + final_ec = error::handshake_failed; + } + }; + + std::shared_ptr d_; + +public: + response_op(response_op&&) = default; + response_op(response_op const&) = default; + + template + response_op(DeducedHandler&& h, + stream& ws, Args&&... args) + : d_(std::allocate_shared(alloc_type{h}, + std::forward(h), ws, + std::forward(args)...)) + { + (*this)(error_code{}, false); + } + + void operator()( + error_code ec, bool again = true); + + friend + void* asio_handler_allocate( + std::size_t size, response_op* op) + { + return boost_asio_handler_alloc_helpers:: + allocate(size, op->d_->h); + } + + friend + void asio_handler_deallocate( + void* p, std::size_t size, response_op* op) + { + return boost_asio_handler_alloc_helpers:: + deallocate(p, size, op->d_->h); + } + + friend + bool asio_handler_is_continuation(response_op* op) + { + return op->d_->cont; + } + + template + friend + void asio_handler_invoke(Function&& f, response_op* op) + { + return boost_asio_handler_invoke_helpers:: + invoke(f, op->d_->h); + } +}; + +template +template +void +stream::response_op:: +operator()(error_code ec, bool again) +{ + auto& d = *d_; + d.cont = d.cont || again; + while(! ec && d.state != 99) + { + switch(d.state) + { + case 0: + // send response + d.state = 1; + http::async_write(d.ws.next_layer(), + d.resp, std::move(*this)); + return; + + // sent response + case 1: + d.state = 99; + ec = d.final_ec; + if(! ec) + d.ws.open(detail::role_type::server); + break; + } + } + d.h(ec); +} + +//------------------------------------------------------------------------------ + // read and respond to an upgrade request // template diff --git a/include/beast/websocket/impl/response_op.ipp b/include/beast/websocket/impl/response_op.ipp deleted file mode 100644 index 2c9d54461c..0000000000 --- a/include/beast/websocket/impl/response_op.ipp +++ /dev/null @@ -1,139 +0,0 @@ -// -// Copyright (c) 2013-2016 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) -// - -#ifndef BEAST_WEBSOCKET_IMPL_RESPONSE_OP_HPP -#define BEAST_WEBSOCKET_IMPL_RESPONSE_OP_HPP - -#include -#include -#include -#include -#include - -namespace beast { -namespace websocket { - -// Respond to an upgrade HTTP request -template -template -class stream::response_op -{ - using alloc_type = - handler_alloc; - - struct data - { - stream& ws; - http::response resp; - Handler h; - error_code final_ec; - bool cont; - int state = 0; - - template - data(DeducedHandler&& h_, stream& ws_, - http::request const& req, - bool cont_) - : ws(ws_) - , resp(ws_.build_response(req)) - , h(std::forward(h_)) - , cont(cont_) - { - // can't call stream::reset() here - // otherwise accept_op will malfunction - // - if(resp.status != 101) - final_ec = error::handshake_failed; - } - }; - - std::shared_ptr d_; - -public: - response_op(response_op&&) = default; - response_op(response_op const&) = default; - - template - response_op(DeducedHandler&& h, - stream& ws, Args&&... args) - : d_(std::allocate_shared(alloc_type{h}, - std::forward(h), ws, - std::forward(args)...)) - { - (*this)(error_code{}, false); - } - - void operator()( - error_code ec, bool again = true); - - friend - void* asio_handler_allocate( - std::size_t size, response_op* op) - { - return boost_asio_handler_alloc_helpers:: - allocate(size, op->d_->h); - } - - friend - void asio_handler_deallocate( - void* p, std::size_t size, response_op* op) - { - return boost_asio_handler_alloc_helpers:: - deallocate(p, size, op->d_->h); - } - - friend - bool asio_handler_is_continuation(response_op* op) - { - return op->d_->cont; - } - - template - friend - void asio_handler_invoke(Function&& f, response_op* op) - { - return boost_asio_handler_invoke_helpers:: - invoke(f, op->d_->h); - } -}; - -template -template -void -stream::response_op:: -operator()(error_code ec, bool again) -{ - auto& d = *d_; - d.cont = d.cont || again; - while(! ec && d.state != 99) - { - switch(d.state) - { - case 0: - // send response - d.state = 1; - http::async_write(d.ws.next_layer(), - d.resp, std::move(*this)); - return; - - // sent response - case 1: - d.state = 99; - ec = d.final_ec; - if(! ec) - d.ws.open(detail::role_type::server); - break; - } - } - d.h(ec); -} - -} // websocket -} // beast - -#endif diff --git a/include/beast/websocket/impl/stream.ipp b/include/beast/websocket/impl/stream.ipp index 985442610c..671dfd9cbb 100644 --- a/include/beast/websocket/impl/stream.ipp +++ b/include/beast/websocket/impl/stream.ipp @@ -10,7 +10,6 @@ #include #include -#include #include #include #include