forked from boostorg/beast
Refactor WebSocket errors (API Change):
fix #949 * New error codes are introduced for WebSocket failures * More verbose messages for error codes * Error codes are mapped to conditions for ease of testing * error::failed and error::handshake_failed are deprecated (don't use) Actions Required: * Code which explicitly compares error_code values against the constant `websocket::error::handshake_failed` should compare against `websocket::condition::handshake_failed` instead. * Code which explicitly compares error_code values against the constant `websocket::error::failed` should compare against `websocket::condition::protocol_violation` instead.
This commit is contained in:
1 parent
08a9ed4c25
commit
cc43b46c42
19 files changed
+705
-346
No files matched your search
@@ -406,7 +406,7 @@ public:
|
||||
catch(system_error const& e)
|
||||
{
|
||||
if( e.code() !=
|
||||
websocket::error::handshake_failed &&
|
||||
websocket::error::no_sec_key &&
|
||||
e.code() !=
|
||||
boost::asio::error::eof)
|
||||
throw;
|
||||
@@ -483,8 +483,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// wrong version
|
||||
check(error::handshake_failed,
|
||||
// bad version
|
||||
check(error::bad_http_version,
|
||||
"GET / HTTP/1.0\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
@@ -493,8 +493,8 @@ public:
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// wrong method
|
||||
check(error::handshake_failed,
|
||||
// bad method
|
||||
check(error::bad_method,
|
||||
"POST / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
@@ -503,8 +503,8 @@ public:
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// missing Host
|
||||
check(error::handshake_failed,
|
||||
// no Host
|
||||
check(error::no_host,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
"Connection: keep-alive,upgrade\r\n"
|
||||
@@ -512,46 +512,17 @@ public:
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// missing Sec-WebSocket-Key
|
||||
check(error::handshake_failed,
|
||||
// no Connection
|
||||
check(error::no_connection,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
"Connection: keep-alive,upgrade\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// missing Sec-WebSocket-Version
|
||||
check(error::handshake_failed,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
"Connection: keep-alive,upgrade\r\n"
|
||||
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// wrong Sec-WebSocket-Version
|
||||
check(error::handshake_failed,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
"Connection: keep-alive,upgrade\r\n"
|
||||
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
||||
"Sec-WebSocket-Version: 1\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// missing upgrade token
|
||||
check(error::handshake_failed,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: HTTP/2\r\n"
|
||||
"Connection: upgrade\r\n"
|
||||
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// missing connection token
|
||||
check(error::handshake_failed,
|
||||
// no Connection upgrade
|
||||
check(error::no_connection_upgrade,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
@@ -560,8 +531,36 @@ public:
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// oversize key
|
||||
check(error::handshake_failed,
|
||||
// no Upgrade
|
||||
check(error::no_upgrade,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Connection: upgrade\r\n"
|
||||
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// no Upgrade websocket
|
||||
check(error::no_upgrade_websocket,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: HTTP/2\r\n"
|
||||
"Connection: upgrade\r\n"
|
||||
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// no Sec-WebSocket-Key
|
||||
check(error::no_sec_key,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
"Connection: keep-alive,upgrade\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// bad Sec-WebSocket-Key
|
||||
check(error::bad_sec_key,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
@@ -570,8 +569,27 @@ public:
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// bad version
|
||||
check(error::handshake_failed,
|
||||
// no Sec-WebSocket-Version
|
||||
check(error::no_sec_version,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
"Connection: keep-alive,upgrade\r\n"
|
||||
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// bad Sec-WebSocket-Version
|
||||
check(error::bad_sec_version,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
"Connection: keep-alive,upgrade\r\n"
|
||||
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
||||
"Sec-WebSocket-Version: 1\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// bad Sec-WebSocket-Version
|
||||
check(error::bad_sec_version,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
@@ -580,15 +598,6 @@ public:
|
||||
"Sec-WebSocket-Version: 12\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// missing version
|
||||
check(error::handshake_failed,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"Host: localhost:80\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
"Connection: upgrade\r\n"
|
||||
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// valid request
|
||||
check({},
|
||||
"GET / HTTP/1.1\r\n"
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
catch(system_error const& se)
|
||||
{
|
||||
BEAST_EXPECTS(
|
||||
se.code() == error::failed,
|
||||
se.code() == error::bad_masked_frame,
|
||||
se.code().message());
|
||||
}
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
catch(system_error const& se)
|
||||
{
|
||||
BEAST_EXPECTS(
|
||||
se.code() == error::failed,
|
||||
se.code() == error::bad_close_size,
|
||||
se.code().message());
|
||||
}
|
||||
}
|
||||
@@ -292,7 +292,7 @@ public:
|
||||
ws.async_read(b,
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
if(ec != error::failed)
|
||||
if(ec != error::bad_control_fragment)
|
||||
BOOST_THROW_EXCEPTION(
|
||||
system_error{ec});
|
||||
BEAST_EXPECT(++count == 1);
|
||||
|
||||
@@ -25,32 +25,53 @@ public:
|
||||
auto const ec = make_error_code(e);
|
||||
ec.category().name();
|
||||
BEAST_EXPECT(! ec.message().empty());
|
||||
#if 0
|
||||
BEAST_EXPECT(std::addressof(ec.category()) ==
|
||||
std::addressof(detail::get_error_category()));
|
||||
BEAST_EXPECT(detail::get_error_category().equivalent(
|
||||
static_cast<std::underlying_type<error>::type>(e),
|
||||
ec.category().default_error_condition(
|
||||
static_cast<std::underlying_type<error>::type>(e))));
|
||||
BEAST_EXPECT(detail::get_error_category().equivalent(
|
||||
ec, static_cast<std::underlying_type<error>::type>(e)));
|
||||
#endif
|
||||
BEAST_EXPECT(ec != condition::handshake_failed);
|
||||
BEAST_EXPECT(ec != condition::protocol_violation);
|
||||
}
|
||||
|
||||
void check(error e, condition c)
|
||||
void check(condition c, error e)
|
||||
{
|
||||
BEAST_EXPECT(error_code{e} == c);
|
||||
auto const ec = make_error_code(e);
|
||||
BEAST_EXPECT(ec.category().name() != nullptr);
|
||||
BEAST_EXPECT(! ec.message().empty());
|
||||
BEAST_EXPECT(ec == c);
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
check(error::closed);
|
||||
check(error::failed);
|
||||
check(error::handshake_failed);
|
||||
check(error::buffer_overflow);
|
||||
check(error::partial_deflate_block);
|
||||
check(error::message_too_big);
|
||||
|
||||
check(error::handshake_failed, condition::handshake_failed);
|
||||
check(condition::protocol_violation, error::bad_opcode);
|
||||
check(condition::protocol_violation, error::bad_data_frame);
|
||||
check(condition::protocol_violation, error::bad_continuation);
|
||||
check(condition::protocol_violation, error::bad_reserved_bits);
|
||||
check(condition::protocol_violation, error::bad_control_fragment);
|
||||
check(condition::protocol_violation, error::bad_control_size);
|
||||
check(condition::protocol_violation, error::bad_unmasked_frame);
|
||||
check(condition::protocol_violation, error::bad_masked_frame);
|
||||
check(condition::protocol_violation, error::bad_size);
|
||||
check(condition::protocol_violation, error::bad_frame_payload);
|
||||
check(condition::protocol_violation, error::bad_close_code);
|
||||
check(condition::protocol_violation, error::bad_close_size);
|
||||
check(condition::protocol_violation, error::bad_close_payload);
|
||||
|
||||
check(condition::handshake_failed, error::bad_http_version);
|
||||
check(condition::handshake_failed, error::bad_method);
|
||||
check(condition::handshake_failed, error::no_host);
|
||||
check(condition::handshake_failed, error::no_connection);
|
||||
check(condition::handshake_failed, error::no_connection_upgrade);
|
||||
check(condition::handshake_failed, error::no_upgrade);
|
||||
check(condition::handshake_failed, error::no_upgrade_websocket);
|
||||
check(condition::handshake_failed, error::no_sec_key);
|
||||
check(condition::handshake_failed, error::bad_sec_key);
|
||||
check(condition::handshake_failed, error::no_sec_version);
|
||||
check(condition::handshake_failed, error::bad_sec_version);
|
||||
check(condition::handshake_failed, error::no_sec_accept);
|
||||
check(condition::handshake_failed, error::bad_sec_accept);
|
||||
check(condition::handshake_failed, error::upgrade_declined);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
});
|
||||
|
||||
auto const check =
|
||||
[&](std::string const& s)
|
||||
[&](error e, std::string const& s)
|
||||
{
|
||||
stream<test::stream> ws{ioc_};
|
||||
auto tr = connect(ws.next_layer());
|
||||
@@ -150,11 +150,11 @@ public:
|
||||
}
|
||||
catch(system_error const& se)
|
||||
{
|
||||
BEAST_EXPECT(se.code() == error::handshake_failed);
|
||||
BEAST_EXPECTS(se.code() == e, se.what());
|
||||
}
|
||||
};
|
||||
// wrong HTTP version
|
||||
check(
|
||||
// bad HTTP version
|
||||
check(error::bad_http_version,
|
||||
"HTTP/1.0 101 Switching Protocols\r\n"
|
||||
"Server: beast\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
@@ -163,28 +163,17 @@ public:
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// wrong status
|
||||
check(
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Server: beast\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
"Connection: upgrade\r\n"
|
||||
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// missing upgrade token
|
||||
check(
|
||||
// no Connection
|
||||
check(error::no_connection,
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Server: beast\r\n"
|
||||
"Upgrade: HTTP/2\r\n"
|
||||
"Connection: upgrade\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// missing connection token
|
||||
check(
|
||||
// no Connection upgrade
|
||||
check(error::no_connection_upgrade,
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Server: beast\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
@@ -193,8 +182,27 @@ public:
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// missing accept key
|
||||
check(
|
||||
// no Upgrade
|
||||
check(error::no_upgrade,
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Server: beast\r\n"
|
||||
"Connection: upgrade\r\n"
|
||||
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// no Upgrade websocket
|
||||
check(error::no_upgrade_websocket,
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Server: beast\r\n"
|
||||
"Upgrade: HTTP/2\r\n"
|
||||
"Connection: upgrade\r\n"
|
||||
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// no Sec-WebSocket-Accept
|
||||
check(error::no_sec_accept,
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Server: beast\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
@@ -202,8 +210,8 @@ public:
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// wrong accept key
|
||||
check(
|
||||
// bad Sec-WebSocket-Accept
|
||||
check(error::bad_sec_accept,
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Server: beast\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
@@ -212,6 +220,16 @@ public:
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
// declined
|
||||
check(error::upgrade_declined,
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Server: beast\r\n"
|
||||
"Upgrade: WebSocket\r\n"
|
||||
"Connection: upgrade\r\n"
|
||||
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"\r\n"
|
||||
);
|
||||
}
|
||||
|
||||
// Compression Extensions for WebSocket
|
||||
|
||||
@@ -218,7 +218,7 @@ public:
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
++count;
|
||||
if(ec != error::failed)
|
||||
if(ec != error::bad_control_fragment)
|
||||
BOOST_THROW_EXCEPTION(
|
||||
system_error{ec});
|
||||
});
|
||||
|
||||
@@ -317,7 +317,7 @@ public:
|
||||
{
|
||||
put(ws.next_layer().buffer(), cbuf(
|
||||
0x88, 0x02, 0x03, 0xed));
|
||||
doFailTest(w, ws, error::failed);
|
||||
doFailTest(w, ws, error::bad_close_code);
|
||||
});
|
||||
|
||||
// message size above 2^64
|
||||
@@ -337,7 +337,7 @@ public:
|
||||
{
|
||||
ws.read_message_max(1);
|
||||
w.write(ws, sbuf("**"));
|
||||
doFailTest(w, ws, error::failed);
|
||||
doFailTest(w, ws, error::message_too_big);
|
||||
});
|
||||
|
||||
// bad utf8
|
||||
@@ -346,7 +346,7 @@ public:
|
||||
{
|
||||
put(ws.next_layer().buffer(), cbuf(
|
||||
0x81, 0x06, 0x03, 0xea, 0xf0, 0x28, 0x8c, 0xbc));
|
||||
doFailTest(w, ws, error::failed);
|
||||
doFailTest(w, ws, error::bad_frame_payload);
|
||||
});
|
||||
|
||||
// incomplete utf8
|
||||
@@ -378,7 +378,7 @@ public:
|
||||
}
|
||||
catch(system_error const& se)
|
||||
{
|
||||
if(se.code() != error::failed)
|
||||
if(se.code() != error::bad_frame_payload)
|
||||
throw;
|
||||
}
|
||||
});
|
||||
@@ -409,15 +409,15 @@ public:
|
||||
};
|
||||
|
||||
// payload length 1
|
||||
check(error::failed,
|
||||
check(error::bad_close_size,
|
||||
"\x88\x01\x01");
|
||||
|
||||
// invalid close code 1005
|
||||
check(error::failed,
|
||||
check(error::bad_close_code,
|
||||
"\x88\x02\x03\xed");
|
||||
|
||||
// invalid utf8
|
||||
check(error::failed,
|
||||
check(error::bad_close_payload,
|
||||
"\x88\x06\xfc\x15\x0f\xd7\x73\x43");
|
||||
|
||||
// good utf8
|
||||
@@ -446,7 +446,7 @@ public:
|
||||
std::string const s = std::string(128, '*');
|
||||
w.write(ws, buffer(s));
|
||||
ws.read_message_max(32);
|
||||
doFailTest(w, ws, error::failed);
|
||||
doFailTest(w, ws, error::message_too_big);
|
||||
});
|
||||
|
||||
// invalid inflate block
|
||||
@@ -656,15 +656,15 @@ public:
|
||||
};
|
||||
|
||||
// payload length 1
|
||||
check(error::failed,
|
||||
check(error::bad_close_size,
|
||||
"\x88\x01\x01");
|
||||
|
||||
// invalid close code 1005
|
||||
check(error::failed,
|
||||
check(error::bad_close_code,
|
||||
"\x88\x02\x03\xed");
|
||||
|
||||
// invalid utf8
|
||||
check(error::failed,
|
||||
check(error::bad_close_payload,
|
||||
"\x88\x06\xfc\x15\x0f\xd7\x73\x43");
|
||||
|
||||
// good utf8
|
||||
|
||||
Reference in new issue
Block a user