mirror of
https://github.com/boostorg/beast.git
synced 2025-08-01 05:44:38 +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
|
||||
* Tidy up MSVC CMake configuration
|
||||
* Make close_code a proper enum
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@@ -67,33 +67,31 @@ is_control(opcode op)
|
||||
return op >= opcode::close;
|
||||
}
|
||||
|
||||
// Returns `true` if a close code is valid
|
||||
inline
|
||||
bool
|
||||
is_valid(close_code::value code)
|
||||
is_valid_close_code(std::uint16_t v)
|
||||
{
|
||||
auto const v = code;
|
||||
switch(v)
|
||||
{
|
||||
case 1000:
|
||||
case 1001:
|
||||
case 1002:
|
||||
case 1003:
|
||||
case 1007:
|
||||
case 1008:
|
||||
case 1009:
|
||||
case 1010:
|
||||
case 1011:
|
||||
case 1012:
|
||||
case 1013:
|
||||
case close_code::normal: // 1000
|
||||
case close_code::going_away: // 1001
|
||||
case close_code::protocol_error: // 1002
|
||||
case close_code::unknown_data: // 1003
|
||||
case close_code::bad_payload: // 1007
|
||||
case close_code::policy_error: // 1008
|
||||
case close_code::too_big: // 1009
|
||||
case close_code::needs_extension: // 1010
|
||||
case close_code::internal_error: // 1011
|
||||
case close_code::service_restart: // 1012
|
||||
case close_code::try_again_later: // 1013
|
||||
return true;
|
||||
|
||||
// explicitly reserved
|
||||
case 1004:
|
||||
case 1005:
|
||||
case 1006:
|
||||
case 1014:
|
||||
case 1015:
|
||||
case close_code::reserved1: // 1004
|
||||
case close_code::no_status: // 1005
|
||||
case close_code::abnormal: // 1006
|
||||
case close_code::reserved2: // 1014
|
||||
case close_code::reserved3: // 1015
|
||||
return false;
|
||||
}
|
||||
// reserved
|
||||
@@ -175,7 +173,7 @@ read(ping_data& data, Buffers const& bs)
|
||||
template<class Buffers>
|
||||
void
|
||||
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_copy;
|
||||
@@ -201,7 +199,7 @@ read(close_reason& cr,
|
||||
cr.code = big_uint16_to_native(&b[0]);
|
||||
cb.consume(2);
|
||||
n -= 2;
|
||||
if(! is_valid(cr.code))
|
||||
if(! is_valid_close_code(cr.code))
|
||||
{
|
||||
code = close_code::protocol_error;
|
||||
return;
|
||||
|
@@ -175,12 +175,12 @@ protected:
|
||||
template<class DynamicBuffer>
|
||||
std::size_t
|
||||
read_fh1(detail::frame_header& fh,
|
||||
DynamicBuffer& db, close_code::value& code);
|
||||
DynamicBuffer& db, close_code& code);
|
||||
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
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
|
||||
template<class = void>
|
||||
@@ -264,13 +264,13 @@ template<class DynamicBuffer>
|
||||
std::size_t
|
||||
stream_base::
|
||||
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_copy;
|
||||
using boost::asio::buffer_size;
|
||||
auto const err =
|
||||
[&](close_code::value cv)
|
||||
[&](close_code cv)
|
||||
{
|
||||
code = cv;
|
||||
return 0;
|
||||
@@ -372,7 +372,7 @@ template<class DynamicBuffer>
|
||||
void
|
||||
stream_base::
|
||||
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_copy;
|
||||
|
@@ -173,7 +173,7 @@ operator()(error_code ec,
|
||||
if(! ec)
|
||||
{
|
||||
d.cont = d.cont || again;
|
||||
close_code::value code = close_code::none;
|
||||
close_code code = close_code::none;
|
||||
do
|
||||
{
|
||||
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_cast;
|
||||
using boost::asio::buffer_size;
|
||||
close_code::value code{};
|
||||
close_code code{};
|
||||
for(;;)
|
||||
{
|
||||
// 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>
|
||||
|
||||
*/
|
||||
#if GENERATING_DOCS
|
||||
enum close_code
|
||||
#else
|
||||
namespace close_code {
|
||||
using value = std::uint16_t;
|
||||
enum
|
||||
#endif
|
||||
{
|
||||
/// used internally to mean "no error"
|
||||
none = 0,
|
||||
|
||||
/// Normal closure; the connection successfully completed whatever purpose for which it was created.
|
||||
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,
|
||||
|
||||
/// The endpoint is terminating the connection due to a protocol error.
|
||||
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,
|
||||
|
||||
/// Indicates a received close frame has no close code
|
||||
//no_code = 1005, // TODO
|
||||
|
||||
/// Indicates the connection was closed without receiving a close frame
|
||||
no_close = 1006,
|
||||
|
||||
/// 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).
|
||||
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,
|
||||
|
||||
/// The endpoint is terminating the connection because a data frame was received that is too large.
|
||||
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,
|
||||
|
||||
/// The server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.
|
||||
internal_error = 1011,
|
||||
|
||||
/// The server is terminating the connection because it is restarting.
|
||||
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,
|
||||
|
||||
reserved1 = 1004,
|
||||
no_status = 1005, // illegal on wire
|
||||
abnormal = 1006, // illegal on wire
|
||||
reserved2 = 1015,
|
||||
//----
|
||||
//
|
||||
// The following are illegal on the wire
|
||||
//
|
||||
|
||||
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.
|
||||
using reason_string = static_string<123, char>;
|
||||
@@ -102,7 +141,7 @@ using ping_data = static_string<125, char>;
|
||||
struct close_reason
|
||||
{
|
||||
/// The close code.
|
||||
close_code::value code = close_code::none;
|
||||
std::uint16_t code = close_code::none;
|
||||
|
||||
/// The optional utf8-encoded reason string.
|
||||
reason_string reason;
|
||||
@@ -115,7 +154,7 @@ struct close_reason
|
||||
close_reason() = default;
|
||||
|
||||
/// Construct from a code.
|
||||
close_reason(close_code::value code_)
|
||||
close_reason(std::uint16_t code_)
|
||||
: code(code_)
|
||||
{
|
||||
}
|
||||
@@ -130,7 +169,7 @@ struct close_reason
|
||||
|
||||
/// Construct from a code and reason.
|
||||
template<std::size_t N>
|
||||
close_reason(close_code::value code_,
|
||||
close_reason(close_code code_,
|
||||
char const (&reason_)[N])
|
||||
: code(code_)
|
||||
, reason(reason_)
|
||||
|
@@ -35,20 +35,20 @@ class frame_test : public beast::unit_test::suite
|
||||
public:
|
||||
void testCloseCodes()
|
||||
{
|
||||
BEAST_EXPECT(! is_valid(0));
|
||||
BEAST_EXPECT(! is_valid(1));
|
||||
BEAST_EXPECT(! is_valid(999));
|
||||
BEAST_EXPECT(! is_valid(1004));
|
||||
BEAST_EXPECT(! is_valid(1005));
|
||||
BEAST_EXPECT(! is_valid(1006));
|
||||
BEAST_EXPECT(! is_valid(1016));
|
||||
BEAST_EXPECT(! is_valid(2000));
|
||||
BEAST_EXPECT(! is_valid(2999));
|
||||
BEAST_EXPECT(is_valid(1000));
|
||||
BEAST_EXPECT(is_valid(1002));
|
||||
BEAST_EXPECT(is_valid(3000));
|
||||
BEAST_EXPECT(is_valid(4000));
|
||||
BEAST_EXPECT(is_valid(5000));
|
||||
BEAST_EXPECT(! is_valid_close_code(0));
|
||||
BEAST_EXPECT(! is_valid_close_code(1));
|
||||
BEAST_EXPECT(! is_valid_close_code(999));
|
||||
BEAST_EXPECT(! is_valid_close_code(1004));
|
||||
BEAST_EXPECT(! is_valid_close_code(1005));
|
||||
BEAST_EXPECT(! is_valid_close_code(1006));
|
||||
BEAST_EXPECT(! is_valid_close_code(1016));
|
||||
BEAST_EXPECT(! is_valid_close_code(2000));
|
||||
BEAST_EXPECT(! is_valid_close_code(2999));
|
||||
BEAST_EXPECT(is_valid_close_code(1000));
|
||||
BEAST_EXPECT(is_valid_close_code(1002));
|
||||
BEAST_EXPECT(is_valid_close_code(3000));
|
||||
BEAST_EXPECT(is_valid_close_code(4000));
|
||||
BEAST_EXPECT(is_valid_close_code(5000));
|
||||
}
|
||||
|
||||
struct test_fh : frame_header
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
{
|
||||
fh_streambuf sb;
|
||||
write(sb, fh);
|
||||
close_code::value code;
|
||||
close_code code;
|
||||
stream_base stream;
|
||||
stream.open(role);
|
||||
detail::frame_header fh1;
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
{
|
||||
fh_streambuf sb;
|
||||
write(sb, fh);
|
||||
close_code::value code;
|
||||
close_code code;
|
||||
stream_base stream;
|
||||
stream.open(role);
|
||||
detail::frame_header fh1;
|
||||
@@ -197,7 +197,7 @@ public:
|
||||
sb.commit(buffer_copy(sb.prepare(v.size()), buffer(v)));
|
||||
stream_base stream;
|
||||
stream.open(role);
|
||||
close_code::value code;
|
||||
close_code code;
|
||||
detail::frame_header fh;
|
||||
auto const n =
|
||||
stream.read_fh1(fh, sb, code);
|
||||
|
Reference in New Issue
Block a user