DeterministicESPAsyncWebServer 1.2.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
CustomConfig.ino
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 CustomConfig.ino
6 * @brief Demonstrates overriding every compile-time sizing constant.
7 *
8 * All buffer and pool dimensions are set via build flags in platformio.ini.
9 * The values below cut memory use roughly in half compared to the defaults,
10 * which is useful for sensor nodes or builds that share the ESP32 heap with
11 * other subsystems.
12 *
13 * Add these to your platformio.ini [env] block to use this profile:
14 *
15 * @code{.ini}
16 * build_flags =
17 * -DMAX_CONNS=2 ; simultaneous TCP connections (default 4)
18 * -DRX_BUF_SIZE=512 ; ring-buffer bytes / connection (default 1024)
19 * -DCONN_TIMEOUT_MS=3000 ; idle timeout in ms (default 5000)
20 * -DMAX_HEADERS=4 ; headers stored per request (default 8)
21 * -DMAX_PATH_LEN=48 ; URL path bytes incl. leading / (default 64)
22 * -DMAX_KEY_LEN=16 ; header field-name bytes (default 24)
23 * -DMAX_VAL_LEN=32 ; header field-value bytes (default 48)
24 * -DMAX_QUERY_LEN=64 ; raw query-string bytes (default 128)
25 * -DMAX_QUERY_PARAMS=4 ; parsed query parameters (default 8)
26 * -DQUERY_KEY_LEN=16 ; query parameter key bytes (default 24)
27 * -DQUERY_VAL_LEN=24 ; query parameter value bytes (default 48)
28 * -DBODY_BUF_SIZE=128 ; request body bytes (default 256)
29 * -DMAX_ROUTES=8 ; registered route handlers (default 16)
30 * @endcode
31 *
32 * Example curl commands:
33 * curl http://<ip>/config
34 * curl http://<ip>/echo -X POST -d "hello"
35 * curl "http://<ip>/search?q=esp32&sort=date"
36 */
37
38#include "DeterministicESPAsyncWebServer.h"
39#include "network_drivers/physical.h"
40#include <WiFi.h>
41
42static const char *SSID = "YOUR_SSID";
43static const char *PASSWORD = "YOUR_PASSWORD";
44
45DetWebServer server;
46
47// GET /config
48// Returns every active sizing constant as JSON so you can verify your
49// build flags took effect without needing a debugger.
50void handle_config(uint8_t slot_id, HttpReq *req)
51{
52 char body[384];
53 snprintf(body, sizeof(body),
54 "{"
55 "\"MAX_CONNS\":%u,"
56 "\"RX_BUF_SIZE\":%u,"
57 "\"CONN_TIMEOUT_MS\":%u,"
58 "\"MAX_HEADERS\":%u,"
59 "\"MAX_PATH_LEN\":%u,"
60 "\"MAX_KEY_LEN\":%u,"
61 "\"MAX_VAL_LEN\":%u,"
62 "\"MAX_QUERY_LEN\":%u,"
63 "\"MAX_QUERY_PARAMS\":%u,"
64 "\"QUERY_KEY_LEN\":%u,"
65 "\"QUERY_VAL_LEN\":%u,"
66 "\"BODY_BUF_SIZE\":%u,"
67 "\"MAX_ROUTES\":%u"
68 "}",
69 (unsigned)MAX_CONNS, (unsigned)RX_BUF_SIZE, (unsigned)CONN_TIMEOUT_MS, (unsigned)MAX_HEADERS,
70 (unsigned)MAX_PATH_LEN, (unsigned)MAX_KEY_LEN, (unsigned)MAX_VAL_LEN, (unsigned)MAX_QUERY_LEN,
71 (unsigned)MAX_QUERY_PARAMS, (unsigned)QUERY_KEY_LEN, (unsigned)QUERY_VAL_LEN, (unsigned)BODY_BUF_SIZE,
72 (unsigned)MAX_ROUTES);
73
74 server.send(slot_id, 200, "application/json", body);
75}
76
77// POST /echo
78// Echoes the request body back. With -DBODY_BUF_SIZE=128, bodies longer
79// than 128 bytes trigger an automatic 413 before this handler is called.
80void handle_echo(uint8_t slot_id, HttpReq *req)
81{
82 server.send(slot_id, 200, "text/plain", (const char *)req->body);
83}
84
85// GET /search
86// Reads up to MAX_QUERY_PARAMS query parameters and echoes them back.
87// With -DMAX_QUERY_PARAMS=4, a fifth parameter is parsed but silently
88// dropped — this handler shows exactly what was retained.
89void handle_search(uint8_t slot_id, HttpReq *req)
90{
91 char body[256] = "params: ";
92 for (uint8_t i = 0; i < req->query_count; i++)
93 {
94 if (i > 0)
95 strncat(body, ", ", sizeof(body) - strlen(body) - 1);
96 strncat(body, req->query_params[i].key, sizeof(body) - strlen(body) - 1);
97 strncat(body, "=", sizeof(body) - strlen(body) - 1);
98 strncat(body, req->query_params[i].val, sizeof(body) - strlen(body) - 1);
99 }
100 server.send(slot_id, 200, "text/plain", body);
101}
102
103void setup()
104{
105 Serial.begin(115200);
106
107 // Print the active config so you can confirm build flags without curl
108 Serial.println("\n--- Active DetWebServer config ---");
109 Serial.printf(" MAX_CONNS = %u\n", (unsigned)MAX_CONNS);
110 Serial.printf(" RX_BUF_SIZE = %u\n", (unsigned)RX_BUF_SIZE);
111 Serial.printf(" CONN_TIMEOUT_MS = %u\n", (unsigned)CONN_TIMEOUT_MS);
112 Serial.printf(" MAX_HEADERS = %u\n", (unsigned)MAX_HEADERS);
113 Serial.printf(" MAX_PATH_LEN = %u\n", (unsigned)MAX_PATH_LEN);
114 Serial.printf(" MAX_KEY_LEN = %u\n", (unsigned)MAX_KEY_LEN);
115 Serial.printf(" MAX_VAL_LEN = %u\n", (unsigned)MAX_VAL_LEN);
116 Serial.printf(" MAX_QUERY_LEN = %u\n", (unsigned)MAX_QUERY_LEN);
117 Serial.printf(" MAX_QUERY_PARAMS= %u\n", (unsigned)MAX_QUERY_PARAMS);
118 Serial.printf(" QUERY_KEY_LEN = %u\n", (unsigned)QUERY_KEY_LEN);
119 Serial.printf(" QUERY_VAL_LEN = %u\n", (unsigned)QUERY_VAL_LEN);
120 Serial.printf(" BODY_BUF_SIZE = %u\n", (unsigned)BODY_BUF_SIZE);
121 Serial.printf(" MAX_ROUTES = %u\n", (unsigned)MAX_ROUTES);
122 Serial.println("----------------------------------");
123
124 init_wifi_physical(SSID, PASSWORD);
125 Serial.print("Connecting to WiFi");
126 while (!wifi_ready())
127 {
128 delay(250);
129 Serial.print('.');
130 }
131 Serial.print("\nIP: ");
132 Serial.println(WiFi.localIP());
133
134 server.on("/config", HTTP_GET, handle_config);
135 server.on("/echo", HTTP_POST, handle_echo);
136 server.on("/search", HTTP_GET, handle_search);
137
138 // Pass a runtime config to override CONN_TIMEOUT_MS without a rebuild
139 WebServerConfig cfg = {.conn_timeout_ms = CONN_TIMEOUT_MS};
140 int32_t result = server.begin(80, &cfg);
141 if (result < 0)
142 {
143 Serial.printf("begin() failed — need %d more heap bytes\n", -result);
144 return;
145 }
146 Serial.println("Server started on port 80");
147}
148
149void loop()
150{
151 server.handle();
152}