Arachne 1.0
Arachne - the perpetual stitcher of Wikidata entities.
Loading...
Searching...
No Matches
corespace::http_client Class Referencefinal

Minimal, synchronous HTTP GET client built on libcurl. More...

#include <include/http_client.hpp>

Collaboration diagram for corespace::http_client:

Public Member Functions

 http_client ()
 Construct a client and initialize libcurl.
http_response get (std::string_view url, const parameter_list &params={}, std::string_view override={})
 Perform an HTTP GET to url with optional query params.
http_response post_form (std::string_view url, const parameter_list &form, const parameter_list &query={}, std::string_view override={})
http_response post_raw (std::string_view url, std::string_view body, std::string_view content_type, const parameter_list &query={}, std::string_view override={})
const network_metricsmetrics_info () const
 Access aggregated network metrics.

Private Types

using curl_url_ptr = std::unique_ptr<CURLU, decltype(&curl_url_cleanup)>
 Unique pointer type for CURLU with proper deleter.

Private Member Functions

http_response request_get (CURLU *url_handle, std::chrono::milliseconds &elapsed, std::string_view override={}) const
 Execute a single HTTP GET using the prepared URL handle.
http_response request_post (CURLU *url_handle, std::chrono::milliseconds &elapsed, std::string_view content_type, std::string_view body, std::string_view override) const
std::string build_form_body (const parameter_list &form) const
void update_headers (http_response &response) const
 Refresh the header multimap from the last transfer.
void update_metrics (const http_response &response, std::chrono::milliseconds elapsed)
 Update counters and histograms after an attempt.
long long next_delay (int attempt) const
 Compute the next backoff delay for attempt (1-based).
void apply_server_retry_hint (long long &sleep_ms) const
 Apply server-provided retry hint if present.

Static Private Member Functions

static curl_url_ptr build_url (std::string_view url, const parameter_list &params)
 Construct a CURLU handle from url and append params.
static bool status_good (const http_response &response)
 Success predicate: transport OK and HTTP 2xx.
static bool status_retry (const http_response &response, bool net_ok)
 Retry predicate for transient outcomes.
static size_t write_callback (const char *ptr, size_t size, size_t n, void *data)
 libcurl write callback: append chunk to response body.

Private Attributes

const network_options opt {}
 Fixed options installed at construction.
network_metrics metrics
 Aggregated metrics (atomic counters).
std::mutex mu
std::unique_ptr< CURL, decltype(&curl_easy_cleanup)> curl
 Reused easy handle (not thread-safe).
std::unique_ptr< curl_slist, decltype(&curl_slist_free_all)> header_list
 Owned request header list.

Detailed Description

Minimal, synchronous HTTP GET client built on libcurl.

Responsibilities:

  • Build request URLs with encoded query parameters.
  • Issue HTTP GET requests with redirect following enabled.
  • Apply bounded exponential backoff with jitter for retryable outcomes: network errors, 408 (Request Timeout), 429 (Too Many Requests), and 5xx.
  • Aggregate lightweight, thread-safe network metrics.

Lifetime and thread-safety:

  • A single easy handle (CURL*) is owned by the instance and reused across requests; therefore an http_client object is not thread-safe. Use one instance per calling thread.
  • curl_global_init is performed once per process via std::call_once.

Definition at line 50 of file http_client.hpp.

Member Typedef Documentation

◆ curl_url_ptr

using corespace::http_client::curl_url_ptr = std::unique_ptr<CURLU, decltype(&curl_url_cleanup)>
private

Unique pointer type for CURLU with proper deleter.

Definition at line 112 of file http_client.hpp.

Constructor & Destructor Documentation

◆ http_client()

corespace::http_client::http_client ( )
explicit

Construct a client and initialize libcurl.

Effects:

  • Ensures curl_global_init is called exactly once process-wide.
  • Creates an easy handle and installs default options: user agent, Accept header, redirect following, transparent decoding, timeouts, and signal suppression.
Exceptions
std::runtime_errorif libcurl initialization fails or header allocation fails.

Definition at line 42 of file http_client.cpp.

