mirror of
https://github.com/boostorg/beast.git
synced 2025-08-01 05:44:38 +02:00
Refactor fail/clode code
This commit is contained in:
@@ -10,6 +10,7 @@ Version 100:
|
|||||||
WebSocket:
|
WebSocket:
|
||||||
|
|
||||||
* Remove obsolete frame tests
|
* Remove obsolete frame tests
|
||||||
|
* Refactor fail/clode code
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@@ -39,7 +39,8 @@ class stream<NextLayer>::fail_op
|
|||||||
stream<NextLayer>& ws_;
|
stream<NextLayer>& ws_;
|
||||||
int step_ = 0;
|
int step_ = 0;
|
||||||
bool dispatched_ = false;
|
bool dispatched_ = false;
|
||||||
fail_how how_;
|
close_code code_;
|
||||||
|
error_code ev_;
|
||||||
token tok_;
|
token tok_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -51,27 +52,12 @@ public:
|
|||||||
fail_op(
|
fail_op(
|
||||||
DeducedHandler&& h,
|
DeducedHandler&& h,
|
||||||
stream<NextLayer>& ws,
|
stream<NextLayer>& ws,
|
||||||
close_code code)
|
close_code code,
|
||||||
|
error_code ev)
|
||||||
: h_(std::forward<DeducedHandler>(h))
|
: h_(std::forward<DeducedHandler>(h))
|
||||||
, ws_(ws)
|
, ws_(ws)
|
||||||
, how_(fail_how::code)
|
, code_(code)
|
||||||
, tok_(ws_.t_.unique())
|
, ev_(ev)
|
||||||
{
|
|
||||||
ws_.rd_.fb.consume(ws_.rd_.fb.size());
|
|
||||||
ws_.template write_close<
|
|
||||||
flat_static_buffer_base>(
|
|
||||||
ws_.rd_.fb, code);
|
|
||||||
}
|
|
||||||
|
|
||||||
// maybe send frame in fb, then teardown
|
|
||||||
template<class DeducedHandler>
|
|
||||||
fail_op(
|
|
||||||
DeducedHandler&& h,
|
|
||||||
stream<NextLayer>& ws,
|
|
||||||
fail_how how)
|
|
||||||
: h_(std::forward<DeducedHandler>(h))
|
|
||||||
, ws_(ws)
|
|
||||||
, how_(how)
|
|
||||||
, tok_(ws_.t_.unique())
|
, tok_(ws_.t_.unique())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -168,12 +154,16 @@ operator()(error_code ec, std::size_t)
|
|||||||
ec = boost::asio::error::operation_aborted;
|
ec = boost::asio::error::operation_aborted;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(how_ == fail_how::teardown)
|
if(code_ == close_code::none)
|
||||||
goto go_teardown;
|
goto go_teardown;
|
||||||
if(ws_.wr_close_)
|
if(ws_.wr_close_)
|
||||||
goto go_teardown;
|
goto go_teardown;
|
||||||
// send close frame
|
// send close frame
|
||||||
step_ = do_teardown;
|
step_ = do_teardown;
|
||||||
|
ws_.rd_.fb.consume(ws_.rd_.fb.size());
|
||||||
|
ws_.template write_close<
|
||||||
|
flat_static_buffer_base>(
|
||||||
|
ws_.rd_.fb, code_);
|
||||||
ws_.wr_close_ = true;
|
ws_.wr_close_ = true;
|
||||||
return boost::asio::async_write(
|
return boost::asio::async_write(
|
||||||
ws_.stream_, ws_.rd_.fb.data(),
|
ws_.stream_, ws_.rd_.fb.data(),
|
||||||
@@ -192,13 +182,12 @@ operator()(error_code ec, std::size_t)
|
|||||||
BOOST_ASSERT(ws_.wr_block_ == tok_);
|
BOOST_ASSERT(ws_.wr_block_ == tok_);
|
||||||
step_ = do_teardown + 1;
|
step_ = do_teardown + 1;
|
||||||
websocket_helpers::call_async_teardown(
|
websocket_helpers::call_async_teardown(
|
||||||
ws_.next_layer(), std::move(*this));
|
ws_.stream_, std::move(*this));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case do_teardown + 1:
|
case do_teardown + 1:
|
||||||
BOOST_ASSERT(ws_.wr_block_ == tok_);
|
BOOST_ASSERT(ws_.wr_block_ == tok_);
|
||||||
dispatched_ = true;
|
dispatched_ = true;
|
||||||
ws_.failed_ = true;
|
|
||||||
ws_.wr_block_.reset();
|
ws_.wr_block_.reset();
|
||||||
if(ec == boost::asio::error::eof)
|
if(ec == boost::asio::error::eof)
|
||||||
{
|
{
|
||||||
@@ -207,15 +196,8 @@ operator()(error_code ec, std::size_t)
|
|||||||
ec.assign(0, ec.category());
|
ec.assign(0, ec.category());
|
||||||
}
|
}
|
||||||
if(! ec)
|
if(! ec)
|
||||||
{
|
ec = ev_;
|
||||||
switch(how_)
|
ws_.failed_ = true;
|
||||||
{
|
|
||||||
default:
|
|
||||||
case fail_how::code:
|
|
||||||
case fail_how::teardown: ec = error::failed; break;
|
|
||||||
case fail_how::close: ec = error::closed; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// upcall
|
// upcall
|
||||||
@@ -230,6 +212,61 @@ operator()(error_code ec, std::size_t)
|
|||||||
h_(ec, 0);
|
h_(ec, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* _Fail the WebSocket Connection_
|
||||||
|
*/
|
||||||
|
template<class NextLayer>
|
||||||
|
void
|
||||||
|
stream<NextLayer>::
|
||||||
|
do_fail(
|
||||||
|
close_code code, // if set, send a close frame first
|
||||||
|
error_code ev, // error code to use upon success
|
||||||
|
error_code& ec) // set to the error, else set to ev
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(ev);
|
||||||
|
if(code != close_code::none && ! wr_close_)
|
||||||
|
{
|
||||||
|
wr_close_ = true;
|
||||||
|
detail::frame_streambuf fb;
|
||||||
|
write_close<flat_static_buffer_base>(fb, code);
|
||||||
|
boost::asio::write(stream_, fb.data(), ec);
|
||||||
|
failed_ = !!ec;
|
||||||
|
if(failed_)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
websocket_helpers::call_teardown(stream_, ec);
|
||||||
|
if(ec == boost::asio::error::eof)
|
||||||
|
{
|
||||||
|
// Rationale:
|
||||||
|
// http://stackoverflow.com/questions/25587403/boost-asio-ssl-async-shutdown-always-finishes-with-an-error
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
}
|
||||||
|
failed_ = !!ec;
|
||||||
|
if(failed_)
|
||||||
|
return;
|
||||||
|
ec = ev;
|
||||||
|
failed_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* _Fail the WebSocket Connection_
|
||||||
|
*/
|
||||||
|
template<class NextLayer>
|
||||||
|
template<class Handler>
|
||||||
|
void
|
||||||
|
stream<NextLayer>::
|
||||||
|
do_async_fail(
|
||||||
|
close_code code, // if set, send a close frame first
|
||||||
|
error_code ev, // error code to use upon success
|
||||||
|
Handler&& handler)
|
||||||
|
{
|
||||||
|
fail_op<typename std::decay<Handler>::type>{
|
||||||
|
std::forward<Handler>(handler),
|
||||||
|
*this,
|
||||||
|
code,
|
||||||
|
ev}();
|
||||||
|
}
|
||||||
|
|
||||||
} // websocket
|
} // websocket
|
||||||
} // beast
|
} // beast
|
||||||
} // boost
|
} // boost
|
||||||
|
@@ -155,7 +155,7 @@ operator()(error_code ec, bool again)
|
|||||||
// got response
|
// got response
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
d.ws.do_response(d.res, d.key, ec);
|
d.ws.on_response(d.res, d.key, ec);
|
||||||
// call handler
|
// call handler
|
||||||
d.state = 99;
|
d.state = 99;
|
||||||
break;
|
break;
|
||||||
@@ -416,7 +416,7 @@ do_handshake(
|
|||||||
http::read(next_layer(), rd_.buf, res, ec);
|
http::read(next_layer(), rd_.buf, res, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
return;
|
return;
|
||||||
do_response(res, key, ec);
|
on_response(res, key, ec);
|
||||||
if(res_p)
|
if(res_p)
|
||||||
*res_p = std::move(res);
|
*res_p = std::move(res);
|
||||||
}
|
}
|
||||||
|
@@ -139,11 +139,9 @@ operator()(
|
|||||||
if(! ws_.parse_fh(ws_.rd_.fh, ws_.rd_.buf, code))
|
if(! ws_.parse_fh(ws_.rd_.fh, ws_.rd_.buf, code))
|
||||||
{
|
{
|
||||||
if(code != close_code::none)
|
if(code != close_code::none)
|
||||||
{
|
|
||||||
// _Fail the WebSocket Connection_
|
// _Fail the WebSocket Connection_
|
||||||
return fail_op<Handler>{
|
return ws_.do_async_fail(
|
||||||
std::move(h_), ws_, code}();
|
code, error::failed, std::move(h_));
|
||||||
}
|
|
||||||
step_ = do_loop + 1;
|
step_ = do_loop + 1;
|
||||||
return ws_.stream_.async_read_some(
|
return ws_.stream_.async_read_some(
|
||||||
ws_.rd_.buf.prepare(read_size(
|
ws_.rd_.buf.prepare(read_size(
|
||||||
@@ -202,19 +200,17 @@ operator()(
|
|||||||
if(code != close_code::none)
|
if(code != close_code::none)
|
||||||
{
|
{
|
||||||
// _Fail the WebSocket Connection_
|
// _Fail the WebSocket Connection_
|
||||||
return fail_op<Handler>{
|
return ws_.do_async_fail(
|
||||||
std::move(h_), ws_, code}();
|
code, error::failed, std::move(h_));
|
||||||
}
|
}
|
||||||
ws_.rd_.buf.consume(len);
|
ws_.rd_.buf.consume(len);
|
||||||
if(ws_.ctrl_cb_)
|
if(ws_.ctrl_cb_)
|
||||||
ws_.ctrl_cb_(frame_type::close,
|
ws_.ctrl_cb_(frame_type::close,
|
||||||
ws_.cr_.reason);
|
ws_.cr_.reason);
|
||||||
if(ws_.wr_close_)
|
if(ws_.wr_close_)
|
||||||
{
|
|
||||||
// _Close the WebSocket Connection_
|
// _Close the WebSocket Connection_
|
||||||
return fail_op<Handler>{
|
return ws_.do_async_fail(close_code::none,
|
||||||
std::move(h_), ws_, fail_how::close}();
|
error::closed, std::move(h_));
|
||||||
}
|
|
||||||
auto cr = ws_.cr_;
|
auto cr = ws_.cr_;
|
||||||
if(cr.code == close_code::none)
|
if(cr.code == close_code::none)
|
||||||
cr.code = close_code::normal;
|
cr.code = close_code::normal;
|
||||||
@@ -224,8 +220,11 @@ operator()(
|
|||||||
flat_static_buffer_base>(
|
flat_static_buffer_base>(
|
||||||
ws_.rd_.fb, cr);
|
ws_.rd_.fb, cr);
|
||||||
// _Start the WebSocket Closing Handshake_
|
// _Start the WebSocket Closing Handshake_
|
||||||
return fail_op<Handler>{
|
return ws_.do_async_fail(
|
||||||
std::move(h_), ws_, fail_how::close}();
|
cr.code == close_code::none ?
|
||||||
|
close_code::normal :
|
||||||
|
static_cast<close_code>(cr.code),
|
||||||
|
error::closed, std::move(h_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ws_.rd_.fh.len == 0 && ! ws_.rd_.fh.fin)
|
if(ws_.rd_.fh.len == 0 && ! ws_.rd_.fh.fin)
|
||||||
@@ -485,11 +484,9 @@ operator()(
|
|||||||
if(! ws_.rd_.utf8.write(mb) ||
|
if(! ws_.rd_.utf8.write(mb) ||
|
||||||
(ws_.rd_.remain == 0 && ws_.rd_.fh.fin &&
|
(ws_.rd_.remain == 0 && ws_.rd_.fh.fin &&
|
||||||
! ws_.rd_.utf8.finish()))
|
! ws_.rd_.utf8.finish()))
|
||||||
{
|
|
||||||
// _Fail the WebSocket Connection_
|
// _Fail the WebSocket Connection_
|
||||||
return fail_op<Handler>{std::move(h_),
|
return ws_.do_async_fail(close_code::bad_payload,
|
||||||
ws_, close_code::bad_payload}({}, 0);
|
error::failed, std::move(h_));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
bytes_written_ += bytes_transferred;
|
bytes_written_ += bytes_transferred;
|
||||||
ws_.rd_.size += bytes_transferred;
|
ws_.rd_.size += bytes_transferred;
|
||||||
@@ -520,11 +517,9 @@ operator()(
|
|||||||
if(! ws_.rd_.utf8.write(mb) ||
|
if(! ws_.rd_.utf8.write(mb) ||
|
||||||
(ws_.rd_.remain == 0 && ws_.rd_.fh.fin &&
|
(ws_.rd_.remain == 0 && ws_.rd_.fh.fin &&
|
||||||
! ws_.rd_.utf8.finish()))
|
! ws_.rd_.utf8.finish()))
|
||||||
{
|
|
||||||
// _Fail the WebSocket Connection_
|
// _Fail the WebSocket Connection_
|
||||||
return fail_op<Handler>{std::move(h_),
|
return ws_.do_async_fail(close_code::bad_payload,
|
||||||
ws_, close_code::bad_payload}();
|
error::failed, std::move(h_));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
bytes_written_ += bytes_transferred;
|
bytes_written_ += bytes_transferred;
|
||||||
ws_.rd_.size += bytes_transferred;
|
ws_.rd_.size += bytes_transferred;
|
||||||
@@ -614,11 +609,9 @@ operator()(
|
|||||||
break;
|
break;
|
||||||
if(ws_.rd_msg_max_ && beast::detail::sum_exceeds(
|
if(ws_.rd_msg_max_ && beast::detail::sum_exceeds(
|
||||||
ws_.rd_.size, zs.total_out, ws_.rd_msg_max_))
|
ws_.rd_.size, zs.total_out, ws_.rd_msg_max_))
|
||||||
{
|
|
||||||
// _Fail the WebSocket Connection_
|
// _Fail the WebSocket Connection_
|
||||||
return fail_op<Handler>{std::move(h_),
|
return ws_.do_async_fail(close_code::too_big,
|
||||||
ws_, close_code::too_big}();
|
error::failed, std::move(h_));
|
||||||
}
|
|
||||||
cb_.consume(zs.total_out);
|
cb_.consume(zs.total_out);
|
||||||
ws_.rd_.size += zs.total_out;
|
ws_.rd_.size += zs.total_out;
|
||||||
ws_.rd_.remain -= zs.total_in;
|
ws_.rd_.remain -= zs.total_in;
|
||||||
@@ -632,11 +625,9 @@ operator()(
|
|||||||
buffer_prefix(bytes_written_, cb_.get())) || (
|
buffer_prefix(bytes_written_, cb_.get())) || (
|
||||||
ws_.rd_.remain == 0 && ws_.rd_.fh.fin &&
|
ws_.rd_.remain == 0 && ws_.rd_.fh.fin &&
|
||||||
! ws_.rd_.utf8.finish()))
|
! ws_.rd_.utf8.finish()))
|
||||||
{
|
|
||||||
// _Fail the WebSocket Connection_
|
// _Fail the WebSocket Connection_
|
||||||
return fail_op<Handler>{std::move(h_),
|
return ws_.do_async_fail(close_code::bad_payload,
|
||||||
ws_, close_code::bad_payload}();
|
error::failed, std::move(h_));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -631,7 +631,7 @@ build_response(http::request<Body,
|
|||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
void
|
void
|
||||||
stream<NextLayer>::
|
stream<NextLayer>::
|
||||||
do_response(response_type const& res,
|
on_response(response_type const& res,
|
||||||
detail::sec_ws_key_type const& key, error_code& ec)
|
detail::sec_ws_key_type const& key, error_code& ec)
|
||||||
{
|
{
|
||||||
bool const success = [&]()
|
bool const success = [&]()
|
||||||
|
@@ -3791,6 +3791,10 @@ private:
|
|||||||
http::basic_fields<Allocator>> const& req,
|
http::basic_fields<Allocator>> const& req,
|
||||||
Decorator const& decorator);
|
Decorator const& decorator);
|
||||||
|
|
||||||
|
void
|
||||||
|
on_response(response_type const& resp,
|
||||||
|
detail::sec_ws_key_type const& key, error_code& ec);
|
||||||
|
|
||||||
template<class Decorator>
|
template<class Decorator>
|
||||||
void
|
void
|
||||||
do_accept(Decorator const& decorator,
|
do_accept(Decorator const& decorator,
|
||||||
@@ -3811,8 +3815,17 @@ private:
|
|||||||
error_code& ec);
|
error_code& ec);
|
||||||
|
|
||||||
void
|
void
|
||||||
do_response(response_type const& resp,
|
do_fail(
|
||||||
detail::sec_ws_key_type const& key, error_code& ec);
|
close_code code,
|
||||||
|
error_code ev,
|
||||||
|
error_code& ec);
|
||||||
|
|
||||||
|
template<class Handler>
|
||||||
|
void
|
||||||
|
do_async_fail(
|
||||||
|
close_code code,
|
||||||
|
error_code ev,
|
||||||
|
Handler&& handler);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // websocket
|
} // websocket
|
||||||
|
Reference in New Issue
Block a user