From ff8966db5cd9c700535c5fd20578dfb77694a37a Mon Sep 17 00:00:00 2001 From: Pablo2048 Date: Mon, 19 Aug 2024 16:41:09 +0200 Subject: [PATCH] Update na verzi 3.1.5 --- README.md | 2 +- docs/index.md | 2 +- library.json_ | 2 +- library.properties | 2 +- platformio.ini | 12 ++-- src/AsyncWebSocket.h | 31 ++++------ src/ESPAsyncWebServer.h | 129 ++++++++++++++++++++++++++++------------ src/WebHandlers.cpp | 10 ++-- src/WebRequest.cpp | 102 +++++++++++-------------------- src/WebResponseImpl.h | 27 ++++++--- src/WebResponses.cpp | 34 +++++------ src/WebServer.cpp | 8 +++ src/literals.h | 2 + 13 files changed, 196 insertions(+), 167 deletions(-) diff --git a/README.md b/README.md index 19ab602..6ca1d1e 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.1.2 +mathieucarbou/ESPAsyncWebServer @ 3.1.5 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 19ab602..6ca1d1e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,7 +14,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.1.2 +mathieucarbou/ESPAsyncWebServer @ 3.1.5 ``` Dependency: diff --git a/library.json_ b/library.json_ index e2c7953..eb946c6 100644 --- a/library.json_ +++ b/library.json_ @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.1.2", + "version": "3.1.5", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 8c610fd..3036044 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.1.2 +version=3.1.5 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/platformio.ini b/platformio.ini index e621af8..6f68d0d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -30,7 +30,7 @@ lib_deps = mathieucarbou/AsyncTCP @ 3.2.4 [env:arduino-2] -platform = espressif32@6.7.0 +platform = espressif32@6.8.1 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 @@ -39,8 +39,8 @@ lib_deps = [env:arduino-3] platform = espressif32 platform_packages= - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.3 - platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.3/esp32-arduino-libs-3.0.3.zip + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.4 + platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.4/esp32-arduino-libs-3.0.4.zip board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 @@ -66,14 +66,14 @@ lib_deps = khoih-prog/AsyncTCP_RP2040W @ 1.2.0 [env:pioarduino-esp32dev] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.3 + mathieucarbou/AsyncTCP @ 3.2.4 [env:pioarduino-c6] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip board = esp32-c6-devkitc-1 lib_deps = bblanchon/ArduinoJson @ 7.1.0 diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index ee7bde1..34256a7 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -230,18 +230,12 @@ class AsyncWebSocketClient { size_t queueLen() const; size_t printf(const char* format, ...) __attribute__((format(printf, 2, 3))); -#ifndef ESP32 - size_t printf_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); -#endif void text(AsyncWebSocketSharedBuffer buffer); void text(const uint8_t* message, size_t len); void text(const char* message, size_t len); void text(const char* message); void text(const String& message); -#ifndef ESP32 - void text(const __FlashStringHelper* message); -#endif // ESP32 void text(AsyncWebSocketMessageBuffer* buffer); void binary(AsyncWebSocketSharedBuffer buffer); @@ -249,9 +243,6 @@ class AsyncWebSocketClient { void binary(const char* message, size_t len); void binary(const char* message); void binary(const String& message); -#ifndef ESP32 - void binary(const __FlashStringHelper* message, size_t len); -#endif // ESP32 void binary(AsyncWebSocketMessageBuffer* buffer); bool canSend() const; @@ -263,6 +254,12 @@ class AsyncWebSocketClient { void _onTimeout(uint32_t time); void _onDisconnect(); void _onData(void* pbuf, size_t plen); + +#ifdef ESP8266 + size_t printf_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); + void text(const __FlashStringHelper* message); + void binary(const __FlashStringHelper* message, size_t len); +#endif }; using AwsHandshakeHandler = std::function; @@ -308,17 +305,11 @@ class AsyncWebSocket : public AsyncWebHandler { void text(uint32_t id, const String& message); void text(uint32_t id, AsyncWebSocketMessageBuffer* buffer); void text(uint32_t id, AsyncWebSocketSharedBuffer buffer); -#ifdef ESP8266 - void text(uint32_t id, const __FlashStringHelper* message); -#endif // ESP8266 void textAll(const uint8_t* message, size_t len); void textAll(const char* message, size_t len); void textAll(const char* message); void textAll(const String& message); -#ifdef ESP8266 - void textAll(const __FlashStringHelper* message); -#endif // ESP8266 void textAll(AsyncWebSocketMessageBuffer* buffer); void textAll(AsyncWebSocketSharedBuffer buffer); @@ -326,9 +317,6 @@ class AsyncWebSocket : public AsyncWebHandler { void binary(uint32_t id, const char* message, size_t len); void binary(uint32_t id, const char* message); void binary(uint32_t id, const String& message); -#ifdef ESP8266 - void binary(uint32_t id, const __FlashStringHelper* message, size_t len); -#endif // ESP8266 void binary(uint32_t id, AsyncWebSocketMessageBuffer* buffer); void binary(uint32_t id, AsyncWebSocketSharedBuffer buffer); @@ -336,9 +324,6 @@ class AsyncWebSocket : public AsyncWebHandler { void binaryAll(const char* message, size_t len); void binaryAll(const char* message); void binaryAll(const String& message); -#ifdef ESP8266 - void binaryAll(const __FlashStringHelper* message, size_t len); -#endif // ESP8266 void binaryAll(AsyncWebSocketMessageBuffer* buffer); void binaryAll(AsyncWebSocketSharedBuffer buffer); @@ -346,6 +331,10 @@ class AsyncWebSocket : public AsyncWebHandler { size_t printfAll(const char* format, ...) __attribute__((format(printf, 2, 3))); #ifdef ESP8266 + void text(uint32_t id, const __FlashStringHelper* message); + void textAll(const __FlashStringHelper* message); + void binary(uint32_t id, const __FlashStringHelper* message, size_t len); + void binaryAll(const __FlashStringHelper* message, size_t len); size_t printf_P(uint32_t id, PGM_P formatP, ...) __attribute__((format(printf, 3, 4))); size_t printfAll_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); #endif diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index f729f7e..de08bc0 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -35,20 +35,20 @@ #include #include #elif defined(TARGET_RP2040) - #include #include - #include #include + #include + #include #else #error Platform not supported #endif #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.1.2" +#define ASYNCWEBSERVER_VERSION "3.1.5" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 1 -#define ASYNCWEBSERVER_VERSION_REVISION 2 +#define ASYNCWEBSERVER_VERSION_REVISION 5 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX @@ -68,20 +68,20 @@ class AsyncStaticWebHandler; class AsyncCallbackWebHandler; class AsyncResponseStream; -#if defined (TARGET_RP2040) - typedef enum http_method WebRequestMethod; +#if defined(TARGET_RP2040) +typedef enum http_method WebRequestMethod; #else #ifndef WEBSERVER_H - typedef enum { - HTTP_GET = 0b00000001, - HTTP_POST = 0b00000010, - HTTP_DELETE = 0b00000100, - HTTP_PUT = 0b00001000, - HTTP_PATCH = 0b00010000, - HTTP_HEAD = 0b00100000, - HTTP_OPTIONS = 0b01000000, - HTTP_ANY = 0b01111111, - } WebRequestMethod; +typedef enum { + HTTP_GET = 0b00000001, + HTTP_POST = 0b00000010, + HTTP_DELETE = 0b00000100, + HTTP_PUT = 0b00001000, + HTTP_PATCH = 0b00010000, + HTTP_HEAD = 0b00100000, + HTTP_OPTIONS = 0b01000000, + HTTP_ANY = 0b01111111, +} WebRequestMethod; #endif #endif @@ -138,6 +138,7 @@ class AsyncWebHeader { AsyncWebHeader() = default; AsyncWebHeader(const AsyncWebHeader&) = default; + AsyncWebHeader(const char* name, const char* value) : _name(name), _value(value) {} AsyncWebHeader(const String& name, const String& value) : _name(name), _value(value) {} AsyncWebHeader(const String& data) { if (!data) @@ -153,7 +154,14 @@ class AsyncWebHeader { const String& name() const { return _name; } const String& value() const { return _value; } - String toString() const { return _name + (char)0x3a + (char)0x20 /*": "*/ + _value + asyncsrv::T_rn; } + String toString() const { + String str = _name; + str.concat((char)0x3a); + str.concat((char)0x20); + str.concat(_value); + str.concat(asyncsrv::T_rn); + return str; + } }; /* @@ -293,14 +301,37 @@ class AsyncWebServerRequest { void redirect(const String& url) { return redirect(url.c_str()); }; void send(AsyncWebServerResponse* response); - void send(int code, const String& contentType = String(), const String& content = String()); - void send(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); - void send(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); - void send(FS& fs, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); - void send(File content, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); - void send(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); - void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); - void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + + 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 char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, len, callback)); } + void send(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, len, callback)); } + + void send(FS& fs, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr) { + if (fs.exists(path) || (!download && fs.exists(path + asyncsrv::T__gz))) { + send(beginResponse(fs, path, contentType, download, callback)); + } else + send(404); + } + void send(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { send(fs, path, contentType.c_str(), download, callback); } + + void send(File content, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr) { + if (content) { + send(beginResponse(content, path, contentType, download, callback)); + } else + send(404); + } + void send(File content, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { send(content, path, contentType.c_str(), download, callback); } + + void send(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(stream, contentType, len, callback)); } + void send(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(stream, contentType, len, callback)); } + + void send(const char* contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginResponse(contentType, len, callback, templateCallback)); } + void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginResponse(contentType, len, callback, templateCallback)); } + + void sendChunked(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginChunkedResponse(contentType, callback, templateCallback)); } + void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginChunkedResponse(contentType, callback, templateCallback)); } [[deprecated("Replaced by send(...)")]] void send_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { @@ -311,16 +342,33 @@ class AsyncWebServerRequest { send(code, contentType, content, callback); } - AsyncWebServerResponse* beginResponse(int code, const String& contentType = String(), const String& content = String()); - AsyncWebServerResponse* beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(File content, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); - AsyncWebServerResponse* beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); - AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = 1460); +#ifdef ESP8266 + void send(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } +#endif + AsyncWebServerResponse* beginResponse(int code, const char* contentType = asyncsrv::empty, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(int code, const String& contentType, const String& content = emptyString, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content.c_str(), callback); } + + AsyncWebServerResponse* beginResponse(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content, len, callback); } + + AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { return beginResponse(fs, path, contentType.c_str(), download, callback); } + + AsyncWebServerResponse* beginResponse(File content, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(File content, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { return beginResponse(content, path, contentType.c_str(), download, callback); } + + AsyncWebServerResponse* beginResponse(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr) { return beginResponse(stream, contentType.c_str(), len, callback); } + + AsyncWebServerResponse* beginResponse(const char* contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncWebServerResponse* beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { return beginResponse(contentType.c_str(), len, callback, templateCallback); } + + AsyncWebServerResponse* beginChunkedResponse(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncWebServerResponse* beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + + AsyncResponseStream* beginResponseStream(const char* contentType, size_t bufferSize = 1460); + AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = 1460) { return beginResponseStream(contentType.c_str(), bufferSize); } [[deprecated("Replaced by beginResponse(...)")]] AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { @@ -331,6 +379,10 @@ class AsyncWebServerRequest { return beginResponse(code, contentType, content, callback); } +#ifdef ESP8266 + 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 @@ -348,7 +400,8 @@ class AsyncWebServerRequest { const AsyncWebHeader* getHeader(size_t num) const; size_t params() const; // get arguments count - bool hasParam(const String& name, bool post = false, bool file = false) const; + 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 @@ -526,8 +579,10 @@ class AsyncWebServerResponse { virtual ~AsyncWebServerResponse(); virtual void setCode(int code); virtual void setContentLength(size_t len); - virtual void setContentType(const String& type); - virtual void addHeader(const String& name, const String& value); + void setContentType(const String& type) { setContentType(type.c_str()); } + virtual void setContentType(const char* type); + virtual void addHeader(const char* name, const char* value); + void addHeader(const String& name, const String& value) { addHeader(name.c_str(), value.c_str()); } virtual String _assembleHead(uint8_t version); virtual bool _started() const; virtual bool _finished() const; diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 580ceba..d904a39 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -231,16 +231,16 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest* request) { } else if (_cache_control.length() && request->hasHeader(T_INM) && request->header(T_INM).equals(etag)) { request->_tempFile.close(); AsyncWebServerResponse* response = new AsyncBasicResponse(304); // Not modified - response->addHeader(T_Cache_Control, _cache_control); - response->addHeader(T_ETag, etag); + response->addHeader(T_Cache_Control, _cache_control.c_str()); + response->addHeader(T_ETag, etag.c_str()); request->send(response); } else { AsyncWebServerResponse* response = new AsyncFileResponse(request->_tempFile, filename, String(), false, _callback); if (_last_modified.length()) - response->addHeader(T_Last_Modified, _last_modified); + response->addHeader(T_Last_Modified, _last_modified.c_str()); if (_cache_control.length()) { - response->addHeader(T_Cache_Control, _cache_control); - response->addHeader(T_ETag, etag); + response->addHeader(T_Cache_Control, _cache_control.c_str()); + response->addHeader(T_ETag, etag.c_str()); } request->send(response); } diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index f0d6bdf..95fda7e 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -274,7 +274,7 @@ bool AsyncWebServerRequest::_parseReqHead() { if (!_temp.startsWith(T_HTTP_1_0)) _version = 1; - _temp = String(); + _temp = emptyString; return true; } @@ -307,7 +307,7 @@ bool AsyncWebServerRequest::_parseReqHeader() { if (name.equalsIgnoreCase(T_UPGRADE) && value.equalsIgnoreCase(T_WS)) { // WebSocket request can be uniquely identified by header: [Upgrade: websocket] _reqconntype = RCT_WS; - } else if (name.equalsIgnoreCase(T_ACCEPT)){ + } else if (name.equalsIgnoreCase(T_ACCEPT)) { String lowcase(value); lowcase.toLowerCase(); #ifndef ESP8266 @@ -327,7 +327,7 @@ bool AsyncWebServerRequest::_parseReqHeader() { _temp.clear(); #else // Ancient PRI core does not have String::clear() method 8-() - _temp = String(); + _temp = emptyString; #endif return true; } @@ -345,10 +345,10 @@ void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data) { _params.emplace_back(urlDecode(name), urlDecode(value), true); #ifndef TARGET_RP2040 - _temp.clear(); + _temp.clear(); #else - // Ancient PRI core does not have String::clear() method 8-() - _temp = String(); + // Ancient PRI core does not have String::clear() method 8-() + _temp = emptyString; #endif } } @@ -390,10 +390,10 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { if (!_parsedLength) { _multiParseState = EXPECT_BOUNDARY; - _temp = String(); - _itemName = String(); - _itemFilename = String(); - _itemType = String(); + _temp = emptyString; + _itemName = emptyString; + _itemFilename = emptyString; + _itemType = emptyString; } if (_multiParseState == WAIT_FOR_RETURN1) { @@ -450,13 +450,13 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { _itemIsFile = true; } } - _temp = String(); + _temp = emptyString; } else { _multiParseState = WAIT_FOR_RETURN1; // value starts from here _itemSize = 0; _itemStartIndex = _parsedLength; - _itemValue = String(); + _itemValue = emptyString; if (_itemIsFile) { if (_itemBuffer) free(_itemBuffer); @@ -654,9 +654,9 @@ size_t AsyncWebServerRequest::params() const { return _params.size(); } -bool AsyncWebServerRequest::hasParam(const String& name, bool post, bool file) const { +bool AsyncWebServerRequest::hasParam(const char* name, bool post, bool file) const { for (const auto& p : _params) { - if (p.name() == name && p.isPost() == post && p.isFile() == file) { + if (p.name().equals(name) && p.isPost() == post && p.isFile() == file) { return true; } } @@ -689,48 +689,52 @@ void AsyncWebServerRequest::addInterestingHeader(const char* name) { _interestingHeaders.emplace_back(name); } -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const String& contentType, const String& content) { +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); return new AsyncBasicResponse(code, contentType, content); } -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) { return new AsyncProgmemResponse(code, contentType, content, len, callback); } -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { - return new AsyncProgmemResponse(code, contentType, (const uint8_t*)content, strlen_P(content), callback); -} - -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(FS& fs, const String& path, const char* contentType, bool download, AwsTemplateProcessor callback) { if (fs.exists(path) || (!download && fs.exists(path + T__gz))) return new AsyncFileResponse(fs, path, contentType, download, callback); return NULL; } -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(File content, const String& path, const char* contentType, bool download, AwsTemplateProcessor callback) { if (content == true) return new AsyncFileResponse(content, path, contentType, download, callback); return NULL; } -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback) { return new AsyncStreamResponse(stream, contentType, len, callback); } -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(const char* contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { return new AsyncCallbackResponse(contentType, len, callback, templateCallback); } -AsyncWebServerResponse* AsyncWebServerRequest::beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginChunkedResponse(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { if (_version) return new AsyncChunkedResponse(contentType, callback, templateCallback); return new AsyncCallbackResponse(contentType, 0, callback, templateCallback); } -AsyncResponseStream* AsyncWebServerRequest::beginResponseStream(const String& contentType, size_t bufferSize) { +AsyncResponseStream* AsyncWebServerRequest::beginResponseStream(const char* contentType, size_t bufferSize) { return new AsyncResponseStream(contentType, bufferSize); } +#ifdef ESP8266 +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { + return new AsyncProgmemResponse(code, contentType, (const uint8_t*)content, strlen_P(content), callback); +} +#endif + void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { _response = response; if (_response == NULL) { @@ -748,44 +752,6 @@ void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { } } -void AsyncWebServerRequest::send(int code, const String& contentType, const String& content) { - send(beginResponse(code, contentType, content)); -} - -void AsyncWebServerRequest::send(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) { - send(beginResponse(code, contentType, content, len, callback)); -} - -void AsyncWebServerRequest::send(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { - send(beginResponse(code, contentType, content, callback)); -} - -void AsyncWebServerRequest::send(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { - if (fs.exists(path) || (!download && fs.exists(path + T__gz))) { - send(beginResponse(fs, path, contentType, download, callback)); - } else - send(404); -} - -void AsyncWebServerRequest::send(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { - if (content == true) { - send(beginResponse(content, path, contentType, download, callback)); - } else - send(404); -} - -void AsyncWebServerRequest::send(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback) { - send(beginResponse(stream, contentType, len, callback)); -} - -void AsyncWebServerRequest::send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { - send(beginResponse(contentType, len, callback, templateCallback)); -} - -void AsyncWebServerRequest::sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { - send(beginChunkedResponse(contentType, callback, templateCallback)); -} - void AsyncWebServerRequest::redirect(const char* url) { AsyncWebServerResponse* response = beginResponse(302); response->addHeader(T_LOCATION, url); @@ -834,11 +800,11 @@ void AsyncWebServerRequest::requestAuthentication(const char* realm, bool isDige String header(T_BASIC_REALM); header.concat(realm); header += '"'; - r->addHeader(T_WWW_AUTH, header); + r->addHeader(T_WWW_AUTH, header.c_str()); } else { String header(T_DIGEST_); header.concat(requestDigestAuthentication(realm)); - r->addHeader(T_WWW_AUTH, header); + r->addHeader(T_WWW_AUTH, header.c_str()); } send(r); } @@ -949,7 +915,7 @@ const char* AsyncWebServerRequest::methodToString() const { return T_OPTIONS; return T_UNKNOWN; } -#else // ESP8266 +#else // ESP8266 const __FlashStringHelper* AsyncWebServerRequest::methodToString() const { if (_method == HTTP_ANY) return FPSTR(T_ANY); @@ -988,7 +954,7 @@ const char* AsyncWebServerRequest::requestedConnTypeToString() const { return T_ERROR; } } -#else // ESP8266 +#else // ESP8266 const __FlashStringHelper* AsyncWebServerRequest::requestedConnTypeToString() const { switch (_reqconntype) { case RCT_NOT_USED: diff --git a/src/WebResponseImpl.h b/src/WebResponseImpl.h index 26ec223..a6f71bb 100644 --- a/src/WebResponseImpl.h +++ b/src/WebResponseImpl.h @@ -28,6 +28,7 @@ #endif #include #include +#include "literals.h" // It is possible to restore these defines, but one can use _min and _max instead. Or std::min, std::max. @@ -36,7 +37,8 @@ class AsyncBasicResponse : public AsyncWebServerResponse { String _content; public: - AsyncBasicResponse(int code, const String& contentType = String(), const String& content = String()); + explicit AsyncBasicResponse(int code, const char* contentType = asyncsrv::empty, const char* content = asyncsrv::empty); + AsyncBasicResponse(int code, const String& contentType, const String& content = emptyString) : AsyncBasicResponse(code, contentType.c_str(), content.c_str()) {} void _respond(AsyncWebServerRequest* request); size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); bool _sourceValid() const { return true; } @@ -76,11 +78,13 @@ class AsyncFileResponse : public AsyncAbstractResponse { private: File _content; String _path; - void _setContentType(const String& path); + void _setContentTypeFromPath(const String& path); public: - AsyncFileResponse(FS& fs, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); - AsyncFileResponse(File content, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncFileResponse(FS& fs, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncFileResponse(FS& fs, const String& path, const String& contentType, bool download = false, AwsTemplateProcessor callback = nullptr) : AsyncFileResponse(fs, path, contentType.c_str(), download, callback) {} + AsyncFileResponse(File content, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncFileResponse(File content, const String& path, const String& contentType, bool download = false, AwsTemplateProcessor callack = nullptr) : AsyncFileResponse(content, path, contentType.c_str(), download, callack) {} ~AsyncFileResponse(); bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; @@ -91,7 +95,8 @@ class AsyncStreamResponse : public AsyncAbstractResponse { Stream* _content; public: - AsyncStreamResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncStreamResponse(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncStreamResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr) : AsyncStreamResponse(stream, contentType.c_str(), len, callback) {} bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -102,7 +107,8 @@ class AsyncCallbackResponse : public AsyncAbstractResponse { size_t _filledLength; public: - AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncCallbackResponse(const char* contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) : AsyncCallbackResponse(contentType.c_str(), len, callback, templateCallback) {} bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -113,7 +119,8 @@ class AsyncChunkedResponse : public AsyncAbstractResponse { size_t _filledLength; public: - AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncChunkedResponse(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) : AsyncChunkedResponse(contentType.c_str(), callback, templateCallback) {} bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -124,7 +131,8 @@ class AsyncProgmemResponse : public AsyncAbstractResponse { size_t _readLength; public: - AsyncProgmemResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncProgmemResponse(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncProgmemResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) : AsyncProgmemResponse(code, contentType.c_str(), content, len, callback) {} bool _sourceValid() const { return true; } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -136,7 +144,8 @@ class AsyncResponseStream : public AsyncAbstractResponse, public Print { std::unique_ptr _content; public: - AsyncResponseStream(const String& contentType, size_t bufferSize); + AsyncResponseStream(const char* contentType, size_t bufferSize); + AsyncResponseStream(const String& contentType, size_t bufferSize) : AsyncResponseStream(contentType.c_str(), bufferSize) {} ~AsyncResponseStream(); bool _sourceValid() const { return (_state < RESPONSE_END); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index 86aa947..f1994b1 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -234,12 +234,12 @@ void AsyncWebServerResponse::setContentLength(size_t len) { _contentLength = len; } -void AsyncWebServerResponse::setContentType(const String& type) { +void AsyncWebServerResponse::setContentType(const char* type) { if (_state == RESPONSE_SETUP) _contentType = type; } -void AsyncWebServerResponse::addHeader(const String& name, const String& value) { +void AsyncWebServerResponse::addHeader(const char* name, const char* value) { _headers.emplace_back(name, value); } @@ -298,7 +298,7 @@ size_t AsyncWebServerResponse::_ack(AsyncWebServerRequest* request, size_t len, /* * String/Code Response * */ -AsyncBasicResponse::AsyncBasicResponse(int code, const String& contentType, const String& content) { +AsyncBasicResponse::AsyncBasicResponse(int code, const char* contentType, const char* content) { _code = code; _content = content; _contentType = contentType; @@ -353,7 +353,7 @@ size_t AsyncBasicResponse::_ack(AsyncWebServerRequest* request, size_t len, uint // we can fit in this packet if (space > available) { _writtenLength += request->client()->write(_content.c_str(), available); - _content = String(); + _content = emptyString; _state = RESPONSE_WAIT_ACK; return available; } @@ -465,7 +465,7 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest* request, size_t len, u } if (headLen) { - _head = String(); + _head = emptyString; } if (outLen) { @@ -607,7 +607,7 @@ AsyncFileResponse::~AsyncFileResponse() { _content.close(); } -void AsyncFileResponse::_setContentType(const String& path) { +void AsyncFileResponse::_setContentTypeFromPath(const String& path) { #if HAVE_EXTERN_GET_Content_Type_FUNCTION #ifndef ESP8266 extern const char* getContentType(const String& path); @@ -657,7 +657,7 @@ void AsyncFileResponse::_setContentType(const String& path) { #endif } -AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { +AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const char* contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = 200; _path = path; @@ -672,8 +672,8 @@ AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const String& c _content = fs.open(_path, fs::FileOpenMode::read); _contentLength = _content.size(); - if (contentType.length() == 0) - _setContentType(path); + if (strlen(contentType) == 0) + _setContentTypeFromPath(path); else _contentType = contentType; @@ -691,7 +691,7 @@ AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const String& c addHeader(T_Content_Disposition, buf); } -AsyncFileResponse::AsyncFileResponse(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { +AsyncFileResponse::AsyncFileResponse(File content, const String& path, const char* contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = 200; _path = path; @@ -705,8 +705,8 @@ AsyncFileResponse::AsyncFileResponse(File content, const String& path, const Str _content = content; _contentLength = _content.size(); - if (contentType.length() == 0) - _setContentType(path); + if (strlen(contentType) == 0) + _setContentTypeFromPath(path); else _contentType = contentType; @@ -730,7 +730,7 @@ size_t AsyncFileResponse::_fillBuffer(uint8_t* data, size_t len) { * Stream Response * */ -AsyncStreamResponse::AsyncStreamResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { +AsyncStreamResponse::AsyncStreamResponse(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = 200; _content = &stream; _contentLength = len; @@ -750,7 +750,7 @@ size_t AsyncStreamResponse::_fillBuffer(uint8_t* data, size_t len) { * Callback Response * */ -AsyncCallbackResponse::AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) : AsyncAbstractResponse(templateCallback) { +AsyncCallbackResponse::AsyncCallbackResponse(const char* contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) : AsyncAbstractResponse(templateCallback) { _code = 200; _content = callback; _contentLength = len; @@ -772,7 +772,7 @@ size_t AsyncCallbackResponse::_fillBuffer(uint8_t* data, size_t len) { * Chunked Response * */ -AsyncChunkedResponse::AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor processorCallback) : AsyncAbstractResponse(processorCallback) { +AsyncChunkedResponse::AsyncChunkedResponse(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor processorCallback) : AsyncAbstractResponse(processorCallback) { _code = 200; _content = callback; _contentLength = 0; @@ -794,7 +794,7 @@ size_t AsyncChunkedResponse::_fillBuffer(uint8_t* data, size_t len) { * Progmem Response * */ -AsyncProgmemResponse::AsyncProgmemResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { +AsyncProgmemResponse::AsyncProgmemResponse(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = code; _content = content; _contentType = contentType; @@ -818,7 +818,7 @@ size_t AsyncProgmemResponse::_fillBuffer(uint8_t* data, size_t len) { * Response Stream (You can print/write/printf to it, up to the contentLen bytes) * */ -AsyncResponseStream::AsyncResponseStream(const String& contentType, size_t bufferSize) { +AsyncResponseStream::AsyncResponseStream(const char* contentType, size_t bufferSize) { _code = 200; _contentLength = 0; _contentType = contentType; diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 0e29a54..d7c9a02 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -24,11 +24,19 @@ using namespace asyncsrv; bool ON_STA_FILTER(AsyncWebServerRequest* request) { + #ifndef CONFIG_IDF_TARGET_ESP32H2 return WiFi.localIP() == request->client()->localIP(); + #else + return false; + #endif } bool ON_AP_FILTER(AsyncWebServerRequest* request) { + #ifndef CONFIG_IDF_TARGET_ESP32H2 return WiFi.localIP() != request->client()->localIP(); + #else + return false; + #endif } #ifndef HAVE_FS_FILE_OPEN_MODE diff --git a/src/literals.h b/src/literals.h index c60a3eb..8a7293b 100644 --- a/src/literals.h +++ b/src/literals.h @@ -2,6 +2,8 @@ namespace asyncsrv { +static constexpr const char* empty = ""; + #ifndef ESP8622 static constexpr const char* T_100_CONTINUE = "100-continue"; static constexpr const char* T_ACCEPT = "Accept";