ProtoCore v0.0.2
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
edge_cache_proxy.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file edge_cache_proxy.h
6 * @brief CDN edge-cache tier - server glue (PC_ENABLE_EDGE_CACHE).
7 *
8 * Wires the pure engine (edge_cache) + async fetch (edge_fetch) into a PC: registers the
9 * cache as a middleware and installs the async-fetch poll hook, maps request path prefixes to upstream
10 * origins (fetched over pc_client), and serves hits with the constant-memory send-pump. A miss or a
11 * stale-entry revalidation suspends the client request and drives the origin fetch from the slot's poll,
12 * so the worker never stalls; every failure path fails open. Purge + stats round it out.
13 *
14 * @author Douglas Quigg (dstroy0)
15 * @date 2026
16 */
17
18#ifndef PROTOCORE_EDGE_CACHE_PROXY_H
19#define PROTOCORE_EDGE_CACHE_PROXY_H
20
21#include "protocore_config.h"
22
23#if PC_ENABLE_EDGE_CACHE
24
25#include "services/web/edge_cache/edge_cache.h" // EdgeCacheStats
26#include <stddef.h>
27#include <stdint.h>
28
29class PC;
30
31/**
32 * @brief Enable the edge cache on @p server: register the cache middleware + the async-fetch poll hook,
33 * bind the origin transport to pc_client, and clear the L1 store. Call once.
34 */
35void pc_edge_cache_enable(PC &server);
36
37/**
38 * @brief Map a request path prefix to an upstream origin (e.g. "/cdn/" -> "http://origin.local").
39 *
40 * A cacheable GET/HEAD under @p path_prefix is fetched from the origin host + the full request path. An
41 * `https://` origin is fetched over TLS when PC_ENABLE_EDGE_ORIGIN_TLS is set, otherwise rejected.
42 * @return false if the map table is full, an argument overflows, or the origin URL is https (TLS off) /
43 * malformed.
44 */
45bool pc_edge_cache_map(const char *path_prefix, const char *origin_base_url);
46
47#if PC_ENABLE_EDGE_ORIGIN_TLS
48/**
49 * @brief Set the CA used to verify a TLS (`https://`) origin (PEM incl. NUL, or DER). Without a CA the
50 * origin fetch is encrypt-only (no authentication - MITM-able); a CA switches to full chain +
51 * hostname verification. NOTE: the client-TLS trust store is shared, so this CA also applies to
52 * MQTTS / wss / the HTTP client. Pass nullptr to clear. Call before the first https fetch.
53 */
54void pc_edge_cache_set_origin_ca(const uint8_t *ca_pem, size_t len);
55
56/** @brief Pin the origin cert by the SHA-256 of its DER (32 bytes); nullptr clears. Also shared client-wide. */
57void pc_edge_cache_set_origin_pin(const uint8_t sha256[32]);
58#endif
59
60#if PC_ENABLE_DBM
61struct pc_dbm;
62/**
63 * @brief Bind an L2 persistent tier: an opened dbm handle (on a mounted WAL store, SD-backed on device)
64 * the cache spills evicted L1 entries to and promotes them back from - so the cached set survives
65 * a reboot. Pass nullptr to detach. Call after ::pc_edge_cache_enable.
66 *
67 * Only entries carrying a validator are spilled (a promoted entry is force-revalidated, since the
68 * monotonic clock resets across a reboot). The dbm should be dedicated to the cache.
69 */
70void pc_edge_cache_bind_sd(pc_dbm *dbm);
71#endif
72
73#if PC_ENABLE_EDGE_MESH
74/**
75 * @brief Add a sibling peer to query on a full local miss before hitting the origin (mesh sibling cache).
76 *
77 * On a cold miss the cache asks each configured peer (in order, first hit wins) over a plaintext
78 * ConnProto::PROTO_MESH link and, if a peer holds a fresh copy, pulls and serves it (age propagated) without
79 * hitting the origin. @p host is a sibling's address, @p port the port it serves PROTO_MESH on. @return false
80 * if the peer table is full or @p host is empty / too long. Pull-only: no push, no invalidation.
81 */
82bool pc_edge_cache_add_peer(const char *host, uint16_t port);
83
84/**
85 * @brief Serve sibling queries: register the PROTO_MESH handler so this node answers a peer's content-addressed
86 * request from its LOCAL cache (one hop - never re-queries this node's own origin or peers). Open the
87 * port first with `server.listen(port, ConnProto::PROTO_MESH)`. Call once.
88 */
89void pc_edge_cache_mesh_serve(void);
90#endif
91
92/** @brief Clear the L1 store, the L2 store (if bound), all route maps, and (mesh) the peer list. */
93void pc_edge_cache_reset(void);
94
95/** @brief Invalidate a single canonical key. @return true if an entry was purged. */
96bool pc_edge_cache_purge(const char *canonical_key);
97
98/** @brief Invalidate every entry whose request path begins with @p prefix. @return the count purged. */
99uint32_t pc_edge_cache_purge_prefix(const char *path_prefix);
100
101/** @brief Snapshot the cache counters. */
102void pc_edge_cache_stats(EdgeCacheStats *out);
103
104#endif // PC_ENABLE_EDGE_CACHE
105
106#endif // PROTOCORE_EDGE_CACHE_PROXY_H
Single-port HTTP server with deterministic, zero-allocation execution.
Definition protocore.h:348
CDN edge-cache tier - pure engine (PC_ENABLE_EDGE_CACHE).
User-facing configuration for ProtoCore.