Support for replacing a response by a new one

This commit is contained in:
Mathieu Carbou
2024-09-14 00:56:47 +02:00
parent 741841a078
commit 571eac4d00
5 changed files with 63 additions and 13 deletions

View File

@@ -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.

View File

@@ -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.

View File

@@ -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
///////////////////////////////////////////////////////////////////////

View File

@@ -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)); }

View File

@@ -140,8 +140,13 @@ void AsyncWebServerRequest::_onData(void* buf, size_t len) {
_parseState = PARSE_REQ_END;
if (_handler)
_handler->handleRequest(this);
if (!_sent)
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)
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) {