42 {
43 std::call_once(global_curl, curl_inited);
44
45 curl.reset(curl_easy_init());
46 if (!curl) {
47 throw std::runtime_error("curl_easy_init failed");
48 }
49
50 const std::string accept_header = "Accept: " + opt.accept;
51 curl_slist* headers = curl_slist_append(nullptr, accept_header.c_str());
52 if (!headers) {
53 throw std::runtime_error("failed to allocate curl headers");
54 }
55 header_list.reset(headers);
56
57 curl_easy_setopt(curl.get(), CURLOPT_USERAGENT, opt.user_agent.c_str());
58 curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header_list.get());
59 curl_easy_setopt(curl.get(), CURLOPT_FOLLOWLOCATION, 1L);
60 curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, "");
61 curl_easy_setopt(curl.get(), CURLOPT_NOSIGNAL, 1L);
62 curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT_MS, opt.timeout_ms);
63 curl_easy_setopt(curl.get(), CURLOPT_CONNECTTIMEOUT_MS, opt.connect_ms);
64}
std::unique_ptr< curl_slist, decltype(&curl_slist_free_all)> header_list
Owned request header list.
const network_options opt
Fixed options installed at construction.
std::unique_ptr< CURL, decltype(&curl_easy_cleanup)> curl
Reused easy handle (not thread-safe).

References corespace::anonymous_namespace{http_client.cpp}::curl_inited(), and corespace::anonymous_namespace{http_client.cpp}::global_curl.

Here is the call graph for this function:

Member Function Documentation

◆ apply_server_retry_hint()

void corespace::http_client::apply_server_retry_hint ( long long & sleep_ms) const
private

Apply server-provided retry hint if present.

If CURLINFO_RETRY_AFTER yields a non-negative value, interpret it as seconds and raise sleep_ms to at least that many milliseconds.

Parameters
sleep_msIn/out: proposed client backoff in milliseconds.

Definition at line 360 of file http_client.cpp.

360 {
361 curl_off_t retry_after = -1;
362 if (curl_easy_getinfo(curl.get(), CURLINFO_RETRY_AFTER, &retry_after)
363 == CURLE_OK
364 && retry_after >= 0) {
365 const long long server_hint_ms
366 = std::chrono::duration_cast<std::chrono::milliseconds>(
367 std::chrono::seconds(retry_after)
368 )
369 .count();
370 sleep_ms = std::max(sleep_ms, server_hint_ms);
371 }
372}

Referenced by get(), post_form(), and post_raw().

Here is the caller graph for this function:

◆ build_form_body()

std::string corespace::http_client::build_form_body ( const parameter_list & form) const
private

Definition at line 292 of file http_client.cpp.

292 {
293 std::string body;
294 bool first = true;
295 for (const auto& [key, value] : form) {
296 char* ekey = curl_easy_escape(
297 curl.get(), key.c_str(), static_cast<int>(key.size())
298 );
299 char* evalue = curl_easy_escape(
300 curl.get(), value.data(), static_cast<int>(value.size())
301 );
302 if (!first) {
303 body.push_back('&');
304 }
305 body.append(ekey ? ekey : "");
306 body.push_back('=');
307 body.append(evalue ? evalue : "");
308 if (ekey) {
309 curl_free(ekey);
310 }
311 if (evalue) {
312 curl_free(evalue);
313 }
314 first = false;
315 }
316 return body;
317}
@ form
Lexeme form IDs such as "L<lexeme>-F<form>".
Definition utils.hpp:52

◆ build_url()

http_client::curl_url_ptr corespace::http_client::build_url ( std::string_view url,
const parameter_list & params )
staticprivate

Construct a CURLU handle from url and append params.

Each parameter is URL-encoded and appended via CURLU_APPENDQUERY.

Parameters
urlBase URL.
paramsQuery parameters.
Returns
Owning smart pointer to a configured CURLU handle.
Exceptions
std::runtime_errorif allocation or URL assembly fails.

Definition at line 173 of file http_client.cpp.

