|
ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
|
Layer: L7 Application ยท Build flags: PC_ENABLE_HTTP_DELIVERY, PC_ENABLE_FILE_SERVING, PC_ENABLE_RANGE
A constrained device is a slow origin: it may be busy serving someone else, throttled, or asleep. Three standards make that acceptable to a browser, and this wires all three together.
1. Stale-while-revalidate (RFC 5861). set_cache_control_swr(60, 300) emits Cache-Control: public, max-age=60, stale-while-revalidate=300 on every served file. For 60 s the client just uses its copy; for 300 s after that it may serve the stale copy and refresh in the background. The page never blocks waiting on this device. The header is built by the same pc_delivery_cache_control core that backs the pc_delivery_swr decision, so the two cannot drift apart.
2. A service worker. pc_delivery_serve_sw() registers two routes:
| Route | Serves |
|---|---|
/sw.js | the worker (flash-resident asset) |
/precache.json | the versioned manifest from pc_delivery_sw_manifest() |
The worker precaches the listed shell, then serves it stale-while-revalidate client-side - so a repeat visit paints without touching the device at all, and still works while it is offline or asleep. The cache is named after the manifest version, so bumping it invalidates the old shell exactly once.
3. Byte ranges (RFC 7233). Already handled by the file server (PC_ENABLE_RANGE) - a client fetches only the new tail of a growing log with Range: bytes=N- and gets a 206. Note this lives in server/http_range.h, which is the single owner of the range math (shared with the edge cache); services/http_delivery deliberately does not carry a second parser.
HW-verified (2026-07-19) on an ESP32-P4 (Waveshare, wired Ethernet) serving real files from its SD card - a 1000-byte file of repeating 0123456789:
Every range form returned the exact expected bytes, and the unsatisfiable one returned 416 with the bytes */size form RFC 7233 requires rather than a truncated 206.
SHELL_VERSION is the cache key. Change a precached file and bump the version, or clients keep the old shell until their cache is evicted:
The manifest is rebuilt per request, so the list and version can change at runtime with no stale copy surviving. If it would not fit PC_DELIVERY_MANIFEST_BUF, the route answers 500 rather than serving truncated JSON a worker would choke on.
| Flag | Default | Meaning |
|---|---|---|
PC_DELIVERY_PRECACHE_MAX | 16 | most paths a manifest may list |
PC_DELIVERY_MANIFEST_BUF | 512 | buffer the manifest JSON is built into |
| Board | Flash | RAM |
|---|---|---|
| ESP32-S3 | 967,120 B (73%) | - |
| ESP32-P4 | 740,230 B (56%) | - |
The flags must reach the library build, so pass them as build flags: