From 4166d9002f260798a819b1c138ab7e2bdbe7cd14 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 13 Sep 2024 16:46:41 +0200 Subject: [PATCH] Fix header removal logic --- examples/SimpleServer/SimpleServer.ino | 23 ++++- src/ESPAsyncWebServer.h | 121 ++++++++++--------------- 2 files changed, 70 insertions(+), 74 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 2a2079a..16f1a71 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -85,6 +85,27 @@ void setup() { WiFi.softAP("esp-captive"); #endif + // Request header manipulations + // curl -v -X GET -H "x-remove-me: value" http://192.168.4.1/headers + server.on("/headers", HTTP_GET, [](AsyncWebServerRequest* request) { + Serial.printf("Request Headers:\n"); + for (auto& h : request->getHeaders()) + Serial.printf("Request Header: %s = %s\n", h.name().c_str(), h.value().c_str()); + + // remove x-remove-me header + request->removeHeader("x-remove-me"); + Serial.printf("Request Headers:\n"); + for (auto& h : request->getHeaders()) + Serial.printf("Request Header: %s = %s\n", h.name().c_str(), h.value().c_str()); + + std::vector headers; + request->getHeaderNames(headers); + for (auto& h : headers) + Serial.printf("Request Header Name: %s\n", h); + + request->send(200); + }); + server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(200, "text/plain", "Hello, world"); }); @@ -197,7 +218,7 @@ void setup() { }); ws.onEvent([](AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len) { - (void) len; + (void)len; if (type == WS_EVT_CONNECT) { Serial.println("ws connect"); client->setCloseClientOnQueueFull(false); diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 4f75c06..afb5982 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -289,12 +289,12 @@ class AsyncWebServerRequest { void setHandler(AsyncWebHandler* handler) { _handler = handler; } #ifndef ESP8266 - [[deprecated("All headers are now collected. Use removeHeadersExcept(name) if you really need to free some headers.")]] + [[deprecated("All headers are now collected. Use removeHeader(name) or HeaderFreeMiddleware 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.")]] + [[deprecated("All headers are now collected. Use removeHeader(name) or HeaderFreeMiddleware if you really need to free some headers.")]] #endif void addInterestingHeader(__unused const String& name) { } @@ -398,77 +398,6 @@ class AsyncWebServerRequest { AsyncWebServerResponse* beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); #endif - size_t headers() const; // get header count - - // check if header exists - bool hasHeader(const char* name) const; - bool hasHeader(const String& name) const { return hasHeader(name.c_str()); }; -#ifdef ESP8266 - bool hasHeader(const __FlashStringHelper* data) const; // check if header exists -#endif - - const AsyncWebHeader* getHeader(const char* name) const; - const AsyncWebHeader* getHeader(const String& name) const { return getHeader(name.c_str()); }; -#ifdef ESP8266 - const AsyncWebHeader* getHeader(const __FlashStringHelper* data) const; -#endif - const AsyncWebHeader* getHeader(size_t num) const; - size_t getHeaderNames(std::vector& 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& 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& 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& 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 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; - bool hasParam(const String& name, bool post = false, bool file = false) const { return hasParam(name.c_str(), post, file); }; -#ifdef ESP8266 - bool hasParam(const __FlashStringHelper* data, bool post = false, bool file = false) const { return hasParam(String(data).c_str(), post, file); }; -#endif - /** * @brief Get the Request parameter by name * @@ -522,6 +451,52 @@ class AsyncWebServerRequest { const String& header(size_t i) const; // get request header value by number const String& headerName(size_t i) const; // get request header name by number + size_t headers() const; // get header count + + // check if header exists + bool hasHeader(const char* name) const; + bool hasHeader(const String& name) const { return hasHeader(name.c_str()); }; +#ifdef ESP8266 + bool hasHeader(const __FlashStringHelper* data) const; // check if header exists +#endif + + const AsyncWebHeader* getHeader(const char* name) const; + const AsyncWebHeader* getHeader(const String& name) const { return getHeader(name.c_str()); }; +#ifdef ESP8266 + const AsyncWebHeader* getHeader(const __FlashStringHelper* data) const; +#endif + + const AsyncWebHeader* getHeader(size_t num) const; + + const std::list& getHeaders() const { return _headers; } + + size_t getHeaderNames(std::vector& 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; + } + + // 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(); } + + size_t params() const; // get arguments count + bool hasParam(const char* name, bool post = false, bool file = false) const; + bool hasParam(const String& name, bool post = false, bool file = false) const { return hasParam(name.c_str(), post, file); }; +#ifdef ESP8266 + bool hasParam(const __FlashStringHelper* data, bool post = false, bool file = false) const { return hasParam(String(data).c_str(), post, file); }; +#endif + // REQUEST ATTRIBUTES void setAttribute(const char* name, const char* value) { _attributes[name] = value; }