DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
http_delivery.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 http_delivery.h
6 * @brief HTTP delivery optimizations: stale-while-revalidate, Range/206 delta fetch, SW precache
7 * (DETWS_ENABLE_HTTP_DELIVERY).
8 *
9 * Three pure cores that make HTTP serving cheaper on a constrained device, each mapping to a real web
10 * standard:
11 *
12 * - **Stale-while-revalidate** (RFC 5861): given a cached response's age and its `max-age` +
13 * `stale-while-revalidate` windows, decide FRESH / serve-stale-and-revalidate / EXPIRED, and build the
14 * matching `Cache-Control` header so a browser keeps the UI responsive while the device refreshes in
15 * the background.
16 * - **Delta / offset log fetch** (RFC 7233 byte ranges): parse a `Range: bytes=...` request against a
17 * resource of known length (all three forms - `X-Y`, `X-`, `-N`), and build the `Content-Range` header
18 * for the `206 Partial Content` reply, so a client streams only the new tail of a growing log.
19 * - **Service-worker precache manifest**: emit the versioned `{"version":..,"precache":[..]}` JSON a
20 * generated service worker consumes to cache-inject the app shell for offline / instant loads.
21 *
22 * Pure, zero heap, no stdlib (hand-rolled decimal parse/format), host-testable.
23 */
24
25#ifndef DETERMINISTICESPASYNCWEBSERVER_HTTP_DELIVERY_H
26#define DETERMINISTICESPASYNCWEBSERVER_HTTP_DELIVERY_H
27
28#include "ServerConfig.h"
29#include <stddef.h>
30#include <stdint.h>
31
32#if DETWS_ENABLE_HTTP_DELIVERY
33
34/** @brief Freshness verdict for a cached response. */
35/** @brief Cache-freshness verdict (the sole return of detws_delivery_swr). */
36enum class DeliveryVerdict : uint8_t
37{
38 DELIVERY_FRESH = 0, ///< age <= max-age: serve from cache, no revalidation.
39 DELIVERY_STALE_REVALIDATE = 1, ///< within the stale-while-revalidate window: serve stale, refresh in bg.
40 DELIVERY_EXPIRED = 2 ///< past both windows: must revalidate before serving.
41};
42
43/**
44 * @brief RFC 5861 freshness decision.
45 * @param age_s seconds since the response was generated.
46 * @param max_age_s the `max-age` window.
47 * @param swr_s the `stale-while-revalidate` window past max-age.
48 * @return DELIVERY_FRESH / DELIVERY_STALE_REVALIDATE / DELIVERY_EXPIRED.
49 */
50DeliveryVerdict detws_delivery_swr(uint32_t age_s, uint32_t max_age_s, uint32_t swr_s);
51
52/**
53 * @brief Build a `Cache-Control` value: `public, max-age=N[, stale-while-revalidate=M]`.
54 * The swr directive is omitted when @p swr_s is 0.
55 * @return length written (excl NUL), or 0 on overflow / bad args.
56 */
57size_t detws_delivery_cache_control(uint32_t max_age_s, uint32_t swr_s, char *out, size_t cap);
58
59/**
60 * @brief Parse a single-range `Range: bytes=...` header against a resource of @p total bytes.
61 *
62 * Handles `bytes=X-Y` (clamped), `bytes=X-` (X to end), and `bytes=-N` (last N). Multi-range requests
63 * (a comma) are treated as unsupported. On success @p start / @p end are the inclusive byte offsets.
64 * @return 1 if a satisfiable range was parsed; 0 otherwise (caller should send the full 200 or a 416).
65 */
66int detws_delivery_range(const char *range_header, uint32_t total, uint32_t *start, uint32_t *end);
67
68/**
69 * @brief Build the `Content-Range` value for a 206 reply: `bytes START-END/TOTAL`.
70 * @return length written (excl NUL), or 0 on overflow / bad args.
71 */
72size_t detws_delivery_content_range(uint32_t start, uint32_t end, uint32_t total, char *out, size_t cap);
73
74/**
75 * @brief Emit the service-worker precache manifest: `{"version":"..","precache":["/a","/b",...]}`.
76 * @param paths asset paths to precache (borrowed).
77 * @param n number of paths.
78 * @param version cache version tag (busts the SW cache on change).
79 * @return length written (excl NUL), or 0 on overflow / bad args. Strings are JSON-escaped.
80 */
81size_t detws_delivery_sw_manifest(const char *const *paths, size_t n, const char *version, char *out, size_t cap);
82
83#endif // DETWS_ENABLE_HTTP_DELIVERY
84#endif // DETERMINISTICESPASYNCWEBSERVER_HTTP_DELIVERY_H
User-facing configuration for DeterministicESPAsyncWebServer.