Merge pull request #103 from mathieucarbou/response

Support for replacing a response by a new one
This commit is contained in:
Mathieu Carbou
2024-09-14 01:41:06 +02:00
committed by GitHub
6 changed files with 63 additions and 14 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 CONFIG_ASYNC_TCP_STACK_SIZE=4096
-D WS_MAX_QUEUED_MESSAGES=64 -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 CONFIG_ASYNC_TCP_STACK_SIZE=4096
-D WS_MAX_QUEUED_MESSAGES=64 -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 // 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 // Request header manipulations
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////

View File

@@ -311,7 +311,7 @@ class AsyncWebServerRequest {
void redirect(const String& url) { return redirect(url.c_str()); }; void redirect(const String& url) { return redirect(url.c_str()); };
void send(AsyncWebServerResponse* response); 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 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)); } 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; _parseState = PARSE_REQ_END;
if (_handler) if (_handler)
_handler->handleRequest(this); _handler->handleRequest(this);
if (!_sent) if (!_sent) {
if (!_response)
send(501, T_text_plain, "Handler did not handle the request"); send(501, T_text_plain, "Handler did not handle the request");
_client->setRxTimeout(0);
_response->_respond(this);
_sent = true;
}
} }
} }
break; break;
@@ -574,8 +579,13 @@ void AsyncWebServerRequest::_parseLine() {
_parseState = PARSE_REQ_END; _parseState = PARSE_REQ_END;
if (_handler) if (_handler)
_handler->handleRequest(this); _handler->handleRequest(this);
if (!_sent) if (!_sent) {
if (!_response)
send(501, T_text_plain, "Handler did not handle the request"); send(501, T_text_plain, "Handler did not handle the request");
_client->setRxTimeout(0);
_response->_respond(this);
_sent = true;
}
} }
} else } else
_parseReqHeader(); _parseReqHeader();
@@ -709,6 +719,10 @@ AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const Str
#endif #endif
void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { void AsyncWebServerRequest::send(AsyncWebServerResponse* response) {
if (_sent)
return;
if (_response)
delete _response;
_response = response; _response = response;
if (_response == NULL) { if (_response == NULL) {
_client->close(true); _client->close(true);
@@ -716,15 +730,8 @@ void AsyncWebServerRequest::send(AsyncWebServerResponse* response) {
_sent = true; _sent = true;
return; return;
} }
if (!_response->_sourceValid()) { if (!_response->_sourceValid())
delete response;
_response = NULL;
send(500); send(500);
} else {
_client->setRxTimeout(0);
_response->_respond(this);
_sent = true;
}
} }
void AsyncWebServerRequest::redirect(const char* url) { void AsyncWebServerRequest::redirect(const char* url) {

View File

@@ -318,7 +318,6 @@ void AsyncWebServerResponse::_assembleHead(String& buffer, uint8_t version) {
buffer.concat(header.value()); buffer.concat(header.value());
buffer.concat(T_rn); buffer.concat(T_rn);
} }
_headers.clear();
buffer.concat(T_rn); buffer.concat(T_rn);
_headLength = buffer.length(); _headLength = buffer.length();