Skip to content

WebSocket Compression support#965

Open
jhugard wants to merge 25 commits intomainfrom
websocket-compression
Open

WebSocket Compression support#965
jhugard wants to merge 25 commits intomainfrom
websocket-compression

Conversation

@jhugard
Copy link
Copy Markdown
Collaborator

@jhugard jhugard commented Apr 28, 2026

Summary

Notes:

  1. NetworkState owns a single built-in WebSocket provider.
  2. Windows-family mixed-backend behavior lives in WinHttpHybrid_WebSocketProvider.
  3. The primary public control surface on the built-in implementations that expose the new behavior is HCWebSocketSetOptions(...).
  4. LegacySemantics explicitly preserves the existing behavior; non-legacy options select deterministic behavior, and compression requests route to the compression-capable path where needed.

This PR adds first-class WebSocket compression support to libHttpClient and includes the build, transport, API, and validation changes needed to use it safely on the important built-in paths.

At a high level, this PR:

  • adds the dependency and build plumbing needed for built-in compression support across Linux, macOS, iOS, and the Windows-family paths that require extra transport support
  • introduces Windows-family hybrid routing so Win32 and GDK can request compression without changing the caller-facing control surface
  • adds HCWebSocketSetOptions(...) and HCWebSocketOptions as the primary public control surface for legacy preservation, deterministic behavior selection, and compression negotiation on the built-in implementations that expose that surface
  • explicitly separates legacy behavior from a deterministic, message-oriented contract instead of keying behavior selection on compression alone
  • makes deterministic behavior reject fragment callback registration and reject oversize receives with HCWebSocketCloseStatus::TooLarge socket close, effectively deprecating the fragment-handling APIs on the built-in implementations that expose the new options surface and enforcing consistent semantics across platforms
  • adds upgrade-response header inspection, disconnect-with-status, and related WebSocket control improvements
  • adds focused Windows compression coverage and unit-test updates that lock down the final behavior, including deterministic oversize handling without compression
  • folds in the clean-branch fixes for websocketpp close-status handling and websocket async queue topology, plus the post-rebase connect-completion, no-websockets build-variant, strict-mode WinTLS build, and Apple strict-warning wrapper repairs

Why this is needed

The motivating problem is straightforward:

  • Some applications depend on compression being broadly available
  • libHttpClient does not provide compression negotiation and control, nor close status control, nor response header access
  • WinHTTP WebSockets do not directly support RFC 7692 permessage-deflate
  • Existing (legacy) handling of over-sized messages is lossy, as well as inconsistent across platforms
  • Win32 desktop and GDK currently default to WinHTTP for built-in WebSockets, so they need extra routing work to participate in that broader compression-capable path without also creating a second behavioral contract for deterministic mode

This PR closes that gap by adding compression-capable built-in WebSocket support across Linux, macOS, iOS, and the Windows-family paths that need it, while keeping the caller-facing configuration surface backend-agnostic and the deterministic receive contract consistent.

Behavior model

Public options surface

  • HCWebSocketSetOptions(...) is the primary control surface on the built-in implementations that expose deterministic behavior and compression negotiation
  • HCWebSocketOptions::LegacySemantics explicitly preserves the existing legacy behavior by retaining the existing provider behavior and semantics
  • HCWebSocketOptions::None selects deterministic behavior without requesting compression
  • HCWebSocketOptions::RequestCompression selects deterministic behavior and requests permessage-deflate
  • CompressionServerNoContextTakeover and CompressionClientNoContextTakeover refine the compression request and require RequestCompression

Legacy behavior

