Skip to content

Commit c9a6b17

Browse files
feat: Add support for CURL networking. (#487)
BEGIN_COMMIT_OVERRIDE feat: Add support for CURL networking. feat: Add proxy support when using CURL networking. END_COMMIT_OVERRIDE This PR adds an alternate networking implementation which uses CURL instead of boost beast. Using CURL enables support for all advanced networking features including support for http, https, socks4, and socks 5 proxies. Proxy configuration can be done using standard environment variables, or using the builder for the SDK. CURL is used via the CURL multi interface combined with boost::asio to provide non-blocking IO. https://curl.se/libcurl/c/libcurl-multi.html This allows for the CURL requests to be driven similarly to the boost.beast networking which is additionally supported. CURL support is conditional based on the LD_CURL_NETWORKING CMake option. When it is enabled all HTTP/HTTPS request in the SDK use CURL. This support does not affect the redis persistence implementation. The CI and release process has been updated to build and test the CURL and boost.Beast versions of all of the libraries. These changes constitute a non-trivial portion of the PR. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds an optional CURL-based HTTP/SSE networking backend with proxy support, a new networking lib, and CI/release/testing to build and verify both CURL and Boost.Beast variants. > > - **Core networking**: > - Introduce `libs/networking` with `CurlMultiManager` and CURL integration (`launchdarkly::networking`). > - Add `network::Requester` abstraction to switch between CURL and Boost.Beast. > - **SDK changes**: > - Implement CURL SSE client and HTTP requester; wire into client/server SDKs and internal events. > - Add proxy config (`HttpProperties.Proxy`) and C bindings (`*_HttpProperties_Proxy`); pass to SSE builder. > - Default/properties updated to carry `ProxyOptions`. > - **Build/CMake**: > - New option `LD_CURL_NETWORKING` to enable CURL networking; `find_package(CURL QUIET)` in config. > - Add code coverage option `LD_BUILD_COVERAGE` and coverage script. > - **CI/Release**: > - New `install-curl` action; extend shared CI to toggle CURL builds and simulate releases (Linux/macOS/Windows). > - Update client/server/SSE workflows to run both Boost.Beast and CURL jobs; add cmake-integration CURL jobs. > - Release action now builds/zips additional `*-curl` artifacts (with `-experimental` suffix for server). > - **Examples/Docs/Tests**: > - Add proxy validation Docker-compose example. > - Update README and cmake-tests docs for CURL setup. > - Add unit tests for CURL requester and SSE CurlClient; extend contract tests to advertise proxy capability. > - Release manifest includes `libs/networking`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit f916106. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Matthew M. Keeler <[email protected]>
1 parent 03e2a59 commit c9a6b17

File tree

75 files changed

+5345
-66
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+5345
-66
lines changed

.github/actions/ci/action.yml

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ inputs:
2929
description: 'Whether to run ./build-release-windows.sh for the CMake target'
3030
required: false
3131
default: 'false'
32+
use_curl:
33+
description: 'Whether to enable CURL networking (LD_CURL_NETWORKING=ON)'
34+
required: false
35+
default: 'false'
3236

3337
runs:
3438
using: composite
@@ -44,22 +48,30 @@ runs:
4448
- name: Install OpenSSL
4549
uses: ./.github/actions/install-openssl
4650
id: install-openssl
51+
- name: Install CURL
52+
if: inputs.use_curl == 'true'
53+
uses: ./.github/actions/install-curl
54+
id: install-curl
4755
- name: Build Library
4856
shell: bash
49-
run: ./scripts/build.sh ${{ inputs.cmake_target }} ON
57+
run: ./scripts/build.sh ${{ inputs.cmake_target }} ON ${{ inputs.use_curl }}
5058
env:
5159
BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }}
5260
Boost_DIR: ${{ steps.install-boost.outputs.Boost_DIR }}
5361
OPENSSL_ROOT_DIR: ${{ steps.install-openssl.outputs.OPENSSL_ROOT_DIR }}
62+
CURL_ROOT: ${{ steps.install-curl.outputs.CURL_ROOT }}
63+
CMAKE_PREFIX_PATH: ${{ steps.install-curl.outputs.CURL_ROOT }}
5464
- name: Build Tests
5565
id: build-tests
5666
if: inputs.run_tests == 'true'
5767
shell: bash
58-
run: ./scripts/build.sh gtest_${{ inputs.cmake_target }} ON
68+
run: ./scripts/build.sh gtest_${{ inputs.cmake_target }} ON ${{ inputs.use_curl }}
5969
env:
6070
BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }}
6171
Boost_DIR: ${{ steps.install-boost.outputs.Boost_DIR }}
6272
OPENSSL_ROOT_DIR: ${{ steps.install-openssl.outputs.OPENSSL_ROOT_DIR }}
73+
CURL_ROOT: ${{ steps.install-curl.outputs.CURL_ROOT }}
74+
CMAKE_PREFIX_PATH: ${{ steps.install-curl.outputs.CURL_ROOT }}
6375
- name: Run Tests
6476
if: steps.build-tests.outcome == 'success'
6577
shell: bash
@@ -70,16 +82,30 @@ runs:
7082
- name: Simulate Release (Linux/MacOS)
7183
if: inputs.simulate_release == 'true'
7284
shell: bash
73-
run: ./scripts/build-release.sh ${{ inputs.cmake_target }}
85+
run: |
86+
if [ "${{ inputs.use_curl }}" == "true" ]; then
87+
./scripts/build-release.sh ${{ inputs.cmake_target }} --with-curl
88+
else
89+
./scripts/build-release.sh ${{ inputs.cmake_target }}
90+
fi
7491
env:
7592
BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }}
7693
OPENSSL_ROOT_DIR: ${{ steps.install-openssl.outputs.OPENSSL_ROOT_DIR }}
94+
CURL_ROOT: ${{ steps.install-curl.outputs.CURL_ROOT }}
95+
CMAKE_PREFIX_PATH: ${{ steps.install-curl.outputs.CURL_ROOT }}
7796

