2016-10-24 08:12:09 -04:00
|
|
|
//
|
2019-02-21 07:00:31 -08:00
|
|
|
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
|
2016-10-24 08:12:09 -04:00
|
|
|
//
|
|
|
|
// 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)
|
|
|
|
//
|
2017-07-20 13:40:34 -07:00
|
|
|
// Official repository: https://github.com/boostorg/beast
|
|
|
|
//
|
2016-10-24 08:12:09 -04:00
|
|
|
|
2017-07-20 13:40:34 -07:00
|
|
|
#ifndef BOOST_BEAST_WEBSOCKET_IMPL_ACCEPT_IPP
|
|
|
|
#define BOOST_BEAST_WEBSOCKET_IMPL_ACCEPT_IPP
|
|
|
|
|
2019-02-13 08:00:07 -08:00
|
|
|
#include <boost/beast/websocket/impl/stream_impl.hpp>
|
2017-07-20 13:40:34 -07:00
|
|
|
#include <boost/beast/websocket/detail/type_traits.hpp>
|
|
|
|
#include <boost/beast/http/empty_body.hpp>
|
|
|
|
#include <boost/beast/http/parser.hpp>
|
|
|
|
#include <boost/beast/http/read.hpp>
|
|
|
|
#include <boost/beast/http/string_body.hpp>
|
|
|
|
#include <boost/beast/http/write.hpp>
|
2019-02-25 09:31:51 -08:00
|
|
|
#include <boost/beast/core/async_base.hpp>
|
2019-03-05 08:25:54 -08:00
|
|
|
#include <boost/beast/core/buffer_traits.hpp>
|
2019-02-04 21:52:54 -08:00
|
|
|
#include <boost/beast/core/stream_traits.hpp>
|
2018-10-30 17:30:48 -07:00
|
|
|
#include <boost/beast/core/detail/buffer.hpp>
|
2019-02-17 05:23:40 -08:00
|
|
|
#include <boost/beast/version.hpp>
|
2017-08-16 19:25:02 -07:00
|
|
|
#include <boost/asio/coroutine.hpp>
|
2017-09-07 07:39:52 -07:00
|
|
|
#include <boost/asio/post.hpp>
|
2016-10-24 08:12:09 -04:00
|
|
|
#include <boost/assert.hpp>
|
2017-05-22 15:30:12 -07:00
|
|
|
#include <boost/throw_exception.hpp>
|
2016-10-24 08:12:09 -04:00
|
|
|
#include <memory>
|
|
|
|
#include <type_traits>
|
|
|
|
|
2017-07-20 13:40:34 -07:00
|
|
|
namespace boost {
|
2016-10-24 08:12:09 -04:00
|
|
|
namespace beast {
|
|
|
|
namespace websocket {
|
|
|
|
|
2019-02-17 05:23:40 -08:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
namespace detail {
|
|
|
|
|
|
|
|
template<class Body, class Allocator>
|
|
|
|
void
|
|
|
|
impl_base<true>::
|
|
|
|
build_response_pmd(
|
|
|
|
http::response<http::string_body>& res,
|
|
|
|
http::request<Body,
|
|
|
|
http::basic_fields<Allocator>> const& req)
|
|
|
|
{
|
|
|
|
pmd_offer offer;
|
|
|
|
pmd_offer unused;
|
|
|
|
pmd_read(offer, req);
|
|
|
|
pmd_negotiate(res, unused, offer, pmd_opts_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class Body, class Allocator>
|
|
|
|
void
|
|
|
|
impl_base<false>::
|
|
|
|
build_response_pmd(
|
|
|
|
http::response<http::string_body>&,
|
|
|
|
http::request<Body,
|
|
|
|
http::basic_fields<Allocator>> const&)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
} // detail
|
|
|
|
|
|
|
|
template<class NextLayer, bool deflateSupported>
|
|
|
|
template<class Body, class Allocator, class Decorator>
|
|
|
|
response_type
|
|
|
|
stream<NextLayer, deflateSupported>::impl_type::
|
|
|
|
build_response(
|
|
|
|
http::request<Body,
|
|
|
|
http::basic_fields<Allocator>> const& req,
|
|
|
|
Decorator const& decorator,
|
|
|
|
error_code& result)
|
|
|
|
{
|
|
|
|
auto const decorate =
|
2019-02-17 16:03:09 -08:00
|
|
|
[this, &decorator](response_type& res)
|
2019-02-17 05:23:40 -08:00
|
|
|
{
|
2019-02-17 16:03:09 -08:00
|
|
|
decorator_opt(res);
|
2019-02-17 05:23:40 -08:00
|
|
|
decorator(res);
|
|
|
|
if(! res.count(http::field::server))
|
2019-05-19 17:37:08 +02:00
|
|
|
res.set(http::field::server,
|
|
|
|
string_view(BOOST_BEAST_VERSION_STRING));
|
2019-02-17 05:23:40 -08:00
|
|
|
};
|
|
|
|
auto err =
|
|
|
|
[&](error e)
|
|
|
|
{
|
|
|
|
result = e;
|
|
|
|
response_type res;
|
|
|
|
res.version(req.version());
|
|
|
|
res.result(http::status::bad_request);
|
|
|
|
res.body() = result.message();
|
|
|
|
res.prepare_payload();
|
|
|
|
decorate(res);
|
|
|
|
return res;
|
|
|
|
};
|
|
|
|
if(req.version() != 11)
|
|
|
|
return err(error::bad_http_version);
|
|
|
|
if(req.method() != http::verb::get)
|
|
|
|
return err(error::bad_method);
|
|
|
|
if(! req.count(http::field::host))
|
|
|
|
return err(error::no_host);
|
|
|
|
{
|
|
|
|
auto const it = req.find(http::field::connection);
|
|
|
|
if(it == req.end())
|
|
|
|
return err(error::no_connection);
|
|
|
|
if(! http::token_list{it->value()}.exists("upgrade"))
|
|
|
|
return err(error::no_connection_upgrade);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
auto const it = req.find(http::field::upgrade);
|
|
|
|
if(it == req.end())
|
|
|
|
return err(error::no_upgrade);
|
|
|
|
if(! http::token_list{it->value()}.exists("websocket"))
|
|
|
|
return err(error::no_upgrade_websocket);
|
|
|
|
}
|
|
|
|
string_view key;
|
|
|
|
{
|
|
|
|
auto const it = req.find(http::field::sec_websocket_key);
|
|
|
|
if(it == req.end())
|
|
|
|
return err(error::no_sec_key);
|
|
|
|
key = it->value();
|
|
|
|
if(key.size() > detail::sec_ws_key_type::max_size_n)
|
|
|
|
return err(error::bad_sec_key);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
auto const it = req.find(http::field::sec_websocket_version);
|
|
|
|
if(it == req.end())
|
|
|
|
return err(error::no_sec_version);
|
|
|
|
if(it->value() != "13")
|
|
|
|
{
|
|
|
|
response_type res;
|
|
|
|
res.result(http::status::upgrade_required);
|
|
|
|
res.version(req.version());
|
|
|
|
res.set(http::field::sec_websocket_version, "13");
|
|
|
|
result = error::bad_sec_version;
|
|
|
|
res.body() = result.message();
|
|
|
|
res.prepare_payload();
|
|
|
|
decorate(res);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
response_type res;
|
|
|
|
res.result(http::status::switching_protocols);
|
|
|
|
res.version(req.version());
|
|
|
|
res.set(http::field::upgrade, "websocket");
|
|
|
|
res.set(http::field::connection, "upgrade");
|
|
|
|
{
|
|
|
|
detail::sec_ws_accept_type acc;
|
|
|
|
detail::make_sec_ws_accept(acc, key);
|
|
|
|
res.set(http::field::sec_websocket_accept, acc);
|
|
|
|
}
|
|
|
|
this->build_response_pmd(res, req);
|
|
|
|
decorate(res);
|
|
|
|
result = {};
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2019-01-19 07:24:00 -08:00
|
|
|
/** Respond to an HTTP request
|
|
|
|
*/
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2016-10-24 08:12:09 -04:00
|
|
|
template<class Handler>
|
2017-11-18 16:52:18 -08:00
|
|
|
class stream<NextLayer, deflateSupported>::response_op
|
2019-02-25 09:31:51 -08:00
|
|
|
: public beast::stable_async_base<
|
2019-02-04 21:52:54 -08:00
|
|
|
Handler, beast::executor_type<stream>>
|
2019-06-16 23:47:44 +02:00
|
|
|
, public asio::coroutine
|
2016-10-24 08:12:09 -04:00
|
|
|
{
|
2019-02-13 08:00:07 -08:00
|
|
|
boost::weak_ptr<impl_type> wp_;
|
2019-01-19 07:24:00 -08:00
|
|
|
error_code result_; // must come before res_
|
|
|
|
response_type& res_;
|
2016-10-24 08:12:09 -04:00
|
|
|
|
|
|
|
public:
|
2019-01-05 19:40:46 -08:00
|
|
|
template<
|
|
|
|
class Handler_,
|
2019-01-19 07:24:00 -08:00
|
|
|
class Body, class Allocator,
|
|
|
|
class Decorator>
|
2019-01-05 19:40:46 -08:00
|
|
|
response_op(
|
|
|
|
Handler_&& h,
|
2019-02-13 08:00:07 -08:00
|
|
|
boost::shared_ptr<impl_type> const& sp,
|
|
|
|
http::request<Body,
|
|
|
|
http::basic_fields<Allocator>> const& req,
|
|
|
|
Decorator const& decorator,
|
|
|
|
bool cont = false)
|
2019-02-25 09:31:51 -08:00
|
|
|
: stable_async_base<Handler,
|
2019-02-13 08:00:07 -08:00
|
|
|
beast::executor_type<stream>>(
|
|
|
|
std::forward<Handler_>(h),
|
2019-02-27 14:48:31 -08:00
|
|
|
sp->stream().get_executor())
|
2019-02-13 08:00:07 -08:00
|
|
|
, wp_(sp)
|
2019-03-07 10:40:48 +01:00
|
|
|
, res_(beast::allocate_stable<response_type>(*this,
|
2019-02-13 08:00:07 -08:00
|
|
|
sp->build_response(req, decorator, result_)))
|
2016-10-24 08:12:09 -04:00
|
|
|
{
|
2019-02-13 08:00:07 -08:00
|
|
|
(*this)({}, 0, cont);
|
2016-10-24 08:12:09 -04:00
|
|
|
}
|
|
|
|
|
2017-09-07 07:39:52 -07:00
|
|
|
void operator()(
|
|
|
|
error_code ec = {},
|
2019-02-13 08:00:07 -08:00
|
|
|
std::size_t bytes_transferred = 0,
|
|
|
|
bool cont = true)
|
2016-10-24 08:12:09 -04:00
|
|
|
{
|
2019-01-05 19:40:46 -08:00
|
|
|
boost::ignore_unused(bytes_transferred);
|
2019-02-13 08:00:07 -08:00
|
|
|
auto sp = wp_.lock();
|
|
|
|
if(! sp)
|
2019-03-07 10:40:48 +01:00
|
|
|
{
|
|
|
|
ec = net::error::operation_aborted;
|
|
|
|
return this->complete(cont, ec);
|
|
|
|
}
|
2019-02-13 08:00:07 -08:00
|
|
|
auto& impl = *sp;
|
2019-01-05 19:40:46 -08:00
|
|
|
BOOST_ASIO_CORO_REENTER(*this)
|
2016-10-24 08:12:09 -04:00
|
|
|
{
|
2019-02-13 08:00:07 -08:00
|
|
|
impl.change_status(status::handshake);
|
|
|
|
impl.update_timer(this->get_executor());
|
|
|
|
|
2019-01-05 19:40:46 -08:00
|
|
|
// Send response
|
|
|
|
BOOST_ASIO_CORO_YIELD
|
2019-01-19 07:24:00 -08:00
|
|
|
http::async_write(
|
2019-02-27 14:48:31 -08:00
|
|
|
impl.stream(), res_, std::move(*this));
|
2019-02-13 08:00:07 -08:00
|
|
|
if(impl.check_stop_now(ec))
|
|
|
|
goto upcall;
|
2019-01-05 19:40:46 -08:00
|
|
|
if(! ec)
|
2019-01-19 07:24:00 -08:00
|
|
|
ec = result_;
|
2019-01-05 19:40:46 -08:00
|
|
|
if(! ec)
|
|
|
|
{
|
2019-02-13 08:00:07 -08:00
|
|
|
impl.do_pmd_config(res_);
|
|
|
|
impl.open(role_type::server);
|
2019-01-05 19:40:46 -08:00
|
|
|
}
|
2019-02-13 08:00:07 -08:00
|
|
|
upcall:
|
2019-03-06 08:09:35 -08:00
|
|
|
this->complete(cont, ec);
|
2018-04-09 16:22:15 -07:00
|
|
|
}
|
2016-10-24 08:12:09 -04:00
|
|
|
}
|
2019-01-05 19:40:46 -08:00
|
|
|
};
|
2016-10-24 08:12:09 -04:00
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// read and respond to an upgrade request
|
|
|
|
//
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2019-02-20 20:25:01 -08:00
|
|
|
template<class Handler, class Decorator>
|
2017-11-18 16:52:18 -08:00
|
|
|
class stream<NextLayer, deflateSupported>::accept_op
|
2019-02-25 09:31:51 -08:00
|
|
|
: public beast::stable_async_base<
|
2019-02-04 21:52:54 -08:00
|
|
|
Handler, beast::executor_type<stream>>
|
2019-06-16 23:47:44 +02:00
|
|
|
, public asio::coroutine
|
2016-10-24 08:12:09 -04:00
|
|
|
{
|
2019-02-13 08:00:07 -08:00
|
|
|
boost::weak_ptr<impl_type> wp_;
|
2019-01-19 07:24:00 -08:00
|
|
|
http::request_parser<http::empty_body>& p_;
|
|
|
|
Decorator d_;
|
2016-10-24 08:12:09 -04:00
|
|
|
|
|
|
|
public:
|
2019-02-13 08:00:07 -08:00
|
|
|
template<class Handler_, class Buffers>
|
2019-01-05 19:40:46 -08:00
|
|
|
accept_op(
|
|
|
|
Handler_&& h,
|
2019-02-13 08:00:07 -08:00
|
|
|
boost::shared_ptr<impl_type> const& sp,
|
2019-02-20 20:25:01 -08:00
|
|
|
Decorator const& decorator,
|
|
|
|
Buffers const& buffers)
|
2019-02-25 09:31:51 -08:00
|
|
|
: stable_async_base<Handler,
|
2019-02-13 08:00:07 -08:00
|
|
|
beast::executor_type<stream>>(
|
|
|
|
std::forward<Handler_>(h),
|
2019-02-27 14:48:31 -08:00
|
|
|
sp->stream().get_executor())
|
2019-02-13 08:00:07 -08:00
|
|
|
, wp_(sp)
|
2019-01-19 07:24:00 -08:00
|
|
|
, p_(beast::allocate_stable<
|
|
|
|
http::request_parser<http::empty_body>>(*this))
|
|
|
|
, d_(decorator)
|
2016-10-24 08:12:09 -04:00
|
|
|
{
|
2019-02-13 08:00:07 -08:00
|
|
|
auto& impl = *sp;
|
2019-01-05 19:40:46 -08:00
|
|
|
error_code ec;
|
2019-02-13 08:00:07 -08:00
|
|
|
auto const mb =
|
|
|
|
beast::detail::dynamic_buffer_prepare(
|
2019-03-05 08:47:02 -08:00
|
|
|
impl.rd_buf, buffer_bytes(buffers),
|
2019-02-13 08:00:07 -08:00
|
|
|
ec, error::buffer_overflow);
|
|
|
|
if(! ec)
|
|
|
|
impl.rd_buf.commit(
|
|
|
|
net::buffer_copy(*mb, buffers));
|
2019-01-05 19:40:46 -08:00
|
|
|
(*this)(ec);
|
2016-10-24 08:12:09 -04:00
|
|
|
}
|
|
|
|
|
2017-09-07 07:39:52 -07:00
|
|
|
void operator()(
|
|
|
|
error_code ec = {},
|
2019-02-13 08:00:07 -08:00
|
|
|
std::size_t bytes_transferred = 0,
|
|
|
|
bool cont = true)
|
2016-10-24 08:12:09 -04:00
|
|
|
{
|
2019-01-19 07:24:00 -08:00
|
|
|
boost::ignore_unused(bytes_transferred);
|
2019-02-13 08:00:07 -08:00
|
|
|
auto sp = wp_.lock();
|
|
|
|
if(! sp)
|
2019-03-07 10:40:48 +01:00
|
|
|
{
|
|
|
|
ec = net::error::operation_aborted;
|
|
|
|
return this->complete(cont, ec);
|
|
|
|
}
|
2019-02-13 08:00:07 -08:00
|
|
|
auto& impl = *sp;
|
2019-01-05 19:40:46 -08:00
|
|
|
BOOST_ASIO_CORO_REENTER(*this)
|
2017-08-16 19:25:02 -07:00
|
|
|
{
|
2019-02-13 08:00:07 -08:00
|
|
|
impl.change_status(status::handshake);
|
|
|
|
impl.update_timer(this->get_executor());
|
|
|
|
|
|
|
|
// The constructor could have set ec
|
2019-01-05 19:40:46 -08:00
|
|
|
if(ec)
|
2019-02-13 08:00:07 -08:00
|
|
|
goto upcall;
|
|
|
|
|
|
|
|
BOOST_ASIO_CORO_YIELD
|
2019-02-27 14:48:31 -08:00
|
|
|
http::async_read(impl.stream(),
|
2019-02-13 08:00:07 -08:00
|
|
|
impl.rd_buf, p_, std::move(*this));
|
|
|
|
if(ec == http::error::end_of_stream)
|
|
|
|
ec = error::closed;
|
|
|
|
if(impl.check_stop_now(ec))
|
|
|
|
goto upcall;
|
2019-03-07 10:40:48 +01:00
|
|
|
|
2017-08-16 19:25:02 -07:00
|
|
|
{
|
2019-02-13 08:00:07 -08:00
|
|
|
// Arguments from our state must be
|
|
|
|
// moved to the stack before releasing
|
|
|
|
// the handler.
|
|
|
|
auto const req = p_.release();
|
|
|
|
auto const decorator = d_;
|
|
|
|
response_op<Handler>(
|
|
|
|
this->release_handler(),
|
|
|
|
sp, req, decorator, true);
|
|
|
|
return;
|
2019-01-05 19:40:46 -08:00
|
|
|
}
|
2019-02-13 08:00:07 -08:00
|
|
|
|
|
|
|
upcall:
|
2019-03-06 08:09:35 -08:00
|
|
|
this->complete(cont, ec);
|
2018-04-09 16:22:15 -07:00
|
|
|
}
|
2016-11-20 07:32:41 -05:00
|
|
|
}
|
2019-01-05 19:40:46 -08:00
|
|
|
};
|
2016-10-24 08:12:09 -04:00
|
|
|
|
2019-02-20 20:25:01 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
|
|
|
struct stream<NextLayer, deflateSupported>::
|
|
|
|
run_response_op
|
|
|
|
{
|
|
|
|
template<
|
|
|
|
class AcceptHandler,
|
|
|
|
class Body, class Allocator,
|
|
|
|
class Decorator>
|
|
|
|
void
|
|
|
|
operator()(
|
|
|
|
AcceptHandler&& h,
|
|
|
|
boost::shared_ptr<impl_type> const& sp,
|
|
|
|
http::request<Body,
|
2019-02-26 07:17:24 -08:00
|
|
|
http::basic_fields<Allocator>> const* m,
|
2019-02-20 20:25:01 -08:00
|
|
|
Decorator const& d)
|
|
|
|
{
|
|
|
|
// If you get an error on the following line it means
|
|
|
|
// that your handler does not meet the documented type
|
|
|
|
// requirements for the handler.
|
|
|
|
|
|
|
|
static_assert(
|
|
|
|
beast::detail::is_invocable<AcceptHandler,
|
|
|
|
void(error_code)>::value,
|
|
|
|
"AcceptHandler type requirements not met");
|
|
|
|
|
|
|
|
response_op<
|
|
|
|
typename std::decay<AcceptHandler>::type>(
|
2019-02-26 07:17:24 -08:00
|
|
|
std::forward<AcceptHandler>(h), sp, *m, d);
|
2019-02-20 20:25:01 -08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<class NextLayer, bool deflateSupported>
|
|
|
|
struct stream<NextLayer, deflateSupported>::
|
|
|
|
run_accept_op
|
|
|
|
{
|
|
|
|
template<
|
|
|
|
class AcceptHandler,
|
|
|
|
class Decorator,
|
|
|
|
class Buffers>
|
|
|
|
void
|
|
|
|
operator()(
|
|
|
|
AcceptHandler&& h,
|
|
|
|
boost::shared_ptr<impl_type> const& sp,
|
|
|
|
Decorator const& d,
|
|
|
|
Buffers const& b)
|
|
|
|
{
|
|
|
|
// If you get an error on the following line it means
|
|
|
|
// that your handler does not meet the documented type
|
|
|
|
// requirements for the handler.
|
|
|
|
|
|
|
|
static_assert(
|
|
|
|
beast::detail::is_invocable<AcceptHandler,
|
|
|
|
void(error_code)>::value,
|
|
|
|
"AcceptHandler type requirements not met");
|
|
|
|
|
|
|
|
accept_op<
|
|
|
|
typename std::decay<AcceptHandler>::type,
|
|
|
|
Decorator>(
|
|
|
|
std::forward<AcceptHandler>(h),
|
|
|
|
sp,
|
|
|
|
d,
|
|
|
|
b);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-04-25 10:12:43 -07:00
|
|
|
//------------------------------------------------------------------------------
|
2016-10-24 08:12:09 -04:00
|
|
|
|
2019-02-13 08:00:07 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
|
|
|
template<class Body, class Allocator,
|
|
|
|
class Decorator>
|
|
|
|
void
|
|
|
|
stream<NextLayer, deflateSupported>::
|
|
|
|
do_accept(
|
|
|
|
http::request<Body,
|
|
|
|
http::basic_fields<Allocator>> const& req,
|
|
|
|
Decorator const& decorator,
|
|
|
|
error_code& ec)
|
|
|
|
{
|
|
|
|
impl_->change_status(status::handshake);
|
|
|
|
|
|
|
|
error_code result;
|
|
|
|
auto const res = impl_->build_response(req, decorator, result);
|
2019-02-27 14:48:31 -08:00
|
|
|
http::write(impl_->stream(), res, ec);
|
2019-02-13 08:00:07 -08:00
|
|
|
if(ec)
|
|
|
|
return;
|
|
|
|
ec = result;
|
|
|
|
if(ec)
|
|
|
|
{
|
|
|
|
// VFALCO TODO Respect keep alive setting, perform
|
|
|
|
// teardown if Connection: close.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
impl_->do_pmd_config(res);
|
|
|
|
impl_->open(role_type::server);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class NextLayer, bool deflateSupported>
|
|
|
|
template<class Buffers, class Decorator>
|
|
|
|
void
|
|
|
|
stream<NextLayer, deflateSupported>::
|
|
|
|
do_accept(
|
|
|
|
Buffers const& buffers,
|
|
|
|
Decorator const& decorator,
|
|
|
|
error_code& ec)
|
|
|
|
{
|
|
|
|
impl_->reset();
|
|
|
|
auto const mb =
|
|
|
|
beast::detail::dynamic_buffer_prepare(
|
2019-03-05 08:47:02 -08:00
|
|
|
impl_->rd_buf, buffer_bytes(buffers), ec,
|
2019-02-13 08:00:07 -08:00
|
|
|
error::buffer_overflow);
|
|
|
|
if(ec)
|
|
|
|
return;
|
|
|
|
impl_->rd_buf.commit(net::buffer_copy(*mb, buffers));
|
|
|
|
|
|
|
|
http::request_parser<http::empty_body> p;
|
|
|
|
http::read(next_layer(), impl_->rd_buf, p, ec);
|
|
|
|
if(ec == http::error::end_of_stream)
|
|
|
|
ec = error::closed;
|
|
|
|
if(ec)
|
|
|
|
return;
|
|
|
|
do_accept(p.get(), decorator, ec);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2016-10-24 08:12:09 -04:00
|
|
|
void
|
2017-11-18 16:52:18 -08:00
|
|
|
stream<NextLayer, deflateSupported>::
|
2016-10-24 08:12:09 -04:00
|
|
|
accept()
|
|
|
|
{
|
2017-05-10 12:03:00 -07:00
|
|
|
static_assert(is_sync_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"SyncStream type requirements not met");
|
2016-10-24 08:12:09 -04:00
|
|
|
error_code ec;
|
2017-04-25 10:12:43 -07:00
|
|
|
accept(ec);
|
2016-10-24 08:12:09 -04:00
|
|
|
if(ec)
|
2017-05-22 15:30:12 -07:00
|
|
|
BOOST_THROW_EXCEPTION(system_error{ec});
|
2016-10-24 08:12:09 -04:00
|
|
|
}
|
|
|
|
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2016-10-24 08:12:09 -04:00
|
|
|
void
|
2017-11-18 16:52:18 -08:00
|
|
|
stream<NextLayer, deflateSupported>::
|
2016-10-24 08:12:09 -04:00
|
|
|
accept(error_code& ec)
|
|
|
|
{
|
2017-05-10 12:03:00 -07:00
|
|
|
static_assert(is_sync_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"SyncStream type requirements not met");
|
2019-02-13 08:00:07 -08:00
|
|
|
do_accept(
|
|
|
|
net::const_buffer{},
|
|
|
|
&default_decorate_res, ec);
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
}
|
|
|
|
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2016-10-24 08:12:09 -04:00
|
|
|
template<class ConstBufferSequence>
|
2017-05-08 12:41:45 -07:00
|
|
|
typename std::enable_if<! http::detail::is_header<
|
|
|
|
ConstBufferSequence>::value>::type
|
2017-11-18 16:52:18 -08:00
|
|
|
stream<NextLayer, deflateSupported>::
|
2016-10-24 08:12:09 -04:00
|
|
|
accept(ConstBufferSequence const& buffers)
|
|
|
|
{
|
2017-05-10 12:03:00 -07:00
|
|
|
static_assert(is_sync_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"SyncStream type requirements not met");
|
2018-11-30 14:58:38 -08:00
|
|
|
static_assert(net::is_const_buffer_sequence<
|
2016-10-24 08:12:09 -04:00
|
|
|
ConstBufferSequence>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"ConstBufferSequence type requirements not met");
|
2016-10-24 08:12:09 -04:00
|
|
|
error_code ec;
|
|
|
|
accept(buffers, ec);
|
|
|
|
if(ec)
|
2017-05-22 15:30:12 -07:00
|
|
|
BOOST_THROW_EXCEPTION(system_error{ec});
|
2016-10-24 08:12:09 -04:00
|
|
|
}
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2016-10-24 08:12:09 -04:00
|
|
|
template<class ConstBufferSequence>
|
2017-05-08 12:41:45 -07:00
|
|
|
typename std::enable_if<! http::detail::is_header<
|
|
|
|
ConstBufferSequence>::value>::type
|
2017-11-18 16:52:18 -08:00
|
|
|
stream<NextLayer, deflateSupported>::
|
2017-08-16 19:25:02 -07:00
|
|
|
accept(
|
|
|
|
ConstBufferSequence const& buffers, error_code& ec)
|
2016-10-24 08:12:09 -04:00
|
|
|
{
|
2017-05-10 12:03:00 -07:00
|
|
|
static_assert(is_sync_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"SyncStream type requirements not met");
|
2018-11-30 14:58:38 -08:00
|
|
|
static_assert(net::is_const_buffer_sequence<
|
2016-10-24 08:12:09 -04:00
|
|
|
ConstBufferSequence>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"ConstBufferSequence type requirements not met");
|
2019-02-13 08:00:07 -08:00
|
|
|
do_accept(buffers, &default_decorate_res, ec);
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
}
|
|
|
|
|
2016-10-24 08:12:09 -04:00
|
|
|
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2017-07-14 13:00:09 -07:00
|
|
|
template<class Body, class Allocator>
|
2016-10-24 08:12:09 -04:00
|
|
|
void
|
2017-11-18 16:52:18 -08:00
|
|
|
stream<NextLayer, deflateSupported>::
|
2017-08-16 19:25:02 -07:00
|
|
|
accept(
|
|
|
|
http::request<Body,
|
|
|
|
http::basic_fields<Allocator>> const& req)
|
2016-10-24 08:12:09 -04:00
|
|
|
{
|
2017-05-10 12:03:00 -07:00
|
|
|
static_assert(is_sync_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"SyncStream type requirements not met");
|
2016-10-24 08:12:09 -04:00
|
|
|
error_code ec;
|
2017-04-25 10:12:43 -07:00
|
|
|
accept(req, ec);
|
2016-10-24 08:12:09 -04:00
|
|
|
if(ec)
|
2017-05-22 15:30:12 -07:00
|
|
|
BOOST_THROW_EXCEPTION(system_error{ec});
|
2016-10-24 08:12:09 -04:00
|
|
|
}
|
|
|
|
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2017-07-14 13:00:09 -07:00
|
|
|
template<class Body, class Allocator>
|
2016-10-24 08:12:09 -04:00
|
|
|
void
|
2017-11-18 16:52:18 -08:00
|
|
|
stream<NextLayer, deflateSupported>::
|
2017-08-16 19:25:02 -07:00
|
|
|
accept(
|
|
|
|
http::request<Body,
|
|
|
|
http::basic_fields<Allocator>> const& req,
|
|
|
|
error_code& ec)
|
2016-10-24 08:12:09 -04:00
|
|
|
{
|
2017-05-10 12:03:00 -07:00
|
|
|
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
|
|
|
impl_->reset();
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
do_accept(req, &default_decorate_res, ec);
|
|
|
|
}
|
|
|
|
|
2017-04-25 10:12:43 -07:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2017-07-27 14:14:47 -07:00
|
|
|
template<
|
|
|
|
class AcceptHandler>
|
2019-03-04 23:13:42 -08:00
|
|
|
BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
|
2017-11-18 16:52:18 -08:00
|
|
|
stream<NextLayer, deflateSupported>::
|
2017-07-27 14:14:47 -07:00
|
|
|
async_accept(
|
|
|
|
AcceptHandler&& handler)
|
2017-04-25 10:12:43 -07:00
|
|
|
{
|
2017-05-10 12:03:00 -07:00
|
|
|
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
|
|
|
impl_->reset();
|
2019-02-20 20:25:01 -08:00
|
|
|
return net::async_initiate<
|
|
|
|
AcceptHandler,
|
|
|
|
void(error_code)>(
|
|
|
|
run_accept_op{},
|
|
|
|
handler,
|
|
|
|
impl_,
|
|
|
|
&default_decorate_res,
|
|
|
|
net::const_buffer{});
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
}
|
|
|
|
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2017-07-27 14:14:47 -07:00
|
|
|
template<
|
|
|
|
class ResponseDecorator,
|
|
|
|
class AcceptHandler>
|
2019-03-04 23:13:42 -08:00
|
|
|
BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
|
2017-11-18 16:52:18 -08:00
|
|
|
stream<NextLayer, deflateSupported>::
|
2017-07-27 14:14:47 -07:00
|
|
|
async_accept_ex(
|
|
|
|
ResponseDecorator const& decorator,
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
AcceptHandler&& handler)
|
|
|
|
{
|
2017-05-10 12:03:00 -07:00
|
|
|
static_assert(is_async_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"AsyncStream type requirements not met");
|
2017-11-18 16:52:18 -08:00
|
|
|
static_assert(detail::is_response_decorator<
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
ResponseDecorator>::value,
|
|
|
|
"ResponseDecorator requirements not met");
|
2019-01-19 07:24:00 -08:00
|
|
|
impl_->reset();
|
2019-02-20 20:25:01 -08:00
|
|
|
return net::async_initiate<
|
|
|
|
AcceptHandler,
|
|
|
|
void(error_code)>(
|
|
|
|
run_accept_op{},
|
|
|
|
handler,
|
|
|
|
impl_,
|
|
|
|
decorator,
|
|
|
|
net::const_buffer{});
|
2017-04-25 10:12:43 -07:00
|
|
|
}
|
|
|
|
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2017-07-27 14:14:47 -07:00
|
|
|
template<
|
|
|
|
class ConstBufferSequence,
|
|
|
|
class AcceptHandler>
|
2019-10-31 05:10:22 -07:00
|
|
|
BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
|
2017-11-18 16:52:18 -08:00
|
|
|
stream<NextLayer, deflateSupported>::
|
2017-07-27 14:14:47 -07:00
|
|
|
async_accept(
|
|
|
|
ConstBufferSequence const& buffers,
|
2019-10-31 05:10:22 -07:00
|
|
|
AcceptHandler&& handler,
|
|
|
|
typename std::enable_if<
|
|
|
|
! http::detail::is_header<
|
|
|
|
ConstBufferSequence>::value>::type*
|
|
|
|
)
|
2017-04-25 10:12:43 -07:00
|
|
|
{
|
2017-05-10 12:03:00 -07:00
|
|
|
static_assert(is_async_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"AsyncStream type requirements not met");
|
2018-11-30 14:58:38 -08:00
|
|
|
static_assert(net::is_const_buffer_sequence<
|
2017-04-25 10:12:43 -07:00
|
|
|
ConstBufferSequence>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"ConstBufferSequence type requirements not met");
|
2019-01-19 07:24:00 -08:00
|
|
|
impl_->reset();
|
2019-02-20 20:25:01 -08:00
|
|
|
return net::async_initiate<
|
|
|
|
AcceptHandler,
|
|
|
|
void(error_code)>(
|
|
|
|
run_accept_op{},
|
|
|
|
handler,
|
|
|
|
impl_,
|
|
|
|
&default_decorate_res,
|
|
|
|
buffers);
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
}
|
|
|
|
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2017-07-27 14:14:47 -07:00
|
|
|
template<
|
|
|
|
class ConstBufferSequence,
|
|
|
|
class ResponseDecorator,
|
|
|
|
class AcceptHandler>
|
2019-10-31 05:10:22 -07:00
|
|
|
BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
|
2017-11-18 16:52:18 -08:00
|
|
|
stream<NextLayer, deflateSupported>::
|
2017-07-27 14:14:47 -07:00
|
|
|
async_accept_ex(
|
|
|
|
ConstBufferSequence const& buffers,
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
ResponseDecorator const& decorator,
|
2019-10-31 05:10:22 -07:00
|
|
|
AcceptHandler&& handler,
|
|
|
|
typename std::enable_if<
|
|
|
|
! http::detail::is_header<
|
|
|
|
ConstBufferSequence>::value>::type*)
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
{
|
2017-05-10 12:03:00 -07:00
|
|
|
static_assert(is_async_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"AsyncStream type requirements not met");
|
2018-11-30 14:58:38 -08:00
|
|
|
static_assert(net::is_const_buffer_sequence<
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
ConstBufferSequence>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"ConstBufferSequence type requirements not met");
|
2017-11-18 16:52:18 -08:00
|
|
|
static_assert(detail::is_response_decorator<
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
ResponseDecorator>::value,
|
|
|
|
"ResponseDecorator requirements not met");
|
2019-01-19 07:24:00 -08:00
|
|
|
impl_->reset();
|
2019-02-20 20:25:01 -08:00
|
|
|
return net::async_initiate<
|
|
|
|
AcceptHandler,
|
|
|
|
void(error_code)>(
|
|
|
|
run_accept_op{},
|
|
|
|
handler,
|
|
|
|
impl_,
|
|
|
|
decorator,
|
|
|
|
buffers);
|
2017-04-25 10:12:43 -07:00
|
|
|
}
|
|
|
|
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2017-07-27 14:14:47 -07:00
|
|
|
template<
|
|
|
|
class Body, class Allocator,
|
2017-07-14 13:00:09 -07:00
|
|
|
class AcceptHandler>
|
2019-03-04 23:13:42 -08:00
|
|
|
BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
|
2017-11-18 16:52:18 -08:00
|
|
|
stream<NextLayer, deflateSupported>::
|
2017-07-27 14:14:47 -07:00
|
|
|
async_accept(
|
|
|
|
http::request<Body, http::basic_fields<Allocator>> const& req,
|
|
|
|
AcceptHandler&& handler)
|
2017-04-25 10:12:43 -07:00
|
|
|
{
|
2017-05-10 12:03:00 -07:00
|
|
|
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
|
|
|
impl_->reset();
|
2019-02-20 20:25:01 -08:00
|
|
|
return net::async_initiate<
|
|
|
|
AcceptHandler,
|
|
|
|
void(error_code)>(
|
|
|
|
run_response_op{},
|
|
|
|
handler,
|
|
|
|
impl_,
|
2019-02-26 07:17:24 -08:00
|
|
|
&req,
|
2019-02-20 20:25:01 -08:00
|
|
|
&default_decorate_res);
|
2017-04-25 10:12:43 -07:00
|
|
|
}
|
|
|
|
|
2017-11-18 16:52:18 -08:00
|
|
|
template<class NextLayer, bool deflateSupported>
|
2017-07-27 14:14:47 -07:00
|
|
|
template<
|
|
|
|
class Body, class Allocator,
|
|
|
|
class ResponseDecorator,
|
|
|
|
class AcceptHandler>
|
2019-03-04 23:13:42 -08:00
|
|
|
BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
|
2017-11-18 16:52:18 -08:00
|
|
|
stream<NextLayer, deflateSupported>::
|
2017-07-27 14:14:47 -07:00
|
|
|
async_accept_ex(
|
|
|
|
http::request<Body, http::basic_fields<Allocator>> const& req,
|
|
|
|
ResponseDecorator const& decorator,
|
|
|
|
AcceptHandler&& handler)
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
{
|
2017-05-10 12:03:00 -07:00
|
|
|
static_assert(is_async_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"AsyncStream type requirements not met");
|
2017-11-18 16:52:18 -08:00
|
|
|
static_assert(detail::is_response_decorator<
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
ResponseDecorator>::value,
|
|
|
|
"ResponseDecorator requirements not met");
|
2019-01-19 07:24:00 -08:00
|
|
|
impl_->reset();
|
2019-02-20 20:25:01 -08:00
|
|
|
return net::async_initiate<
|
|
|
|
AcceptHandler,
|
|
|
|
void(error_code)>(
|
|
|
|
run_response_op{},
|
|
|
|
handler,
|
|
|
|
impl_,
|
2019-02-26 07:17:24 -08:00
|
|
|
&req,
|
2019-02-20 20:25:01 -08:00
|
|
|
decorator);
|
2016-10-24 08:12:09 -04:00
|
|
|
}
|
|
|
|
|
2019-02-17 16:03:09 -08:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
template<class NextLayer, bool deflateSupported>
|
|
|
|
template<class ResponseDecorator>
|
|
|
|
void
|
|
|
|
stream<NextLayer, deflateSupported>::
|
|
|
|
accept_ex(ResponseDecorator const& decorator)
|
|
|
|
{
|
2019-03-06 08:09:35 -08:00
|
|
|
#ifndef BOOST_BEAST_ALLOW_DEPRECATED
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(sizeof(ResponseDecorator) == 0,
|
|
|
|
BOOST_BEAST_DEPRECATION_STRING);
|
|
|
|
#endif
|
|
|
|
static_assert(is_sync_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"SyncStream type requirements not met");
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(detail::is_response_decorator<
|
|
|
|
ResponseDecorator>::value,
|
|
|
|
"ResponseDecorator requirements not met");
|
|
|
|
error_code ec;
|
|
|
|
accept_ex(decorator, ec);
|
|
|
|
if(ec)
|
|
|
|
BOOST_THROW_EXCEPTION(system_error{ec});
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class NextLayer, bool deflateSupported>
|
|
|
|
template<class ResponseDecorator>
|
|
|
|
void
|
|
|
|
stream<NextLayer, deflateSupported>::
|
|
|
|
accept_ex(ResponseDecorator const& decorator, error_code& ec)
|
|
|
|
{
|
2019-03-06 08:09:35 -08:00
|
|
|
#ifndef BOOST_BEAST_ALLOW_DEPRECATED
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(sizeof(ResponseDecorator) == 0,
|
|
|
|
BOOST_BEAST_DEPRECATION_STRING);
|
|
|
|
#endif
|
|
|
|
static_assert(is_sync_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"SyncStream type requirements not met");
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(detail::is_response_decorator<
|
|
|
|
ResponseDecorator>::value,
|
|
|
|
"ResponseDecorator requirements not met");
|
|
|
|
do_accept(
|
|
|
|
net::const_buffer{},
|
|
|
|
decorator, ec);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class NextLayer, bool deflateSupported>
|
|
|
|
template<
|
|
|
|
class ConstBufferSequence,
|
|
|
|
class ResponseDecorator>
|
|
|
|
typename std::enable_if<! http::detail::is_header<
|
|
|
|
ConstBufferSequence>::value>::type
|
|
|
|
stream<NextLayer, deflateSupported>::
|
|
|
|
accept_ex(
|
|
|
|
ConstBufferSequence const& buffers,
|
|
|
|
ResponseDecorator const &decorator)
|
|
|
|
{
|
2019-03-06 08:09:35 -08:00
|
|
|
#ifndef BOOST_BEAST_ALLOW_DEPRECATED
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(sizeof(ResponseDecorator) == 0,
|
|
|
|
BOOST_BEAST_DEPRECATION_STRING);
|
|
|
|
#endif
|
|
|
|
static_assert(is_sync_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"SyncStream type requirements not met");
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(net::is_const_buffer_sequence<
|
|
|
|
ConstBufferSequence>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"ConstBufferSequence type requirements not met");
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(detail::is_response_decorator<
|
|
|
|
ResponseDecorator>::value,
|
|
|
|
"ResponseDecorator requirements not met");
|
|
|
|
error_code ec;
|
|
|
|
accept_ex(buffers, decorator, ec);
|
|
|
|
if(ec)
|
|
|
|
BOOST_THROW_EXCEPTION(system_error{ec});
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class NextLayer, bool deflateSupported>
|
|
|
|
template<
|
|
|
|
class ConstBufferSequence,
|
|
|
|
class ResponseDecorator>
|
|
|
|
typename std::enable_if<! http::detail::is_header<
|
|
|
|
ConstBufferSequence>::value>::type
|
|
|
|
stream<NextLayer, deflateSupported>::
|
|
|
|
accept_ex(
|
|
|
|
ConstBufferSequence const& buffers,
|
|
|
|
ResponseDecorator const& decorator,
|
|
|
|
error_code& ec)
|
|
|
|
{
|
2019-03-06 08:09:35 -08:00
|
|
|
#ifndef BOOST_BEAST_ALLOW_DEPRECATED
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(sizeof(ResponseDecorator) == 0,
|
|
|
|
BOOST_BEAST_DEPRECATION_STRING);
|
|
|
|
#endif
|
|
|
|
static_assert(is_sync_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"SyncStream type requirements not met");
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(net::is_const_buffer_sequence<
|
|
|
|
ConstBufferSequence>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"ConstBufferSequence type requirements not met");
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(net::is_const_buffer_sequence<
|
|
|
|
ConstBufferSequence>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"ConstBufferSequence type requirements not met");
|
2019-02-17 16:03:09 -08:00
|
|
|
do_accept(buffers, decorator, ec);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class NextLayer, bool deflateSupported>
|
|
|
|
template<
|
|
|
|
class Body, class Allocator,
|
|
|
|
class ResponseDecorator>
|
|
|
|
void
|
|
|
|
stream<NextLayer, deflateSupported>::
|
|
|
|
accept_ex(
|
|
|
|
http::request<Body,
|
|
|
|
http::basic_fields<Allocator>> const& req,
|
|
|
|
ResponseDecorator const& decorator)
|
|
|
|
{
|
2019-03-06 08:09:35 -08:00
|
|
|
#ifndef BOOST_BEAST_ALLOW_DEPRECATED
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(sizeof(ResponseDecorator) == 0,
|
|
|
|
BOOST_BEAST_DEPRECATION_STRING);
|
|
|
|
#endif
|
|
|
|
static_assert(is_sync_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"SyncStream type requirements not met");
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(detail::is_response_decorator<
|
|
|
|
ResponseDecorator>::value,
|
|
|
|
"ResponseDecorator requirements not met");
|
|
|
|
error_code ec;
|
|
|
|
accept_ex(req, decorator, ec);
|
|
|
|
if(ec)
|
|
|
|
BOOST_THROW_EXCEPTION(system_error{ec});
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class NextLayer, bool deflateSupported>
|
|
|
|
template<
|
|
|
|
class Body, class Allocator,
|
|
|
|
class ResponseDecorator>
|
|
|
|
void
|
|
|
|
stream<NextLayer, deflateSupported>::
|
|
|
|
accept_ex(
|
|
|
|
http::request<Body,
|
|
|
|
http::basic_fields<Allocator>> const& req,
|
|
|
|
ResponseDecorator const& decorator,
|
|
|
|
error_code& ec)
|
|
|
|
{
|
2019-03-06 08:09:35 -08:00
|
|
|
#ifndef BOOST_BEAST_ALLOW_DEPRECATED
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(sizeof(ResponseDecorator) == 0,
|
|
|
|
BOOST_BEAST_DEPRECATION_STRING);
|
|
|
|
#endif
|
|
|
|
static_assert(is_sync_stream<next_layer_type>::value,
|
2019-02-20 19:19:59 -08:00
|
|
|
"SyncStream type requirements not met");
|
2019-02-17 16:03:09 -08:00
|
|
|
static_assert(detail::is_response_decorator<
|
|
|
|
ResponseDecorator>::value,
|
|
|
|
"ResponseDecorator requirements not met");
|
|
|
|
impl_->reset();
|
|
|
|
do_accept(req, decorator, ec);
|
|
|
|
}
|
|
|
|
|
2016-10-24 08:12:09 -04:00
|
|
|
} // websocket
|
|
|
|
} // beast
|
2017-07-20 13:40:34 -07:00
|
|
|
} // boost
|
2016-10-24 08:12:09 -04:00
|
|
|
|
|
|
|
#endif
|