mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-01 05:02:29 +07:00
Return ws::Result from WebSocketClient::connect() instead of bool
Issue #2531 asked for connect() to expose error detail the way ClientImpl/SSLClient do via Result, instead of collapsing every failure into a bare bool. The groundwork (detail::ClientTlsSessionError) was already laid during the WebSocketClient/SSLClient dedup but left unwired. - Add httplib::ws::Result: explicit operator bool(), error(), and flattened upgrade-response accessors (status(), headers(), get_header_value(), has_header()); ssl_error()/ssl_backend_error() on SSL builds. - Add Error::WebSocketHandshake for upgrade-validation failures (non-101 status, bad Sec-WebSocket-Accept, bad Upgrade/Connection headers). - Extract detail::parse_status_line from ClientImpl::read_response_line and reuse it in read_websocket_upgrade_response, replacing the previous "HTTP/1.1 101" substring match with a proper parse. Non-101 responses now surface their status and headers instead of being read and discarded. - Wire WebSocketClient::create_stream() to capture ClientTlsSessionError so TLS failures (SSLServerVerification, SSLServerHostnameVerification, ...) reach the caller with backend error codes. - Update tests and README-websocket.md accordingly. This is a source-breaking change for callers that assign the result to bool (e.g. bool ok = cli.connect();); if (cli.connect()) and gtest's ASSERT_TRUE/EXPECT_FALSE(...) macros are unaffected since operator bool still participates in contextual conversion.
This commit is contained in:
+35
-5
@@ -19896,7 +19896,11 @@ TEST(WebSocketTest, ConnectAndDisconnect) {
|
||||
svr.wait_until_ready();
|
||||
|
||||
ws::WebSocketClient client("ws://localhost:" + std::to_string(port) + "/ws");
|
||||
ASSERT_TRUE(client.connect());
|
||||
auto res = client.connect();
|
||||
ASSERT_TRUE(res);
|
||||
EXPECT_EQ(Error::Success, res.error());
|
||||
EXPECT_EQ(StatusCode::SwitchingProtocol_101, res.status());
|
||||
EXPECT_TRUE(res.has_header("Sec-WebSocket-Accept"));
|
||||
EXPECT_TRUE(client.is_open());
|
||||
client.close();
|
||||
EXPECT_FALSE(client.is_open());
|
||||
@@ -19972,7 +19976,23 @@ TEST(WebSocketTest, UnsupportedScheme) {
|
||||
TEST(WebSocketTest, ConnectWhenInvalid) {
|
||||
ws::WebSocketClient ws("not a valid url");
|
||||
EXPECT_FALSE(ws.is_valid());
|
||||
EXPECT_FALSE(ws.connect());
|
||||
auto res = ws.connect();
|
||||
EXPECT_FALSE(res);
|
||||
EXPECT_EQ(Error::Connection, res.error());
|
||||
EXPECT_EQ(-1, res.status());
|
||||
}
|
||||
|
||||
TEST(WebSocketTest, ConnectRefusedReportsError) {
|
||||
// Grab a port that is free, then close it again so nothing listens there
|
||||
Server svr;
|
||||
auto port = svr.bind_to_any_port(HOST);
|
||||
svr.stop();
|
||||
|
||||
ws::WebSocketClient client("ws://localhost:" + std::to_string(port) + "/ws");
|
||||
auto res = client.connect();
|
||||
ASSERT_FALSE(res);
|
||||
EXPECT_EQ(Error::Connection, res.error());
|
||||
EXPECT_EQ(-1, res.status());
|
||||
}
|
||||
|
||||
TEST(WebSocketTest, DefaultPort) {
|
||||
@@ -20368,7 +20388,10 @@ TEST_F(WebSocketIntegrationTest, MaxPayloadAtLimit) {
|
||||
TEST_F(WebSocketIntegrationTest, ConnectToInvalidPath) {
|
||||
ws::WebSocketClient client("ws://localhost:" + std::to_string(port_) +
|
||||
"/nonexistent");
|
||||
EXPECT_FALSE(client.connect());
|
||||
auto res = client.connect();
|
||||
EXPECT_FALSE(res);
|
||||
EXPECT_EQ(Error::WebSocketHandshake, res.error());
|
||||
EXPECT_EQ(StatusCode::NotFound_404, res.status());
|
||||
EXPECT_FALSE(client.is_open());
|
||||
}
|
||||
|
||||
@@ -20955,7 +20978,11 @@ TEST_F(WebSocketSSLCATest, WrongCustomCaFailsVerification) {
|
||||
read_file(CLIENT_CA_CERT_FILE, cert);
|
||||
client.load_ca_cert_store(cert.c_str(), cert.size());
|
||||
|
||||
ASSERT_FALSE(client.connect());
|
||||
auto res = client.connect();
|
||||
ASSERT_FALSE(res);
|
||||
EXPECT_EQ(Error::SSLServerVerification, res.error());
|
||||
EXPECT_EQ(-1, res.status());
|
||||
EXPECT_NE(0u, res.ssl_backend_error());
|
||||
}
|
||||
|
||||
// The same CA as a file path rather than PEM in memory
|
||||
@@ -21090,7 +21117,10 @@ TEST_F(WebSocketSSLDnsHostTest, TrustedChainWrongNameFails) {
|
||||
ws::WebSocketClient client(url());
|
||||
client.set_ca_cert_path(SERVER_CERT_FILE);
|
||||
|
||||
ASSERT_FALSE(client.connect());
|
||||
auto res = client.connect();
|
||||
ASSERT_FALSE(res);
|
||||
EXPECT_EQ(Error::SSLServerHostnameVerification, res.error());
|
||||
EXPECT_EQ(-1, res.status());
|
||||
}
|
||||
|
||||
// A CA that did not sign the server certificate fails the chain, even though
|
||||
|
||||
Reference in New Issue
Block a user