Merge pull request #101 from mathieucarbou/headers

(perf) Remove "interesting headers" to fasten request processing (replaced with `removeHeadersExcept`)
This commit is contained in:
Mathieu Carbou
2024-09-11 18:02:16 +02:00
committed by GitHub
11 changed files with 59 additions and 59 deletions

View File

@@ -20,7 +20,6 @@ class CaptiveRequestHandler : public AsyncWebHandler {
virtual ~CaptiveRequestHandler() {}
bool canHandle(__unused AsyncWebServerRequest* request) {
// request->addInterestingHeader("ANY");
return true;
}

View File

@@ -22,7 +22,6 @@ class CaptiveRequestHandler : public AsyncWebHandler {
virtual ~CaptiveRequestHandler() {}
bool canHandle(__unused AsyncWebServerRequest* request) {
// request->addInterestingHeader("ANY");
return true;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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) {

View File

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

View File

@@ -155,7 +155,6 @@ void AsyncWebServer::_attachHandler(AsyncWebServerRequest* request) {
}
}
request->addInterestingHeader(T_ANY);
request->setHandler(_catchAllHandler);
}