Existing behavior, aka legacy behavior, on Win32 / GDK differs from other platforms:

  • Once an incoming payload exceeds the receive buffer (20KB by default), WinHTTP starts forwarding partial chunks through a raw-byte binary fragment path
  • Without a caller-registered fragment handler, the fallback is lossy and misleading instead of message-oriented:
    • oversized binary messages are surfaced as multiple partial binary whole-message callbacks
    • oversized UTF-8 messages surface as binary whole-message callbacks for the earlier chunks plus a final text whole-message callback for only the residual tail
    • if no binary whole-message callback is installed, those earlier oversized text chunks are dropped entirely and instead deliver only a final text whole-message callback for only the residual tail
  • With a fragment handler installed, receive processing becomes fragmented:
    • undersized binary and UTF-8 messages are delivered through their normal respective message delivery callbacks
    • both oversized binary and oversized UTF-8 messages are delivered to the fragment handler chunk-by-chunk, without distinguishing between binary and text messages
  • No means is provided to notify the server when a too-large message is received

Other platforms:

  • default to ~32MB max receive buffer size, with no functioning means to adjust that size
  • automatically close the socket with a too-large status if an oversized message is detected
  • do not provide fragment handling callback support

Legacy versus deterministic behavior

  • If HCWebSocketSetOptions(...) is never called, Win32 and GDK stay on the legacy WinHTTP-facing behavior
  • LegacySemantics is an explicit no-op that preserves that same behavior
  • Non-legacy options select deterministic behavior on supported paths
  • Deterministic behavior provides a single message-oriented contract across those supported built-in paths: fragment callback registration is rejected, fragment callback delivery does not occur, and inbound message-size enforcement is consistent
  • Deterministic behavior treats HCWebSocketSetMaxReceiveBufferSize(...) as a hard inbound message-size cap; when a message exceeds that cap, the socket is closed with HCWebSocketCloseStatus::TooLarge (1009)
  • If the max receive buffer is not set explicitly before connect, deterministic behavior uses the default 32,000,000 byte limit
  • On Win32 and GDK, HCWebSocketOptions::None keeps the existing WinHTTP transport while enforcing that same deterministic hard-cap behavior; compression requests route through the hybrid provider to the compression-capable path
  • Android does not expose HCWebSocketSetOptions(...) or HCWebSocketSetMaxReceiveBufferSize(...), as the OkHttp provider automatically negotiates compression and has a fixed ~32MB message limit
  • WinRT / UWP remains on the existing MessageWebSocket path and is out of scope for this compression work: this PR does not add compression negotiation there, and the deterministic HCWebSocketSetOptions(...) / hard-cap receive-limit behavior does not apply to that provider

What changed

Build and dependency groundwork

  • refreshed the dependency graph needed for the websocketpp transport, including asio, websocketpp, and boost-wintls
  • moved asio forward to the newest revision that still preserves the public APIs boost-wintls depends on, instead of taking the latest upstream breaking API removals in the same change
  • updated the Windows shared project items, solution files, package metadata, Linux build helpers, and Apple Xcode project so the new transport builds through the existing entry points
  • hardened the Linux helper scripts for containerized dependency installation, OpenSSL install, and cURL artifact export on bind-mounted workspaces
  • disabled optional libzstd autodetection in the Linux vendored cURL helper so static CI-style builds do not pick up an undeclared zstd link dependency
  • aligned the Apple Xcode minizip wiring with the Linux and Android build definitions by adding ioapi.c and the contrib/minizip include path
  • localized Apple Clang -Wdocumentation suppression around the vendored websocketpp permessage-deflate include so strict Xcode warning-as-error builds do not fail on a third-party documentation comment defect
  • enabled Linux and Apple build-time plumbing for WebSocket compression while preserving explicit build control

Windows hybrid routing and receive-limit unification

  • added the websocketpp provider and the supporting WinTLS transport adapter
  • introduced WinHttpHybrid_WebSocketProvider so Windows-family backend selection stays inside a concrete provider instead of leaking into global selector state
  • wired Win32 and GDK to route compression requests through the compression-capable transport while leaving deterministic non-compression connections on WinHTTP
  • updated the WinHTTP receive path so deterministic mode enforces the same hard inbound message-size cap and TooLarge close behavior as the other built-in deterministic paths
  • updated related WinHTTP, WinRT, Apple, and NetworkState plumbing so the new transport integrates with the existing lifecycle and shutdown paths

