From 85ea4e995a75abe061f6fc375ea0481084dddd43 Mon Sep 17 00:00:00 2001 From: schererleander Date: Tue, 20 Jan 2026 08:34:54 +0100 Subject: initial commit --- .../ChunkRetryResponse/ChunkRetryResponse.ino | 216 +++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 libraries/ESP_Async_WebServer/examples/ChunkRetryResponse/ChunkRetryResponse.ino (limited to 'libraries/ESP_Async_WebServer/examples/ChunkRetryResponse/ChunkRetryResponse.ino') diff --git a/libraries/ESP_Async_WebServer/examples/ChunkRetryResponse/ChunkRetryResponse.ino b/libraries/ESP_Async_WebServer/examples/ChunkRetryResponse/ChunkRetryResponse.ino new file mode 100644 index 0000000..48772cc --- /dev/null +++ b/libraries/ESP_Async_WebServer/examples/ChunkRetryResponse/ChunkRetryResponse.ino @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov + +// +// Shows how to wait in a chunk response for incoming data +// + +#include +#ifdef ESP32 +#include +#include +#elif defined(ESP8266) +#include +#include +#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) +#include +#include +#endif + +#include + +#if __has_include("ArduinoJson.h") +#include +#include +#include +#endif + +static const char *htmlContent PROGMEM = R"( + + + + Sample HTML + + +

Hello, World!

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+ + +)"; + +static const size_t htmlContentLength = strlen_P(htmlContent); + +static AsyncWebServer server(80); +static AsyncLoggingMiddleware requestLogger; + +static String triggerUART; +static int key = -1; + +void setup() { + Serial.begin(115200); + +#ifndef CONFIG_IDF_TARGET_ESP32H2 + WiFi.mode(WIFI_AP); + WiFi.softAP("esp-captive"); +#endif + + // adds some internal request logging for debugging + requestLogger.setEnabled(true); + requestLogger.setOutput(Serial); + + server.addMiddleware(&requestLogger); + +#if __has_include("ArduinoJson.h") + + // + // HOW TO RUN THIS EXAMPLE: + // + // 1. Trigger a request that will be blocked for a long time: + // > time curl -v -X POST http://192.168.4.1/api -H "Content-Type: application/json" -d '{"input": "Please type a key to continue in Serial console..."}' --output - + // + // 2. While waiting, in another terminal, run some concurrent requests: + // > time curl -v http://192.168.4.1/ + // + // 3. Type a key in the Serial console to continue the processing within 30 seconds. + // This should unblock the first request. + // + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { + // need to cast to uint8_t* + // if you do not, the const char* will be copied in a temporary String buffer + request->send(200, "text/html", (uint8_t *)htmlContent, htmlContentLength); + }); + + server.on( + "/api", HTTP_POST, + [](AsyncWebServerRequest *request) { + // request parsing has finished + + // no data ? + if (!((String *)request->_tempObject)->length()) { + request->send(400); + return; + } + + JsonDocument doc; + + // deserialize and check for errors + if (deserializeJson(doc, *(String *)request->_tempObject)) { + request->send(400); + return; + } + + // start UART com: UART will send the data to the Serial console and wait for the key press + triggerUART = doc["input"].as(); + key = -1; + + AsyncWebServerResponse *response = request->beginChunkedResponse("text/plain", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + // still waiting for UARY ? + if (triggerUART.length() && key == -1) { + return RESPONSE_TRY_AGAIN; + } + + // finished ? + if (!triggerUART.length() && key == -1) { + return 0; // 0 means we are done + } + + // log_d("UART answered!"); + + String answer = "You typed: "; + answer.concat((char)key); + + // note: I did not check for maxLen, but you should (see ChunkResponse.ino) + memcpy(buffer, answer.c_str(), answer.length()); + + // finish! + triggerUART = emptyString; + key = -1; + + return answer.length(); + }); + + request->send(response); + }, + NULL, // upload handler is not used so it should be NULL + [](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) { + // log_d("Body: index: %u, len: %u, total: %u", index, len, total); + + if (!index) { + // log_d("Start body parsing"); + request->_tempObject = new String(); + // cast request->_tempObject pointer to String and reserve total size + ((String *)request->_tempObject)->reserve(total); + // set timeout 30s + request->client()->setRxTimeout(30); + } + + // log_d("Append body data"); + ((String *)request->_tempObject)->concat((const char *)data, len); + } + ); + +#endif + + server.begin(); +} + +void loop() { + if (triggerUART.length() && key == -1) { + Serial.println(triggerUART); + // log_d("Waiting for UART input..."); + while (!Serial.available()) { + delay(100); + } + key = Serial.read(); + Serial.flush(); + // log_d("UART input: %c", key); + triggerUART = emptyString; + } +} -- cgit v1.3.1