What's Changed
Breaking changes
WebSocketClient::connect()now returnshttplib::ws::Resultinstead ofbool(issue #2531).ws::Resultsupportsexplicit operator bool(),error(), and flattened accessors for the upgrade response (status(),headers(),get_header_value(),has_header()), plusssl_error()/ssl_backend_error()on SSL builds, matching howClientImpl/SSLClientalready reportResult. A newError::WebSocketHandshakecovers upgrade-validation failures (non-101 status, badSec-WebSocket-Accept, badUpgrade/Connectionheaders), and the handshake response is now parsed withdetail::parse_status_lineinstead of a"HTTP/1.1 101"substring match, so a non-101 response surfaces its real status and headers instead of being silently discarded. This is source-breaking only for code that assigns the result directly tobool(e.g.bool ok = cli.connect(););if (cli.connect())and gtest'sASSERT_TRUE/EXPECT_FALSEstill work via contextual conversion
WebSocketClient/SSLClient API alignment (closes #2531)
WebSocketClientgains the settersSSLClientalready had:enable_server_hostname_verification(), aPemMemoryclient-certificate constructor for mutual TLS, a(ca_cert_file_path, ca_cert_dir_path)overload forset_ca_cert_path(), and thestd::chrono::durationoverloads for its read/write/connection timeouts- The TLS session setup the two clients had each implemented separately is now one shared
detail::setup_client_tls_session(). As part of merging them,WebSocketClientmoves from callingtls::set_hostname()(which turns on OpenSSL's in-handshake verification) to SSLClient's SNI-then-post-handshake-verify approach, and the default Host/User-Agent header logic is shared between both clients as well - That merge exposed two backend-parity bugs, now fixed: on Mbed TLS and wolfSSL,
enable_server_hostname_verification(false)had no effect on DNS hosts, becausembedtls_ssl_set_hostname()andwolfSSL_check_domain_name()bind SNI and identity checking together; and Mbed TLS reported the genericError::SSLServerVerificationon a genuine hostname mismatch instead ofError::SSLServerHostnameVerification.set_sni()now takes averify_hostnameflag, andmap_mbedtls_error()inspects which verify flag actually fired
Bug fixes
- Match mount points on a path segment boundary in
handle_file_request()(#2529, thanks @metsw24-max). The mount point was compared as a plain byte prefix, soset_mount_point("/mount", "./www2")also served/mountdir/...out of./www2. Nothing escaped the base directory (is_valid_path()still rejects traversal), but a mount became reachable under URLs outside the prefix it declared, which is enough to slip past a reverse-proxy location, auth filter, or cache rule keyed on/mount/. A mount point ending in/(the root mount included) is unaffected - Drain the socket gracefully before closing it in
Server::process_and_close_socket()(#2534, root cause identified by @Hyukya in #2533). Closing a connection while the receive queue still has unread data, or bytes are still in flight, can make the OS send an abortive RST instead of a graceful FIN; on Windows this surfaces asWSAECONNABORTED/WSAECONNRESETon the peer's read, making an otherwise fully-written response look like a failed request. This was a likely contributor to the intermittentServerTest.HTTP2Magicfailures on the Windows CI job (#2533).detail::drain_and_close_socket()half-closes the write side, drains queued/in-flight bytes (bounded to 100ms / 1MB), then does the final shutdown+close
Development
- Document the WebSocketClient/SSLClient TLS parity gaps closed above in both READMEs, and add two Cookbook recipes (W05: wss:// TLS setup, W06: WebSocketClient's three timeouts) so this content lives in the WebSocket section instead of scattered asides in the mTLS/timeout/CA pages
- Document
Headers/Params/FormFields/FormFilesordering guarantees (added in v0.52.0) in the README, including the iterator-invalidation note - Auto-comment on issue #2533 with the run URL, commit, and failed-test lines when the windows-without-SSL job fails, to build up failure-pattern history while that flakiness is tracked down (temporary instrumentation)
- Fix a stale filename in the
example/server.ccheader comment (#2532, thanks @shaozk)
Full Changelog: v0.52.0...v0.53.0