Explicit WebSocket options semantics

  • primary public control surface on the applicable built-in implementations is HCWebSocketSetOptions(...), with HCWebSocketOptions providing the control knobs
  • handle-level state tracks whether options and max receive buffer values were set explicitly before connect
  • preserved legacy behavior explicitly through LegacySemantics and tightened deterministic behavior across the supported built-in paths
  • updated exports, docs, and platform-facing surfaces to match the new options contract

Samples and validation coverage

  • added a local WebSocket echo-server sample used by the validation harnesses
  • added dedicated Win32 compression coverage projects and certificate validation coverage
  • added unit coverage around options validation, LegacySemantics, fragment-handler rejection, and explicit max-receive-buffer behavior

Current websocketpp scale posture

  • This branch does not modify the upstream websocketpp provider-owned background thread per WebSocket (m_websocketThread = std::thread(...) and std::thread m_websocketThread)
  • This places severe limits on how many client connections can be made per process, due to thread thrashing and other internal contention
  • The Win32/GDK uncompressed WinHTTP websocket path was tested up to 12K clients in a single process, without issue
  • However, all paths using the websocketpp provider, including the Win32/GDK compressed path, are likely to start failing due to contention at around 5K and have high CPU utilization
  • Adjusting the websocketpp architecture for better scalability is out-of-scope for this PR, but has been tested as feasible as a basis for an independent PR

Review feedback fixes

  • added boost-wintls to NOTICE.txt and cgmanifest.json; corrected the stale asio commit hash in both files
  • added DEFINE_ENUM_FLAG_OPERATORS(HCWebSocketOptions) so callers can combine flags with | without casting through uint32_t
  • simplified the remaining low-risk HCWebSocketOptions flag-handling sites in the runtime and tests now that the enum flag operators exist; removed leftover test-only helper functions and replaced the remaining raw legacy-options equality check
  • added m_stateMutex lock to SetOptions() and SetPingInterval() for consistency with the locking pattern in SetMaxReceiveBufferSize() and the other pre-connect setters
  • changed GetResponseHeaderAtIndex() to return E_INVALIDARG on out-of-range index, consistent with the existing HCHttpCallResponseGetHeaderAtIndex() contract
  • added Win32 .vcxitems.filters entries for the new websocketpp and hybrid-routing files
  • added documentation comments for the intentional raw new in wintls_socket.hpp, the detached-joiner shutdown fallback, and the duplicated proxy URI parser
  • clarified the public httpClient.h and README wording around LegacySemantics, deterministic behavior, and receive-limit behavior; aligned the related WinHTTP wording/flow to match
  • repaired a late merge regression in WebSocket connect completion handling
  • fixed the Win32 and GDK no-websockets export surfaces and promoted Linux HC_NOWEBSOCKETS to a first-class build option so the post-rebase no-websockets variants stay buildable
  • made the WinHttpHybrid_WebSocketProvider provider-selection helpers const in response to late review feedback
  • fixed a latent WinTLS websocketpp translate_ec(...) compile issue so the branch still builds cleanly under stricter MSVC conformance modes used by downstream consumers
  • moved the Release /OPT:NOREF intent for the Win32 compression test executables into the linker settings and paired it with plain /LTCG so the setting actually takes effect
  • rejected HCWebSocketSetMaxReceiveBufferSize(0) with E_INVALIDARG to avoid invalid deterministic receive-buffer states
  • removed the non-GDK always-true curl_multi_poll warning while preserving the GDK dynamic-loader fallback behavior

Validation performed

Local Windows build matrix

  • built libHttpClient.vs2022.sln for Debug|x64
  • built libHttpClient.vs2022.sln for Release|x64
  • built libHttpClient.vs2022.sln for Debug|x86
  • built libHttpClient.vs2022.sln for Release|x86
  • built libHttpClient.vs2022.sln for Debug|ARM64
  • Release|ARM64 is blocked locally by missing Spectre-mitigated libraries (MSB8040)
  • Debug|Gaming.Desktop.x64 and Release|Gaming.Desktop.x64 are blocked locally by missing Microsoft GDK integration and missing local v143 GDK toolset support (MSB8020)

