From 741841a078069e8bbeb6b27bde11e5c543710993 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 14 Sep 2024 00:46:38 +0200 Subject: [PATCH 1/2] not needed to clear response headers: they will be freed once response will be deleted --- src/WebResponses.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index 1fb6188..2705fd3 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -318,7 +318,6 @@ void AsyncWebServerResponse::_assembleHead(String& buffer, uint8_t version) { buffer.concat(header.value()); buffer.concat(T_rn); } - _headers.clear(); buffer.concat(T_rn); _headLength = buffer.length(); From 571eac4d0093dc51f1cf592788f24a6e20f84f40 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 14 Sep 2024 00:56:47 +0200 Subject: [PATCH 2/2] Support for replacing a response by a new one --- README.md | 15 +++++++++++++ docs/index.md | 15 +++++++++++++ examples/SimpleServer/SimpleServer.ino | 13 +++++++++++ src/ESPAsyncWebServer.h | 2 +- src/WebRequest.cpp | 31 ++++++++++++++++---------- 5 files changed, 63 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 55292c8..b39a55f 100644 --- a/README.md +++ b/README.md @@ -121,3 +121,18 @@ If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 -D WS_MAX_QUEUED_MESSAGES=64 ``` + +## Replace response + +```c++ + // It is possible to replace a response. + // The previous one will be deleted. + // Response sending happens when the handler returns. + server.on("/replace", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "Hello, world"); + // oups! finally we want to send a different response + request->send(400, "text/plain", "validation error"); + }); +``` + +This will send error 400 instead of 200. diff --git a/docs/index.md b/docs/index.md index 55292c8..b39a55f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -121,3 +121,18 @@ If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 -D WS_MAX_QUEUED_MESSAGES=64 ``` + +## Replace response + +```c++ + // It is possible to replace a response. + // The previous one will be deleted. + // Response sending happens when the handler returns. + server.on("/replace", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "Hello, world"); + // oups! finally we want to send a different response + request->send(400, "text/plain", "validation error"); + }); +``` + +This will send error 400 instead of 200. diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index aec8110..b14b473 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -90,6 +90,19 @@ void setup() { // handler forgot to send a response to the client => 501 Not Implemented }); + // This is possible to replace a response. + // the previous one will be deleted. + // response sending happens when the handler returns. + // curl -v -X GET http://192.168.4.1/replace + server.on("/replace", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "Hello, world"); + // oups! finally we want to send a different response + request->send(400, "text/plain", "validation error"); +#ifndef TARGET_RP2040 + Serial.printf("Free heap: %" PRIu32 "\n", ESP.getFreeHeap()); +#endif + }); + /////////////////////////////////////////////////////////////////////// // Request header manipulations /////////////////////////////////////////////////////////////////////// diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index b2274b5..a55a608 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -311,7 +311,7 @@ class AsyncWebServerRequest { void redirect(const String& url) { return redirect(url.c_str()); }; void send(AsyncWebServerResponse* response); - const AsyncWebServerResponse* sentResponse() const { return _response; } + AsyncWebServerResponse* getResponse() const { return _response; } void send(int code, const char* contentType = asyncsrv::empty, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } void send(int code, const String& contentType, const String& content = emptyString, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index ad2a96f..c901e94 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -140,8 +140,13 @@ void AsyncWebServerRequest::_onData(void* buf, size_t len) { _parseState = PARSE_REQ_END; if (_handler) _handler->handleRequest(this); - if (!_sent) - send(501, T_text_plain, "Handler did not handle the request"); + if (!_sent) { + if (!_response) + send(501, T_text_plain, "Handler did not handle the request"); + _client->setRxTimeout(0); + _response->_respond(this); + _sent = true; + } } } break; @@ -574,8 +579,13 @@ void AsyncWebServerRequest::_parseLine() { _parseState = PARSE_REQ_END; if (_handler) _handler->handleRequest(this); - if (!_sent) - send(501, T_text_plain, "Handler did not handle the request"); + if (!_sent) { + if (!_response) + send(501, T_text_plain, "Handler did not handle the request"); + _client->setRxTimeout(0); + _response->_respond(this); + _sent = true; + } } } else _parseReqHeader(); @@ -709,6 +719,10 @@ AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const Str #endif void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { + if (_sent) + return; + if (_response) + delete _response; _response = response; if (_response == NULL) { _client->close(true); @@ -716,15 +730,8 @@ void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { _sent = true; return; } - if (!_response->_sourceValid()) { - delete response; - _response = NULL; + if (!_response->_sourceValid()) send(500); - } else { - _client->setRxTimeout(0); - _response->_respond(this); - _sent = true; - } } void AsyncWebServerRequest::redirect(const char* url) {