ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
mdl_net_curl_internal.h File Reference

Module-private libcurl-backend helpers promoted for host unit tests. More...

#include <curl/curl.h>
#include <stddef.h>
#include "mdl_net.h"
#include "ra8_attributes.h"
#include "ra8_err.h"
Include dependency graph for mdl_net_curl_internal.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  buf_sink_t
 Bounded-buffer sink state for a page fetch. More...
struct  mdl_net_curl_body_state_t
 Test-visible bounded adapter from libcurl chunks to an injected sink. More...

Functions

ra8_err_t priv_mdl_net_curl_apply_cookies (CURL *curl, const mdl_net_bytes_t *cookies)
 Enable the cookie engine and import validated caller-owned rows.
ra8_err_t priv_mdl_net_curl_apply_ca_blob (CURL *curl, const mdl_net_bytes_t *ca_pem, struct curl_blob *blob)
 Bind complete caller-owned CA PEM bytes with NOCOPY semantics.
ra8_err_t priv_mdl_net_curl_classify (CURLcode code, bool overflow, long status)
 Map a completed libcurl transfer to an ra8_err_t (pure classifier).
size_t priv_mdl_net_curl_buf_write (char *data, size_t size, size_t nmemb, void *user)
 libcurl write callback: append into a bounded buffer, abort on cap.
size_t priv_mdl_net_curl_body_write (char *data, size_t size, size_t nmemb, void *user)
 Adapt one libcurl body chunk to an injected bounded sink.

Detailed Description

Module-private libcurl-backend helpers promoted for host unit tests.

The libcurl backend's transfer-result classifier and its bounded-buffer write callback are pure decisions with no network dependency, but they live in a translation unit that pulls in <curl/curl.h>. Promoting them to TU-external linkage here (per the "Test access to internal symbols" rule in CLAUDE.md) lets the host tests drive each status class and the overflow-abort path directly, rather than only through a live transfer that no test can perform.

Nothing here is part of the backend-facing API in mdl_net.h or the factory in mdl_net_curl.h; production callers use the vtable dispatchers.

Since
0.1.0

Definition in file mdl_net_curl_internal.h.

Function Documentation

◆ priv_mdl_net_curl_apply_ca_blob()

ra8_err_t priv_mdl_net_curl_apply_ca_blob ( CURL * curl,
const mdl_net_bytes_t * ca_pem,
struct curl_blob * blob )

Bind complete caller-owned CA PEM bytes with NOCOPY semantics.

Parameters
[in,out]curlFresh libcurl easy handle.
[in]ca_pemComplete nonempty PEM bytes, or an empty absent view.
[in,out]blobStable descriptor retained by the backend when supported.
Returns
Canonical validation, option, or unsupported status.
Return values
k_ra8_okSystem CA policy remains active or the blob was bound.
k_ra8_err_invalid_argThe view or blob descriptor is inconsistent.
k_ra8_err_not_supportedThis libcurl/TLS build lacks CA blob support.
k_ra8_failLibcurl rejected the custom CA option.
Precondition
Nonempty ca_pem bytes remain readable through backend destruction.
Postcondition
No CA filename or hidden file read is configured.
Note
The descriptor may be NULL only when custom CA blobs are unavailable.
Since
0.1.0

Applies validated caller-owned credentials to one easy handle. Borrowed storage remains caller-owned for libcurl's required lifetime.

Precondition
Every required pointer is non-null and remains valid for the call.
Postcondition
Documented outputs and the return value describe the same outcome.

Definition at line 422 of file mdl_net_curl_credentials.c.

References mdl_net_bytes_t::data, k_ra8_err_invalid_arg, k_ra8_err_not_supported, k_ra8_fail, k_ra8_ok, and mdl_net_bytes_t::length.

Referenced by internal_apply_security_opts().

◆ priv_mdl_net_curl_apply_cookies()

ra8_err_t priv_mdl_net_curl_apply_cookies ( CURL * curl,
const mdl_net_bytes_t * cookies )

Enable the cookie engine and import validated caller-owned rows.

Parameters
[in,out]curlFresh libcurl easy handle.
[in]cookiesNewline-delimited bounded cookie bytes.
Returns
Canonical validation or option status.
Return values
k_ra8_okEvery accepted cookie row was copied by libcurl.
k_ra8_err_invalid_argThe view or a row is malformed or unsafe.
k_ra8_err_invalid_sizeOne row exceeds the fixed importer bound.
k_ra8_faillibcurl rejected an otherwise valid option.
Precondition
curl and cookies are non-NULL.
Postcondition
Success enables the cookie engine without path-based file I/O.
Caller command strings cannot reach CURLOPT_COOKIELIST.
Note
Libcurl owns its copy of every accepted row.
Since
0.1.0

Applies validated caller-owned credentials to one easy handle. Borrowed storage remains caller-owned for libcurl's required lifetime.

Precondition
Every required pointer is non-null and remains valid for the call.

Definition at line 389 of file mdl_net_curl_credentials.c.

References mdl_net_bytes_t::data, internal_apply_cookie_line(), k_ra8_err_invalid_arg, k_ra8_fail, k_ra8_ok, and mdl_net_bytes_t::length.

Referenced by internal_apply_behavior_opts().

◆ priv_mdl_net_curl_body_write()