Local Windows test runs

  • ran the full x64 Debug TE suite via vstest.console.exe
  • all WebSocket unit coverage passed in that run, including the options and deterministic-semantics tests
  • local TE noise remains in TaskQueueTests, as expected
  • AsyncBlockTests::VerifyFailureInDoWork failed once in the full TE run but passed immediately when rerun in isolation
  • built and ran Tests\WebSocketCompression\WebSocketCompressionTests.Win32.vcxproj
  • validated deterministic oversize-close behavior, permessage-deflate negotiation, and the no-context-takeover combinations successfully against the local echo server
  • built and ran Tests\WebSocketCompression\WebSocketCompressionIntegrationTests.Win32.vcxproj
  • validated trusted localhost, wrong-host CERT_E_CN_NO_MATCH, untrusted-root CERT_E_UNTRUSTEDROOT, and refused-connect diagnostics successfully

Linux and Android probe results

  • Linux Debug builds completed for libHttpClient.Linux.so and WebSocketCompressionTests.Linux
  • ran WebSocketCompressionTests.Linux directly under WSL and validated both the deterministic non-compression path (HCWebSocketOptions::None, including the TooLarge oversize close) and the negotiated compression path (RequestCompression plus the no-context-takeover variants) successfully against the local echo server
  • Local machine does not currently have a configured Android SDK or NDK, so assembleDebug could not start

Post-rebase Windows and Linux variant checks

  • built Build\libHttpClient.Win32\libHttpClient.Win32.vcxproj for Release|x64
  • ran Out\x64\Release\WebSocketCompressionTests.Win32\WebSocketCompressionTests.Win32.exe successfully
  • built Build\libHttpClient.Win32\libHttpClient.Win32.vcxproj for Release|x64 with /p:HCEnableWebSocketCompression=false
  • built Build\libHttpClient.Win32\libHttpClient.Win32.vcxproj for Release|x64 with /p:HCNoWebSockets=true
  • built Tests\WebSocketCompression\WebSocketCompressionTests.Win32.vcxproj for Release|x64 with the Release /OPT:NOREF + /LTCG follow-up applied
  • built Tests\WebSocketCompression\WebSocketCompressionIntegrationTests.Win32.vcxproj for Release|x64 with the same Release linker follow-up applied
  • manually compiled Source\WebSocket\Websocketpp\websocketpp_websocket.cpp under /permissive- against the branch include/define set to confirm the WinTLS transport also builds under stricter MSVC conformance settings
  • ran Build\libHttpClient.Linux\libHttpClient_Linux.bash --install-dependencies -c Release successfully inside an ubuntu:22.04 container
  • built the Linux Release shared library with the default compression-enabled configuration and ran ctest --output-on-failure -R websocket-compression-linux successfully under WSL
  • reran the Linux Release helper build after the CurlMulti.cpp cleanup; WebSocketCompressionTests.Linux still linked successfully and the non-GDK warning disappeared
  • built the Linux Release shared library with HC_ENABLE_WEBSOCKET_COMPRESSION=OFF
  • built the Linux Release shared library with HC_NOWEBSOCKETS=1

Not validated locally

  • broader Linux matrix coverage beyond the WSL Debug runtime validation above was not rerun locally
  • The latest iOS CI compile failure was diagnosed from the upstream log and fixed by localizing the websocketpp -Wdocumentation suppression in the configured permessage-deflate wrapper, but that rerun has not been observed locally
  • GDK compilation, including the post-rebase no-websockets export-surface follow-up, is blocked locally by missing toolchain components, as noted above

