ProtoCore v0.0.2
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
http_delivery_routes.cpp
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 http_delivery_routes.cpp
6 * @brief Serves the service worker + its precache manifest (see http_delivery.h).
7 *
8 * Separated from the host-testable core (http_delivery.cpp) so the manifest serializer unit-tests
9 * without pulling in the server, matching dashboard.cpp / dashboard_routes.cpp.
10 */
11
13
14#if PC_ENABLE_HTTP_DELIVERY && defined(ARDUINO)
15
16#include "network_drivers/application/web_assets.h" // PC_SERVICE_WORKER
17#include "protocore.h"
19
20// All service-worker route state, owned by one instance (internal linkage): the server handle plus
21// the borrowed precache list the manifest is rebuilt from on each request. The route handlers are
22// fixed-signature callbacks, so they reach this single owner directly.
23struct DeliveryRoutesCtx
24{
25 PC *srv = nullptr;
26 const char *const *paths = nullptr;
27 size_t n = 0;
28 const char *version = nullptr;
29};
30static DeliveryRoutesCtx s_delr;
31
32static void sw_script_handler(uint8_t slot_id, HttpReq *req)
33{
34 (void)req;
35 if (s_delr.srv)
36 {
37 s_delr.srv->send(slot_id, 200, PC_MIME_JAVASCRIPT, PC_SERVICE_WORKER);
38 }
39}
40
41static void sw_manifest_handler(uint8_t slot_id, HttpReq *req)
42{
43 (void)req;
44 if (!s_delr.srv)
45 {
46 return;
47 }
49 // Rebuilt per request rather than cached: it is small, and the version/list can be changed at
50 // runtime without a stale copy surviving.
51 if (pc_delivery_sw_manifest(s_delr.paths, s_delr.n, s_delr.version, buf, sizeof(buf)) == 0)
52 {
53 s_delr.srv->send(slot_id, 500, PC_MIME_JSON, "{\"error\":\"manifest too large\"}");
54 return;
55 }
56 s_delr.srv->send(slot_id, 200, PC_MIME_JSON, buf);
57}
58
59bool pc_delivery_serve_sw(PC &srv, const char *const *paths, size_t n, const char *version)
60{
61 if (!paths || n == 0 || n > PC_DELIVERY_PRECACHE_MAX || !version)
62 {
63 return false;
64 }
65 s_delr.srv = &srv;
66 s_delr.paths = paths;
67 s_delr.n = n;
68 s_delr.version = version;
69 // The worker's scope is the path it is served from, so it must sit at the root to control the
70 // whole origin - "/sw.js", not "/assets/sw.js".
71 srv.on("/sw.js", HttpMethod::HTTP_GET, sw_script_handler);
72 srv.on("/precache.json", HttpMethod::HTTP_GET, sw_manifest_handler);
73 return true;
74}
75
76#endif // PC_ENABLE_HTTP_DELIVERY && ARDUINO
Single-port HTTP server with deterministic, zero-allocation execution.
Definition protocore.h:348
void on(const char *path, HttpMethod method, Handler callback)
Register a route handler.
HTTP delivery optimizations: stale-while-revalidate, Range/206 delta fetch, SW precache (PC_ENABLE_HT...
Shared HTTP Content-Type ("MIME") string constants (one source of truth).
Layer 7 (Application) - public HTTP routing API.
@ HTTP_GET
Safe, idempotent read.
#define PC_DELIVERY_MANIFEST_BUF
Buffer the precache manifest JSON is built into (PC_DELIVERY_MANIFEST_BUF).
#define PC_DELIVERY_PRECACHE_MAX
Most asset paths a service-worker precache manifest may list (PC_DELIVERY_PRECACHE_MAX).
Fully-parsed HTTP/1.1 request.
const char PC_SERVICE_WORKER[]
Service worker: precaches the app shell from the versioned manifest and serves it stale-while-revalid...
Layer 7 (Application) - embedded web assets generated from web_assets/input/.