175 {
176 curl_url_ptr url_handle(curl_url(), &curl_url_cleanup);
177 if (!url_handle) {
178 throw std::runtime_error("curl_url failed");
179 }
180
181 const std::string url_copy(url);
182 if (curl_url_set(url_handle.get(), CURLUPART_URL, url_copy.c_str(), 0)
183 != CURLUE_OK) {
184 throw std::runtime_error("failed to set request url");
185 }
186
187 for (const auto& [key, value] : params) {
188 std::string parameter = key + "=" + std::string(value);
189 if (curl_url_set(
190 url_handle.get(), CURLUPART_QUERY, parameter.c_str(),
191 CURLU_APPENDQUERY | CURLU_URLENCODE
192 )
193 != CURLUE_OK) {
194 throw std::runtime_error("failed to append query parameter");
195 }
196 }
197
198 return url_handle;
199}
std::unique_ptr< CURLU, decltype(&curl_url_cleanup)> curl_url_ptr
Unique pointer type for CURLU with proper deleter.
std::pair< std::string, std::string > parameter
Single query parameter: key=value (pre-encoding is handled by libcurl).
Definition utils.hpp:60

◆ get()

http_response corespace::http_client::get ( std::string_view url,
const parameter_list & params = {},
std::string_view override = {} )

Perform an HTTP GET to url with optional query params.

Behavior:

  • Builds a CURLU URL with params URL-encoded and appended.
  • Executes the request; on non-2xx or transport errors, applies the retry policy up to opt.max_retries with jittered backoff and an optional server Retry-After hint.
  • On success (2xx + CURLE_OK) returns the populated response.

Failure:

  • If all attempts fail with a libcurl error, throws std::runtime_error("curl error: ...").
  • If all attempts return non-success HTTP codes, throws std::runtime_error("http error: <status>").

Metrics:

  • Updates metrics after each attempt (including retries).
Parameters
urlAbsolute or base URL.
paramsOptional list of query parameters to append.
override
Returns
http_response on success (2xx).
Exceptions
std::runtime_erroron terminal failure as described above.

Definition at line 68 of file http_client.cpp.

71 {
72 std::lock_guard lk(mu);
73 const auto url_handle = build_url(url, params);
74 for (int attempt = 1;; ++attempt) {
75 std::chrono::milliseconds elapsed { 0l };
76 http_response response
77 = request_get(url_handle.get(), elapsed, override);
78
79 update_metrics(response, elapsed);
80
81 const bool net_ok = (response.error_code == CURLE_OK);
82 if (status_good(response)) {
83 return response;
84 }
85 if (attempt <= opt.max_retries && status_retry(response, net_ok)) {
86 ++metrics.retries;
87 long long sleep_ms = next_delay(attempt);
89 metrics.sleep_ms += sleep_ms;
90 std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms));
91 continue;
92 }
93
94 if (!net_ok) {
95 throw std::runtime_error("curl error: " + response.error_message);
96 }
97 throw std::runtime_error(
98 "http error: " + std::to_string(response.status_code)
99 );
100 }
101}
static bool status_retry(const http_response &response, bool net_ok)
Retry predicate for transient outcomes.
network_metrics metrics
Aggregated metrics (atomic counters).
long long next_delay(int attempt) const
Compute the next backoff delay for attempt (1-based).
http_response request_get(CURLU *url_handle, std::chrono::milliseconds &elapsed, std::string_view override={}) const
Execute a single HTTP GET using the prepared URL handle.
static curl_url_ptr build_url(std::string_view url, const parameter_list &params)
Construct a CURLU handle from url and append params.
static bool status_good(const http_response &response)
Success predicate: transport OK and HTTP 2xx.
void apply_server_retry_hint(long long &sleep_ms) const
Apply server-provided retry hint if present.
void update_metrics(const http_response &response, std::chrono::milliseconds elapsed)
Update counters and histograms after an attempt.

References apply_server_retry_hint(), corespace::http_response::error_code, next_delay(), status_good(), and update_metrics().

Here is the call graph for this function:

◆ metrics_info()

const network_metrics & corespace::http_client::metrics_info ( ) const
nodiscard

Access aggregated network metrics.

Returns
Const reference to the metrics snapshot.

Definition at line 66 of file http_client.cpp.

66{ return metrics; }

◆ next_delay()

long long corespace::http_client::next_delay ( int attempt) const
nodiscardprivate

Compute the next backoff delay for attempt (1-based).