Scope boundary for this PR

  • this PR does not patch websocketpp itself
  • this PR keeps the Windows mixed-backend decision inside the built-in provider layer rather than surfacing backend selection to callers
  • this PR intentionally does not preserve the old WinHTTP oversized-fragment behavior once callers opt into deterministic behavior
  • this PR does not expose the new options surface on Android, which negotiates compression by default and has a fixed ~32MB maximum message size
  • this PR does not add compression support or deterministic receive-limit enforcement to WinRT / UWP, which continues to use the existing MessageWebSocket provider behavior
  • this PR does not move Android onto websocketpp; the built-in Android provider remains the existing OkHttp-based implementation

Risks / review focus

Internal review should focus especially on:

  • whether the websocketpp + WinTLS dependency footprint is acceptable for this PR
  • whether WinHttpHybrid_WebSocketProvider is the right long-term ownership point for Windows-family mixed-backend behavior
  • whether HCWebSocketSetOptions(...) is the right caller contract for expressing both legacy preservation and deterministic behavior selection
  • whether the deterministic hard-cap behavior is the right replacement for the older fragment-overflow behavior when callers opt out of legacy semantics
  • whether the Android posture of omitting the new options and max-buffer APIs is the right product choice
  • whether the current compression and certificate coverage is sufficient without additional semantics-specific coverage

Suggested review path

  1. 7a3ef9bAdd WebSocket compression build and dependency plumbing
    Dependency updates, shared-project wiring, Linux and Apple compression build plumbing, and solution/package metadata changes.

  2. b739781Introduce the websocketpp-backed Windows transport
    The websocketpp provider, WinTLS transport adapter, WinHTTP hybrid routing, and the platform-specific wiring for Win32 and GDK.

  3. 5698ddbReplace compression flags with explicit WebSocket options
    The HCWebSocketSetOptions(...) surface, LegacySemantics, deterministic behavior, Android surface cleanup, and the export/documentation updates.

  4. 818751bAdd WebSocket samples and compression validation coverage
    The echo-server sample, compression and certificate integration coverage, and the unit-test updates that lock down the final behavior.

  5. a593c5bUnify deterministic WebSocket behavior on WinHTTP
    The WinHTTP deterministic receive-limit enforcement, hybrid routing adjustment for non-compression deterministic mode, deterministic oversize validation updates, and the final README/public documentation alignment.

  6. 0fa4a01Update third-party compliance metadata (AI Review)
    Adds boost-wintls to NOTICE.txt and cgmanifest.json; corrects the stale asio commit hash.

  7. 0a76816Fix WebSocket API issues (AI Review)
    Adds DEFINE_ENUM_FLAG_OPERATORS, mutex consistency for SetOptions/SetPingInterval, E_INVALIDARG for out-of-range header index.

  8. 81436e8Build hygiene and documentation comments (AI Review)
    Win32 .vcxitems.filters entries, documentation comments for design choices and intentional duplication.

  9. d1e0f90Simplify WebSocket option flag handling (AI Review)
    Low-risk cleanup of the remaining option-flag handling in the runtime and tests after the enum flag operators landed.

  10. b1b8d97Handle websocketpp close status consistently
    Aligns websocketpp close-status handling with the rest of the deterministic behavior and removes a late clean-branch inconsistency in the websocketpp path.

  11. c475339Fix websocket async queue topology
    Keeps the clean branch's websocket async queue usage aligned with the intended control flow.

  12. 10aed2dAddress PR feedback on WebSocket semantics docs
    Clarifies the public httpClient.h and README wording around LegacySemantics, deterministic behavior, and receive-limit expectations; includes the small aligned WinHTTP wording/flow cleanup.

  13. 5ba0134Fix websocket connect completion merge
    Repairs a late merge regression in hcwebsocket.cpp so connect completion follows the intended post-rebase control flow.

  14. 6b8a612Fix no-websockets build variants
    Fixes the Win32 and GDK no-websockets export surfaces and the Linux HC_NOWEBSOCKETS build plumbing so the post-rebase no-websockets variants remain buildable.

  15. 9fbc9c1Make hybrid websocket helpers const
    Applies the late review-feedback const-correctness cleanup to the non-mutating WinHttpHybrid_WebSocketProvider provider-selection helpers.

  16. cdaebe6Fix strict-mode WinTLS websocket build
    Fixes a latent wintls_socket.hpp transport-error translation compile issue so the websocketpp-backed Windows compression path still builds under stricter MSVC conformance settings.

  17. c90949aHarden Linux helper scripts for container builds
    Hardens the Linux dependency-install, OpenSSL, and cURL helper scripts for the containerized build path used in local and CI-style validation.

  18. 6cdd639Silence non-GDK curl multi poll warning
    Removes the always-true non-GDK curl_multi_poll check while preserving the GDK dynamic-loader fallback behavior.

  19. cc5fa18Align Apple minizip Xcode wiring
    Adds ioapi.c and the contrib/minizip include path to the Apple Xcode project so its minizip wiring matches the Linux and Android build definitions.

  20. 5f8ec91Fix Win32 compression test linker settings
    Moves the Release /OPT:NOREF control for the Win32 compression test executables into Link and forces plain /LTCG so that setting is compatible.

  21. fba869dReject zero WebSocket receive buffer size
    Rejects HCWebSocketSetMaxReceiveBufferSize(0) with E_INVALIDARG to avoid invalid deterministic receive-buffer states.

  22. bae2321Disable zstd in Linux curl helper
    Disables optional zstd autodetection in the Linux vendored cURL helper so static builds keep a deterministic link surface and do not require undeclared libzstd symbols.

  23. 7dad3d9Silence Apple websocketpp documentation warning
    Localizes Apple Clang -Wdocumentation suppression to the configured permessage-deflate wrapper so strict iOS/macOS warning-as-error builds do not fail on the vendored websocketpp header.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class WebSocket compression support to libHttpClient across built-in providers, introducing an explicit options surface (HCWebSocketSetOptions / HCWebSocketOptions) for legacy vs deterministic semantics, compression negotiation, response-header access, and Windows-family hybrid routing to a compression-capable backend when requested.

