mirror of
https://github.com/boostorg/beast.git
synced 2025-08-02 14:24:31 +02:00
Make websocket::close_code a proper enum:
fix #311 This changes close_code to be a proper enumeration.
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
* Add Appveyor build scripts and badge
|
* Add Appveyor build scripts and badge
|
||||||
* Tidy up MSVC CMake configuration
|
* Tidy up MSVC CMake configuration
|
||||||
|
* Make close_code a proper enum
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@@ -67,33 +67,31 @@ is_control(opcode op)
|
|||||||
return op >= opcode::close;
|
return op >= opcode::close;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns `true` if a close code is valid
|
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
is_valid(close_code::value code)
|
is_valid_close_code(std::uint16_t v)
|
||||||
{
|
{
|
||||||
auto const v = code;
|
|
||||||
switch(v)
|
switch(v)
|
||||||
{
|
{
|
||||||
case 1000:
|
case close_code::normal: // 1000
|
||||||
case 1001:
|
case close_code::going_away: // 1001
|
||||||
case 1002:
|
case close_code::protocol_error: // 1002
|
||||||
case 1003:
|
case close_code::unknown_data: // 1003
|
||||||
case 1007:
|
case close_code::bad_payload: // 1007
|
||||||
case 1008:
|
case close_code::policy_error: // 1008
|
||||||
case 1009:
|
case close_code::too_big: // 1009
|
||||||
case 1010:
|
case close_code::needs_extension: // 1010
|
||||||
case 1011:
|
case close_code::internal_error: // 1011
|
||||||
case 1012:
|
case close_code::service_restart: // 1012
|
||||||
case 1013:
|
case close_code::try_again_later: // 1013
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// explicitly reserved
|
// explicitly reserved
|
||||||
case 1004:
|
case close_code::reserved1: // 1004
|
||||||
case 1005:
|
case close_code::no_status: // 1005
|
||||||
case 1006:
|
case close_code::abnormal: // 1006
|
||||||
case 1014:
|
case close_code::reserved2: // 1014
|
||||||
case 1015:
|
case close_code::reserved3: // 1015
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// reserved
|
// reserved
|
||||||
@@ -175,7 +173,7 @@ read(ping_data& data, Buffers const& bs)
|
|||||||
template<class Buffers>
|
template<class Buffers>
|
||||||
void
|
void
|
||||||
read(close_reason& cr,
|
read(close_reason& cr,
|
||||||
Buffers const& bs, close_code::value& code)
|
Buffers const& bs, close_code& code)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer;
|
using boost::asio::buffer;
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
@@ -201,7 +199,7 @@ read(close_reason& cr,
|
|||||||
cr.code = big_uint16_to_native(&b[0]);
|
cr.code = big_uint16_to_native(&b[0]);
|
||||||
cb.consume(2);
|
cb.consume(2);
|
||||||
n -= 2;
|
n -= 2;
|
||||||
if(! is_valid(cr.code))
|
if(! is_valid_close_code(cr.code))
|
||||||
{
|
{
|
||||||
code = close_code::protocol_error;
|
code = close_code::protocol_error;
|
||||||
return;
|
return;
|
||||||
|
@@ -175,12 +175,12 @@ protected:
|
|||||||
template<class DynamicBuffer>
|
template<class DynamicBuffer>
|
||||||
std::size_t
|
std::size_t
|
||||||
read_fh1(detail::frame_header& fh,
|
read_fh1(detail::frame_header& fh,
|
||||||
DynamicBuffer& db, close_code::value& code);
|
DynamicBuffer& db, close_code& code);
|
||||||
|
|
||||||
template<class DynamicBuffer>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
read_fh2(detail::frame_header& fh,
|
read_fh2(detail::frame_header& fh,
|
||||||
DynamicBuffer& db, close_code::value& code);
|
DynamicBuffer& db, close_code& code);
|
||||||
|
|
||||||
// Called before receiving the first frame of each message
|
// Called before receiving the first frame of each message
|
||||||
template<class = void>
|
template<class = void>
|
||||||
@@ -264,13 +264,13 @@ template<class DynamicBuffer>
|
|||||||
std::size_t
|
std::size_t
|
||||||
stream_base::
|
stream_base::
|
||||||
read_fh1(detail::frame_header& fh,
|
read_fh1(detail::frame_header& fh,
|
||||||
DynamicBuffer& db, close_code::value& code)
|
DynamicBuffer& db, close_code& code)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer;
|
using boost::asio::buffer;
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
using boost::asio::buffer_size;
|
using boost::asio::buffer_size;
|
||||||
auto const err =
|
auto const err =
|
||||||
[&](close_code::value cv)
|
[&](close_code cv)
|
||||||
{
|
{
|
||||||
code = cv;
|
code = cv;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -372,7 +372,7 @@ template<class DynamicBuffer>
|
|||||||
void
|
void
|
||||||
stream_base::
|
stream_base::
|
||||||
read_fh2(detail::frame_header& fh,
|
read_fh2(detail::frame_header& fh,
|
||||||
DynamicBuffer& db, close_code::value& code)
|
DynamicBuffer& db, close_code& code)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer;
|
using boost::asio::buffer;
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
|
@@ -173,7 +173,7 @@ operator()(error_code ec,
|
|||||||
if(! ec)
|
if(! ec)
|
||||||
{
|
{
|
||||||
d.cont = d.cont || again;
|
d.cont = d.cont || again;
|
||||||
close_code::value code = close_code::none;
|
close_code code = close_code::none;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
switch(d.state)
|
switch(d.state)
|
||||||
@@ -727,7 +727,7 @@ read_frame(frame_info& fi, DynamicBuffer& dynabuf, error_code& ec)
|
|||||||
using boost::asio::buffer;
|
using boost::asio::buffer;
|
||||||
using boost::asio::buffer_cast;
|
using boost::asio::buffer_cast;
|
||||||
using boost::asio::buffer_size;
|
using boost::asio::buffer_size;
|
||||||
close_code::value code{};
|
close_code code{};
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
// Read frame header
|
// Read frame header
|
||||||
|
@@ -45,48 +45,87 @@ enum class opcode : std::uint8_t
|
|||||||
@see <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455 7.4.1 Defined Status Codes</a>
|
@see <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455 7.4.1 Defined Status Codes</a>
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#if GENERATING_DOCS
|
|
||||||
enum close_code
|
enum close_code
|
||||||
#else
|
|
||||||
namespace close_code {
|
|
||||||
using value = std::uint16_t;
|
|
||||||
enum
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
/// used internally to mean "no error"
|
/// Normal closure; the connection successfully completed whatever purpose for which it was created.
|
||||||
none = 0,
|
|
||||||
|
|
||||||
normal = 1000,
|
normal = 1000,
|
||||||
|
|
||||||
|
/// The endpoint is going away, either because of a server failure or because the browser is navigating away from the page that opened the connection.
|
||||||
going_away = 1001,
|
going_away = 1001,
|
||||||
|
|
||||||
|
/// The endpoint is terminating the connection due to a protocol error.
|
||||||
protocol_error = 1002,
|
protocol_error = 1002,
|
||||||
|
|
||||||
|
/// The connection is being terminated because the endpoint received data of a type it cannot accept (for example, a text-only endpoint received binary data).
|
||||||
unknown_data = 1003,
|
unknown_data = 1003,
|
||||||
|
|
||||||
/// Indicates a received close frame has no close code
|
/// The endpoint is terminating the connection because a message was received that contained inconsistent data (e.g., non-UTF-8 data within a text message).
|
||||||
//no_code = 1005, // TODO
|
|
||||||
|
|
||||||
/// Indicates the connection was closed without receiving a close frame
|
|
||||||
no_close = 1006,
|
|
||||||
|
|
||||||
bad_payload = 1007,
|
bad_payload = 1007,
|
||||||
|
|
||||||
|
/// The endpoint is terminating the connection because it received a message that violates its policy. This is a generic status code, used when codes 1003 and 1009 are not suitable.
|
||||||
policy_error = 1008,
|
policy_error = 1008,
|
||||||
|
|
||||||
|
/// The endpoint is terminating the connection because a data frame was received that is too large.
|
||||||
too_big = 1009,
|
too_big = 1009,
|
||||||
|
|
||||||
|
/// The client is terminating the connection because it expected the server to negotiate one or more extension, but the server didn't.
|
||||||
needs_extension = 1010,
|
needs_extension = 1010,
|
||||||
|
|
||||||
|
/// The server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.
|
||||||
internal_error = 1011,
|
internal_error = 1011,
|
||||||
|
|
||||||
|
/// The server is terminating the connection because it is restarting.
|
||||||
service_restart = 1012,
|
service_restart = 1012,
|
||||||
|
|
||||||
|
/// The server is terminating the connection due to a temporary condition, e.g. it is overloaded and is casting off some of its clients.
|
||||||
try_again_later = 1013,
|
try_again_later = 1013,
|
||||||
|
|
||||||
reserved1 = 1004,
|
//----
|
||||||
no_status = 1005, // illegal on wire
|
//
|
||||||
abnormal = 1006, // illegal on wire
|
// The following are illegal on the wire
|
||||||
reserved2 = 1015,
|
//
|
||||||
|
|
||||||
last = 5000 // satisfy warnings
|
/** Used internally to mean "no error"
|
||||||
|
|
||||||
|
This code is reserved and may not be sent.
|
||||||
|
*/
|
||||||
|
none = 0,
|
||||||
|
|
||||||
|
/** Reserved for future use by the WebSocket standard.
|
||||||
|
|
||||||
|
This code is reserved and may not be sent.
|
||||||
|
*/
|
||||||
|
reserved1 = 1004,
|
||||||
|
|
||||||
|
/** No status code was provided even though one was expected.
|
||||||
|
|
||||||
|
This code is reserved and may not be sent.
|
||||||
|
*/
|
||||||
|
no_status = 1005,
|
||||||
|
|
||||||
|
/** Connection was closed without receiving a close frame
|
||||||
|
|
||||||
|
This code is reserved and may not be sent.
|
||||||
|
*/
|
||||||
|
abnormal = 1006,
|
||||||
|
|
||||||
|
/** Reserved for future use by the WebSocket standard.
|
||||||
|
|
||||||
|
This code is reserved and may not be sent.
|
||||||
|
*/
|
||||||
|
reserved2 = 1014,
|
||||||
|
|
||||||
|
/** Reserved for future use by the WebSocket standard.
|
||||||
|
|
||||||
|
This code is reserved and may not be sent.
|
||||||
|
*/
|
||||||
|
reserved3 = 1015
|
||||||
|
|
||||||
|
//
|
||||||
|
//----
|
||||||
|
|
||||||
|
//last = 5000 // satisfy warnings
|
||||||
};
|
};
|
||||||
#if ! GENERATING_DOCS
|
|
||||||
} // close_code
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// The type representing the reason string in a close frame.
|
/// The type representing the reason string in a close frame.
|
||||||
using reason_string = static_string<123, char>;
|
using reason_string = static_string<123, char>;
|
||||||
@@ -102,7 +141,7 @@ using ping_data = static_string<125, char>;
|
|||||||
struct close_reason
|
struct close_reason
|
||||||
{
|
{
|
||||||
/// The close code.
|
/// The close code.
|
||||||
close_code::value code = close_code::none;
|
std::uint16_t code = close_code::none;
|
||||||
|
|
||||||
/// The optional utf8-encoded reason string.
|
/// The optional utf8-encoded reason string.
|
||||||
reason_string reason;
|
reason_string reason;
|
||||||
@@ -115,7 +154,7 @@ struct close_reason
|
|||||||
close_reason() = default;
|
close_reason() = default;
|
||||||
|
|
||||||
/// Construct from a code.
|
/// Construct from a code.
|
||||||
close_reason(close_code::value code_)
|
close_reason(std::uint16_t code_)
|
||||||
: code(code_)
|
: code(code_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -130,7 +169,7 @@ struct close_reason
|
|||||||
|
|
||||||
/// Construct from a code and reason.
|
/// Construct from a code and reason.
|
||||||
template<std::size_t N>
|
template<std::size_t N>
|
||||||
close_reason(close_code::value code_,
|
close_reason(close_code code_,
|
||||||
char const (&reason_)[N])
|
char const (&reason_)[N])
|
||||||
: code(code_)
|
: code(code_)
|
||||||
, reason(reason_)
|
, reason(reason_)
|
||||||
|
@@ -35,20 +35,20 @@ class frame_test : public beast::unit_test::suite
|
|||||||
public:
|
public:
|
||||||
void testCloseCodes()
|
void testCloseCodes()
|
||||||
{
|
{
|
||||||
BEAST_EXPECT(! is_valid(0));
|
BEAST_EXPECT(! is_valid_close_code(0));
|
||||||
BEAST_EXPECT(! is_valid(1));
|
BEAST_EXPECT(! is_valid_close_code(1));
|
||||||
BEAST_EXPECT(! is_valid(999));
|
BEAST_EXPECT(! is_valid_close_code(999));
|
||||||
BEAST_EXPECT(! is_valid(1004));
|
BEAST_EXPECT(! is_valid_close_code(1004));
|
||||||
BEAST_EXPECT(! is_valid(1005));
|
BEAST_EXPECT(! is_valid_close_code(1005));
|
||||||
BEAST_EXPECT(! is_valid(1006));
|
BEAST_EXPECT(! is_valid_close_code(1006));
|
||||||
BEAST_EXPECT(! is_valid(1016));
|
BEAST_EXPECT(! is_valid_close_code(1016));
|
||||||
BEAST_EXPECT(! is_valid(2000));
|
BEAST_EXPECT(! is_valid_close_code(2000));
|
||||||
BEAST_EXPECT(! is_valid(2999));
|
BEAST_EXPECT(! is_valid_close_code(2999));
|
||||||
BEAST_EXPECT(is_valid(1000));
|
BEAST_EXPECT(is_valid_close_code(1000));
|
||||||
BEAST_EXPECT(is_valid(1002));
|
BEAST_EXPECT(is_valid_close_code(1002));
|
||||||
BEAST_EXPECT(is_valid(3000));
|
BEAST_EXPECT(is_valid_close_code(3000));
|
||||||
BEAST_EXPECT(is_valid(4000));
|
BEAST_EXPECT(is_valid_close_code(4000));
|
||||||
BEAST_EXPECT(is_valid(5000));
|
BEAST_EXPECT(is_valid_close_code(5000));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct test_fh : frame_header
|
struct test_fh : frame_header
|
||||||
@@ -77,7 +77,7 @@ public:
|
|||||||
{
|
{
|
||||||
fh_streambuf sb;
|
fh_streambuf sb;
|
||||||
write(sb, fh);
|
write(sb, fh);
|
||||||
close_code::value code;
|
close_code code;
|
||||||
stream_base stream;
|
stream_base stream;
|
||||||
stream.open(role);
|
stream.open(role);
|
||||||
detail::frame_header fh1;
|
detail::frame_header fh1;
|
||||||
@@ -129,7 +129,7 @@ public:
|
|||||||
{
|
{
|
||||||
fh_streambuf sb;
|
fh_streambuf sb;
|
||||||
write(sb, fh);
|
write(sb, fh);
|
||||||
close_code::value code;
|
close_code code;
|
||||||
stream_base stream;
|
stream_base stream;
|
||||||
stream.open(role);
|
stream.open(role);
|
||||||
detail::frame_header fh1;
|
detail::frame_header fh1;
|
||||||
@@ -197,7 +197,7 @@ public:
|
|||||||
sb.commit(buffer_copy(sb.prepare(v.size()), buffer(v)));
|
sb.commit(buffer_copy(sb.prepare(v.size()), buffer(v)));
|
||||||
stream_base stream;
|
stream_base stream;
|
||||||
stream.open(role);
|
stream.open(role);
|
||||||
close_code::value code;
|
close_code code;
|
||||||
detail::frame_header fh;
|
detail::frame_header fh;
|
||||||
auto const n =
|
auto const n =
|
||||||
stream.read_fh1(fh, sb, code);
|
stream.read_fh1(fh, sb, code);
|
||||||
|
Reference in New Issue
Block a user