Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: specify a custom CA file for TLS peer verification #409

Merged
merged 13 commits into from
May 30, 2024
3 changes: 3 additions & 0 deletions contract-tests/client-contract-tests/src/entity_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "entity_manager.hpp"

Check failure on line 1 in contract-tests/client-contract-tests/src/entity_manager.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/client-contract-tests/src/entity_manager.cpp:1:10 [clang-diagnostic-error]

'entity_manager.hpp' file not found

#include <launchdarkly/config/client.hpp>
#include <launchdarkly/context_builder.hpp>
Expand All @@ -17,7 +17,7 @@
logger_{logger} {}

static tl::expected<launchdarkly::Context, launchdarkly::JsonError>
ParseContext(nlohmann::json value) {

Check warning on line 20 in contract-tests/client-contract-tests/src/entity_manager.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/client-contract-tests/src/entity_manager.cpp:20:1 [cppcoreguidelines-avoid-non-const-global-variables]

variable 'ParseContext' is non-const and globally accessible, consider making it const
auto boost_json_val = boost::json::parse(value.dump());
return boost::json::value_to<
tl::expected<launchdarkly::Context, launchdarkly::JsonError>>(
Expand Down Expand Up @@ -134,6 +134,9 @@
if (in.tls->skipVerifyPeer) {
builder.SkipVerifyPeer(*in.tls->skipVerifyPeer);
}
if (in.tls->customCAFile) {
builder.CustomCAFile(*in.tls->customCAFile);
}
config_builder.HttpProperties().Tls(std::move(builder));
}

Expand Down
3 changes: 2 additions & 1 deletion contract-tests/client-contract-tests/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "server.hpp"

Check notice on line 1 in contract-tests/client-contract-tests/src/main.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

Run clang-format on contract-tests/client-contract-tests/src/main.cpp

File contract-tests/client-contract-tests/src/main.cpp does not conform to Custom style guidelines. (lines 48)

Check failure on line 1 in contract-tests/client-contract-tests/src/main.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/client-contract-tests/src/main.cpp:1:10 [clang-diagnostic-error]

'server.hpp' file not found

#include <launchdarkly/logging/console_backend.hpp>

Expand All @@ -18,7 +18,7 @@
using launchdarkly::LogLevel;

int main(int argc, char* argv[]) {
launchdarkly::Logger logger{

Check warning on line 21 in contract-tests/client-contract-tests/src/main.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/client-contract-tests/src/main.cpp:21:26 [cppcoreguidelines-init-variables]

variable 'logger' is not initialized
std::make_unique<ConsoleBackend>("client-contract-tests")};

std::string const default_port = "8123";
Expand All @@ -31,8 +31,8 @@
try {
net::io_context ioc{1};

auto p = boost::lexical_cast<unsigned short>(port);

Check warning on line 34 in contract-tests/client-contract-tests/src/main.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/client-contract-tests/src/main.cpp:34:14 [readability-identifier-length]

variable name 'p' is too short, expected at least 3 characters
server srv(ioc, "0.0.0.0", p, logger);

Check warning on line 35 in contract-tests/client-contract-tests/src/main.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/client-contract-tests/src/main.cpp:35:16 [cppcoreguidelines-init-variables]

variable 'srv' is not initialized

srv.add_capability("client-side");
srv.add_capability("mobile");
Expand All @@ -45,7 +45,8 @@
srv.add_capability("anonymous-redaction");
srv.add_capability("tls:verify-peer");
srv.add_capability("tls:skip-verify-peer");

srv.add_capability("tls:custom-ca");

net::signal_set signals{ioc, SIGINT, SIGTERM};

boost::asio::spawn(ioc.get_executor(), [&](auto yield) mutable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <optional>
#include <string>
#include <unordered_map>
#include "nlohmann/json.hpp"

Check failure on line 6 in contract-tests/data-model/include/data_model/data_model.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/data-model/include/data_model/data_model.hpp:6:10 [clang-diagnostic-error]

'nlohmann/json.hpp' file not found

namespace nlohmann {

Expand Down Expand Up @@ -31,9 +31,12 @@

struct ConfigTLSParams {
std::optional<bool> skipVerifyPeer;
std::optional<std::string> customCAFile;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(ConfigTLSParams,
skipVerifyPeer);
skipVerifyPeer,
customCAFile);

struct ConfigStreamingParams {
std::optional<std::string> baseUri;
Expand All @@ -51,7 +54,7 @@
baseUri,
pollIntervalMs);

struct ConfigEventParams {

Check warning on line 57 in contract-tests/data-model/include/data_model/data_model.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/data-model/include/data_model/data_model.hpp:57:8 [cppcoreguidelines-pro-type-member-init]

constructor does not initialize these fields: globalPrivateAttributes
std::optional<std::string> baseUri;
std::optional<uint32_t> capacity;
std::optional<bool> enableDiagnostics;
Expand All @@ -76,7 +79,7 @@
polling,
events);

struct ConfigClientSideParams {

Check warning on line 82 in contract-tests/data-model/include/data_model/data_model.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/data-model/include/data_model/data_model.hpp:82:8 [cppcoreguidelines-pro-type-member-init]

constructor does not initialize these fields: initialContext
nlohmann::json initialContext;
std::optional<bool> evaluationReasons;
std::optional<bool> useReport;
Expand Down Expand Up @@ -118,7 +121,7 @@
tags,
tls);

struct ContextSingleParams {

Check warning on line 124 in contract-tests/data-model/include/data_model/data_model.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/data-model/include/data_model/data_model.hpp:124:8 [cppcoreguidelines-pro-type-member-init]

constructor does not initialize these fields: custom
std::optional<std::string> kind;
std::string key;
std::optional<std::string> name;
Expand Down Expand Up @@ -209,7 +212,7 @@
defaultValue,
detail);

struct EvaluateFlagResponse {

Check warning on line 215 in contract-tests/data-model/include/data_model/data_model.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/data-model/include/data_model/data_model.hpp:215:8 [cppcoreguidelines-pro-type-member-init]

constructor does not initialize these fields: value, reason
nlohmann::json value;
std::optional<uint32_t> variationIndex;
std::optional<nlohmann::json> reason;
Expand All @@ -219,7 +222,7 @@
variationIndex,
reason);

struct EvaluateAllFlagParams {

Check warning on line 225 in contract-tests/data-model/include/data_model/data_model.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/data-model/include/data_model/data_model.hpp:225:8 [cppcoreguidelines-pro-type-member-init]

constructor does not initialize these fields: context
std::optional<nlohmann::json> context;
std::optional<bool> withReasons;
std::optional<bool> clientSideOnly;
Expand All @@ -230,7 +233,7 @@
withReasons,
clientSideOnly,
detailsOnlyForTrackedFlags);
struct EvaluateAllFlagsResponse {

Check warning on line 236 in contract-tests/data-model/include/data_model/data_model.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/data-model/include/data_model/data_model.hpp:236:8 [cppcoreguidelines-pro-type-member-init]

constructor does not initialize these fields: state
nlohmann::json state;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(EvaluateAllFlagsResponse,
Expand Down
3 changes: 3 additions & 0 deletions contract-tests/server-contract-tests/src/entity_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "entity_manager.hpp"

Check failure on line 1 in contract-tests/server-contract-tests/src/entity_manager.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/server-contract-tests/src/entity_manager.cpp:1:10 [clang-diagnostic-error]

'entity_manager.hpp' file not found

#include <launchdarkly/context_builder.hpp>
#include <launchdarkly/serialization/json_context.hpp>
Expand Down Expand Up @@ -125,6 +125,9 @@
if (in.tls->skipVerifyPeer) {
builder.SkipVerifyPeer(*in.tls->skipVerifyPeer);
}
if (in.tls->customCAFile) {
builder.CustomCAFile(*in.tls->customCAFile);
}
config_builder.HttpProperties().Tls(std::move(builder));
}

Expand Down
1 change: 1 addition & 0 deletions contract-tests/server-contract-tests/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "server.hpp"

Check failure on line 1 in contract-tests/server-contract-tests/src/main.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/contract-tests/server-contract-tests/src/main.cpp:1:10 [clang-diagnostic-error]

'server.hpp' file not found

#include <launchdarkly/logging/console_backend.hpp>

Expand Down Expand Up @@ -44,6 +44,7 @@
srv.add_capability("anonymous-redaction");
srv.add_capability("tls:verify-peer");
srv.add_capability("tls:skip-verify-peer");
srv.add_capability("tls:custom-ca");

net::signal_set signals{ioc, SIGINT, SIGTERM};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,26 @@ LDClientHttpPropertiesTlsBuilder_SkipVerifyPeer(
LDClientHttpPropertiesTlsBuilder b,
bool skip_verify_peer);

/**
* Configures TLS peer certificate verification to use a custom
* CA file.
*
* The parameter is a filepath pointing to a bundle of
* one or more PEM-encoded x509 certificates comprising the root of trust for
* the SDK's outbound connections.
*
* By default, the SDK uses the system's CA bundle. Passing the empty string
* will unset any previously set path and revert to the system's CA bundle.
*
* @param b Client config builder. Must not be NULL.
* @param custom_ca_file Filepath of the custom CA bundle, or empty string. Must
* not be NULL.
*/
LD_EXPORT(void)
LDClientHttpPropertiesTlsBuilder_CustomCAFile(
LDClientHttpPropertiesTlsBuilder b,
char const* custom_ca_file);

/**
* Disables the default SDK logging.
* @param b Client config builder. Must not be NULL.
Expand Down
10 changes: 10 additions & 0 deletions libs/client-sdk/src/bindings/c/builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,16 @@ LDClientHttpPropertiesTlsBuilder_SkipVerifyPeer(
TO_TLS_BUILDER(b)->SkipVerifyPeer(skip_verify_peer);
}

LD_EXPORT(void)
LDClientHttpPropertiesTlsBuilder_CustomCAFile(
LDClientHttpPropertiesTlsBuilder b,
char const* custom_ca_file) {
LD_ASSERT_NOT_NULL(b);
LD_ASSERT_NOT_NULL(custom_ca_file);

TO_TLS_BUILDER(b)->CustomCAFile(custom_ca_file);
}

LD_EXPORT(LDClientHttpPropertiesTlsBuilder)
LDClientHttpPropertiesTlsBuilder_New(void) {
return FROM_TLS_BUILDER(new TlsBuilder());
Expand Down
10 changes: 10 additions & 0 deletions libs/client-sdk/src/client_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ ClientImpl::ClientImpl(Config in_cfg,
eval_reasons_available_(config_.DataSourceConfig().with_reasons) {
flag_manager_.LoadCache(context_);

if (auto custom_ca = http_properties_.Tls().CustomCAFile()) {
LD_LOG(logger_, LogLevel::kInfo)
<< "TLS peer verification configured with custom CA file: "
<< *custom_ca;
}
if (http_properties_.Tls().PeerVerifyMode() ==
config::shared::built::TlsOptions::VerifyMode::kVerifyNone) {
LD_LOG(logger_, LogLevel::kInfo) << "TLS peer verification disabled";
}

if (config_.Events().Enabled() && !config_.Offline()) {
event_processor_ =
std::make_unique<events::AsioEventProcessor<ClientSDK>>(
Expand Down
6 changes: 1 addition & 5 deletions libs/client-sdk/src/data_sources/polling_data_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ PollingDataSource::PollingDataSource(
status_manager_(status_manager),
data_source_handler_(
DataSourceEventHandler(context, handler, logger, status_manager_)),
requester_(ioc, http_properties.Tls().PeerVerifyMode()),
requester_(ioc, http_properties.Tls()),
timer_(ioc),
polling_interval_(
std::get<
Expand All @@ -88,10 +88,6 @@ PollingDataSource::PollingDataSource(
auto const& polling_config = std::get<
config::shared::built::PollingConfig<config::shared::ClientSDK>>(
data_source_config.method);
if (http_properties.Tls().PeerVerifyMode() ==
config::shared::built::TlsOptions::VerifyMode::kVerifyNone) {
LD_LOG(logger_, LogLevel::kDebug) << "TLS peer verification disabled";
}
if (polling_interval_ < polling_config.min_polling_interval) {
LD_LOG(logger_, LogLevel::kWarn)
<< "Polling interval too frequent, defaulting to "
Expand Down
4 changes: 4 additions & 0 deletions libs/client-sdk/src/data_sources/streaming_data_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ void StreamingDataSource::Start() {
client_builder.skip_verify_peer(true);
}

if (auto ca_file = http_config_.Tls().CustomCAFile()) {
client_builder.custom_ca_file(*ca_file);
}

auto weak_self = weak_from_this();

client_builder.receiver([weak_self](launchdarkly::sse::Event const& event) {
Expand Down
1 change: 1 addition & 0 deletions libs/client-sdk/tests/client_config_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ TEST(ClientConfigBindings, AllConfigs) {
LDClientHttpPropertiesTlsBuilder tls_builder =
LDClientHttpPropertiesTlsBuilder_New();
LDClientHttpPropertiesTlsBuilder_SkipVerifyPeer(tls_builder, false);
LDClientHttpPropertiesTlsBuilder_CustomCAFile(tls_builder, "ca.pem");
LDClientConfigBuilder_HttpProperties_Tls(builder, tls_builder);

LDClientHttpPropertiesTlsBuilder tls_builder2 =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ class TlsBuilder {
*/
TlsBuilder& SkipVerifyPeer(bool skip_verify_peer);

/**
* Path to a file containing one or more CAs to verify
* the peer with. The certificate(s) must be PEM-encoded.
*
* By default, the SDK uses the system's root CA bundle.
*
* If the empty string is passed, this function will clear any existing
* CA bundle path previously set, and the system's root CA bundle will be
* used.
*
* @param custom_ca_file File path.
* @return A reference to this builder.
*/
TlsBuilder& CustomCAFile(std::string custom_ca_file);

/**
* Builds the TLS options.
* @return The built options.
Expand All @@ -48,6 +63,7 @@ class TlsBuilder {

private:
enum built::TlsOptions::VerifyMode verify_mode_;
std::optional<std::string> custom_ca_file_;
};
/**
* Class used for building a set of HttpProperties.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <chrono>
#include <map>
#include <optional>
#include <string>
#include <vector>

Expand All @@ -10,12 +11,16 @@ namespace launchdarkly::config::shared::built {
class TlsOptions final {
public:
enum class VerifyMode { kVerifyPeer, kVerifyNone };
TlsOptions(VerifyMode verify_mode);
explicit TlsOptions(VerifyMode verify_mode);
TlsOptions(VerifyMode verify_mode,
std::optional<std::string> ca_bundle_path);
TlsOptions();
[[nodiscard]] VerifyMode PeerVerifyMode() const;
[[nodiscard]] std::optional<std::string> const& CustomCAFile() const;

private:
VerifyMode verify_mode_;
std::optional<std::string> ca_bundle_path_;
};

class HttpProperties final {
Expand Down
18 changes: 14 additions & 4 deletions libs/common/src/config/http_properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,24 @@

namespace launchdarkly::config::shared::built {

TlsOptions::TlsOptions(enum TlsOptions::VerifyMode verify_mode)
: verify_mode_(verify_mode) {}
TlsOptions::TlsOptions(TlsOptions::VerifyMode verify_mode,
std::optional<std::string> ca_bundle_path)
: verify_mode_(verify_mode), ca_bundle_path_(std::move(ca_bundle_path)) {}

TlsOptions::TlsOptions() : TlsOptions(TlsOptions::VerifyMode::kVerifyPeer) {}
TlsOptions::TlsOptions(TlsOptions::VerifyMode verify_mode)
: TlsOptions(verify_mode, std::nullopt) {}

TlsOptions::TlsOptions()
: TlsOptions(TlsOptions::VerifyMode::kVerifyPeer, std::nullopt) {}

TlsOptions::VerifyMode TlsOptions::PeerVerifyMode() const {
return verify_mode_;
}

std::optional<std::string> const& TlsOptions::CustomCAFile() const {
return ca_bundle_path_;
}

HttpProperties::HttpProperties(std::chrono::milliseconds connect_timeout,
std::chrono::milliseconds read_timeout,
std::chrono::milliseconds write_timeout,
Expand Down Expand Up @@ -58,7 +67,8 @@ bool operator==(HttpProperties const& lhs, HttpProperties const& rhs) {
}

bool operator==(TlsOptions const& lhs, TlsOptions const& rhs) {
return lhs.PeerVerifyMode() == rhs.PeerVerifyMode();
return lhs.PeerVerifyMode() == rhs.PeerVerifyMode() &&
lhs.CustomCAFile() == rhs.CustomCAFile();
}

} // namespace launchdarkly::config::shared::built
13 changes: 12 additions & 1 deletion libs/common/src/config/http_properties_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ TlsBuilder<SDK>::TlsBuilder() : TlsBuilder(shared::Defaults<SDK>::TLS()) {}
template <typename SDK>
TlsBuilder<SDK>::TlsBuilder(built::TlsOptions const& tls) {
verify_mode_ = tls.PeerVerifyMode();
custom_ca_file_ = tls.CustomCAFile();
}

template <typename SDK>
Expand All @@ -22,9 +23,19 @@ TlsBuilder<SDK>& TlsBuilder<SDK>::SkipVerifyPeer(bool skip_verify_peer) {
return *this;
}

template <typename SDK>
TlsBuilder<SDK>& TlsBuilder<SDK>::CustomCAFile(std::string custom_ca_file) {
if (custom_ca_file.empty()) {
custom_ca_file_ = std::nullopt;
} else {
custom_ca_file_ = std::move(custom_ca_file);
}
return *this;
}

template <typename SDK>
built::TlsOptions TlsBuilder<SDK>::Build() const {
return {verify_mode_};
return {verify_mode_, custom_ca_file_};
}

template <typename SDK>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,12 @@ class RequestWorker {
* @param mode TLS peer verification mode.
* @param logger Logger.
*/
RequestWorker(
boost::asio::any_io_executor io,
std::chrono::milliseconds retry_after,
std::size_t id,
std::optional<std::locale> date_header_locale,
enum config::shared::built::TlsOptions::VerifyMode verify_mode,
Logger& logger);
RequestWorker(boost::asio::any_io_executor io,
std::chrono::milliseconds retry_after,
std::size_t id,
std::optional<std::locale> date_header_locale,
config::shared::built::TlsOptions tls_options,
Logger& logger);

/**
* Returns true if the worker is available for delivery.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ class WorkerPool {
* @param pool_size How many workers to make available.
* @param delivery_retry_delay How long a worker should wait after a failed
* delivery before trying again.
* @param verify_mode The TLS verification mode.
* @param tls_options The TLS options to use for the connection to
* LaunchDarkly event delivery endpoint.
* @param logger Logger.
*/
WorkerPool(boost::asio::any_io_executor io,
std::size_t pool_size,
std::chrono::milliseconds delivery_retry_delay,
enum config::shared::built::TlsOptions::VerifyMode verify_mode,
config::shared::built::TlsOptions const& tls_options,
Logger& logger);

/**
Expand Down
23 changes: 18 additions & 5 deletions libs/internal/include/launchdarkly/network/asio_requester.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "http_requester.hpp"

#include <launchdarkly/config/shared/built/http_properties.hpp>
#include <launchdarkly/detail/c_binding_helpers.hpp>
#include <launchdarkly/detail/unreachable.hpp>

#include <boost/asio.hpp>
Expand Down Expand Up @@ -30,7 +31,7 @@ using tcp = boost::asio::ip::tcp;

namespace launchdarkly::network {

using VerifyMode = config::shared::built::TlsOptions::VerifyMode;
using TlsOptions = config::shared::built::TlsOptions;

static unsigned char const kRedirectLimit = 20;

Expand Down Expand Up @@ -258,14 +259,26 @@ class AsioRequester {
* must be accounted for.
*/
public:
AsioRequester(net::any_io_executor ctx, VerifyMode verify_mode)
AsioRequester(net::any_io_executor ctx, TlsOptions const& tls_options)
: ctx_(std::move(ctx)),
ssl_ctx_(std::make_shared<net::ssl::context>(
launchdarkly::foxy::make_ssl_ctx(ssl::context::tlsv12_client))) {
ssl_ctx_->set_verify_mode(ssl::verify_peer);
ssl_ctx_->set_default_verify_paths();
ssl_ctx_->set_verify_mode(verify_mode == VerifyMode::kVerifyPeer
? ssl::verify_peer
: ssl::verify_none);

std::optional<std::string> const& custom_ca_file =
tls_options.CustomCAFile();

if (custom_ca_file) {
// The builder should enforce that the path (if set) is not empty.
LD_ASSERT(!custom_ca_file->empty());
ssl_ctx_->load_verify_file(custom_ca_file->c_str());
}

using VerifyMode = config::shared::built::TlsOptions::VerifyMode;
if (tls_options.PeerVerifyMode() == VerifyMode::kVerifyNone) {
ssl_ctx_->set_verify_mode(ssl::verify_none);
}
}

template <typename CompletionToken>
Expand Down
2 changes: 1 addition & 1 deletion libs/internal/src/events/asio_event_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ AsioEventProcessor<SDK>::AsioEventProcessor(
workers_(io_,
events_config.FlushWorkers(),
events_config.DeliveryRetryDelay(),
http_properties.Tls().PeerVerifyMode(),
http_properties.Tls(),
logger),
inbox_capacity_(events_config.Capacity()),
inbox_size_(0),
Expand Down
15 changes: 7 additions & 8 deletions libs/internal/src/events/request_worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@

namespace launchdarkly::events::detail {

RequestWorker::RequestWorker(
boost::asio::any_io_executor io,
std::chrono::milliseconds retry_after,
std::size_t id,
std::optional<std::locale> date_header_locale,
enum config::shared::built::TlsOptions::VerifyMode verify_mode,
Logger& logger)
RequestWorker::RequestWorker(boost::asio::any_io_executor io,
std::chrono::milliseconds retry_after,
std::size_t id,
std::optional<std::locale> date_header_locale,
config::shared::built::TlsOptions tls_options,
Logger& logger)
: timer_(std::move(io)),
retry_delay_(retry_after),
state_(State::Idle),
requester_(timer_.get_executor(), verify_mode),
requester_(timer_.get_executor(), tls_options),
batch_(std::nullopt),
tag_("flush-worker[" + std::to_string(id) + "]: "),
date_header_locale_(std::move(date_header_locale)),
Expand Down
Loading
Loading