Changes:

  • Introduces HCWebSocketOptions + HCWebSocketSetOptions(...), deterministic receive semantics (hard-cap + TooLarge close), and HCWebSocketDisconnectWithStatus(...).
  • Adds upgrade response header capture + public accessors (HCWebSocketGetResponseHeader*), and plumbs capture through WinHTTP/WinRT/Android paths.
  • Adds build/dependency plumbing (boost-wintls, websocketpp/asio updates), Windows hybrid provider routing, and new compression validation tests/samples.

Reviewed changes

Copilot reviewed 63 out of 64 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
libHttpClient.vs2022.sln Adds Win32 compression test projects
libHttpClient.vs2019.sln Adds Win32 compression test projects
hc_settings.props.example Documents compression build knobs
cgmanifest.json Updates deps; adds boost-wintls
Utilities/FrameworkResources/exports.exp Exports new WebSocket APIs
Tests/WebSocketCompression/WebSocketCompressionTests.Win32.vcxproj New Win32 compression test app
Tests/WebSocketCompression/WebSocketCompressionIntegrationTests.Win32.vcxproj New Win32 cert-store integration app
Tests/UnitTests/Tests/WebsocketTests.cpp Adds options/headers/disconnect tests
Source/WebSocket/websocket_publics.cpp Adds new public WebSocket entrypoints
Source/WebSocket/websocket_options.h Adds WebSocket options helpers
Source/WebSocket/iOS/ios_websocket.cpp Removes stub iOS WebSocket file
Source/WebSocket/hcwebsocket.h Adds options/headers APIs + state tracking
Source/WebSocket/hcwebsocket.cpp Implements options/headers + deterministic logic
Source/WebSocket/WinRT/winrt_websocket.cpp Caches upgrade response headers (WinRT)
Source/WebSocket/Websocketpp/wintls_socket.hpp WinTLS transport adapter (websocketpp)
Source/WebSocket/Websocketpp/websocketpp_websocket.h Provider lifecycle + options support surface
Source/WebSocket/Websocketpp/websocketpp_disabled_permessage_deflate.hpp Wrapper for vendored websocketpp bug
Source/WebSocket/Websocketpp/websocketpp_configured_permessage_deflate.hpp Wrapper to control offer params
Source/WebSocket/Android/AndroidWebSocketProvider.cpp Caches upgrade response headers (Android)
Source/Platform/Win32/PlatformComponents_Win32.cpp Uses hybrid provider when enabled
Source/Platform/IWebSocketProvider.h Adds OptionsResult + IProviderLifecycle
Source/Platform/GDK/PlatformComponents_GDK.cpp Hybrid provider + lifecycle notifications
Source/HTTP/WinHttp/winhttp_websocket_hybrid.h Declares WinHTTP hybrid WS provider
Source/HTTP/WinHttp/winhttp_websocket_hybrid.cpp Implements hybrid routing + lifecycle fanout
Source/HTTP/WinHttp/winhttp_provider.h WinHttp WS provider implements lifecycle
Source/HTTP/WinHttp/winhttp_provider.cpp Implements suspend/resume hooks (GDK)
Source/HTTP/WinHttp/winhttp_connection.h Adds close + header helpers
Source/HTTP/WinHttp/winhttp_connection.cpp Deterministic hard-cap + header capture
Source/Global/NetworkState.h Adds WS suspend/resume notifications
Source/Global/NetworkState.cpp Implements lifecycle notifications + queue dup
Source/Common/Apple/utils_apple.mm Switches proxy username/pass to String
Source/Common/Apple/utils_apple.h Updates proxy helper signature
Samples/WebSocketEchoServer/WebSocketEchoServer.vcxproj.filters Adds zlib sources to filters
Samples/WebSocketEchoServer/WebSocketEchoServer.vcxproj Adds zlib sources/include paths
Samples/WebSocketEchoServer/WebSocketEchoServer.cpp Enables permessage-deflate negotiation
SECURITY_AUDIT_BOOST-WINTLS.md Adds security audit writeup
README.md Documents options/legacy vs deterministic behavior
NOTICE.txt Updates notices for deps + boost-wintls
Include/httpClient/pal.h Adds S_FALSE definition
Include/httpClient/httpProvider.h Adds response header API declarations
Include/httpClient/httpClient.h Adds options enum + new public WS APIs/docs
Build/libHttpClient.Win32/libHttpClient.Win32.vcxproj No-websockets .def selection
Build/libHttpClient.Win32/libHttpClient.Win32.def Exports new WS APIs
Build/libHttpClient.Win32/libHttpClient.Win32.NoWebSockets.def New no-websockets export list
Build/libHttpClient.Win32.Shared/libHttpClient.Win32.Shared.vcxitems.filters Adds hybrid/websocketpp filters
Build/libHttpClient.Win32.Shared/libHttpClient.Win32.Shared.vcxitems Adds compression build gating
Build/libHttpClient.Linux/libHttpClient_Linux.bash Adds websocket compression toggle
Build/libHttpClient.Linux/README.md Documents compression build toggle
Build/libHttpClient.Linux/CMakeLists.txt Adds compression option + test target
Build/libHttpClient.GDK/libHttpClient.GDK.vcxproj No-websockets .def selection
Build/libHttpClient.GDK/libHttpClient.GDK.def Exports new WS APIs
Build/libHttpClient.GDK/libHttpClient.GDK.NoWebSockets.def New no-websockets export list
Build/libHttpClient.GDK.Shared/libHttpClient.GDK.Shared.vcxitems.filters Adds websocketpp filters
Build/libHttpClient.GDK.Shared/libHttpClient.GDK.Shared.vcxitems Adds compression + console gating
Build/libHttpClient.CMake/GetLibHCFlags.cmake Adds compression + fixes nowe check
Build/libHttpClient.Apple.C/libHttpClient.xcodeproj/project.pbxproj Enables compression + zlib include path
Build/libHttpClient.Android/src/main/java/com/xbox/httpclient/HttpClientWebSocket.java Passes upgrade headers via JNI
.gitmodules Adds boost-wintls submodule
.gitignore Ignores .github/working/