7897
- name: Simulate Release (Windows)
7998
if: inputs.simulate_windows_release == 'true'
8099
shell: bash
81-
run: ./scripts/build-release-windows.sh ${{ inputs.cmake_target }}
100+
run: |
101+
if [ "${{ inputs.use_curl }}" == "true" ]; then
102+
./scripts/build-release-windows.sh ${{ inputs.cmake_target }} --with-curl
103+
else
104+
./scripts/build-release-windows.sh ${{ inputs.cmake_target }}
105+
fi
82106
env:
83107
BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }}
84108
OPENSSL_ROOT_DIR: ${{ steps.install-openssl.outputs.OPENSSL_ROOT_DIR }}
85109
Boost_DIR: 'C:\local\boost_1_87_0\lib64-msvc-14.3\cmake\Boost-1.87.0'
110+
CURL_ROOT: ${{ steps.install-curl.outputs.CURL_ROOT }}
111+
CMAKE_PREFIX_PATH: ${{ steps.install-curl.outputs.CURL_ROOT }}

.github/actions/cmake-test/action.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ inputs:
1111
toolset:
1212
description: 'Boost toolset'
1313
required: false
14+
cmake_extra_args:
15+
description: 'Extra arguments to pass to CMake'
16+
required: false
17+
default: ''
1418

1519
runs:
1620
using: composite
@@ -36,6 +40,7 @@ runs:
3640
BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }}
3741
OPENSSL_ROOT_DIR: ${{ steps.install-openssl.outputs.OPENSSL_ROOT_DIR }}
3842
CMAKE_INSTALL_PREFIX: ../LAUNCHDARKLY_INSTALL
43+
CMAKE_EXTRA_ARGS: ${{ inputs.cmake_extra_args }}
3944
- name: Build the SDK
4045
shell: bash
4146
run: |
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: Install CURL
2+
description: 'Install CURL development libraries for all platforms.'
3+
4+
outputs:
5+
CURL_ROOT:
6+
description: The location of the installed CURL.
7+
value: ${{ steps.determine-root.outputs.CURL_ROOT }}
8+
9+
runs:
10+
using: composite
11+
steps:
12+
# Linux: Install via apt-get
13+
- name: Install CURL for Ubuntu
14+
if: runner.os == 'Linux'
15+
id: apt-action
16+
shell: bash
17+
run: |
18+
sudo apt-get update
19+
sudo apt-get install -y libcurl4-openssl-dev
20+
echo "CURL_ROOT=/usr" >> $GITHUB_OUTPUT
21+
22+
# macOS: Install via homebrew
23+
- name: Install CURL for macOS
24+
if: runner.os == 'macOS'
25+
id: brew-action
26+
shell: bash
27+
run: |
28+
brew install curl
29+
echo "CURL_ROOT=$(brew --prefix curl)" >> $GITHUB_OUTPUT
30+
31+
# Windows: Build CURL from source with MSVC using helper script
32+
- name: Install CURL for Windows
33+
if: runner.os == 'Windows'
34+
id: windows-action
35+
shell: pwsh
36+
run: |
37+
# Use the build script from the repository
38+
& "${{ github.workspace }}\scripts\build-curl-windows.ps1" -Version "8.11.1" -InstallPrefix "C:\curl-install"
39+
40+
if ($LASTEXITCODE -ne 0) {
41+
Write-Error "CURL build failed"
42+
exit 1
43+
}
44+
45+
echo "CURL_ROOT=C:\curl-install" >> $env:GITHUB_OUTPUT
46+
47+
- name: Determine root
48+
id: determine-root
49+
shell: bash
50+
run: |
51+
if [ ! -z "$ROOT_APT" ]; then
52+
echo "CURL_ROOT=$ROOT_APT" >> $GITHUB_OUTPUT
53+
echo Setting CURL_ROOT to "$ROOT_APT"
54+
elif [ ! -z "$ROOT_BREW" ]; then
55+
echo "CURL_ROOT=$ROOT_BREW" >> $GITHUB_OUTPUT
56+
echo Setting CURL_ROOT to "$ROOT_BREW"
57+
elif [ ! -z "$ROOT_WINDOWS" ]; then
58+
echo "CURL_ROOT=$ROOT_WINDOWS" >> $GITHUB_OUTPUT
59+
echo Setting CURL_ROOT to "$ROOT_WINDOWS"
60+
fi
61+
env:
62+
ROOT_APT: ${{ steps.apt-action.outputs.CURL_ROOT }}
63+
ROOT_BREW: ${{ steps.brew-action.outputs.CURL_ROOT }}
64+
ROOT_WINDOWS: ${{ steps.windows-action.outputs.CURL_ROOT }}

0 commit comments

Comments
 (0)