Strategy: exponential backoff with full jitter. The base grows as retry_base_ms * 2^(attempt-1) and a uniform random component in [0, base] is added; the result is capped at retry_max_ms.

Parameters
attemptAttempt number starting from 1.
Returns
Milliseconds to sleep before the next attempt.

Definition at line 354 of file http_client.cpp.

354 {
355 const long long base = opt.retry_base_ms * (1 << (attempt - 1));
356 std::uniform_int_distribution<long long> d(0, base);
357 return std::min(base + d(rng()), opt.retry_max_ms);
358}
std::mt19937_64 & rng()
Shared PRNG seeded on first use.
Definition rng.cpp:28

Referenced by get(), post_form(), and post_raw().

Here is the caller graph for this function:

◆ post_form()

http_response corespace::http_client::post_form ( std::string_view url,
const parameter_list & form,
const parameter_list & query = {},
std::string_view override = {} )

Definition at line 103 of file http_client.cpp.

106 {
107 std::lock_guard lk(mu);
108 const auto url_handle = build_url(url, query);
109 const std::string body = build_form_body(form);
110 for (int attempt = 1;; ++attempt) {
111 std::chrono::milliseconds elapsed { 0l };
112 http_response response = request_post(
113 url_handle.get(), elapsed, "application/x-www-form-urlencoded",
114 body, override
115 );
116 update_metrics(response, elapsed);
117 const bool net_ok = (response.error_code == CURLE_OK);
118 if (status_good(response)) {
119 return response;
120 }
121 if (attempt <= opt.max_retries && status_retry(response, net_ok)) {
122 ++metrics.retries;
123 long long sleep_ms = next_delay(attempt);
124 apply_server_retry_hint(sleep_ms);
125 metrics.sleep_ms += sleep_ms;
126 std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms));
127 continue;
128 }
129 if (!net_ok) {
130 throw std::runtime_error("curl error: " + response.error_message);
131 }
132 throw std::runtime_error(
133 "http error: " + std::to_string(response.status_code)
134 );
135 }
136}
http_response request_post(CURLU *url_handle, std::chrono::milliseconds &elapsed, std::string_view content_type, std::string_view body, std::string_view override) const
std::string build_form_body(const parameter_list &form) const

References apply_server_retry_hint(), corespace::http_response::error_code, next_delay(), status_good(), and update_metrics().

Here is the call graph for this function:

◆ post_raw()

http_response corespace::http_client::post_raw ( std::string_view url,
std::string_view body,
std::string_view content_type,
const parameter_list & query = {},
std::string_view override = {} )

Definition at line 138 of file http_client.cpp.

142 {
143 std::lock_guard lk(mu);
144 const auto url_handle = build_url(url, query);
145 const std::string body_copy(body);
146 for (int attempt = 1;; ++attempt) {
147 std::chrono::milliseconds elapsed { 0l };
148 http_response response = request_post(
149 url_handle.get(), elapsed, content_type, body_copy, override
150 );
151 update_metrics(response, elapsed);
152 const bool net_ok = (response.error_code == CURLE_OK);
153 if (status_good(response)) {
154 return response;
155 }
156 if (attempt <= opt.max_retries && status_retry(response, net_ok)) {
157 ++metrics.retries;
158 long long sleep_ms = next_delay(attempt);
159 apply_server_retry_hint(sleep_ms);
160 metrics.sleep_ms += sleep_ms;
161 std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms));
162 continue;
163 }
164 if (!net_ok) {
165 throw std::runtime_error("curl error: " + response.error_message);
166 }
167 throw std::runtime_error(
168 "http error: " + std::to_string(response.status_code)
169 );
170 }
171}

References apply_server_retry_hint(), corespace::http_response::error_code, next_delay(), status_good(), and update_metrics().

Here is the call graph for this function:

◆ request_get()

http_response corespace::http_client::request_get ( CURLU * url_handle,
std::chrono::milliseconds & elapsed,
std::string_view override = {} ) const
private

Execute a single HTTP GET using the prepared URL handle.

Side effects:

  • Installs write callback to accumulate the response body.
  • Measures elapsed steady-clock time and returns it via elapsed.
  • Reads HTTP status and headers after the transfer.