Comment thread Tests/WebSocketCompression/WebSocketCompressionTests.Win32.vcxproj
Comment thread Source/WebSocket/hcwebsocket.cpp
jhugard and others added 23 commits April 28, 2026 15:20
Add the websocketpp WebSocket provider, the WinHTTP hybrid routing layer, and the platform-specific plumbing needed to select that provider on Win32 and GDK. Update the WinHTTP connection path, WinRT and Apple helpers, network-state handling, and the websocketpp configuration headers so the new transport can own deterministic and compression-capable connections.
Rename the compression-only control surface to HCWebSocketSetOptions and HCWebSocketOptions, add the LegacySemantics escape hatch, and make deterministic behavior explicit on the handle. Update the Android-facing surface, public headers, exports, and documentation so callers can reason about fragment-handler support, max receive buffer behavior, and compression negotiation through one options contract.
Add the local echo-server sample, the focused Win32 compression test projects, and the unit-test updates that lock down the final options contract. Keep the review surface centered on compression, certificate validation, and explicit options behavior by dropping the now-redundant standalone semantics harness from the branch.
- Add boost-wintls (BSL-1.0) to NOTICE.txt and cgmanifest.json
- Update asio commit hash from 22afb86 to 03ae834 (asio-1-32-0) in
  both files to match the current submodule pointer
