libHttpClient

repository·main·Indexed 43 days ago

https://github.com/microsoft/libhttpclient

A high-performance, asynchronous, and memory-controlled C API platform abstraction layer for HTTP and WebSocket. Optimized for professional game development and used by Microsoft Xbox Live and PlayFab services, it supports GDK, XDK ERA, Win32, UWP, iOS, Android, and Linux.

Tokens
5.1K
Snippets
16
Records
30
Agent score
54%

What's inside libHttpClient

  1. Overview of libHttpClient

    main

    libHttpClient is a platform abstraction layer for HTTP and WebSocket designed for professional game developers. It provides a flat, asynchronous C API that works across multiple platforms including GDK, XDK ERA, Win32, UWP, iOS, Android, and Linux.

    Key Features

    • Platform Abstraction: Uses native platform APIs by default but allows custom implementations via callbacks.
    • Asynchronous Design: Designed to prevent blocking game threads; results can be dispatched to specific game threads to avoid manual marshaling.
    • Memory Control: Supports caller-controlled memory allocation via callback APIs.
    • Robustness: Includes built-in retry logic (obeying Retry-After headers and jitter) and Xbox Live throttle handling.
    • No Heavy Dependencies: Does not require PPL or Boost and does not use exceptions for error reporting.
    • P/Invoke Friendly: The flat C API is designed for easy interop with languages like C#.
  2. Customizing HTTP and WebSocket Implementations

    main

    You can replace the built-in platform implementations with your own logic using callback APIs:

    Custom HTTP Implementation

    Use HCSetHttpCallPerformFunction() to provide your own handling. Your implementation will receive access to:

    • HCHttpCallRequestGet*()
    • HCHttpCallResponseSet*()
    • HCSettingsGet*()

    Custom WebSocket Implementation

    Use HCSetWebSocketFunctions() to replace the built-in WebSocket implementation with your own connect, send, and disconnect callbacks.

  3. How WebSocket compression works in libHttpClient Linux

    main

    On Linux, HC_ENABLE_WEBSOCKET_COMPRESSION is enabled by default. This compiles the compression-capable websocketpp provider path and enables the local Linux WebSocket compression integration test target.

    Note: Compression is only negotiated at runtime when the caller explicitly requests it via HCWebSocketSetOptions().

    To run the compression tests from the CMake build directory, use:

    ctest --output-on-failure -R websocket-compression-linux
  4. WebSocket Compression Options

    main

    Compression is available on Linux, macOS, iOS, Win32, and GDK PC (and optionally GDK Console).

    To use compression, call HCWebSocketSetOptions() on a handle before calling HCWebSocketConnectAsync().

    Available Flags

    • RequestCompression: Enables permessage-deflate compression. This is required for the following flags to work:
      • CompressionServerNoContextTakeover: Requests fresh zlib state for server-to-client messages.
      • CompressionClientNoContextTakeover: Requests fresh zlib state for client-to-server messages.
    • None: Selects deterministic behavior without compression.
    • LegacySemantics: Preserves legacy behavior.

    Platform Specifics

    • Android: Manages compression internally; HCWebSocketSetOptions() is not exposed.
    • UWP/WinRT: Does not support built-in compression negotiation.
    • GDK Console: Enable via the HC_ENABLE_GDK_XBOX_WEBSOCKET_COMPRESSION build flag.
  5. WebSocket Behavior: Legacy vs. Deterministic

    main

    libHttpClient supports two modes of WebSocket operation via HCWebSocketSetOptions():

    Legacy Behavior

    • Trigger: Not calling HCWebSocketSetOptions() or using HCWebSocketOptions::LegacySemantics.
    • Buffer: On Win32/GDK, the default receive buffer is 20KB.
    • Oversized Payloads: If a payload exceeds the buffer, it is surfaced via the HCWebSocketSetBinaryMessageFragmentEventFunction() as raw bytes (fragments). This applies to both text and binary.
    • Platform Limits: On macOS/iOS/Linux, the provider uses a configured 32,000,000-byte maximum; HCWebSocketSetMaxReceiveBufferSize() does not act as a hard cap in legacy mode.

    Deterministic Behavior

    • Trigger: Calling HCWebSocketSetOptions(HCWebSocketOptions::None) or any compression flag.
    • Buffer: HCWebSocketSetMaxReceiveBufferSize() becomes a hard inbound message-size cap.
    • Default Limit: If no size is set, the default is 32,000,000 bytes. Oversized messages will close the socket with HCWebSocketCloseStatus::TooLarge.
    • Fragments: Fragment callbacks are not supported in deterministic mode.
  6. Initialize submodules in an existing clone

    main

    If you have already cloned the libHttpClient repository without the --recursive flag, you can manually initialize and update the submodules by running the following commands in your terminal:

    git submodule sync
    git submodule update --init --recursive
  7. Use the standalone JSON parser

    main

    To use the JSON parser in your C++ project, include the header <json_cpp/json.h>. This library provides a standalone version of the cpprestsdk JSON parser, allowing you to use the web::json namespace without requiring the full cpprestsdk dependency.

    Common tasks include parsing strings into web::json::value objects using web::json::value::parse, which accepts a string and an std::error_code to report parsing errors.

    #include <json_cpp/json.h>
    
    // ...
    
    std::error_code err;
    std::wstring exampleString = L"{\"exampleName\":\"exampleValue\"}";
    web::json::value jsonConfig = web::json::value::parse(exampleString, err);
  8. Build libssl for Android using CMake and Gradle

    main

    To build libssl for Android, use the CMake build system located in Build/libssl.Android/. This setup is designed to work with Gradle's external native build integration.

    Note that these CMake files are not intended to be used in isolation; they are referenced by specific Gradle projects. To find the relevant Gradle projects, look in the /Build/<project-name>.Android directories. For a comprehensive overview of the workspace structure, refer to /Build/libHttpClient.Android.Workspace.

  9. Install TAEF for unit testing

    main

    To compile the TAEF (Test Authoring and Execution Framework) project, you must install the TAEF MSI via the Windows Driver Kit (WDK).

    1. Install Windows Driver Kit (WDK 10), version 1607 from the Microsoft WDK website.
    2. Locate and run the TAEF MSI installer, typically found at: C:\Program Files (x86)\Windows Kits\10\Testing\Runtimes\Test Authoring and Execution Framework x64-x64_en-us.msi

    After installation, TAEF will be located in C:\Program Files (x86)\Windows Kits\10\Testing.

    C:\Program Files (x86)\Windows Kits\10\Testing\Runtimes\Test Authoring and Execution Framework x64-x64_en-us.msi
  10. Manually install libcurl.UWP for UWP projects

    main

    The standard curl NuGet package does not support Universal Windows Platform (UWP). Instead, you must use libcurl.UWP. Because this package may not install automatically in certain sample environments, you may need to manually extract it into your project directory.

    Follow these steps to set up libcurl.UWP for the CustomHttpImplWithCurl sample:

    1. Download the libcurl.UWP package from NuGet: https://www.nuget.org/api/v2/package/libcurl.UWP/1.0.4
    2. Rename the downloaded file from libcurl.uwp.1.0.4.nupkg to libcurl.uwp.1.0.4.nupkg.zip.
    3. Extract the contents of the zip file into the following directory: CustomHttpImplWithCurl\libcurl.uwp.1.0.4.nupkg\.
    4. Build and run the sample.
    # Example of the manual extraction workflow
    # 1. Download package
    # 2. Rename extension
    mv libcurl.uwp.1.0.4.nupkg libcurl.uwp.1.0.4.nupkg.zip
    # 3. Extract to the specific sample directory
    unzip libcurl.uwp.1.0.4.nupkg.zip -d CustomHttpImplWithCurl/libcurl.uwp.1.0.4.nupkg/