Parameters
url_handlePrepared CURLU handle (owned by caller).
elapsedOut: time spent in curl_easy_perform.
override
Returns
Populated http_response (may carry a libcurl error).

Definition at line 201 of file http_client.cpp.

204 {
205 using namespace std::chrono;
206
207 http_response response;
208
209 curl_slist* tmp_headers = nullptr;
210 if (!override.empty()) {
211 const std::string h = "Accept: " + std::string(override);
212 tmp_headers = curl_slist_append(nullptr, h.c_str());
213 curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, tmp_headers);
214 } else {
215 curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header_list.get());
216 }
217
218 curl_easy_setopt(curl.get(), CURLOPT_HTTPGET, 1L);
219 curl_easy_setopt(curl.get(), CURLOPT_CURLU, url_handle);
220 curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, write_callback);
221 curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &response.text);
222
223 const auto t0 = steady_clock::now();
224 response.error_code = curl_easy_perform(curl.get());
225 curl_easy_setopt(curl.get(), CURLOPT_CURLU, nullptr);
226 const auto t1 = steady_clock::now();
227 elapsed = duration_cast<milliseconds>(t1 - t0);
228
229 curl_easy_getinfo(
230 curl.get(), CURLINFO_RESPONSE_CODE, &response.status_code
231 );
232 update_headers(response);
233
234 if (response.error_code != CURLE_OK) {
235 response.error_message = curl_easy_strerror(response.error_code);
236 }
237
238 if (tmp_headers) {
239 curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header_list.get());
240 curl_slist_free_all(tmp_headers);
241 }
242
243 return response;
244}
void update_headers(http_response &response) const
Refresh the header multimap from the last transfer.
static size_t write_callback(const char *ptr, size_t size, size_t n, void *data)
libcurl write callback: append chunk to response body.

References corespace::http_response::error_code, corespace::http_response::error_message, and update_headers().

Here is the call graph for this function:

◆ request_post()

http_response corespace::http_client::request_post ( CURLU * url_handle,
std::chrono::milliseconds & elapsed,
std::string_view content_type,
std::string_view body,
std::string_view override ) const
private

Definition at line 246 of file http_client.cpp.

250 {
251 using namespace std::chrono;
252 http_response response;
253 curl_slist* tmp_headers = nullptr;
254
255 const std::string ct = "Content-Type: " + std::string(content_type);
256 tmp_headers = curl_slist_append(tmp_headers, ct.c_str());
257 const std::string acc = "Accept: "
258 + std::string(override.empty() ? opt.accept : std::string(override));
259 tmp_headers = curl_slist_append(tmp_headers, acc.c_str());
260 curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, tmp_headers);
261
262 curl_easy_setopt(curl.get(), CURLOPT_CURLU, url_handle);
263 curl_easy_setopt(curl.get(), CURLOPT_POST, 1L);
264 curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS, body.data());
265 curl_easy_setopt(
266 curl.get(), CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size())
267 );
268 curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, write_callback);
269 curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &response.text);
270 const auto t0 = steady_clock::now();
271 response.error_code = curl_easy_perform(curl.get());
272 curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS, nullptr);
273 curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDSIZE, 0L);
274 curl_easy_setopt(curl.get(), CURLOPT_POST, 0L);
275 curl_easy_setopt(curl.get(), CURLOPT_CURLU, nullptr);
276 const auto t1 = steady_clock::now();
277 elapsed = duration_cast<milliseconds>(t1 - t0);
278 curl_easy_getinfo(
279 curl.get(), CURLINFO_RESPONSE_CODE, &response.status_code
280 );
281 update_headers(response);
282 if (response.error_code != CURLE_OK) {
283 response.error_message = curl_easy_strerror(response.error_code);
284 }
285 curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header_list.get());
286 if (tmp_headers) {
287 curl_slist_free_all(tmp_headers);
288 }
289 return response;
290}

References corespace::http_response::error_code, corespace::http_response::error_message, and update_headers().

Here is the call graph for this function:

◆ status_good()

bool corespace::http_client::status_good ( const http_response & response)
staticnodiscardprivate

Success predicate: transport OK and HTTP 2xx.

Parameters
responseResponse to check.
Returns
true if CURLE_OK and 200 <= status < 300.

Definition at line 342 of file http_client.cpp.

342 {
343 return response.error_code == CURLE_OK && response.status_code >= 200
344 && response.status_code < 300;
345}

References corespace::http_response::error_code.

Referenced by get(), post_form(), and post_raw().

Here is the caller graph for this function:

◆ status_retry()

bool corespace::http_client::status_retry ( const http_response & response,
bool net_ok )
staticnodiscardprivate

Retry predicate for transient outcomes.

Retries on:

  • any libcurl error (i.e., !net_ok),
  • HTTP 408 (Request Timeout),
  • HTTP 429 (Too Many Requests),
  • HTTP 5xx.
Parameters
responseResponse to inspect.
net_okWhether the transport completed without libcurl error.
Returns
true if another attempt should be made.

Definition at line 347 of file http_client.cpp.

349 {
350 return !net_ok || response.status_code == 429 || response.status_code == 408
351 || (response.status_code >= 500 && response.status_code < 600);
352}

◆ update_headers()

void corespace::http_client::update_headers ( http_response & response) const
private

Refresh the header multimap from the last transfer.

Enumerates headers via curl_easy_nextheader and fills response.header.

Parameters
responseResponse object to update.

Definition at line 319 of file http_client.cpp.

319 {
320 response.header.clear();
321 for (curl_header* header = nullptr;;) {
322 header = curl_easy_nextheader(curl.get(), CURLH_HEADER, 0, header);
323 if (!header) {
324 break;
325 }
326 response.header.emplace(header->name, header->value);
327 }
328}

Referenced by request_get(), and request_post().

Here is the caller graph for this function:

◆ update_metrics()

void corespace::http_client::update_metrics ( const http_response & response,
std::chrono::milliseconds elapsed )
private

Update counters and histograms after an attempt.

Increments requests, accumulates network_ms, bumps status histogram (if within bounds), and adds to bytes_received.

Parameters
responseResult of the attempt.
elapsedDuration spent in libcurl during the attempt.

Definition at line 330 of file http_client.cpp.

332 {
333 ++metrics.requests;
334 metrics.network_ms += elapsed.count();
335
336 if (response.status_code < metrics.statuses.size()) {
337 ++metrics.statuses[response.status_code];
338 }
339 metrics.bytes_received += response.text.size();
340}

Referenced by get(), post_form(), and post_raw().

Here is the caller graph for this function:

◆ write_callback()

size_t corespace::http_client::write_callback ( const char * ptr,
size_t size,
size_t n,
void * data )
staticprivate

libcurl write callback: append chunk to response body.

Parameters
ptrPointer to received data.
sizeElement size.
nNumber of elements.
datastd::string* accumulator (response body).
Returns
Number of bytes consumed (size * n).

Definition at line 374 of file http_client.cpp.

376 {
377 const size_t total = size * n;
378 auto* text = static_cast<std::string*>(data);
379 text->append(ptr, total);
380 return total;
381}

Member Data Documentation

◆ curl

std::unique_ptr<CURL, decltype(&curl_easy_cleanup)> corespace::http_client::curl
private
Initial value:
{
nullptr, &curl_easy_cleanup
}

Reused easy handle (not thread-safe).

Definition at line 226 of file http_client.hpp.

226 {
227 nullptr, &curl_easy_cleanup
228 };

◆ header_list

std::unique_ptr<curl_slist, decltype(&curl_slist_free_all)> corespace::http_client::header_list
private
Initial value:
{
nullptr, &curl_slist_free_all
}

Owned request header list.

Definition at line 229 of file http_client.hpp.

229 {
230 nullptr, &curl_slist_free_all
231 };

◆ metrics

network_metrics corespace::http_client::metrics
private

Aggregated metrics (atomic counters).

Definition at line 224 of file http_client.hpp.

◆ mu

std::mutex corespace::http_client::mu
mutableprivate

Definition at line 225 of file http_client.hpp.

◆ opt

const network_options corespace::http_client::opt {}
private

Fixed options installed at construction.

Definition at line 223 of file http_client.hpp.

223{};

The documentation for this class was generated from the following files: