36 if ((destination ==
nullptr) || (capacity == 0U) || (source ==
nullptr)) {
39 const size_t length =
strlen(source);
40 if (length >= capacity) {
41 destination[0] =
'\0';
44 memcpy(destination, source, length + 1U);
67 if (relative[0] ==
'\0') {
71 return mdl_path_join(series_directory, relative, existing,
sizeof(existing)) &&
100 "mdl: downloaded series cover is not a "
101 "supported image (");
105 return (output_error ==
k_ra8_ok) ? error : output_error;
141 if (bytes > UINT32_MAX) {
147 uint32_t accepted = 0U;
149 error = sink.
write(sink.
ctx, (
const uint8_t*)ctx->
page_buf, (uint32_t)bytes, &accepted);
151 if ((error ==
k_ra8_ok) && (accepted != (uint32_t)bytes)) {
156 return (aborted ==
k_ra8_ok) ? error : aborted;
183 uint32_t minimum_delay,
184 uint32_t maximum_delay)
209 error = (aborted ==
k_ra8_ok) ? error : aborted;
237 uint32_t minimum_delay,
238 uint32_t maximum_delay,
275 const char* series_directory)
277 if ((ctx ==
nullptr) || (series_directory ==
nullptr)) {
284 if (current && (ctx->
cache ==
nullptr) && !ctx->
refetch) {
288 if (!
mdl_path_join(series_directory,
"cover.download", holding,
sizeof(holding))) {
299 const uint32_t minimum_delay =
301 const uint32_t maximum_delay =
303 return (ctx->
cache !=
nullptr)
@ k_fw_fs_path_cap
Largest portable path including its NUL.
mdl_app_context_t * priv_mdl_app_context(void)
The working set the composition root bound with mdl_app_bind.
static bool internal_cover_copy(char *destination, size_t capacity, const char *source)
Copy one complete cover metadata string.
static ra8_err_t internal_cover_cached(mdl_fetch_ctx_t *ctx, const char *holding, const char *host, uint32_t minimum_delay, uint32_t maximum_delay, bool current)
Fetch or revalidate one cover through the persistent host cache.
static ra8_err_t internal_cover_finish(mdl_fetch_body_t *body, size_t bytes)
Validate, name, and publish one complete cover body transaction.
static ra8_err_t internal_cover_publish_cached(mdl_fetch_ctx_t *ctx, const char *holding, size_t bytes)
Feed one cached cover buffer into the validated image transaction.
static ra8_err_t internal_cover_stream(mdl_fetch_ctx_t *ctx, const char *holding, const char *host, uint32_t minimum_delay, uint32_t maximum_delay)
Fetch one cover directly into a private image transaction.
static bool internal_cover_current(mdl_fetch_ctx_t *ctx, const char *series_directory)
Determine whether the recorded local cover still has image magic.
ra8_err_t priv_mdl_app_ensure_series_cover(mdl_fetch_ctx_t *ctx, const char *series_directory)
Ensure series state names one verified cached or freshly fetched cover.
Module-private contract shared by the application-mode translation units.
ra8_err_t priv_mdl_app_report_cache(const char *url, const mdl_cache_result_t *result)
Report corruption recovery or verified cache reuse with staleness.
ra8_err_t mdl_cache_get_buf(mdl_cache_t *cache, const char *url, const mdl_net_req_t *base_request, mdl_cache_fetch_fn fetch, void *fetch_context, char *buffer, size_t capacity, size_t *out_length, mdl_net_resp_t *response, mdl_cache_result_t *result)
Fetch one document through the per-host persistent cache.
ra8_err_t priv_mdl_fetch_with_retry(mdl_fetch_ctx_t *ctx, const char *host, const char *url, const mdl_net_req_t *req, mdl_net_body_sink_t *sink, uint32_t jmin, uint32_t jmax, mdl_net_resp_t *out_resp, size_t *out_bytes)
Bounded, governed retry of one image transfer; last status latched.
void priv_mdl_fetch_record_fail(const mdl_fetch_ctx_t *ctx, const char *url, long status, ra8_err_t err)
Append one failure to the run's log (when set); always tally total.
ra8_err_t priv_mdl_fetch_cache_get_buf(void *context, const char *url, const mdl_net_req_t *request, char *buffer, size_t capacity, size_t *out_length, mdl_net_resp_t *response)
Fetch one cache attempt through governor and bounded retry policy.
ra8_err_t priv_mdl_fetch_body_commit(mdl_fetch_body_t *body)
Validate exact size/hash and publish one prepared body.
mdl_net_body_sink_t priv_mdl_fetch_body_sink(mdl_fetch_body_t *body)
Return the network sink view of one body state.
ra8_err_t priv_mdl_fetch_body_prepare(mdl_fetch_body_t *body)
Finish prefix classification and make a nonempty stage commit-ready.
ra8_err_t priv_mdl_fetch_body_init_image(mdl_fetch_body_t *body, mdl_storage_t *storage, const char *target_abs, const char *target_rel)
Initialize a magic-typed image body sink.
ra8_err_t priv_mdl_fetch_body_abort(mdl_fetch_body_t *body)
Abort any private stage owned by a body sink.
Portable single-transaction response-body sink for media fetches.
struct mdl_fetch_cache_request mdl_fetch_cache_request_t
Caller-owned governor parameters for one cached buffer fetch.
@ k_mdl_gov_host_max
Host-key buffer bytes (matches config).
bool mdl_path_join(const char *parent, const char *seg, char *out, size_t cap)
Join one safe child segment under a parent directory path.
bool mdl_session_url_allowed(mdl_session_t *session, const char *url, uint32_t *crawl_delay_ms)
Decide whether url may be fetched under robots.txt, and its delay.
ra8_err_t priv_mdl_stream_text(ra8_err_t prior, ra8_io_stream_t *stream, const char *text)
Append text unless an earlier operation already failed.
ra8_err_t priv_mdl_stream_u64(ra8_err_t prior, ra8_io_stream_t *stream, uint64_t value)
Append one unsigned integer unless an earlier append failed.
bool mdl_url_host(const char *url, char *out, size_t cap)
Extract the authority (host and optional port) from an http(s) URL.
ra8_err_t mdl_urlname_sniff_file(mdl_storage_t *storage, const char *file_path, const char *content_type, char *out_ext, size_t ext_cap, char *out_mime, size_t mime_cap)
Sniff true image extension and MIME type from portable storage.
#define RA8_PRIV
Module-private helper: shared across TUs but only inside one library.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_access_denied
Operation refused because the target is protected against it.
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
size_t strlen(const char *s)
Calculate string length.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
mdl_state_t state
Persistent tracked state.
Observable outcome of one cache lookup.
bool body_reused
Returned bytes came from verified storage.
Caller-owned state for one retryable streamed fetch.
char actual_rel[k_mdl_relpath_max]
Magic-derived relative path.
char host[k_mdl_gov_host_max]
Governor host key.
Everything mdl_fetch_run needs, injected for testability.
const mdl_site_t * site
Selectors + politeness bounds.
mdl_storage_t * storage
Portable storage binding + workspaces.
char * page_buf
Chapter-HTML scratch (caller-owned).
mdl_cache_t * cache
Per-host HTML cache binding.
bool refetch
Ignore local page reuse and hit network.
mdl_session_t * session
Identity + robots + net backend.
size_t page_cap
Capacity of page_buf.
uint32_t timeout_ms
Per-request time budget.
Caller-owned lifecycle and write seam for one response body.
mdl_net_body_write_fn write
Consume one response chunk.
void * ctx
Caller-owned callback state.
Per-request session parameters.
Per-transfer response metadata surfaced to the politeness governor.
long status
Finished transfer's HTTP status, 0 if none.
const char * user_agent
Full UA header (caller-owned).
uint32_t img_delay_max
Per-image spacing ceiling.
uint32_t img_delay_min
Per-image spacing floor.
char cover_path[k_mdl_relpath_max]
Local cover path.
char series_url[k_mdl_url_max]
Series page URL.