size_t priv_mdl_net_curl_body_write ( char * data,
size_t size,
size_t nmemb,
void * user )

Adapt one libcurl body chunk to an injected bounded sink.

Validates multiplication and configured capacity before dispatching one complete chunk to the injected writer.

Parameters
[in]dataBytes supplied by libcurl.
[in]sizeElement size.
[in]nmembElement count.
[in,out]usermdl_net_curl_body_state_t state.
Returns
Exact byte count accepted, or zero to abort libcurl.
Return values
0Overflow, invalid state, or sink failure aborted the transfer.
otherExact size * nmemb bytes accepted by the sink.
Precondition
Representable nonempty input is readable for size * nmemb bytes.
user is NULL or points to mutable callback state.
Postcondition
Overflow or sink failure is latched before returning zero.
Success advances the cumulative written extent exactly once.
Note
Signature is fixed by libcurl's callback ABI.
Since
0.1.0

Definition at line 247 of file mdl_net_curl.c.

References mdl_net_curl_body_state_t::cap, mdl_net_body_sink_t::ctx, k_ra8_err_invalid_state, k_ra8_ok, mdl_size_exceeds(), mdl_net_curl_body_state_t::overflow, RA8_PRIV, mdl_net_curl_body_state_t::sink, mdl_net_curl_body_state_t::sink_error, mdl_net_body_sink_t::write, and mdl_net_curl_body_state_t::written.

Referenced by internal_curl_get_body().

◆ priv_mdl_net_curl_buf_write()

size_t priv_mdl_net_curl_buf_write ( char * data,
size_t size,
size_t nmemb,
void * user )

libcurl write callback: append into a bounded buffer, abort on cap.

The registered CURLOPT_WRITEFUNCTION for a page fetch. Appends size * nmemb bytes into the buf_sink_t user unless doing so would exceed its capacity, in which case it latches overflow and returns 0 to abort the transfer (libcurl's contract for a short write).

Parameters
[in]dataBytes libcurl delivered (not NUL-terminated).
[in]sizeSize of each member (libcurl passes 1).
[in]nmembNumber of members.
[in,out]userThe buf_sink_t receiving the bytes, or NULL.
Returns
The number of members consumed, or 0 to abort.
Return values
nmembAll bytes were appended.
0user is NULL, or the append would exceed cap (overflow).
Precondition
user, when non-NULL, is a buf_sink_t with a valid buf/cap.
The caller treats a 0 return as a deliberate transfer abort.
Postcondition
On success sink->len advanced by size * nmemb.
On overflow sink->overflow is true and sink->buf is unchanged.
Note
Thread-safe: writes only the caller-provided sink.
MC/DC:
The two guards – user == NULL and (len + bytes) > cap – are single conditions, not compound decisions. Vectors: NULL sink, an appending write, and an over-cap write that latches overflow.
Since
0.1.0

Definition at line 228 of file mdl_net_curl.c.

References buf_sink_t::buf, buf_sink_t::cap, buf_sink_t::len, memcpy(), buf_sink_t::overflow, and RA8_PRIV.

Referenced by internal_curl_get_buf().

◆ priv_mdl_net_curl_classify()

ra8_err_t priv_mdl_net_curl_classify ( CURLcode code,
bool overflow,
long status )

Map a completed libcurl transfer to an ra8_err_t (pure classifier).

The backend's decision table, factored out of the getinfo wrapper so it is a pure function of the finished transfer's three observable outcomes and can be unit-tested for every status class without a network. Precedence is overflow, then timeout, then any other transport error, then the HTTP status class. Mapping distinct status classes to distinct codes is what lets the politeness governor tell a throttle (back off) from an absent page (skip) from a server error (retry later).

Parameters
[in]codelibcurl completion code from curl_easy_perform.
[in]overflowWhether a sink latched a size-cap overflow.
[in]statusHTTP response status (from CURLINFO_RESPONSE_CODE).
Returns
The classified transfer result.
Return values
k_ra8_err_no_memoverflow is true.
k_ra8_err_timeoutcode is CURLE_OPERATION_TIMEDOUT.
k_ra8_err_busyOK code and status is 429 or 503 (throttle).
k_ra8_err_not_foundOK code and status is 404 or another 4xx.
k_ra8_failAny other non-OK code, or status >= 500.
k_ra8_okOK code and status < 400.
Precondition
status is a meaningful HTTP status only when code == CURLE_OK.
The caller has finished the transfer before classifying it.
Postcondition
No state is modified.
Note
Thread-safe: depends only on its arguments.
MC/DC:
The status tests (status == 429 || status == 503, then status >= 500, then status >= 400) gate independent ifs reached only when code == CURLE_OK. The throttle test is a two-condition OR: vectors 429 and 503 each vary one condition true while a non-throttle status (e.g. 200/404/500) holds both false, and the 500/404/200 vectors exercise the remaining relational branches. Combined with the overflow and timeout vectors, every class the function distinguishes has a vector.
Since
0.1.0
Postcondition
Documented outputs and the return value describe the same outcome.

Definition at line 601 of file mdl_net_curl.c.

References k_ra8_err_no_mem, k_ra8_err_timeout, k_ra8_fail, priv_mdl_net_classify_http(), and RA8_PRIV.

Referenced by internal_finish_transfer().