forked from boostorg/beast
Add WebSocket error conditions:
This introduces the condition enumeration type for grouping websocket error codes together as a convenience to callers.
This commit is contained in:
@@ -6,6 +6,7 @@ WebSocket:
|
|||||||
|
|
||||||
* Redistribute the read tests in the translation units
|
* Redistribute the read tests in the translation units
|
||||||
* Refactor error headers
|
* Refactor error headers
|
||||||
|
* Add WebSocket error conditions
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@ namespace boost {
|
|||||||
namespace beast {
|
namespace beast {
|
||||||
namespace websocket {
|
namespace websocket {
|
||||||
enum class error;
|
enum class error;
|
||||||
|
enum class condition;
|
||||||
} // websocket
|
} // websocket
|
||||||
} // beast
|
} // beast
|
||||||
|
|
||||||
@@ -27,6 +28,11 @@ struct is_error_code_enum<beast::websocket::error>
|
|||||||
{
|
{
|
||||||
static bool const value = true;
|
static bool const value = true;
|
||||||
};
|
};
|
||||||
|
template<>
|
||||||
|
struct is_error_condition_enum<beast::websocket::condition>
|
||||||
|
{
|
||||||
|
static bool const value = true;
|
||||||
|
};
|
||||||
} // system
|
} // system
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
@@ -37,7 +43,7 @@ class error_codes : public error_category
|
|||||||
{
|
{
|
||||||
template<class = void>
|
template<class = void>
|
||||||
string_view
|
string_view
|
||||||
get_message(error ev) const;
|
message(error e) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const char*
|
const char*
|
||||||
@@ -49,7 +55,43 @@ public:
|
|||||||
std::string
|
std::string
|
||||||
message(int ev) const override
|
message(int ev) const override
|
||||||
{
|
{
|
||||||
return get_message(static_cast<error>(ev)).to_string();
|
return message(
|
||||||
|
static_cast<error>(ev)).to_string();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class error_conditions : public error_category
|
||||||
|
{
|
||||||
|
template<class = void>
|
||||||
|
string_view
|
||||||
|
message(condition c) const;
|
||||||
|
|
||||||
|
template<class = void>
|
||||||
|
bool
|
||||||
|
equivalent(error_code const& ec,
|
||||||
|
condition c) const noexcept;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const char*
|
||||||
|
name() const noexcept override
|
||||||
|
{
|
||||||
|
return "boost.beast.websocket";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
message(int cv) const override
|
||||||
|
{
|
||||||
|
return message(
|
||||||
|
static_cast<condition>(cv)).to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
equivalent(
|
||||||
|
error_code const& ec,
|
||||||
|
int cv) const noexcept
|
||||||
|
{
|
||||||
|
return equivalent(ec,
|
||||||
|
static_cast<condition>(cv));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,6 +106,15 @@ make_error_code(error e)
|
|||||||
std::underlying_type<error>::type>(e), cat};
|
std::underlying_type<error>::type>(e), cat};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
error_condition
|
||||||
|
make_error_condition(condition c)
|
||||||
|
{
|
||||||
|
static detail::error_conditions const cat{};
|
||||||
|
return error_condition{static_cast<
|
||||||
|
std::underlying_type<condition>::type>(c), cat};
|
||||||
|
}
|
||||||
|
|
||||||
} // websocket
|
} // websocket
|
||||||
} // beast
|
} // beast
|
||||||
|
|
||||||
|
@@ -37,6 +37,18 @@ enum class error
|
|||||||
partial_deflate_block
|
partial_deflate_block
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Error conditions corresponding to sets of error codes.
|
||||||
|
enum class condition
|
||||||
|
{
|
||||||
|
/** Handshake failed
|
||||||
|
|
||||||
|
This condition indicates that the WebSocket handshake failed. If
|
||||||
|
the corresponding HTTP response indicates the keep-alive behavior,
|
||||||
|
then the handshake may be reattempted.
|
||||||
|
*/
|
||||||
|
handshake_failed = 1,
|
||||||
|
};
|
||||||
|
|
||||||
} // websocket
|
} // websocket
|
||||||
} // beast
|
} // beast
|
||||||
} // boost
|
} // boost
|
||||||
|
@@ -18,9 +18,9 @@ namespace detail {
|
|||||||
template<class>
|
template<class>
|
||||||
string_view
|
string_view
|
||||||
error_codes::
|
error_codes::
|
||||||
get_message(error ev) const
|
message(error e) const
|
||||||
{
|
{
|
||||||
switch(ev)
|
switch(e)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case error::failed: return "WebSocket connection failed due to a protocol violation";
|
case error::failed: return "WebSocket connection failed due to a protocol violation";
|
||||||
@@ -31,6 +31,42 @@ get_message(error ev) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class>
|
||||||
|
string_view
|
||||||
|
error_conditions::
|
||||||
|
message(condition c) const
|
||||||
|
{
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case condition::handshake_failed: return "WebSocket upgrade handshake failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class>
|
||||||
|
bool
|
||||||
|
error_conditions::
|
||||||
|
equivalent(
|
||||||
|
error_code const& ec,
|
||||||
|
condition c) const noexcept
|
||||||
|
{
|
||||||
|
if(ec.category() == error_code{error{}}.category())
|
||||||
|
{
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case condition::handshake_failed:
|
||||||
|
switch(static_cast<error>(ec.value()))
|
||||||
|
{
|
||||||
|
case error::handshake_failed:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
} // websocket
|
} // websocket
|
||||||
} // beast
|
} // beast
|
||||||
|
@@ -20,23 +20,28 @@ namespace websocket {
|
|||||||
class error_test : public unit_test::suite
|
class error_test : public unit_test::suite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void check(error ev)
|
void check(error e)
|
||||||
{
|
{
|
||||||
auto const ec = make_error_code(ev);
|
auto const ec = make_error_code(e);
|
||||||
ec.category().name();
|
ec.category().name();
|
||||||
BEAST_EXPECT(! ec.message().empty());
|
BEAST_EXPECT(! ec.message().empty());
|
||||||
#if 0
|
#if 0
|
||||||
BEAST_EXPECT(std::addressof(ec.category()) ==
|
BEAST_EXPECT(std::addressof(ec.category()) ==
|
||||||
std::addressof(detail::get_error_category()));
|
std::addressof(detail::get_error_category()));
|
||||||
BEAST_EXPECT(detail::get_error_category().equivalent(
|
BEAST_EXPECT(detail::get_error_category().equivalent(
|
||||||
static_cast<std::underlying_type<error>::type>(ev),
|
static_cast<std::underlying_type<error>::type>(e),
|
||||||
ec.category().default_error_condition(
|
ec.category().default_error_condition(
|
||||||
static_cast<std::underlying_type<error>::type>(ev))));
|
static_cast<std::underlying_type<error>::type>(e))));
|
||||||
BEAST_EXPECT(detail::get_error_category().equivalent(
|
BEAST_EXPECT(detail::get_error_category().equivalent(
|
||||||
ec, static_cast<std::underlying_type<error>::type>(ev)));
|
ec, static_cast<std::underlying_type<error>::type>(e)));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check(error e, condition c)
|
||||||
|
{
|
||||||
|
BEAST_EXPECT(error_code{e} == c);
|
||||||
|
}
|
||||||
|
|
||||||
void run() override
|
void run() override
|
||||||
{
|
{
|
||||||
check(error::closed);
|
check(error::closed);
|
||||||
@@ -44,6 +49,8 @@ public:
|
|||||||
check(error::handshake_failed);
|
check(error::handshake_failed);
|
||||||
check(error::buffer_overflow);
|
check(error::buffer_overflow);
|
||||||
check(error::partial_deflate_block);
|
check(error::partial_deflate_block);
|
||||||
|
|
||||||
|
check(error::handshake_failed, condition::handshake_failed);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user