- Add DEFINE_ENUM_FLAG_OPERATORS(HCWebSocketOptions) so callers can
  combine flags with | without casting through uint32_t
- Add m_stateMutex lock to SetOptions() to match the locking pattern
  already used in SetMaxReceiveBufferSize()
- Add m_stateMutex lock and pre-connect guard to SetPingInterval() for
  consistency with all other pre-connect setters
- Return E_INVALIDARG from GetResponseHeaderAtIndex() when headerIndex
  is out of range instead of returning S_OK with null output pointers
- Add Websocketpp and WinHttp Hybrid filter entries to the Win32.Shared
  vcxitems.filters so the new files appear under proper Solution
  Explorer folders (matching the existing GDK.Shared pattern)
- Document the intentional raw new in wintls_socket.hpp where
  websocketpp's transport layer requires std::shared_ptr
- Document the leak-rather-than-deadlock design choice in the detached
  joiner thread shutdown fallback
- Note the intentional proxy URI parser duplication between
  websocketpp_websocket.cpp and winhttp_connection.cpp
- clarify deterministic vs legacy WebSocket behavior across platforms
- document receive buffer, fragment callback, and compression behavior in the public header and README
- reorder pre-connect WebSocket APIs in the header to match the intended setup flow
- scope WinHTTP websocket-only proxy helpers under HC_NOWEBSOCKETS

Co-authored-by: Copilot <copilot@github.com>
@jhugard jhugard force-pushed the websocket-compression branch from 11e6957 to 7dad3d9 Compare April 28, 2026 22:29
Comment thread Source/WebSocket/hcwebsocket.cpp
Comment thread Source/WebSocket/Websocketpp/wintls_socket.hpp
Comment thread Source/WebSocket/Websocketpp/websocketpp_websocket.cpp
jhugard added 2 commits April 30, 2026 12:59
…e assert

1. SetOptions: move HasBinaryMessageFragmentHandlers() before m_stateMutex
   acquisition to eliminate latent m_stateMutex -> m_eventCallbacksMutex
   nesting hazard.

2. wintls_socket translate_ec: add comment explaining that wintls::error_code
   resolves to the lib::error_code identity overload (same type via
   WINTLS_USE_STANDALONE_ASIO), so TLS errors propagate correctly.

3. websocketpp_client_base::impl<T>(): add debug-only type tag (typeid hash)
   set at construction and asserted on access, catching config-type dispatch
   mismatches at zero release cost.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants