mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-08-22 01:55:00 +00: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:
@@ -151,8 +151,15 @@ explicit WebSocketClient(const std::string &scheme_host_port_path,
|
||||
// Check if the URL was parsed successfully
|
||||
bool is_valid() const;
|
||||
|
||||
// Connect (performs HTTP upgrade handshake)
|
||||
bool connect();
|
||||
// Connect (performs HTTP upgrade handshake). The returned Result is truthy
|
||||
// only when the handshake fully succeeded; on failure it describes what went
|
||||
// wrong:
|
||||
// res.error() httplib::Error identifying the failing layer
|
||||
// res.status() HTTP status of the upgrade response (-1 if none)
|
||||
// res.headers() headers of the upgrade response
|
||||
// res.ssl_error() TLS error detail (wss://, SSL builds only)
|
||||
// res.ssl_backend_error() backend-specific TLS error code (SSL builds only)
|
||||
Result connect();
|
||||
|
||||
// Get the subprotocol selected by the server (empty if none)
|
||||
const std::string &subprotocol() const;
|
||||
@@ -221,6 +228,26 @@ if (ws.connect()) {
|
||||
}
|
||||
```
|
||||
|
||||
### Inspecting Connection Failures
|
||||
|
||||
`connect()` returns a `Result` that tells you why a connection attempt failed.
|
||||
`error()` distinguishes network problems (`Connection`, `ConnectionTimeout`),
|
||||
TLS problems (`SSLConnection`, `SSLServerVerification`,
|
||||
`SSLServerHostnameVerification`), and upgrade rejections
|
||||
(`WebSocketHandshake`). When the server answered with something other than
|
||||
`101 Switching Protocols`, `status()` and `headers()` carry that response:
|
||||
|
||||
```cpp
|
||||
auto res = ws.connect();
|
||||
if (!res) {
|
||||
std::cerr << "connect failed: " << httplib::to_string(res.error()) << std::endl;
|
||||
if (res.status() != -1) {
|
||||
// The server responded but refused the upgrade (e.g. 401, 404)
|
||||
std::cerr << "HTTP status: " << res.status() << std::endl;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Text and Binary Messages
|
||||
|
||||
Check the `ReadResult` return value to distinguish between text and binary:
|
||||
|
||||
Reference in New Issue
Block a user