DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
presentation.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 presentation.h
6 * @brief Layer 6 (Presentation) - wires the transport ring buffer to the HTTP parser.
7 *
8 * This layer owns two responsibilities:
9 * 1. Drain bytes via the transport read API (det_conn_available / det_conn_read_byte)
10 * and feed them into the HTTP parser one at a time - the ring is transport's.
11 * 2. Expose slot-indexed `http_reset()` and `http_parse()` helpers that the
12 * session layer (server_tick) and application layer (handle) call by slot ID.
13 *
14 * The actual HTTP parsing logic lives in `http_parser.h / http_parser.cpp`.
15 * This file merely includes it so callers only need one include.
16 *
17 * @author Douglas Quigg (dstroy0)
18 * @date 2026
19 */
20
21#ifndef DETERMINISTICESPASYNCWEBSERVER_PRESENTATION_H
22#define DETERMINISTICESPASYNCWEBSERVER_PRESENTATION_H
23
24#include "../transport/tcp.h"
26
27// ---------------------------------------------------------------------------
28// Slot-indexed wrappers called by the session and application layers
29// ---------------------------------------------------------------------------
30
31/**
32 * @brief Reset the HTTP parser for a connection slot.
33 *
34 * Delegates to http_parser_reset() for the slot's request struct.
35 * Silently ignores out-of-range slot IDs.
36 *
37 * @param slot_id Index into conn_pool / http_pool (0 … MAX_CONNS-1).
38 */
39void http_reset(uint8_t slot_id);
40
41#if DETWS_ENABLE_KEEPALIVE
42/**
43 * @brief Requests served on each connection slot (HTTP keep-alive fairness bound).
44 *
45 * Reset to 0 by http_conn_open() when a connection is accepted; incremented by
46 * the application layer per response it elects to keep alive. Lives here (not in
47 * TcpConn) so the transport layer stays free of HTTP semantics. Defined in
48 * presentation.cpp.
49 */
50extern uint16_t http_req_count[MAX_CONNS];
51#endif
52
53/**
54 * @brief Initialize a slot for a freshly-accepted HTTP connection.
55 *
56 * Resets the HTTP parser (like http_reset()) and, when keep-alive is enabled,
57 * zeroes the slot's persistent request counter. The session layer calls this on
58 * EvtType::EVT_CONNECT; http_reset() is used for the lighter inter-request reset that must
59 * not clear the counter. With keep-alive off this is identical to http_reset().
60 *
61 * @param slot_id Index into conn_pool / http_pool (0 … MAX_CONNS-1).
62 */
63void http_conn_open(uint8_t slot_id);
64
65/**
66 * @brief Drain the transport ring buffer and advance the HTTP parser.
67 *
68 * Reads all available bytes from the slot's transport ring buffer and feeds
69 * each byte to `http_parser_feed()`. Stops early if the parser reaches a
70 * terminal state (ParseState::PARSE_COMPLETE, ParseState::PARSE_ERROR, ParseState::PARSE_ENTITY_TOO_LARGE,
71 * ParseState::PARSE_URI_TOO_LONG).
72 *
73 * Silently ignores out-of-range slot IDs.
74 *
75 * @param slot_id Connection slot to parse.
76 */
77void http_parse(uint8_t slot_id);
78
79/**
80 * @brief The HTTP connection ProtoHandler (the L5 dispatch seam).
81 *
82 * The accept/data/close handlers - the data path multiplexes the TLS handshake,
83 * HTTP/2 ALPN, and the WebSocket upgrade before the HTTP/1.1 parser. Returned by
84 * accessor (not self-registered) so this module carries no dependency on the
85 * session layer; proto_register_builtins() installs it.
86 */
87struct ProtoHandler;
88const struct ProtoHandler *http_proto_handler(void);
89
90/**
91 * @brief Install the HTTP per-slot poll pump (the routing core's instance-bound `on_poll`).
92 *
93 * HTTP is the one protocol whose poll needs the `DetWebServer` instance (routing), so the
94 * application layer installs its pump here at `begin()` - the TX-seam (`resp_sink`) counterpart
95 * for the poll direction. With it set, HTTP plugs into the uniform `ProtoHandler::on_poll` seam
96 * exactly like every other protocol, so the L5/worker dispatch loop has no HTTP special case.
97 */
98void http_proto_set_poll(void (*fn)(uint8_t slot));
99
100#if DETWS_ENABLE_EDGE_CACHE
101/**
102 * @brief Install the edge-cache per-slot fetch pump (defined in dwserver.cpp, called first in
103 * http_poll_slot).
104 *
105 * A cache miss / stale-entry revalidation suspends the client request and drives a non-blocking origin
106 * fetch from the slot's poll. @p fn returns true while it is servicing an in-flight fetch for the slot,
107 * so the HTTP pipeline is skipped until the fetch completes and starts the cached response. Nullable
108 * (unset = no-op). Installed by det_edge_cache_enable(); see services/edge_cache/edge_cache_proxy.
109 */
110void detws_http_set_edge_poll(bool (*fn)(uint8_t slot));
111#endif
112
113#endif
#define MAX_CONNS
Maximum simultaneous TCP connections (fixed static pool; ~3.95 KB of internal RAM per slot).
Standalone HTTP/1.1 request parser - no transport dependency.
void http_reset(uint8_t slot_id)
Reset the HTTP parser for a connection slot.
void http_proto_set_poll(void(*fn)(uint8_t slot))
Install the HTTP per-slot poll pump (the routing core's instance-bound on_poll).
void http_parse(uint8_t slot_id)
Drain the transport ring buffer and advance the HTTP parser.
void http_conn_open(uint8_t slot_id)
Initialize a slot for a freshly-accepted HTTP connection.
const struct ProtoHandler * http_proto_handler(void)
Per-protocol connection event/poll callbacks (Layer 5 dispatch vtable).