mirror of
https://github.com/me-no-dev/ESPAsyncWebServer.git
synced 2025-10-01 00:30:54 +02:00
(perf) Remove interesting headers to fasten request processing
All headers are already parsed: interesting headers allowed to cleanup parsed headers to only keep interesting ones during request processing. Removing "interesting headers" support will keep these parsed headers in heap memory during request processing before being freed at the end of the request. If you really need to cleanup some headers to get more heap space during request processing, use a middleware and removeHeadersExcept(names) to remove some.
This commit is contained in:
@@ -20,7 +20,6 @@ class CaptiveRequestHandler : public AsyncWebHandler {
|
||||
virtual ~CaptiveRequestHandler() {}
|
||||
|
||||
bool canHandle(__unused AsyncWebServerRequest* request) {
|
||||
// request->addInterestingHeader("ANY");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,6 @@ class CaptiveRequestHandler : public AsyncWebHandler {
|
||||
virtual ~CaptiveRequestHandler() {}
|
||||
|
||||
bool canHandle(__unused AsyncWebServerRequest* request) {
|
||||
// request->addInterestingHeader("ANY");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -374,8 +374,6 @@ bool AsyncEventSource::canHandle(AsyncWebServerRequest* request) {
|
||||
if (request->method() != HTTP_GET || !request->url().equals(_url)) {
|
||||
return false;
|
||||
}
|
||||
request->addInterestingHeader(T_Last_Event_ID);
|
||||
request->addInterestingHeader(T_Cookie);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -198,7 +198,6 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler {
|
||||
if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(JSON_MIMETYPE))
|
||||
return false;
|
||||
|
||||
request->addInterestingHeader("ANY");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -97,7 +97,6 @@ class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler {
|
||||
if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(asyncsrv::T_application_msgpack))
|
||||
return false;
|
||||
|
||||
request->addInterestingHeader("ANY");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -1078,13 +1078,6 @@ bool AsyncWebSocket::canHandle(AsyncWebServerRequest* request) {
|
||||
if (request->method() != HTTP_GET || !request->url().equals(_url) || !request->isExpectedRequestedConnType(RCT_WS))
|
||||
return false;
|
||||
|
||||
request->addInterestingHeader(WS_STR_CONNECTION);
|
||||
request->addInterestingHeader(WS_STR_UPGRADE);
|
||||
request->addInterestingHeader(WS_STR_ORIGIN);
|
||||
request->addInterestingHeader(WS_STR_COOKIE);
|
||||
request->addInterestingHeader(WS_STR_VERSION);
|
||||
request->addInterestingHeader(WS_STR_KEY);
|
||||
request->addInterestingHeader(WS_STR_PROTOCOL);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -192,7 +192,6 @@ class AsyncWebServerRequest {
|
||||
AsyncWebServer* _server;
|
||||
AsyncWebHandler* _handler;
|
||||
AsyncWebServerResponse* _response;
|
||||
std::vector<String> _interestingHeaders;
|
||||
ArDisconnectHandler _onDisconnectfn;
|
||||
|
||||
String _temp;
|
||||
@@ -206,7 +205,6 @@ class AsyncWebServerRequest {
|
||||
String _boundary;
|
||||
String _authorization;
|
||||
RequestedConnectionType _reqconntype;
|
||||
void _removeNotInterestingHeaders();
|
||||
bool _isDigest;
|
||||
bool _isMultipart;
|
||||
bool _isPlainPost;
|
||||
@@ -289,13 +287,16 @@ class AsyncWebServerRequest {
|
||||
|
||||
void setHandler(AsyncWebHandler* handler) { _handler = handler; }
|
||||
|
||||
/**
|
||||
* @brief add header to collect from a response
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
void addInterestingHeader(const char* name);
|
||||
void addInterestingHeader(const String& name) { return addInterestingHeader(name.c_str()); };
|
||||
#ifndef ESP8266
|
||||
[[deprecated("All headers are now collected. Use removeHeadersExcept(name) if you really need to free some headers.")]]
|
||||
#endif
|
||||
void addInterestingHeader(__unused const char* name) {
|
||||
}
|
||||
#ifndef ESP8266
|
||||
[[deprecated("All headers are now collected. Use removeHeadersExcept(name) if you really need to free some headers.")]]
|
||||
#endif
|
||||
void addInterestingHeader(__unused const String& name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief issue 302 redirect response
|
||||
@@ -411,6 +412,54 @@ class AsyncWebServerRequest {
|
||||
const AsyncWebHeader* getHeader(const __FlashStringHelper* data) const;
|
||||
#endif
|
||||
const AsyncWebHeader* getHeader(size_t num) const;
|
||||
size_t getHeaderNames(std::vector<const char*>& names) const {
|
||||
names.clear();
|
||||
const size_t size = _headers.size();
|
||||
names.reserve(size);
|
||||
for (const auto& h : _headers) {
|
||||
names.push_back(h.name().c_str());
|
||||
}
|
||||
return size;
|
||||
}
|
||||
const std::list<AsyncWebHeader>& getHeaders() const { return _headers; }
|
||||
// Remove a header from the request.
|
||||
// It will free the memory and prevent the header to be seen during request processing.
|
||||
bool removeHeader(const char* name) {
|
||||
const size_t size = _headers.size();
|
||||
_headers.remove_if([&name](const AsyncWebHeader& header) { return header.name().equalsIgnoreCase(name); });
|
||||
return size != _headers.size();
|
||||
}
|
||||
// Remove all request headers.
|
||||
void removeHeaders() { _headers.clear(); }
|
||||
// Remove all request headers with the given names.
|
||||
void removeHeaders(std::vector<const char*>& namesToRemove) {
|
||||
for (const char* name : namesToRemove)
|
||||
removeHeader(name);
|
||||
}
|
||||
void removeHeaders(const char* names...) {
|
||||
va_list args;
|
||||
va_start(args, names);
|
||||
for (const char* name = names; name != NULL; name = va_arg(args, const char*))
|
||||
removeHeader(name);
|
||||
va_end(args);
|
||||
}
|
||||
void removeHeadersExcept(std::vector<const char*>& namesToKeep) {
|
||||
_headers.remove_if([&namesToKeep](const AsyncWebHeader& header) {
|
||||
for (const char* name : namesToKeep)
|
||||
if (header.name().equalsIgnoreCase(name))
|
||||
return false;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
void removeHeadersExcept(const char* names...) {
|
||||
va_list args;
|
||||
va_start(args, names);
|
||||
std::vector<const char*> namesToKeep;
|
||||
for (const char* name = names; name != NULL; name = va_arg(args, const char*))
|
||||
namesToKeep.push_back(name);
|
||||
va_end(args);
|
||||
removeHeadersExcept(namesToKeep);
|
||||
}
|
||||
|
||||
size_t params() const; // get arguments count
|
||||
bool hasParam(const char* name, bool post = false, bool file = false) const;
|
||||
|
@@ -125,7 +125,6 @@ class AsyncCallbackWebHandler : public AsyncWebHandler {
|
||||
} else if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/")))
|
||||
return false;
|
||||
|
||||
request->addInterestingHeader("ANY");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -23,7 +23,6 @@
|
||||
|
||||
using namespace asyncsrv;
|
||||
|
||||
|
||||
AsyncStaticWebHandler::AsyncStaticWebHandler(const char* uri, FS& fs, const char* path, const char* cache_control)
|
||||
: _fs(fs), _uri(uri), _path(path), _default_file(F("index.htm")), _cache_control(cache_control), _last_modified(), _callback(nullptr) {
|
||||
// Ensure leading '/'
|
||||
@@ -94,18 +93,7 @@ bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest* request) {
|
||||
if (request->method() != HTTP_GET || !request->url().startsWith(_uri) || !request->isExpectedRequestedConnType(RCT_DEFAULT, RCT_HTTP)) {
|
||||
return false;
|
||||
}
|
||||
if (_getFile(request)) {
|
||||
// We interested in "If-Modified-Since" header to check if file was modified
|
||||
if (_last_modified.length())
|
||||
request->addInterestingHeader(F("If-Modified-Since"));
|
||||
|
||||
if (_cache_control.length())
|
||||
request->addInterestingHeader(F("If-None-Match"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return _getFile(request);
|
||||
}
|
||||
|
||||
bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest* request) {
|
||||
|
@@ -49,8 +49,6 @@ AsyncWebServerRequest::~AsyncWebServerRequest() {
|
||||
|
||||
_pathParams.clear();
|
||||
|
||||
_interestingHeaders.clear();
|
||||
|
||||
if (_response != NULL) {
|
||||
delete _response;
|
||||
}
|
||||
@@ -152,20 +150,6 @@ void AsyncWebServerRequest::_onData(void* buf, size_t len) {
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::_removeNotInterestingHeaders() {
|
||||
if (std::any_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), [](const String& str) { return str.equalsIgnoreCase(T_ANY); }))
|
||||
return; // nothing to do
|
||||
|
||||
for (auto iter = std::begin(_headers); iter != std::end(_headers);) {
|
||||
const auto name = iter->name();
|
||||
|
||||
if (std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), [&name](const String& str) { return str.equalsIgnoreCase(name); }))
|
||||
iter = _headers.erase(iter);
|
||||
else
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::_onPoll() {
|
||||
// os_printf("p\n");
|
||||
if (_response != NULL && _client != NULL && _client->canSend()) {
|
||||
@@ -583,7 +567,6 @@ void AsyncWebServerRequest::_parseLine() {
|
||||
// end of headers
|
||||
_server->_rewriteRequest(this);
|
||||
_server->_attachHandler(this);
|
||||
_removeNotInterestingHeaders();
|
||||
if (_expectingContinue) {
|
||||
String response(T_HTTP_100_CONT);
|
||||
_client->write(response.c_str(), response.length());
|
||||
@@ -683,11 +666,6 @@ const AsyncWebParameter* AsyncWebServerRequest::getParam(size_t num) const {
|
||||
return &(*std::next(_params.cbegin(), num));
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::addInterestingHeader(const char* name) {
|
||||
if (std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), [&name](const String& str) { return str.equalsIgnoreCase(name); }))
|
||||
_interestingHeaders.emplace_back(name);
|
||||
}
|
||||
|
||||
AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const char* contentType, const char* content, AwsTemplateProcessor callback) {
|
||||
if (callback)
|
||||
return new AsyncProgmemResponse(code, contentType, (const uint8_t*)content, strlen(content), callback);
|
||||
|
@@ -155,7 +155,6 @@ void AsyncWebServer::_attachHandler(AsyncWebServerRequest* request) {
|
||||
}
|
||||
}
|
||||
|
||||
request->addInterestingHeader(T_ANY);
|
||||
request->setHandler(_catchAllHandler);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user