From 9dc93747886c114281e7e6b81b3982ad22d73a49 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Sat, 4 Apr 2026 11:11:35 -1000 Subject: [PATCH 01/19] Support hosted builds against Arduino-Emulator * Factors the locking into one place * Adds "|| defined(HOST)" as needed elsewhere * Adds "override" in a few places where it was missing --- src/AsyncEventSource.cpp | 45 +++++------------- src/AsyncEventSource.h | 18 +++----- src/AsyncWebServerLogging.h | 7 +++ src/AsyncWebSocket.cpp | 91 ++++++++++--------------------------- src/AsyncWebSocket.h | 22 +++++---- src/ESPAsyncWebServer.h | 28 ++++++++++++ src/WebAuthentication.cpp | 7 +-- src/WebRequest.cpp | 4 +- src/WebServer.cpp | 2 +- 9 files changed, 97 insertions(+), 127 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index fb1d7ab71..977b58f90 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -191,19 +191,15 @@ AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest *request, A } AsyncEventSourceClient::~AsyncEventSourceClient() { -#ifdef ESP32 // Protect message queue access (size checks and modifications) which is not thread-safe. - std::lock_guard lock(_lockmq); -#endif + LOCK(_lockmq); _messageQueue.clear(); close(); } bool AsyncEventSourceClient::_queueMessage(const char *message, size_t len) { -#ifdef ESP32 // Protect message queue access (size checks and modifications) which is not thread-safe. - std::lock_guard lock(_lockmq); -#endif + LOCK(_lockmq); if (_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES) { async_ws_log_w("Event message queue overflow: discard message"); @@ -231,10 +227,8 @@ bool AsyncEventSourceClient::_queueMessage(const char *message, size_t len) { } bool AsyncEventSourceClient::_queueMessage(AsyncEvent_SharedData_t &&msg) { -#ifdef ESP32 // Protect message queue access (size checks and modifications) which is not thread-safe. - std::lock_guard lock(_lockmq); -#endif + LOCK(_lockmq); if (_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES) { async_ws_log_w("Event message queue overflow: discard message"); @@ -261,10 +255,8 @@ bool AsyncEventSourceClient::_queueMessage(AsyncEvent_SharedData_t &&msg) { } void AsyncEventSourceClient::_onAck(size_t len __attribute__((unused)), uint32_t time __attribute__((unused))) { -#ifdef ESP32 // Protect message queue access (size checks and modifications) which is not thread-safe. - std::lock_guard lock(_lockmq); -#endif + LOCK(_lockmq); // adjust in-flight len if (len < _inflight) { @@ -289,10 +281,8 @@ void AsyncEventSourceClient::_onAck(size_t len __attribute__((unused)), uint32_t } void AsyncEventSourceClient::_onPoll() { -#ifdef ESP32 // Protect message queue access (size checks and modifications) which is not thread-safe. - std::lock_guard lock(_lockmq); -#endif + LOCK(_lockmq); if (_messageQueue.size()) { _runQueue(); } @@ -373,10 +363,7 @@ void AsyncEventSource::_addClient(AsyncEventSourceClient *client) { _connectcb(client); } -#ifdef ESP32 - std::lock_guard lock(_client_queue_lock); -#endif - + LOCK(_client_queue_lock); _clients.emplace_back(client); _adjust_inflight_window(); @@ -386,9 +373,7 @@ void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient *client) { if (_disconnectcb) { _disconnectcb(client); } -#ifdef ESP32 - std::lock_guard lock(_client_queue_lock); -#endif + LOCK(_client_queue_lock); for (auto i = _clients.begin(); i != _clients.end(); ++i) { if (i->get() == client) { _clients.erase(i); @@ -402,9 +387,7 @@ void AsyncEventSource::close() { // While the whole loop is not done, the linked list is locked and so the // iterator should remain valid even when AsyncEventSource::_handleDisconnect() // is called very early -#ifdef ESP32 - std::lock_guard lock(_client_queue_lock); -#endif + LOCK(_client_queue_lock); for (const auto &c : _clients) { if (c->connected()) { /** @@ -421,9 +404,7 @@ void AsyncEventSource::close() { size_t AsyncEventSource::avgPacketsWaiting() const { size_t aql = 0; uint32_t nConnectedClients = 0; -#ifdef ESP32 - std::lock_guard lock(_client_queue_lock); -#endif + LOCK(_client_queue_lock); for (const auto &c : _clients) { if (c->connected()) { aql += c->packetsWaiting(); @@ -435,9 +416,7 @@ size_t AsyncEventSource::avgPacketsWaiting() const { AsyncEventSource::SendStatus AsyncEventSource::send(const char *message, const char *event, uint32_t id, uint32_t reconnect) { AsyncEvent_SharedData_t shared_msg = std::make_shared(generateEventMessage(message, event, id, reconnect)); -#ifdef ESP32 - std::lock_guard lock(_client_queue_lock); -#endif + LOCK(_client_queue_lock); size_t hits = 0; size_t miss = 0; for (const auto &c : _clients) { @@ -453,9 +432,7 @@ AsyncEventSource::SendStatus AsyncEventSource::send(const char *message, const c } size_t AsyncEventSource::count() const { -#ifdef ESP32 - std::lock_guard lock(_client_queue_lock); -#endif + LOCK(_client_queue_lock); size_t n_clients{0}; for (const auto &i : _clients) { if (i->connected()) { diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 4282fff3b..560e352e1 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -5,7 +5,7 @@ #include -#if defined(ESP32) || defined(LIBRETINY) +#if defined(ESP32) || defined(LIBRETINY) || defined(HOST) #include #ifdef LIBRETINY #ifdef round @@ -136,9 +136,7 @@ class AsyncEventSourceClient { size_t _inflight{0}; // num of unacknowledged bytes that has been written to socket buffer size_t _max_inflight{SSE_MAX_INFLIGH}; // max num of unacknowledged bytes that could be written to socket buffer std::list _messageQueue; -#ifdef ESP32 - mutable std::recursive_mutex _lockmq; -#endif + MAKE_LOCK(_lockmq); bool _queueMessage(const char *message, size_t len); bool _queueMessage(AsyncEvent_SharedData_t &&msg); void _runQueue(); @@ -205,9 +203,7 @@ class AsyncEventSourceClient { return _lastId; } size_t packetsWaiting() const { -#ifdef ESP32 - std::lock_guard lock(_lockmq); -#endif + LOCK(_lockmq); return _messageQueue.size(); }; @@ -245,11 +241,9 @@ class AsyncEventSource : public AsyncWebHandler { private: String _url; std::list> _clients; -#ifdef ESP32 // Same as for individual messages, protect mutations of _clients list // since simultaneous access from different tasks is possible - mutable std::recursive_mutex _client_queue_lock; -#endif + MAKE_LOCK(_client_queue_lock); ArEventHandlerFunction _connectcb = nullptr; ArEventHandlerFunction _disconnectcb = nullptr; @@ -331,11 +325,11 @@ class AsyncEventSourceResponse : public AsyncWebServerResponse { public: AsyncEventSourceResponse(AsyncEventSource *server); - void _respond(AsyncWebServerRequest *request); + void _respond(AsyncWebServerRequest *request) override; size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time) override { return 0; }; - bool _sourceValid() const { + bool _sourceValid() const override { return true; } }; diff --git a/src/AsyncWebServerLogging.h b/src/AsyncWebServerLogging.h index f550fd9ec..daef25942 100644 --- a/src/AsyncWebServerLogging.h +++ b/src/AsyncWebServerLogging.h @@ -31,6 +31,13 @@ #define async_ws_log_d(format, ...) log_d(format, ##__VA_ARGS__) #define async_ws_log_v(format, ...) log_v(format, ##__VA_ARGS__) +#elif defined(HOST) +#define async_ws_log_e(format, ...) +#define async_ws_log_w(format, ...) +#define async_ws_log_i(format, ...) +#define async_ws_log_d(format, ...) +#define async_ws_log_v(format, ...) + /** * Raspberry Pi Pico specific configurations */ diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 1f6adee01..1060edad9 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -17,6 +17,8 @@ #include #elif defined(LIBRETINY) #include +#elif defined(HOST) +#include "BackPort_SHA1Builder.h" #endif #include @@ -24,6 +26,7 @@ #include #include #include +#include #define STATE_FRAME_START 0 #define STATE_FRAME_MASK 1 @@ -291,9 +294,7 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncClient *client, AsyncWebSocket * AsyncWebSocketClient::~AsyncWebSocketClient() { { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); _messageQueue.clear(); _controlQueue.clear(); } @@ -309,9 +310,7 @@ void AsyncWebSocketClient::_clearQueue() { void AsyncWebSocketClient::_onAck(size_t len, uint32_t time) { _lastMessageTime = millis(); -#ifdef ESP32 - std::unique_lock lock(_lock); -#endif + UNIQUE_LOCK(_lock); async_ws_log_v("[%s][%" PRIu32 "] START ACK(%u, %" PRIu32 ") Q:%u", _server->url(), _clientId, len, time, _messageQueue.size()); @@ -324,14 +323,12 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time) { _status = WS_DISCONNECTED; async_ws_log_v("[%s][%" PRIu32 "] ACK WS_DISCONNECTED", _server->url(), _clientId); if (_client) { -#ifdef ESP32 /* Unlocking has to be called before return execution otherwise std::unique_lock ::~unique_lock() will get an exception pthread_mutex_unlock. Due to _client->close() shall call the callback function _onDisconnect() The calling flow _onDisconnect() --> _handleDisconnect() --> ~AsyncWebSocketClient() */ - lock.unlock(); -#endif + UNLOCK(); _client->close(); } return; @@ -361,15 +358,11 @@ void AsyncWebSocketClient::_onPoll() { return; } -#ifdef ESP32 - std::unique_lock lock(_lock); -#endif + UNIQUE_LOCK(_lock); if (_client && _client->canSend() && (!_controlQueue.empty() || !_messageQueue.empty())) { _runQueue(); } else if (_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && (_controlQueue.empty() && _messageQueue.empty())) { -#ifdef ESP32 - lock.unlock(); -#endif + UNLOCK(); ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); } } @@ -433,23 +426,17 @@ void AsyncWebSocketClient::_runQueue() { } bool AsyncWebSocketClient::queueIsFull() const { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); return (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED); } size_t AsyncWebSocketClient::queueLen() const { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); return _messageQueue.size(); } bool AsyncWebSocketClient::canSend() const { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); return _messageQueue.size() < WS_MAX_QUEUED_MESSAGES; } @@ -458,9 +445,7 @@ bool AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t *data, si return false; } -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); _controlQueue.emplace_back(opcode, data, len, mask); async_ws_log_v("[%s][%" PRIu32 "] QUEUE CTRL (%u) << %" PRIu8, _server->url(), _clientId, _controlQueue.size(), opcode); @@ -477,23 +462,19 @@ bool AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint return false; } -#ifdef ESP32 - std::unique_lock lock(_lock); -#endif + UNIQUE_LOCK(_lock); if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) { if (closeWhenFull) { _status = WS_DISCONNECTED; if (_client) { -#ifdef ESP32 /* Unlocking has to be called before return execution otherwise std::unique_lock ::~unique_lock() will get an exception pthread_mutex_unlock. Due to _client->close() shall call the callback function _onDisconnect() The calling flow _onDisconnect() --> _handleDisconnect() --> ~AsyncWebSocketClient() */ - lock.unlock(); -#endif + UNLOCK(); _client->close(); } @@ -988,9 +969,7 @@ void AsyncWebSocket::_handleEvent(AsyncWebSocketClient *client, AwsEventType typ } AsyncWebSocketClient *AsyncWebSocket::_newClient(AsyncWebServerRequest *request) { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); _clients.emplace_back(request, this); // we've just detached AsyncTCP client from AsyncWebServerRequest _handleEvent(&_clients.back(), WS_EVT_CONNECT, request, NULL, 0); @@ -1000,9 +979,7 @@ AsyncWebSocketClient *AsyncWebSocket::_newClient(AsyncWebServerRequest *request) } void AsyncWebSocket::_handleDisconnect(AsyncWebSocketClient *client) { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); const auto client_id = client->id(); const auto iter = std::find_if(std::begin(_clients), std::end(_clients), [client_id](const AsyncWebSocketClient &c) { return c.id() == client_id; @@ -1013,18 +990,14 @@ void AsyncWebSocket::_handleDisconnect(AsyncWebSocketClient *client) { } bool AsyncWebSocket::availableForWriteAll() { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); return std::none_of(std::begin(_clients), std::end(_clients), [](const AsyncWebSocketClient &c) { return c.queueIsFull(); }); } bool AsyncWebSocket::availableForWrite(uint32_t id) { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); const auto iter = std::find_if(std::begin(_clients), std::end(_clients), [id](const AsyncWebSocketClient &c) { return c.id() == id; }); @@ -1035,18 +1008,14 @@ bool AsyncWebSocket::availableForWrite(uint32_t id) { } size_t AsyncWebSocket::count() const { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); return std::count_if(std::begin(_clients), std::end(_clients), [](const AsyncWebSocketClient &c) { return c.status() == WS_CONNECTED; }); } AsyncWebSocketClient *AsyncWebSocket::client(uint32_t id) { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); const auto iter = std::find_if(_clients.begin(), _clients.end(), [id](const AsyncWebSocketClient &c) { return c.id() == id && c.status() == WS_CONNECTED; }); @@ -1064,9 +1033,7 @@ void AsyncWebSocket::close(uint32_t id, uint16_t code, const char *message) { } void AsyncWebSocket::closeAll(uint16_t code, const char *message) { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); for (auto &c : _clients) { if (c.status() == WS_CONNECTED) { c.close(code, message); @@ -1075,9 +1042,7 @@ void AsyncWebSocket::closeAll(uint16_t code, const char *message) { } void AsyncWebSocket::cleanupClients(uint16_t maxClients) { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); const size_t c = count(); if (c > maxClients) { async_ws_log_v("[%s] CLEANUP %" PRIu32 " (%u/%" PRIu16 ")", _url.c_str(), _clients.front().id(), c, maxClients); @@ -1098,9 +1063,7 @@ bool AsyncWebSocket::ping(uint32_t id, const uint8_t *data, size_t len) { } AsyncWebSocket::SendStatus AsyncWebSocket::pingAll(const uint8_t *data, size_t len) { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); size_t hit = 0; size_t miss = 0; for (auto &c : _clients) { @@ -1209,9 +1172,7 @@ AsyncWebSocket::SendStatus AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * } AsyncWebSocket::SendStatus AsyncWebSocket::textAll(AsyncWebSocketSharedBuffer buffer) { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); size_t hit = 0; size_t miss = 0; for (auto &c : _clients) { @@ -1301,9 +1262,7 @@ AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer return status; } AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(AsyncWebSocketSharedBuffer buffer) { -#ifdef ESP32 - std::lock_guard lock(_lock); -#endif + LOCK(_lock); size_t hit = 0; size_t miss = 0; for (auto &c : _clients) { diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index ea181c590..339e0068c 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -16,6 +16,14 @@ #ifndef WS_MAX_QUEUED_MESSAGES #define WS_MAX_QUEUED_MESSAGES 32 #endif +#elif defined(HOST) +#ifndef FPSTR +#define FPSTR (const char *) +#endif +#include +#ifndef WS_MAX_QUEUED_MESSAGES +#define WS_MAX_QUEUED_MESSAGES 32 +#endif #elif defined(ESP8266) #include #ifndef WS_MAX_QUEUED_MESSAGES @@ -44,7 +52,7 @@ #endif #ifndef DEFAULT_MAX_WS_CLIENTS -#ifdef ESP32 +#if defined(ESP32) || defined(HOST) #define DEFAULT_MAX_WS_CLIENTS 8 #else #define DEFAULT_MAX_WS_CLIENTS 4 @@ -222,9 +230,7 @@ class AsyncWebSocketClient { uint8_t _pstate; uint32_t _lastMessageTime; uint32_t _keepAlivePeriod; -#ifdef ESP32 - mutable std::recursive_mutex _lock; -#endif + MAKE_LOCK(_lock); std::deque _controlQueue; std::deque _messageQueue; bool closeWhenFull = true; @@ -372,9 +378,7 @@ class AsyncWebSocket : public AsyncWebHandler { AwsEventHandler _eventHandler; AwsHandshakeHandler _handshakeHandler; bool _enabled; -#ifdef ESP32 - mutable std::recursive_mutex _lock; -#endif + MAKE_LOCK(_lock); public: typedef enum { @@ -488,11 +492,11 @@ class AsyncWebSocketResponse : public AsyncWebServerResponse { public: AsyncWebSocketResponse(const String &key, AsyncWebSocket *server); - void _respond(AsyncWebServerRequest *request); + void _respond(AsyncWebServerRequest *request) override; size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time) override { return 0; }; - bool _sourceValid() const { + bool _sourceValid() const override { return true; } }; diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 5f57649ef..0326f9a59 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -5,7 +5,9 @@ #include #include +#ifndef HOST #include +#endif #include #include @@ -17,6 +19,10 @@ #include #include +#ifndef __unused +#define __unused __attribute__((unused)) +#endif + #if __has_include("ArduinoJson.h") #include @@ -37,6 +43,9 @@ #if defined(ESP32) || defined(LIBRETINY) #include #include +#elif defined(HOST) +#include +#include #elif defined(ESP8266) #include #elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) @@ -45,6 +54,25 @@ #error Platform not supported #endif +#if defined(ESP32) || defined(HOST) +#include +#define MAKE_LOCK(var) mutable std::recursive_mutex var +#define LOCK(var) std::lock_guard lock(var) +#define UNIQUE_LOCK(var) std::unique_lock lock(var) +#define UNLOCK() lock.unlock() +#else +#define MAKE_LOCK(var) +#define LOCK(var) \ + do { \ + } while (0) +#define UNIQUE_LOCK(var) \ + do { \ + } while (0) +#define UNLOCK() \ + do { \ + } while (0) +#endif + #include "AsyncWebServerVersion.h" #define ASYNCWEBSERVER_FORK_ESP32Async diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index fff0c5c17..04668556c 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -3,9 +3,10 @@ #include "WebAuthentication.h" #include "AsyncWebServerLogging.h" - +#include "ESPAsyncWebServer.h" #include -#if defined(ESP32) || defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) + +#if defined(ESP32) || defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(HOST) #include #else #include @@ -53,7 +54,7 @@ String generateBasicHash(const char *username, const char *password) { } static bool getMD5(uint8_t *data, uint16_t len, char *output) { // 33 bytes or more -#if defined(ESP32) || defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) +#if defined(ESP32) || defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(HOST) MD5Builder md5; md5.begin(); md5.add(data, len); diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index fa692057e..3b8da1e82 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -543,7 +543,7 @@ bool AsyncWebServerRequest::_parseReqHeader() { } _headers.emplace_back(std::move(header)); } -#if defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(LIBRETINY) +#if defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(LIBRETINY) || defined(HOST) // Ancient PRI core does not have String::clear() method 8-() _temp = asyncsrv::emptyString; #else @@ -568,7 +568,7 @@ void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data) { _params.emplace_back(name, urlDecode(value), true); } -#if defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(LIBRETINY) +#if defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(LIBRETINY) || defined(HOST) // Ancient PRI core does not have String::clear() method 8-() _temp = asyncsrv::emptyString; #else diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 15fa701af..cbdca129b 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -7,7 +7,7 @@ #include #include -#if defined(ESP32) || defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(LIBRETINY) +#if defined(ESP32) || defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(LIBRETINY) || defined(HOST) #include #elif defined(ESP8266) #include From a302812153eb6ae3d0ce7ab97ec7b404a47560e4 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Sat, 4 Apr 2026 11:45:02 -1000 Subject: [PATCH 02/19] Changed comments to address Copilot nitpicking --- src/WebRequest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 3b8da1e82..8b0a680bd 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -544,7 +544,7 @@ bool AsyncWebServerRequest::_parseReqHeader() { _headers.emplace_back(std::move(header)); } #if defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(LIBRETINY) || defined(HOST) - // Ancient PRI core does not have String::clear() method 8-() + // ArduinoCore-API does not have String::clear() method 8-() _temp = asyncsrv::emptyString; #else _temp.clear(); @@ -569,7 +569,7 @@ void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data) { } #if defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(LIBRETINY) || defined(HOST) - // Ancient PRI core does not have String::clear() method 8-() + // ArduinoCore-API does not have String::clear() method 8-() _temp = asyncsrv::emptyString; #else _temp.clear(); From 9f138a23e6a2538878cea6b284cb13690722c61e Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Sun, 5 Apr 2026 10:57:18 -1000 Subject: [PATCH 03/19] Changed cpp macros to c++ possibly-null classes, thanks willmmiles --- src/AsyncEventSource.cpp | 22 ++++++++++---------- src/AsyncEventSource.h | 6 +++--- src/AsyncWebSocket.cpp | 44 ++++++++++++++++++++-------------------- src/AsyncWebSocket.h | 4 ++-- src/ESPAsyncWebServer.h | 37 ++++++++++++++++++++------------- 5 files changed, 61 insertions(+), 52 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 977b58f90..b35f1324b 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -192,14 +192,14 @@ AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest *request, A AsyncEventSourceClient::~AsyncEventSourceClient() { // Protect message queue access (size checks and modifications) which is not thread-safe. - LOCK(_lockmq); + lock_guard_type lock(_lockmq); _messageQueue.clear(); close(); } bool AsyncEventSourceClient::_queueMessage(const char *message, size_t len) { // Protect message queue access (size checks and modifications) which is not thread-safe. - LOCK(_lockmq); + lock_guard_type lock(_lockmq); if (_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES) { async_ws_log_w("Event message queue overflow: discard message"); @@ -228,7 +228,7 @@ bool AsyncEventSourceClient::_queueMessage(const char *message, size_t len) { bool AsyncEventSourceClient::_queueMessage(AsyncEvent_SharedData_t &&msg) { // Protect message queue access (size checks and modifications) which is not thread-safe. - LOCK(_lockmq); + lock_guard_type lock(_lockmq); if (_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES) { async_ws_log_w("Event message queue overflow: discard message"); @@ -256,7 +256,7 @@ bool AsyncEventSourceClient::_queueMessage(AsyncEvent_SharedData_t &&msg) { void AsyncEventSourceClient::_onAck(size_t len __attribute__((unused)), uint32_t time __attribute__((unused))) { // Protect message queue access (size checks and modifications) which is not thread-safe. - LOCK(_lockmq); + lock_guard_type lock(_lockmq); // adjust in-flight len if (len < _inflight) { @@ -282,7 +282,7 @@ void AsyncEventSourceClient::_onAck(size_t len __attribute__((unused)), uint32_t void AsyncEventSourceClient::_onPoll() { // Protect message queue access (size checks and modifications) which is not thread-safe. - LOCK(_lockmq); + lock_guard_type lock(_lockmq); if (_messageQueue.size()) { _runQueue(); } @@ -363,7 +363,7 @@ void AsyncEventSource::_addClient(AsyncEventSourceClient *client) { _connectcb(client); } - LOCK(_client_queue_lock); + lock_guard_type lock(_client_queue_lock); _clients.emplace_back(client); _adjust_inflight_window(); @@ -373,7 +373,7 @@ void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient *client) { if (_disconnectcb) { _disconnectcb(client); } - LOCK(_client_queue_lock); + lock_guard_type lock(_client_queue_lock); for (auto i = _clients.begin(); i != _clients.end(); ++i) { if (i->get() == client) { _clients.erase(i); @@ -387,7 +387,7 @@ void AsyncEventSource::close() { // While the whole loop is not done, the linked list is locked and so the // iterator should remain valid even when AsyncEventSource::_handleDisconnect() // is called very early - LOCK(_client_queue_lock); + lock_guard_type lock(_client_queue_lock); for (const auto &c : _clients) { if (c->connected()) { /** @@ -404,7 +404,7 @@ void AsyncEventSource::close() { size_t AsyncEventSource::avgPacketsWaiting() const { size_t aql = 0; uint32_t nConnectedClients = 0; - LOCK(_client_queue_lock); + lock_guard_type lock(_client_queue_lock); for (const auto &c : _clients) { if (c->connected()) { aql += c->packetsWaiting(); @@ -416,7 +416,7 @@ size_t AsyncEventSource::avgPacketsWaiting() const { AsyncEventSource::SendStatus AsyncEventSource::send(const char *message, const char *event, uint32_t id, uint32_t reconnect) { AsyncEvent_SharedData_t shared_msg = std::make_shared(generateEventMessage(message, event, id, reconnect)); - LOCK(_client_queue_lock); + lock_guard_type lock(_client_queue_lock); size_t hits = 0; size_t miss = 0; for (const auto &c : _clients) { @@ -432,7 +432,7 @@ AsyncEventSource::SendStatus AsyncEventSource::send(const char *message, const c } size_t AsyncEventSource::count() const { - LOCK(_client_queue_lock); + lock_guard_type lock(_client_queue_lock); size_t n_clients{0}; for (const auto &i : _clients) { if (i->connected()) { diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 560e352e1..efee955c6 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -136,7 +136,7 @@ class AsyncEventSourceClient { size_t _inflight{0}; // num of unacknowledged bytes that has been written to socket buffer size_t _max_inflight{SSE_MAX_INFLIGH}; // max num of unacknowledged bytes that could be written to socket buffer std::list _messageQueue; - MAKE_LOCK(_lockmq); + mutable mutex_type _lockmq; bool _queueMessage(const char *message, size_t len); bool _queueMessage(AsyncEvent_SharedData_t &&msg); void _runQueue(); @@ -203,7 +203,7 @@ class AsyncEventSourceClient { return _lastId; } size_t packetsWaiting() const { - LOCK(_lockmq); + lock_guard_type lock(_lockmq); return _messageQueue.size(); }; @@ -243,7 +243,7 @@ class AsyncEventSource : public AsyncWebHandler { std::list> _clients; // Same as for individual messages, protect mutations of _clients list // since simultaneous access from different tasks is possible - MAKE_LOCK(_client_queue_lock); + mutable mutex_type _client_queue_lock; ArEventHandlerFunction _connectcb = nullptr; ArEventHandlerFunction _disconnectcb = nullptr; diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 1060edad9..233bed5d8 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -294,7 +294,7 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncClient *client, AsyncWebSocket * AsyncWebSocketClient::~AsyncWebSocketClient() { { - LOCK(_lock); + lock_guard_type lock(_lock); _messageQueue.clear(); _controlQueue.clear(); } @@ -310,7 +310,7 @@ void AsyncWebSocketClient::_clearQueue() { void AsyncWebSocketClient::_onAck(size_t len, uint32_t time) { _lastMessageTime = millis(); - UNIQUE_LOCK(_lock); + unique_lock_type lock(_lock); async_ws_log_v("[%s][%" PRIu32 "] START ACK(%u, %" PRIu32 ") Q:%u", _server->url(), _clientId, len, time, _messageQueue.size()); @@ -328,7 +328,7 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time) { Due to _client->close() shall call the callback function _onDisconnect() The calling flow _onDisconnect() --> _handleDisconnect() --> ~AsyncWebSocketClient() */ - UNLOCK(); + lock.unlock(); _client->close(); } return; @@ -358,11 +358,11 @@ void AsyncWebSocketClient::_onPoll() { return; } - UNIQUE_LOCK(_lock); + unique_lock_type lock(_lock); if (_client && _client->canSend() && (!_controlQueue.empty() || !_messageQueue.empty())) { _runQueue(); } else if (_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && (_controlQueue.empty() && _messageQueue.empty())) { - UNLOCK(); + lock.unlock(); ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); } } @@ -426,17 +426,17 @@ void AsyncWebSocketClient::_runQueue() { } bool AsyncWebSocketClient::queueIsFull() const { - LOCK(_lock); + lock_guard_type lock(_lock); return (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED); } size_t AsyncWebSocketClient::queueLen() const { - LOCK(_lock); + lock_guard_type lock(_lock); return _messageQueue.size(); } bool AsyncWebSocketClient::canSend() const { - LOCK(_lock); + lock_guard_type lock(_lock); return _messageQueue.size() < WS_MAX_QUEUED_MESSAGES; } @@ -445,7 +445,7 @@ bool AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t *data, si return false; } - LOCK(_lock); + lock_guard_type lock(_lock); _controlQueue.emplace_back(opcode, data, len, mask); async_ws_log_v("[%s][%" PRIu32 "] QUEUE CTRL (%u) << %" PRIu8, _server->url(), _clientId, _controlQueue.size(), opcode); @@ -462,7 +462,7 @@ bool AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint return false; } - UNIQUE_LOCK(_lock); + unique_lock_type lock(_lock); if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) { if (closeWhenFull) { @@ -474,7 +474,7 @@ bool AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint Due to _client->close() shall call the callback function _onDisconnect() The calling flow _onDisconnect() --> _handleDisconnect() --> ~AsyncWebSocketClient() */ - UNLOCK(); + lock.unlock(); _client->close(); } @@ -969,7 +969,7 @@ void AsyncWebSocket::_handleEvent(AsyncWebSocketClient *client, AwsEventType typ } AsyncWebSocketClient *AsyncWebSocket::_newClient(AsyncWebServerRequest *request) { - LOCK(_lock); + lock_guard_type lock(_lock); _clients.emplace_back(request, this); // we've just detached AsyncTCP client from AsyncWebServerRequest _handleEvent(&_clients.back(), WS_EVT_CONNECT, request, NULL, 0); @@ -979,7 +979,7 @@ AsyncWebSocketClient *AsyncWebSocket::_newClient(AsyncWebServerRequest *request) } void AsyncWebSocket::_handleDisconnect(AsyncWebSocketClient *client) { - LOCK(_lock); + lock_guard_type lock(_lock); const auto client_id = client->id(); const auto iter = std::find_if(std::begin(_clients), std::end(_clients), [client_id](const AsyncWebSocketClient &c) { return c.id() == client_id; @@ -990,14 +990,14 @@ void AsyncWebSocket::_handleDisconnect(AsyncWebSocketClient *client) { } bool AsyncWebSocket::availableForWriteAll() { - LOCK(_lock); + lock_guard_type lock(_lock); return std::none_of(std::begin(_clients), std::end(_clients), [](const AsyncWebSocketClient &c) { return c.queueIsFull(); }); } bool AsyncWebSocket::availableForWrite(uint32_t id) { - LOCK(_lock); + lock_guard_type lock(_lock); const auto iter = std::find_if(std::begin(_clients), std::end(_clients), [id](const AsyncWebSocketClient &c) { return c.id() == id; }); @@ -1008,14 +1008,14 @@ bool AsyncWebSocket::availableForWrite(uint32_t id) { } size_t AsyncWebSocket::count() const { - LOCK(_lock); + lock_guard_type lock(_lock); return std::count_if(std::begin(_clients), std::end(_clients), [](const AsyncWebSocketClient &c) { return c.status() == WS_CONNECTED; }); } AsyncWebSocketClient *AsyncWebSocket::client(uint32_t id) { - LOCK(_lock); + lock_guard_type lock(_lock); const auto iter = std::find_if(_clients.begin(), _clients.end(), [id](const AsyncWebSocketClient &c) { return c.id() == id && c.status() == WS_CONNECTED; }); @@ -1033,7 +1033,7 @@ void AsyncWebSocket::close(uint32_t id, uint16_t code, const char *message) { } void AsyncWebSocket::closeAll(uint16_t code, const char *message) { - LOCK(_lock); + lock_guard_type lock(_lock); for (auto &c : _clients) { if (c.status() == WS_CONNECTED) { c.close(code, message); @@ -1042,7 +1042,7 @@ void AsyncWebSocket::closeAll(uint16_t code, const char *message) { } void AsyncWebSocket::cleanupClients(uint16_t maxClients) { - LOCK(_lock); + lock_guard_type lock(_lock); const size_t c = count(); if (c > maxClients) { async_ws_log_v("[%s] CLEANUP %" PRIu32 " (%u/%" PRIu16 ")", _url.c_str(), _clients.front().id(), c, maxClients); @@ -1063,7 +1063,7 @@ bool AsyncWebSocket::ping(uint32_t id, const uint8_t *data, size_t len) { } AsyncWebSocket::SendStatus AsyncWebSocket::pingAll(const uint8_t *data, size_t len) { - LOCK(_lock); + lock_guard_type lock(_lock); size_t hit = 0; size_t miss = 0; for (auto &c : _clients) { @@ -1172,7 +1172,7 @@ AsyncWebSocket::SendStatus AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * } AsyncWebSocket::SendStatus AsyncWebSocket::textAll(AsyncWebSocketSharedBuffer buffer) { - LOCK(_lock); + lock_guard_type lock(_lock); size_t hit = 0; size_t miss = 0; for (auto &c : _clients) { @@ -1262,7 +1262,7 @@ AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer return status; } AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(AsyncWebSocketSharedBuffer buffer) { - LOCK(_lock); + lock_guard_type lock(_lock); size_t hit = 0; size_t miss = 0; for (auto &c : _clients) { diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 339e0068c..e92f791a8 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -230,7 +230,7 @@ class AsyncWebSocketClient { uint8_t _pstate; uint32_t _lastMessageTime; uint32_t _keepAlivePeriod; - MAKE_LOCK(_lock); + mutable mutex_type _lock; std::deque _controlQueue; std::deque _messageQueue; bool closeWhenFull = true; @@ -378,7 +378,7 @@ class AsyncWebSocket : public AsyncWebHandler { AwsEventHandler _eventHandler; AwsHandshakeHandler _handshakeHandler; bool _enabled; - MAKE_LOCK(_lock); + mutable mutex_type _lock; public: typedef enum { diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 0326f9a59..f3ce9b0ce 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -56,21 +56,30 @@ #if defined(ESP32) || defined(HOST) #include -#define MAKE_LOCK(var) mutable std::recursive_mutex var -#define LOCK(var) std::lock_guard lock(var) -#define UNIQUE_LOCK(var) std::unique_lock lock(var) -#define UNLOCK() lock.unlock() +typedef std::recursive_mutex mutex_type; +typedef std::lock_guard lock_guard_type; +typedef std::unique_lock unique_lock_type; #else -#define MAKE_LOCK(var) -#define LOCK(var) \ - do { \ - } while (0) -#define UNIQUE_LOCK(var) \ - do { \ - } while (0) -#define UNLOCK() \ - do { \ - } while (0) +// Do-nothing locks that will evaporate under optimization +class null_mutex { +public: + void lock() {} + void unlock() {} + bool try_lock() { + return true; + }; +}; +typedef null_mutex mutex_type; + +class lock_guard_type { +public: + lock_guard_type(mutex_type &) {}; +}; +class unique_lock_type { +public: + unique_lock_type(mutex_type &) {}; + void unlock() {}; +}; #endif #include "AsyncWebServerVersion.h" From 704daee6a813b2a0bb19873ac799c48ada76fd75 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Mon, 6 Apr 2026 10:16:18 -1000 Subject: [PATCH 04/19] locks in asyncsrv namespace, guarded by ASYNCSRV_USE_MUTEX --- src/AsyncEventSource.cpp | 22 +++++++-------- src/AsyncEventSource.h | 6 ++--- src/AsyncWebSocket.cpp | 38 +++++++++++++------------- src/AsyncWebSocket.h | 6 ++--- src/ESPAsyncWebServer.h | 58 +++++++++++++++++++++------------------- 5 files changed, 67 insertions(+), 63 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index b35f1324b..dc15ef76a 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -192,14 +192,14 @@ AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest *request, A AsyncEventSourceClient::~AsyncEventSourceClient() { // Protect message queue access (size checks and modifications) which is not thread-safe. - lock_guard_type lock(_lockmq); + asyncsrv::lock_guard_type lock(_lockmq); _messageQueue.clear(); close(); } bool AsyncEventSourceClient::_queueMessage(const char *message, size_t len) { // Protect message queue access (size checks and modifications) which is not thread-safe. - lock_guard_type lock(_lockmq); + asyncsrv::lock_guard_type lock(_lockmq); if (_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES) { async_ws_log_w("Event message queue overflow: discard message"); @@ -228,7 +228,7 @@ bool AsyncEventSourceClient::_queueMessage(const char *message, size_t len) { bool AsyncEventSourceClient::_queueMessage(AsyncEvent_SharedData_t &&msg) { // Protect message queue access (size checks and modifications) which is not thread-safe. - lock_guard_type lock(_lockmq); + asyncsrv::lock_guard_type lock(_lockmq); if (_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES) { async_ws_log_w("Event message queue overflow: discard message"); @@ -256,7 +256,7 @@ bool AsyncEventSourceClient::_queueMessage(AsyncEvent_SharedData_t &&msg) { void AsyncEventSourceClient::_onAck(size_t len __attribute__((unused)), uint32_t time __attribute__((unused))) { // Protect message queue access (size checks and modifications) which is not thread-safe. - lock_guard_type lock(_lockmq); + asyncsrv::lock_guard_type lock(_lockmq); // adjust in-flight len if (len < _inflight) { @@ -282,7 +282,7 @@ void AsyncEventSourceClient::_onAck(size_t len __attribute__((unused)), uint32_t void AsyncEventSourceClient::_onPoll() { // Protect message queue access (size checks and modifications) which is not thread-safe. - lock_guard_type lock(_lockmq); + asyncsrv::lock_guard_type lock(_lockmq); if (_messageQueue.size()) { _runQueue(); } @@ -363,7 +363,7 @@ void AsyncEventSource::_addClient(AsyncEventSourceClient *client) { _connectcb(client); } - lock_guard_type lock(_client_queue_lock); + asyncsrv::lock_guard_type lock(_client_queue_lock); _clients.emplace_back(client); _adjust_inflight_window(); @@ -373,7 +373,7 @@ void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient *client) { if (_disconnectcb) { _disconnectcb(client); } - lock_guard_type lock(_client_queue_lock); + asyncsrv::lock_guard_type lock(_client_queue_lock); for (auto i = _clients.begin(); i != _clients.end(); ++i) { if (i->get() == client) { _clients.erase(i); @@ -387,7 +387,7 @@ void AsyncEventSource::close() { // While the whole loop is not done, the linked list is locked and so the // iterator should remain valid even when AsyncEventSource::_handleDisconnect() // is called very early - lock_guard_type lock(_client_queue_lock); + asyncsrv::lock_guard_type lock(_client_queue_lock); for (const auto &c : _clients) { if (c->connected()) { /** @@ -404,7 +404,7 @@ void AsyncEventSource::close() { size_t AsyncEventSource::avgPacketsWaiting() const { size_t aql = 0; uint32_t nConnectedClients = 0; - lock_guard_type lock(_client_queue_lock); + asyncsrv::lock_guard_type lock(_client_queue_lock); for (const auto &c : _clients) { if (c->connected()) { aql += c->packetsWaiting(); @@ -416,7 +416,7 @@ size_t AsyncEventSource::avgPacketsWaiting() const { AsyncEventSource::SendStatus AsyncEventSource::send(const char *message, const char *event, uint32_t id, uint32_t reconnect) { AsyncEvent_SharedData_t shared_msg = std::make_shared(generateEventMessage(message, event, id, reconnect)); - lock_guard_type lock(_client_queue_lock); + asyncsrv::lock_guard_type lock(_client_queue_lock); size_t hits = 0; size_t miss = 0; for (const auto &c : _clients) { @@ -432,7 +432,7 @@ AsyncEventSource::SendStatus AsyncEventSource::send(const char *message, const c } size_t AsyncEventSource::count() const { - lock_guard_type lock(_client_queue_lock); + asyncsrv::lock_guard_type lock(_client_queue_lock); size_t n_clients{0}; for (const auto &i : _clients) { if (i->connected()) { diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index efee955c6..312db4609 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -136,7 +136,7 @@ class AsyncEventSourceClient { size_t _inflight{0}; // num of unacknowledged bytes that has been written to socket buffer size_t _max_inflight{SSE_MAX_INFLIGH}; // max num of unacknowledged bytes that could be written to socket buffer std::list _messageQueue; - mutable mutex_type _lockmq; + mutable asyncsrv::mutex_type _lockmq; bool _queueMessage(const char *message, size_t len); bool _queueMessage(AsyncEvent_SharedData_t &&msg); void _runQueue(); @@ -203,7 +203,7 @@ class AsyncEventSourceClient { return _lastId; } size_t packetsWaiting() const { - lock_guard_type lock(_lockmq); + asyncsrv::lock_guard_type lock(_lockmq); return _messageQueue.size(); }; @@ -243,7 +243,7 @@ class AsyncEventSource : public AsyncWebHandler { std::list> _clients; // Same as for individual messages, protect mutations of _clients list // since simultaneous access from different tasks is possible - mutable mutex_type _client_queue_lock; + mutable asyncsrv::mutex_type _client_queue_lock; ArEventHandlerFunction _connectcb = nullptr; ArEventHandlerFunction _disconnectcb = nullptr; diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 233bed5d8..ee1ea8db8 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -294,7 +294,7 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncClient *client, AsyncWebSocket * AsyncWebSocketClient::~AsyncWebSocketClient() { { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); _messageQueue.clear(); _controlQueue.clear(); } @@ -310,7 +310,7 @@ void AsyncWebSocketClient::_clearQueue() { void AsyncWebSocketClient::_onAck(size_t len, uint32_t time) { _lastMessageTime = millis(); - unique_lock_type lock(_lock); + asyncsrv::unique_lock_type lock(_lock); async_ws_log_v("[%s][%" PRIu32 "] START ACK(%u, %" PRIu32 ") Q:%u", _server->url(), _clientId, len, time, _messageQueue.size()); @@ -358,7 +358,7 @@ void AsyncWebSocketClient::_onPoll() { return; } - unique_lock_type lock(_lock); + asyncsrv::unique_lock_type lock(_lock); if (_client && _client->canSend() && (!_controlQueue.empty() || !_messageQueue.empty())) { _runQueue(); } else if (_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && (_controlQueue.empty() && _messageQueue.empty())) { @@ -426,17 +426,17 @@ void AsyncWebSocketClient::_runQueue() { } bool AsyncWebSocketClient::queueIsFull() const { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); return (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED); } size_t AsyncWebSocketClient::queueLen() const { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); return _messageQueue.size(); } bool AsyncWebSocketClient::canSend() const { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); return _messageQueue.size() < WS_MAX_QUEUED_MESSAGES; } @@ -445,7 +445,7 @@ bool AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t *data, si return false; } - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); _controlQueue.emplace_back(opcode, data, len, mask); async_ws_log_v("[%s][%" PRIu32 "] QUEUE CTRL (%u) << %" PRIu8, _server->url(), _clientId, _controlQueue.size(), opcode); @@ -462,7 +462,7 @@ bool AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint return false; } - unique_lock_type lock(_lock); + asyncsrv::unique_lock_type lock(_lock); if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) { if (closeWhenFull) { @@ -969,7 +969,7 @@ void AsyncWebSocket::_handleEvent(AsyncWebSocketClient *client, AwsEventType typ } AsyncWebSocketClient *AsyncWebSocket::_newClient(AsyncWebServerRequest *request) { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); _clients.emplace_back(request, this); // we've just detached AsyncTCP client from AsyncWebServerRequest _handleEvent(&_clients.back(), WS_EVT_CONNECT, request, NULL, 0); @@ -979,7 +979,7 @@ AsyncWebSocketClient *AsyncWebSocket::_newClient(AsyncWebServerRequest *request) } void AsyncWebSocket::_handleDisconnect(AsyncWebSocketClient *client) { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); const auto client_id = client->id(); const auto iter = std::find_if(std::begin(_clients), std::end(_clients), [client_id](const AsyncWebSocketClient &c) { return c.id() == client_id; @@ -990,14 +990,14 @@ void AsyncWebSocket::_handleDisconnect(AsyncWebSocketClient *client) { } bool AsyncWebSocket::availableForWriteAll() { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); return std::none_of(std::begin(_clients), std::end(_clients), [](const AsyncWebSocketClient &c) { return c.queueIsFull(); }); } bool AsyncWebSocket::availableForWrite(uint32_t id) { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); const auto iter = std::find_if(std::begin(_clients), std::end(_clients), [id](const AsyncWebSocketClient &c) { return c.id() == id; }); @@ -1008,14 +1008,14 @@ bool AsyncWebSocket::availableForWrite(uint32_t id) { } size_t AsyncWebSocket::count() const { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); return std::count_if(std::begin(_clients), std::end(_clients), [](const AsyncWebSocketClient &c) { return c.status() == WS_CONNECTED; }); } AsyncWebSocketClient *AsyncWebSocket::client(uint32_t id) { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); const auto iter = std::find_if(_clients.begin(), _clients.end(), [id](const AsyncWebSocketClient &c) { return c.id() == id && c.status() == WS_CONNECTED; }); @@ -1033,7 +1033,7 @@ void AsyncWebSocket::close(uint32_t id, uint16_t code, const char *message) { } void AsyncWebSocket::closeAll(uint16_t code, const char *message) { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); for (auto &c : _clients) { if (c.status() == WS_CONNECTED) { c.close(code, message); @@ -1042,7 +1042,7 @@ void AsyncWebSocket::closeAll(uint16_t code, const char *message) { } void AsyncWebSocket::cleanupClients(uint16_t maxClients) { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); const size_t c = count(); if (c > maxClients) { async_ws_log_v("[%s] CLEANUP %" PRIu32 " (%u/%" PRIu16 ")", _url.c_str(), _clients.front().id(), c, maxClients); @@ -1063,7 +1063,7 @@ bool AsyncWebSocket::ping(uint32_t id, const uint8_t *data, size_t len) { } AsyncWebSocket::SendStatus AsyncWebSocket::pingAll(const uint8_t *data, size_t len) { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); size_t hit = 0; size_t miss = 0; for (auto &c : _clients) { @@ -1172,7 +1172,7 @@ AsyncWebSocket::SendStatus AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * } AsyncWebSocket::SendStatus AsyncWebSocket::textAll(AsyncWebSocketSharedBuffer buffer) { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); size_t hit = 0; size_t miss = 0; for (auto &c : _clients) { @@ -1262,7 +1262,7 @@ AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer return status; } AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(AsyncWebSocketSharedBuffer buffer) { - lock_guard_type lock(_lock); + asyncsrv::lock_guard_type lock(_lock); size_t hit = 0; size_t miss = 0; for (auto &c : _clients) { diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index e92f791a8..013cf33d4 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -230,7 +230,7 @@ class AsyncWebSocketClient { uint8_t _pstate; uint32_t _lastMessageTime; uint32_t _keepAlivePeriod; - mutable mutex_type _lock; + mutable asyncsrv::mutex_type _lock; std::deque _controlQueue; std::deque _messageQueue; bool closeWhenFull = true; @@ -256,7 +256,7 @@ class AsyncWebSocketClient { * @param request * @param server */ - AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server) : AsyncWebSocketClient(request->clientRelease(), server){}; + AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server) : AsyncWebSocketClient(request->clientRelease(), server) {}; ~AsyncWebSocketClient(); // client id increments for the given server @@ -378,7 +378,7 @@ class AsyncWebSocket : public AsyncWebHandler { AwsEventHandler _eventHandler; AwsHandshakeHandler _handshakeHandler; bool _enabled; - mutable mutex_type _lock; + mutable asyncsrv::mutex_type _lock; public: typedef enum { diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index f3ce9b0ce..d2c05f2c8 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -54,34 +54,9 @@ #error Platform not supported #endif -#if defined(ESP32) || defined(HOST) -#include -typedef std::recursive_mutex mutex_type; -typedef std::lock_guard lock_guard_type; -typedef std::unique_lock unique_lock_type; -#else -// Do-nothing locks that will evaporate under optimization -class null_mutex { -public: - void lock() {} - void unlock() {} - bool try_lock() { - return true; - }; -}; -typedef null_mutex mutex_type; - -class lock_guard_type { -public: - lock_guard_type(mutex_type &) {}; -}; -class unique_lock_type { -public: - unique_lock_type(mutex_type &) {}; - void unlock() {}; -}; +#if !defined(ASYNCWEBSERVER_USE_MUTEX) +#define ASYNCWEBSERVER_USE_MUTEX defined(ESP32) || defined(HOST) #endif - #include "AsyncWebServerVersion.h" #define ASYNCWEBSERVER_FORK_ESP32Async @@ -278,6 +253,35 @@ constexpr WebRequestMethodComposite HTTP_ANY = HTTP_ALL; // WebRequestMethod string conversion functions namespace asyncsrv { + +#if ASYNCWEBSERVER_USE_MUTEX +#include +typedef std::recursive_mutex mutex_type; +typedef std::lock_guard lock_guard_type; +typedef std::unique_lock unique_lock_type; +#else +// Do-nothing locks that will evaporate under optimization +class null_mutex { +public: + void lock() {} + void unlock() {} + bool try_lock() { + return true; + }; +}; +typedef null_mutex mutex_type; + +class lock_guard_type { +public: + lock_guard_type(mutex_type &) {}; +}; +class unique_lock_type { +public: + unique_lock_type(mutex_type &) {}; + void unlock() {}; +}; +#endif + WebRequestMethod stringToMethod(const String &); const char *methodToString(WebRequestMethod); } // namespace asyncsrv From f13f005be992e93b707a998ba6440b126b346933 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Mon, 6 Apr 2026 12:32:32 -1000 Subject: [PATCH 05/19] HOST versions of logging. --- src/AsyncWebServerLogging.h | 51 +++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/AsyncWebServerLogging.h b/src/AsyncWebServerLogging.h index daef25942..ea8d5683b 100644 --- a/src/AsyncWebServerLogging.h +++ b/src/AsyncWebServerLogging.h @@ -32,11 +32,61 @@ #define async_ws_log_v(format, ...) log_v(format, ##__VA_ARGS__) #elif defined(HOST) +// Arduino-Emulator has Serial, but it does not have Serial.printf, which +// is not a member of the Arduino Core API Print class. + +// define log levels +#define ASYNC_WS_LOG_NONE 0 /*!< No log output */ +#define ASYNC_WS_LOG_ERROR 1 /*!< Critical errors, software module can not recover on its own */ +#define ASYNC_WS_LOG_WARN 2 /*!< Error conditions from which recovery measures have been taken */ +#define ASYNC_WS_LOG_INFO 3 /*!< Information messages which describe normal flow of events */ +#define ASYNC_WS_LOG_DEBUG 4 /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */ +#define ASYNC_WS_LOG_VERBOSE 5 /*!< Verbose information for debugging purposes */ +#define ASYNC_WS_LOG_MAX 6 /*!< Number of levels supported */ +// set default log level +#ifndef ASYNCWEBSERVER_LOG_LEVEL +#define ASYNCWEBSERVER_LOG_LEVEL ASYNC_WS_LOG_INFO +#endif +// error +#if ASYNCWEBSERVER_LOG_LEVEL >= ASYNC_WS_LOG_ERROR +#define async_ws_log_e(format, ...) \ + ::printf("E async_ws %s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + ::putchar('\n'); +#else #define async_ws_log_e(format, ...) +#endif +// warn +#if ASYNCWEBSERVER_LOG_LEVEL >= ASYNC_WS_LOG_WARN +#define async_ws_log_w(format, ...) \ + ::printf("W async_ws %s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + ::putchar('\n'); +#else #define async_ws_log_w(format, ...) +#endif +// info +#if ASYNCWEBSERVER_LOG_LEVEL >= ASYNC_WS_LOG_INFO +#define async_ws_log_i(format, ...) \ + ::printf("I async_ws %s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + ::putchar('\n'); +#else #define async_ws_log_i(format, ...) +#endif +// debug +#if ASYNCWEBSERVER_LOG_LEVEL >= ASYNC_WS_LOG_DEBUG +#define async_ws_log_d(format, ...) \ + ::printf("D async_ws %s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + ::putchar('\n'); +#else #define async_ws_log_d(format, ...) +#endif +// verbose +#if ASYNCWEBSERVER_LOG_LEVEL >= ASYNC_WS_LOG_VERBOSE +#define async_ws_log_v(format, ...) \ + ::printf("V async_ws %s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + ::putchar('\n'); +#else #define async_ws_log_v(format, ...) +#endif /** * Raspberry Pi Pico specific configurations @@ -150,6 +200,7 @@ * Arduino specific configurations */ #elif defined(ARDUINO) + #if defined(USE_ESP_IDF_LOG) #include #define async_ws_log_e(format, ...) ESP_LOGE("async_ws", "%s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__) From 4ab4d792647b8cd36b27331a80933937bfbb6c80 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Tue, 7 Apr 2026 12:51:21 -1000 Subject: [PATCH 06/19] __unused -> __asyncws_unused --- examples/CaptivePortal/CaptivePortal.ino | 2 +- examples/Filters/Filters.ino | 2 +- .../HTTPMethodsWithArduino.ino | 2 +- .../HTTPMethodsWithESPIDF.ino | 2 +- src/AsyncJson.h | 4 ++-- src/ESPAsyncWebServer.h | 21 ++++++++++--------- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino index 820ac037c..fb3556724 100644 --- a/examples/CaptivePortal/CaptivePortal.ino +++ b/examples/CaptivePortal/CaptivePortal.ino @@ -19,7 +19,7 @@ static AsyncWebServer server(80); class CaptiveRequestHandler : public AsyncWebHandler { public: - bool canHandle(__unused AsyncWebServerRequest *request) const override { + bool canHandle(__asyncws_unused AsyncWebServerRequest *request) const override { return true; } diff --git a/examples/Filters/Filters.ino b/examples/Filters/Filters.ino index 582345cb5..e2623c5e2 100644 --- a/examples/Filters/Filters.ino +++ b/examples/Filters/Filters.ino @@ -23,7 +23,7 @@ static AsyncWebServer server(80); class CaptiveRequestHandler : public AsyncWebHandler { public: - bool canHandle(__unused AsyncWebServerRequest *request) const override { + bool canHandle(__asyncws_unused AsyncWebServerRequest *request) const override { return true; } diff --git a/examples/HTTPMethodsWithArduino/HTTPMethodsWithArduino.ino b/examples/HTTPMethodsWithArduino/HTTPMethodsWithArduino.ino index a83368162..209417087 100644 --- a/examples/HTTPMethodsWithArduino/HTTPMethodsWithArduino.ino +++ b/examples/HTTPMethodsWithArduino/HTTPMethodsWithArduino.ino @@ -58,7 +58,7 @@ static WebRequestMethodComposite allowed = AsyncWebRequestMethod::HTTP_HEAD | As class MyRequestHandler : public AsyncWebHandler { public: - bool canHandle(__unused AsyncWebServerRequest *request) const override { + bool canHandle(__asyncws_unused AsyncWebServerRequest *request) const override { // Test backward compatibility with previous way of checking if a method is allowed in a composite using a bit operator return allowed & request->method(); } diff --git a/examples/HTTPMethodsWithESPIDF/HTTPMethodsWithESPIDF.ino b/examples/HTTPMethodsWithESPIDF/HTTPMethodsWithESPIDF.ino index c2e7cbc0a..7112a7a9a 100644 --- a/examples/HTTPMethodsWithESPIDF/HTTPMethodsWithESPIDF.ino +++ b/examples/HTTPMethodsWithESPIDF/HTTPMethodsWithESPIDF.ino @@ -57,7 +57,7 @@ static WebRequestMethodComposite allowed = AsyncWebRequestMethod::HTTP_HEAD | As class MyRequestHandler : public AsyncWebHandler { public: - bool canHandle(__unused AsyncWebServerRequest *request) const override { + bool canHandle(__asyncws_unused AsyncWebServerRequest *request) const override { // Test backward compatibility with previous way of checking if a method is allowed in a composite using a bit operator return allowed & request->method(); } diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 423e019c0..6f0372cea 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -118,8 +118,8 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { bool canHandle(AsyncWebServerRequest *request) const final; void handleRequest(AsyncWebServerRequest *request) final; void handleUpload( - __unused AsyncWebServerRequest *request, __unused const String &filename, __unused size_t index, __unused uint8_t *data, __unused size_t len, - __unused bool final + __asyncws_unused AsyncWebServerRequest *request, __asyncws_unused const String &filename, __asyncws_unused size_t index, __asyncws_unused uint8_t *data, + __asyncws_unused size_t len, __asyncws_unused bool final ) final {} void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) final; bool isRequestHandlerTrivial() const final { diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index d2c05f2c8..7253f11b7 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -19,9 +19,7 @@ #include #include -#ifndef __unused -#define __unused __attribute__((unused)) -#endif +#define __asyncws_unused __attribute__((unused)) #if __has_include("ArduinoJson.h") #include @@ -600,12 +598,12 @@ class AsyncWebServerRequest { #ifndef ESP8266 [[deprecated("All headers are now collected. Use removeHeader(name) or AsyncHeaderFreeMiddleware if you really need to free some headers.")]] #endif - void addInterestingHeader(__unused const char *name) { + void addInterestingHeader(__asyncws_unused const char *name) { } #ifndef ESP8266 [[deprecated("All headers are now collected. Use removeHeader(name) or AsyncHeaderFreeMiddleware if you really need to free some headers.")]] #endif - void addInterestingHeader(__unused const String &name) { + void addInterestingHeader(__asyncws_unused const String &name) { } /** @@ -1208,7 +1206,7 @@ using ArMiddlewareCallback = std::function Date: Tue, 7 Apr 2026 12:57:53 -1000 Subject: [PATCH 07/19] More explicit formulation of ASYNCWEBSERVER_USE_MUTEX define --- src/ESPAsyncWebServer.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 7253f11b7..f2d5b98c6 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -53,8 +53,13 @@ #endif #if !defined(ASYNCWEBSERVER_USE_MUTEX) -#define ASYNCWEBSERVER_USE_MUTEX defined(ESP32) || defined(HOST) +#if defined(ESP32) || defined(HOST) +#define ASYNCWEBSERVER_USE_MUTEX 1 +#else +#define ASYNCWEBSERVER_USE_MUTEX 0 +#endif #endif + #include "AsyncWebServerVersion.h" #define ASYNCWEBSERVER_FORK_ESP32Async From d09c360ab7078460fbd7095b370b3ccf280c9ba4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 09:56:50 +0000 Subject: [PATCH 08/19] ci(pre-commit): Apply automatic fixes --- src/AsyncWebSocket.h | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 013cf33d4..b91e66600 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -256,7 +256,7 @@ class AsyncWebSocketClient { * @param request * @param server */ - AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server) : AsyncWebSocketClient(request->clientRelease(), server) {}; + AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server) : AsyncWebSocketClient(request->clientRelease(), server){}; ~AsyncWebSocketClient(); // client id increments for the given server diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index f2d5b98c6..1875f1586 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -276,11 +276,11 @@ typedef null_mutex mutex_type; class lock_guard_type { public: - lock_guard_type(mutex_type &) {}; + lock_guard_type(mutex_type &){}; }; class unique_lock_type { public: - unique_lock_type(mutex_type &) {}; + unique_lock_type(mutex_type &){}; void unlock() {}; }; #endif From d0c7e8d48114f7200149b834b0a1a807d209b18f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 8 Apr 2026 11:59:11 +0200 Subject: [PATCH 09/19] Apply suggestion from @mathieucarbou --- src/AsyncWebServerLogging.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AsyncWebServerLogging.h b/src/AsyncWebServerLogging.h index 7d337166e..33a4cb6a2 100644 --- a/src/AsyncWebServerLogging.h +++ b/src/AsyncWebServerLogging.h @@ -32,6 +32,7 @@ #define async_ws_log_v(format, ...) log_v(format, ##__VA_ARGS__) #elif defined(HOST) +#include // Arduino-Emulator has Serial, but it does not have Serial.printf, which // is not a member of the Arduino Core API Print class. From 5b72d9e98b826d74c271ff1f56d7e497b80d6738 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 8 Apr 2026 12:15:00 +0200 Subject: [PATCH 10/19] Fix compile sisue --- src/ESPAsyncWebServer.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 1875f1586..895442fea 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -255,10 +255,12 @@ constexpr WebRequestMethodComposite HTTP_ANY = HTTP_ALL; } // namespace AsyncWebRequestMethod // WebRequestMethod string conversion functions -namespace asyncsrv { - #if ASYNCWEBSERVER_USE_MUTEX #include +#endif + +namespace asyncsrv { +#if ASYNCWEBSERVER_USE_MUTEX typedef std::recursive_mutex mutex_type; typedef std::lock_guard lock_guard_type; typedef std::unique_lock unique_lock_type; From 237dd641ecd644b321f44a9171309cefc9e7f934 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 8 Apr 2026 12:33:00 +0200 Subject: [PATCH 11/19] Add CI for Arduino-Emulator --- .github/workflows/build-arduino-emulator.yml | 80 ++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 .github/workflows/build-arduino-emulator.yml diff --git a/.github/workflows/build-arduino-emulator.yml b/.github/workflows/build-arduino-emulator.yml new file mode 100644 index 000000000..7afd26d6d --- /dev/null +++ b/.github/workflows/build-arduino-emulator.yml @@ -0,0 +1,80 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: Build (Arduino Emulator) + +on: + workflow_dispatch: + push: + branches: + - main + - release/* + paths-ignore: + - "docs/**" + - "mkdocs.yml" + - "README.md" + pull_request: + paths-ignore: + - "docs/**" + - "mkdocs.yml" + - "README.md" + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + arduino-emulator: + name: Arduino Emulator (cmake, HOST) + runs-on: ubuntu-latest + env: + ASYNCTCP_REPO: https://github.com/ESP32Async/AsyncTCP + ASYNCTCP_REF: main + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Install build tools + run: | + sudo apt-get update + sudo apt-get install -y cmake ninja-build build-essential git + + - name: Clone Arduino-Emulator + run: | + git clone --depth 1 --recurse-submodules https://github.com/pschatzmann/Arduino-Emulator.git .ci/arduino-emulator + + - name: Generate host build project + run: | + mkdir -p .ci/arduino-emulator-build + cat > .ci/arduino-emulator-build/CMakeLists.txt <<'EOF' + cmake_minimum_required(VERSION 3.11) + project(espasyncwebserver_host_build LANGUAGES C CXX) + + add_subdirectory(${CMAKE_SOURCE_DIR}/../arduino-emulator ${CMAKE_BINARY_DIR}/arduino-emulator) + include(${CMAKE_SOURCE_DIR}/../arduino-emulator/Arduino.cmake) + + arduino_library(asynctcp "$ENV{ASYNCTCP_REPO}" TAG "$ENV{ASYNCTCP_REF}") + arduino_library(espasyncwebserver "${CMAKE_SOURCE_DIR}/../..") + + arduino_sketch(host-build-check host-build-check.ino LIBRARIES asynctcp espasyncwebserver DEFINITIONS HOST) + EOF + + cat > .ci/arduino-emulator-build/host-build-check.ino <<'EOF' + #include + #include + + AsyncWebServer server(80); + + void setup() { + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { + request->send(200, "text/plain", "host-ok"); + }); + } + + void loop() {} + EOF + + - name: Build with Arduino-Emulator + run: | + cmake -S .ci/arduino-emulator-build -B .ci/arduino-emulator-build/out -G Ninja + cmake --build .ci/arduino-emulator-build/out --parallel From 4ccec502086cf5c290abd460acd993d50a3fb0af Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 8 Apr 2026 13:16:49 +0200 Subject: [PATCH 12/19] Fix compilation issue where tcp_state enum type was not found project must be compiled with lwip when using arduino emulator --- src/ESPAsyncWebServer.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 895442fea..01ce641e0 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -5,9 +5,7 @@ #include #include -#ifndef HOST #include -#endif #include #include From ca7c83bcbb4140819a4de3dba7dbf14d625680c9 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 8 Apr 2026 13:20:46 +0200 Subject: [PATCH 13/19] Add CI for Arduino-Emulator --- .github/workflows/build-arduino-emulator.yml | 38 ++++---------------- arduino_emulator_example/CMakeLists.txt | 17 +++++++++ arduino_emulator_example/freertos/semphr.h | 3 ++ arduino_emulator_example/lwipopts.h | 7 ++++ arduino_emulator_example/sdkconfig.h | 3 ++ 5 files changed, 37 insertions(+), 31 deletions(-) create mode 100644 arduino_emulator_example/CMakeLists.txt create mode 100644 arduino_emulator_example/freertos/semphr.h create mode 100644 arduino_emulator_example/lwipopts.h create mode 100644 arduino_emulator_example/sdkconfig.h diff --git a/.github/workflows/build-arduino-emulator.yml b/.github/workflows/build-arduino-emulator.yml index 7afd26d6d..33859242c 100644 --- a/.github/workflows/build-arduino-emulator.yml +++ b/.github/workflows/build-arduino-emulator.yml @@ -43,38 +43,14 @@ jobs: run: | git clone --depth 1 --recurse-submodules https://github.com/pschatzmann/Arduino-Emulator.git .ci/arduino-emulator - - name: Generate host build project + - name: Clone AsyncTCP, Arduino FS headers, lwIP and lwIP contrib run: | - mkdir -p .ci/arduino-emulator-build - cat > .ci/arduino-emulator-build/CMakeLists.txt <<'EOF' - cmake_minimum_required(VERSION 3.11) - project(espasyncwebserver_host_build LANGUAGES C CXX) - - add_subdirectory(${CMAKE_SOURCE_DIR}/../arduino-emulator ${CMAKE_BINARY_DIR}/arduino-emulator) - include(${CMAKE_SOURCE_DIR}/../arduino-emulator/Arduino.cmake) - - arduino_library(asynctcp "$ENV{ASYNCTCP_REPO}" TAG "$ENV{ASYNCTCP_REF}") - arduino_library(espasyncwebserver "${CMAKE_SOURCE_DIR}/../..") - - arduino_sketch(host-build-check host-build-check.ino LIBRARIES asynctcp espasyncwebserver DEFINITIONS HOST) - EOF - - cat > .ci/arduino-emulator-build/host-build-check.ino <<'EOF' - #include - #include - - AsyncWebServer server(80); - - void setup() { - server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { - request->send(200, "text/plain", "host-ok"); - }); - } - - void loop() {} - EOF + git clone --depth 1 --branch "${ASYNCTCP_REF}" "${ASYNCTCP_REPO}" .ci/asynctcp + git clone --depth 1 https://github.com/espressif/arduino-esp32.git .ci/arduino-esp32 + git clone --depth 1 https://github.com/lwip-tcpip/lwip.git .ci/lwip + git clone --depth 1 https://git.savannah.nongnu.org/git/lwip/lwip-contrib.git .ci/lwip-contrib - name: Build with Arduino-Emulator run: | - cmake -S .ci/arduino-emulator-build -B .ci/arduino-emulator-build/out -G Ninja - cmake --build .ci/arduino-emulator-build/out --parallel + cmake -S arduino_emulator_example -B .ci/arduino-emulator-build/out -G Ninja + cmake --build .ci/arduino-emulator-build/out --target espasyncwebserver --parallel diff --git a/arduino_emulator_example/CMakeLists.txt b/arduino_emulator_example/CMakeLists.txt new file mode 100644 index 000000000..688e513bd --- /dev/null +++ b/arduino_emulator_example/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.11) +project(espasyncwebserver_host_compile LANGUAGES C CXX) + +add_subdirectory(${CMAKE_SOURCE_DIR}/../.ci/arduino-emulator ${CMAKE_BINARY_DIR}/arduino-emulator) +file(GLOB WEB_SRC "${CMAKE_SOURCE_DIR}/../src/*.cpp") +add_library(espasyncwebserver STATIC ${WEB_SRC}) + +target_compile_definitions(espasyncwebserver PUBLIC HOST ARDUINO=10813) +target_include_directories(espasyncwebserver PUBLIC + ${CMAKE_SOURCE_DIR}/../src + ${CMAKE_SOURCE_DIR}/../.ci/asynctcp/src + ${CMAKE_SOURCE_DIR}/../.ci/arduino-esp32/libraries/FS/src + ${CMAKE_SOURCE_DIR}/../.ci/lwip/src/include + ${CMAKE_SOURCE_DIR}/../.ci/lwip-contrib/ports/unix/port/include + ${CMAKE_SOURCE_DIR} +) +target_link_libraries(espasyncwebserver PUBLIC arduino_emulator) diff --git a/arduino_emulator_example/freertos/semphr.h b/arduino_emulator_example/freertos/semphr.h new file mode 100644 index 000000000..e375268bb --- /dev/null +++ b/arduino_emulator_example/freertos/semphr.h @@ -0,0 +1,3 @@ +#pragma once + +typedef void *SemaphoreHandle_t; diff --git a/arduino_emulator_example/lwipopts.h b/arduino_emulator_example/lwipopts.h new file mode 100644 index 000000000..8f3f1d60e --- /dev/null +++ b/arduino_emulator_example/lwipopts.h @@ -0,0 +1,7 @@ +#pragma once + +#define NO_SYS 1 +#define LWIP_SOCKET 0 +#define LWIP_NETCONN 0 +#define LWIP_TCP 1 +#define LWIP_IPV6 1 diff --git a/arduino_emulator_example/sdkconfig.h b/arduino_emulator_example/sdkconfig.h new file mode 100644 index 000000000..e668816ec --- /dev/null +++ b/arduino_emulator_example/sdkconfig.h @@ -0,0 +1,3 @@ +#pragma once + +#define LWIP_IPV6 1 From 3ec0583ce30284d0b600ef1c5acfe729a45afdf1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 11:21:32 +0000 Subject: [PATCH 14/19] ci(pre-commit): Apply automatic fixes --- arduino_emulator_example/lwipopts.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arduino_emulator_example/lwipopts.h b/arduino_emulator_example/lwipopts.h index 8f3f1d60e..28a426eba 100644 --- a/arduino_emulator_example/lwipopts.h +++ b/arduino_emulator_example/lwipopts.h @@ -1,7 +1,7 @@ #pragma once -#define NO_SYS 1 -#define LWIP_SOCKET 0 +#define NO_SYS 1 +#define LWIP_SOCKET 0 #define LWIP_NETCONN 0 -#define LWIP_TCP 1 -#define LWIP_IPV6 1 +#define LWIP_TCP 1 +#define LWIP_IPV6 1 From 717925a78ca2703dad7b960863a0c27ae72f2d28 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 8 Apr 2026 14:45:31 +0200 Subject: [PATCH 15/19] Fix Arduino Elumator CI --- .gitignore | 1 + arduino_emulator_example/CMakeLists.txt | 2 +- arduino_emulator_example/{ => host_config}/freertos/semphr.h | 0 arduino_emulator_example/{ => host_config}/lwipopts.h | 0 arduino_emulator_example/{ => host_config}/sdkconfig.h | 0 src/AsyncWebServerLogging.h | 1 - src/ESPAsyncWebServer.h | 5 +---- src/WebAuthentication.cpp | 1 - 8 files changed, 3 insertions(+), 7 deletions(-) rename arduino_emulator_example/{ => host_config}/freertos/semphr.h (100%) rename arduino_emulator_example/{ => host_config}/lwipopts.h (100%) rename arduino_emulator_example/{ => host_config}/sdkconfig.h (100%) diff --git a/.gitignore b/.gitignore index 14b7d3060..16ccecd27 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .DS_Store .lh +/.ci /.pio /.vscode /logs diff --git a/arduino_emulator_example/CMakeLists.txt b/arduino_emulator_example/CMakeLists.txt index 688e513bd..3156025cc 100644 --- a/arduino_emulator_example/CMakeLists.txt +++ b/arduino_emulator_example/CMakeLists.txt @@ -12,6 +12,6 @@ target_include_directories(espasyncwebserver PUBLIC ${CMAKE_SOURCE_DIR}/../.ci/arduino-esp32/libraries/FS/src ${CMAKE_SOURCE_DIR}/../.ci/lwip/src/include ${CMAKE_SOURCE_DIR}/../.ci/lwip-contrib/ports/unix/port/include - ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/host_config ) target_link_libraries(espasyncwebserver PUBLIC arduino_emulator) diff --git a/arduino_emulator_example/freertos/semphr.h b/arduino_emulator_example/host_config/freertos/semphr.h similarity index 100% rename from arduino_emulator_example/freertos/semphr.h rename to arduino_emulator_example/host_config/freertos/semphr.h diff --git a/arduino_emulator_example/lwipopts.h b/arduino_emulator_example/host_config/lwipopts.h similarity index 100% rename from arduino_emulator_example/lwipopts.h rename to arduino_emulator_example/host_config/lwipopts.h diff --git a/arduino_emulator_example/sdkconfig.h b/arduino_emulator_example/host_config/sdkconfig.h similarity index 100% rename from arduino_emulator_example/sdkconfig.h rename to arduino_emulator_example/host_config/sdkconfig.h diff --git a/src/AsyncWebServerLogging.h b/src/AsyncWebServerLogging.h index 33a4cb6a2..c075e98ab 100644 --- a/src/AsyncWebServerLogging.h +++ b/src/AsyncWebServerLogging.h @@ -201,7 +201,6 @@ * Arduino specific configurations */ #elif defined(ARDUINO) - #if defined(USE_ESP_IDF_LOG) #include #define async_ws_log_e(format, ...) ESP_LOGE("async_ws", "%s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 01ce641e0..b790eb63a 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -36,10 +36,7 @@ #endif // __has_include("ArduinoJson.h") -#if defined(ESP32) || defined(LIBRETINY) -#include -#include -#elif defined(HOST) +#if defined(ESP32) || defined(LIBRETINY) || defined(HOST) #include #include #elif defined(ESP8266) diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index 04668556c..a7805dc8b 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -3,7 +3,6 @@ #include "WebAuthentication.h" #include "AsyncWebServerLogging.h" -#include "ESPAsyncWebServer.h" #include #if defined(ESP32) || defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(HOST) From ccdef5f3035a7c312c8c3b8bc1c21572fba1f7f8 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 8 Apr 2026 15:28:18 +0200 Subject: [PATCH 16/19] Move FPSTR in cpp --- src/AsyncWebSocket.cpp | 3 +++ src/AsyncWebSocket.h | 10 +--------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 9999fd2fb..f4e2c4084 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -19,6 +19,9 @@ #include #elif defined(HOST) #include "BackPort_SHA1Builder.h" +#ifndef FPSTR +#define FPSTR (const char *) +#endif #endif #include diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index b91e66600..1e9a78af2 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -5,7 +5,7 @@ #include -#if defined(ESP32) || defined(LIBRETINY) +#if defined(ESP32) || defined(LIBRETINY) || defined(HOST) #include #ifdef LIBRETINY #ifdef round @@ -16,14 +16,6 @@ #ifndef WS_MAX_QUEUED_MESSAGES #define WS_MAX_QUEUED_MESSAGES 32 #endif -#elif defined(HOST) -#ifndef FPSTR -#define FPSTR (const char *) -#endif -#include -#ifndef WS_MAX_QUEUED_MESSAGES -#define WS_MAX_QUEUED_MESSAGES 32 -#endif #elif defined(ESP8266) #include #ifndef WS_MAX_QUEUED_MESSAGES From 6580dd163929ae40e5923ee717f76b5c70ce2e33 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 8 Apr 2026 16:23:35 +0200 Subject: [PATCH 17/19] Try fix CI on linux (works on mac) --- .github/workflows/build-arduino-emulator.yml | 6 +----- arduino_emulator_example/host_config/lwipopts.h | 4 ++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-arduino-emulator.yml b/.github/workflows/build-arduino-emulator.yml index 33859242c..085ba6918 100644 --- a/.github/workflows/build-arduino-emulator.yml +++ b/.github/workflows/build-arduino-emulator.yml @@ -26,10 +26,6 @@ jobs: arduino-emulator: name: Arduino Emulator (cmake, HOST) runs-on: ubuntu-latest - env: - ASYNCTCP_REPO: https://github.com/ESP32Async/AsyncTCP - ASYNCTCP_REF: main - steps: - name: Checkout uses: actions/checkout@v6 @@ -45,7 +41,7 @@ jobs: - name: Clone AsyncTCP, Arduino FS headers, lwIP and lwIP contrib run: | - git clone --depth 1 --branch "${ASYNCTCP_REF}" "${ASYNCTCP_REPO}" .ci/asynctcp + git clone --depth 1 https://github.com/ESP32Async/AsyncTCP .ci/asynctcp git clone --depth 1 https://github.com/espressif/arduino-esp32.git .ci/arduino-esp32 git clone --depth 1 https://github.com/lwip-tcpip/lwip.git .ci/lwip git clone --depth 1 https://git.savannah.nongnu.org/git/lwip/lwip-contrib.git .ci/lwip-contrib diff --git a/arduino_emulator_example/host_config/lwipopts.h b/arduino_emulator_example/host_config/lwipopts.h index 28a426eba..89e5a55b5 100644 --- a/arduino_emulator_example/host_config/lwipopts.h +++ b/arduino_emulator_example/host_config/lwipopts.h @@ -5,3 +5,7 @@ #define LWIP_NETCONN 0 #define LWIP_TCP 1 #define LWIP_IPV6 1 + +#if defined(__linux__) && !defined(LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS) +#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1 +#endif From 41e8e7004717ebc18cae6fded505f11e3951e1d2 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 8 Apr 2026 15:58:49 +0200 Subject: [PATCH 18/19] Project Structure Reorg: regrouping all examples under examples folder --- .github/workflows/build-esp32.yml | 40 ++++----- .github/workflows/build-esp8266.yml | 16 ++-- .github/workflows/build-libretiny.yml | 6 +- .github/workflows/build-rpi.yml | 16 ++-- docs/backup/wiki.md | 2 +- docs/eventsource.md | 2 +- docs/filters.md | 2 +- docs/middleware.md | 4 +- docs/requests.md | 12 +-- docs/responses.md | 22 ++--- docs/routing.md | 2 +- docs/websockets.md | 2 +- .../AsyncResponseStream.ino | 0 .../{ => arduino}/AsyncTunnel/AsyncTunnel.ino | 0 examples/{ => arduino}/Auth/Auth.ino | 0 examples/{ => arduino}/CORS/CORS.ino | 0 .../CaptivePortal/CaptivePortal.ino | 0 .../CatchAllHandler/CatchAllHandler.ino | 0 .../ChunkRequest/ChunkRequest.ino | 0 .../ChunkResponse/ChunkResponse.ino | 0 .../ChunkRetryResponse/ChunkRetryResponse.ino | 0 examples/{ => arduino}/EndBegin/EndBegin.ino | 0 examples/{ => arduino}/Filters/Filters.ino | 0 .../FlashResponse/FlashResponse.ino | 0 .../HTTPMethodsWithArduino.ino | 0 .../HTTPMethodsWithESPIDF.ino | 0 .../HeaderManipulation/HeaderManipulation.ino | 0 examples/{ => arduino}/Headers/Headers.ino | 0 examples/{ => arduino}/Json/Json.ino | 0 .../LargeResponse/LargeResponse.ino | 0 examples/{ => arduino}/Logging/Logging.ino | 0 .../{ => arduino}/MessagePack/MessagePack.ino | 0 .../{ => arduino}/Middleware/Middleware.ino | 0 examples/{ => arduino}/Params/Params.ino | 0 .../PartitionDownloader.ino | 0 .../{ => arduino}/PerfTests/PerfTests.ino | 0 .../{ => arduino}/RateLimit/RateLimit.ino | 0 examples/{ => arduino}/Redirect/Redirect.ino | 0 .../RequestContinuation.ino | 0 .../RequestContinuationComplete.ino | 0 .../ResumableDownload/ResumableDownload.ino | 0 examples/{ => arduino}/Rewrite/Rewrite.ino | 0 .../ServerSentEvents/ServerSentEvents.ino | 0 .../ServerSentEvents_PR156.ino | 0 .../{ => arduino}/ServerState/ServerState.ino | 0 .../SkipServerMiddleware.ino | 0 .../SlowChunkResponse/SlowChunkResponse.ino | 0 .../{ => arduino}/StaticFile/StaticFile.ino | 0 .../{ => arduino}/Templates/Templates.ino | 0 examples/{ => arduino}/URIMatcher/README.md | 0 .../{ => arduino}/URIMatcher/URIMatcher.ino | 0 .../URIMatcherTest/URIMatcherTest.ino | 0 .../URIMatcherTest/test_routes.sh | 0 examples/{ => arduino}/Upload/Upload.ino | 0 .../{ => arduino}/UploadFlash/UploadFlash.ino | 0 .../WebDAVMethods/WebDAVMethods.ino | 0 .../{ => arduino}/WebSocket/WebSocket.ino | 0 .../WebSocketEasy/WebSocketEasy.ino | 0 .../idf_component}/catchall/CMakeLists.txt | 0 .../idf_component}/catchall/README.md | 0 .../catchall/main/CMakeLists.txt | 0 .../catchall/main/idf_component.yml | 2 +- .../idf_component}/catchall/main/main.cpp | 0 .../catchall/sdkconfig.defaults | 0 .../serversentevents/CMakeLists.txt | 0 .../idf_component}/serversentevents/README.md | 0 .../serversentevents/main/CMakeLists.txt | 0 .../serversentevents/main/idf_component.yml | 2 +- .../serversentevents/main/main.cpp | 0 .../serversentevents/sdkconfig.defaults | 0 .../idf_component}/websocket/CMakeLists.txt | 0 .../idf_component}/websocket/README.md | 0 .../websocket/main/CMakeLists.txt | 0 .../websocket/main/idf_component.yml | 2 +- .../idf_component}/websocket/main/main.cpp | 0 .../websocket/sdkconfig.defaults | 0 .../pioarduino}/IncreaseMaxSockets/.gitignore | 0 .../IncreaseMaxSockets/platformio.ini | 0 .../IncreaseMaxSockets/src/main.cpp | 0 idf_component.yml | 8 +- platformio.ini | 86 +++++++++---------- 81 files changed, 112 insertions(+), 114 deletions(-) rename examples/{ => arduino}/AsyncResponseStream/AsyncResponseStream.ino (100%) rename examples/{ => arduino}/AsyncTunnel/AsyncTunnel.ino (100%) rename examples/{ => arduino}/Auth/Auth.ino (100%) rename examples/{ => arduino}/CORS/CORS.ino (100%) rename examples/{ => arduino}/CaptivePortal/CaptivePortal.ino (100%) rename examples/{ => arduino}/CatchAllHandler/CatchAllHandler.ino (100%) rename examples/{ => arduino}/ChunkRequest/ChunkRequest.ino (100%) rename examples/{ => arduino}/ChunkResponse/ChunkResponse.ino (100%) rename examples/{ => arduino}/ChunkRetryResponse/ChunkRetryResponse.ino (100%) rename examples/{ => arduino}/EndBegin/EndBegin.ino (100%) rename examples/{ => arduino}/Filters/Filters.ino (100%) rename examples/{ => arduino}/FlashResponse/FlashResponse.ino (100%) rename examples/{ => arduino}/HTTPMethodsWithArduino/HTTPMethodsWithArduino.ino (100%) rename examples/{ => arduino}/HTTPMethodsWithESPIDF/HTTPMethodsWithESPIDF.ino (100%) rename examples/{ => arduino}/HeaderManipulation/HeaderManipulation.ino (100%) rename examples/{ => arduino}/Headers/Headers.ino (100%) rename examples/{ => arduino}/Json/Json.ino (100%) rename examples/{ => arduino}/LargeResponse/LargeResponse.ino (100%) rename examples/{ => arduino}/Logging/Logging.ino (100%) rename examples/{ => arduino}/MessagePack/MessagePack.ino (100%) rename examples/{ => arduino}/Middleware/Middleware.ino (100%) rename examples/{ => arduino}/Params/Params.ino (100%) rename examples/{ => arduino}/PartitionDownloader/PartitionDownloader.ino (100%) rename examples/{ => arduino}/PerfTests/PerfTests.ino (100%) rename examples/{ => arduino}/RateLimit/RateLimit.ino (100%) rename examples/{ => arduino}/Redirect/Redirect.ino (100%) rename examples/{ => arduino}/RequestContinuation/RequestContinuation.ino (100%) rename examples/{ => arduino}/RequestContinuationComplete/RequestContinuationComplete.ino (100%) rename examples/{ => arduino}/ResumableDownload/ResumableDownload.ino (100%) rename examples/{ => arduino}/Rewrite/Rewrite.ino (100%) rename examples/{ => arduino}/ServerSentEvents/ServerSentEvents.ino (100%) rename examples/{ => arduino}/ServerSentEvents_PR156/ServerSentEvents_PR156.ino (100%) rename examples/{ => arduino}/ServerState/ServerState.ino (100%) rename examples/{ => arduino}/SkipServerMiddleware/SkipServerMiddleware.ino (100%) rename examples/{ => arduino}/SlowChunkResponse/SlowChunkResponse.ino (100%) rename examples/{ => arduino}/StaticFile/StaticFile.ino (100%) rename examples/{ => arduino}/Templates/Templates.ino (100%) rename examples/{ => arduino}/URIMatcher/README.md (100%) rename examples/{ => arduino}/URIMatcher/URIMatcher.ino (100%) rename examples/{ => arduino}/URIMatcherTest/URIMatcherTest.ino (100%) rename examples/{ => arduino}/URIMatcherTest/test_routes.sh (100%) rename examples/{ => arduino}/Upload/Upload.ino (100%) rename examples/{ => arduino}/UploadFlash/UploadFlash.ino (100%) rename examples/{ => arduino}/WebDAVMethods/WebDAVMethods.ino (100%) rename examples/{ => arduino}/WebSocket/WebSocket.ino (100%) rename examples/{ => arduino}/WebSocketEasy/WebSocketEasy.ino (100%) rename {idf_component_examples => examples/idf_component}/catchall/CMakeLists.txt (100%) rename {idf_component_examples => examples/idf_component}/catchall/README.md (100%) rename {idf_component_examples => examples/idf_component}/catchall/main/CMakeLists.txt (100%) rename {idf_component_examples => examples/idf_component}/catchall/main/idf_component.yml (78%) rename {idf_component_examples => examples/idf_component}/catchall/main/main.cpp (100%) rename {idf_component_examples => examples/idf_component}/catchall/sdkconfig.defaults (100%) rename {idf_component_examples => examples/idf_component}/serversentevents/CMakeLists.txt (100%) rename {idf_component_examples => examples/idf_component}/serversentevents/README.md (100%) rename {idf_component_examples => examples/idf_component}/serversentevents/main/CMakeLists.txt (100%) rename {idf_component_examples => examples/idf_component}/serversentevents/main/idf_component.yml (78%) rename {idf_component_examples => examples/idf_component}/serversentevents/main/main.cpp (100%) rename {idf_component_examples => examples/idf_component}/serversentevents/sdkconfig.defaults (100%) rename {idf_component_examples => examples/idf_component}/websocket/CMakeLists.txt (100%) rename {idf_component_examples => examples/idf_component}/websocket/README.md (100%) rename {idf_component_examples => examples/idf_component}/websocket/main/CMakeLists.txt (100%) rename {idf_component_examples => examples/idf_component}/websocket/main/idf_component.yml (78%) rename {idf_component_examples => examples/idf_component}/websocket/main/main.cpp (100%) rename {idf_component_examples => examples/idf_component}/websocket/sdkconfig.defaults (100%) rename {pioarduino_examples => examples/pioarduino}/IncreaseMaxSockets/.gitignore (100%) rename {pioarduino_examples => examples/pioarduino}/IncreaseMaxSockets/platformio.ini (100%) rename {pioarduino_examples => examples/pioarduino}/IncreaseMaxSockets/src/main.cpp (100%) diff --git a/.github/workflows/build-esp32.yml b/.github/workflows/build-esp32.yml index c320dec69..77cb1500a 100644 --- a/.github/workflows/build-esp32.yml +++ b/.github/workflows/build-esp32.yml @@ -45,13 +45,13 @@ jobs: - name: Checkout uses: actions/checkout@v6 - - name: Build Examples + - name: Build Arduono Examples run: | - for i in `ls examples`; do + for i in `ls examples/arduino`; do echo "=============================================================" - echo "Building examples/$i..." + echo "Building examples/arduino/$i..." echo "=============================================================" - arduino-cli compile --library . --warnings none -b esp32:esp32:esp32 "examples/$i/$i.ino" + arduino-cli compile --library . --warnings none -b esp32:esp32:esp32 "examples/arduino/$i/$i.ino" done arduino-esp32-dev: @@ -76,13 +76,13 @@ jobs: - name: Checkout uses: actions/checkout@v6 - - name: Build Examples + - name: Build Arduino Examples run: | - for i in `ls examples`; do + for i in `ls examples/arduino`; do echo "=============================================================" - echo "Building examples/$i..." + echo "Building examples/arduino/$i..." echo "=============================================================" - arduino-cli compile --library . --warnings none -b esp32:esp32:esp32 "examples/$i/$i.ino" + arduino-cli compile --library . --warnings none -b esp32:esp32:esp32 "examples/arduino/$i/$i.ino" done platformio-esp32-arduino2: @@ -113,13 +113,13 @@ jobs: run: | uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.18.zip - - name: Build Examples + - name: Build Arduino Examples run: | - for i in `ls examples`; do + for i in `ls examples/arduino`; do echo "=============================================================" - echo "Building examples/$i..." + echo "Building examples/arduino/$i..." echo "=============================================================" - PLATFORMIO_SRC_DIR=examples/$i PIO_BOARD=${{ matrix.board }} pio run -e ci-arduino-2 + PLATFORMIO_SRC_DIR=examples/arduino/$i PIO_BOARD=${{ matrix.board }} pio run -e ci-arduino-2 done platformio-esp32-arduino-3: @@ -153,13 +153,13 @@ jobs: run: | uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.18.zip - - name: Build Examples + - name: Build Arduino Examples run: | - for i in `ls examples`; do + for i in `ls examples/arduino`; do echo "=============================================================" - echo "Building examples/$i..." + echo "Building examples/arduino/$i..." echo "=============================================================" - PLATFORMIO_SRC_DIR=examples/$i PIO_BOARD=${{ matrix.board }} pio run -e ci-arduino-3 + PLATFORMIO_SRC_DIR=examples/arduino/$i PIO_BOARD=${{ matrix.board }} pio run -e ci-arduino-3 done platformio-specific-envs: @@ -192,11 +192,11 @@ jobs: run: | uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.18.zip - - name: Build Examples + - name: Build Arduino Examples run: | - for i in `ls examples`; do + for i in `ls examples/arduino`; do echo "=============================================================" - echo "Building examples/$i..." + echo "Building examples/arduino/$i..." echo "=============================================================" - PLATFORMIO_SRC_DIR=examples/$i PIO_BOARD=esp32dev pio run -e ${{ matrix.env }} + PLATFORMIO_SRC_DIR=examples/arduino/$i PIO_BOARD=esp32dev pio run -e ${{ matrix.env }} done diff --git a/.github/workflows/build-esp8266.yml b/.github/workflows/build-esp8266.yml index 6190a7758..163f53e3b 100644 --- a/.github/workflows/build-esp8266.yml +++ b/.github/workflows/build-esp8266.yml @@ -45,13 +45,13 @@ jobs: - name: Checkout uses: actions/checkout@v6 - - name: Build Examples + - name: Build Arduino Examples run: | - for i in `ls examples`; do + for i in `ls examples/arduino`; do echo "=============================================================" - echo "Building examples/$i..." + echo "Building examples/arduino/$i..." echo "=============================================================" - arduino-cli compile --library . --warnings none -b esp8266:esp8266:huzzah "examples/$i/$i.ino" + arduino-cli compile --library . --warnings none -b esp8266:esp8266:huzzah "examples/arduino/$i/$i.ino" done platformio-esp8266: @@ -80,11 +80,11 @@ jobs: run: | uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.18.zip - - name: Build Examples + - name: Build Arduino Examples run: | - for i in `ls examples`; do + for i in `ls examples/arduino`; do echo "=============================================================" - echo "Building examples/$i..." + echo "Building examples/arduino/$i..." echo "=============================================================" - PLATFORMIO_SRC_DIR=examples/$i PIO_BOARD=${{ matrix.board }} pio run -e ci-esp8266 + PLATFORMIO_SRC_DIR=examples/arduino/$i PIO_BOARD=${{ matrix.board }} pio run -e ci-esp8266 done diff --git a/.github/workflows/build-libretiny.yml b/.github/workflows/build-libretiny.yml index 6745ad470..8f19bfbf5 100644 --- a/.github/workflows/build-libretiny.yml +++ b/.github/workflows/build-libretiny.yml @@ -49,11 +49,11 @@ jobs: run: | uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.18.zip - - name: Build Examples + - name: Build Arduino Examples run: | for i in AsyncResponseStream Auth Headers; do echo "=============================================================" - echo "Building examples/$i..." + echo "Building examples/arduino/$i..." echo "=============================================================" - PLATFORMIO_SRC_DIR=examples/$i PIO_BOARD=${{ matrix.board }} pio run -e ci-libretiny + PLATFORMIO_SRC_DIR=examples/arduino/$i PIO_BOARD=${{ matrix.board }} pio run -e ci-libretiny done diff --git a/.github/workflows/build-rpi.yml b/.github/workflows/build-rpi.yml index 7f2bb1fdc..288a60d8c 100644 --- a/.github/workflows/build-rpi.yml +++ b/.github/workflows/build-rpi.yml @@ -52,13 +52,13 @@ jobs: - name: Checkout uses: actions/checkout@v6 - - name: Build Examples + - name: Build Arduino Examples run: | - for i in `ls examples`; do + for i in `ls examples/arduino`; do echo "=============================================================" - echo "Building examples/$i..." + echo "Building examples/arduino/$i..." echo "=============================================================" - arduino-cli compile --library . --warnings none -b rp2040:rp2040:${{ matrix.board }} "examples/$i/$i.ino" + arduino-cli compile --library . --warnings none -b rp2040:rp2040:${{ matrix.board }} "examples/arduino/$i/$i.ino" done platformio-rpi: @@ -87,11 +87,11 @@ jobs: run: | uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.18.zip - - name: Build Examples + - name: Build Arduino Examples run: | - for i in `ls examples`; do + for i in `ls examples/arduino`; do echo "=============================================================" - echo "Building examples/$i..." + echo "Building examples/arduino/$i..." echo "=============================================================" - PLATFORMIO_SRC_DIR=examples/$i PIO_BOARD=${{ matrix.board }} pio run -e ci-raspberrypi + PLATFORMIO_SRC_DIR=examples/arduino/$i PIO_BOARD=${{ matrix.board }} pio run -e ci-raspberrypi done diff --git a/docs/backup/wiki.md b/docs/backup/wiki.md index 881cb38c5..4f253ed25 100644 --- a/docs/backup/wiki.md +++ b/docs/backup/wiki.md @@ -376,7 +376,7 @@ Request Continuation is the ability to pause the processing of a request (the ac This is a common supported use case amongst web servers. -A usage example can be found in the example called [RequestContinuation.ino](https://github.com/ESP32Async/ESPAsyncWebServer/blob/main/examples/RequestContinuation/RequestContinuation.ino) +A usage example can be found in the example called [RequestContinuation.ino](https://github.com/ESP32Async/ESPAsyncWebServer/blob/main/examples/arduino/RequestContinuation/RequestContinuation.ino) In the handler receiving the request, just execute: diff --git a/docs/eventsource.md b/docs/eventsource.md index 56d8f92be..3d5dd86a5 100644 --- a/docs/eventsource.md +++ b/docs/eventsource.md @@ -5,7 +5,7 @@ The server includes EventSource (Server-Sent Events) plugin which can be used to send short text events to the browser. Difference between EventSource and WebSockets is that EventSource is single direction, text-only protocol. -See the [ServerSentEvents example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/ServerSentEvents/ServerSentEvents.ino). +See the [ServerSentEvents example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/ServerSentEvents/ServerSentEvents.ino). ### Setup Event Source on the server diff --git a/docs/filters.md b/docs/filters.md index b4c6fc587..9b85d1da4 100644 --- a/docs/filters.md +++ b/docs/filters.md @@ -10,7 +10,7 @@ Two filter callback are provided for convince: - `ON_STA_FILTER` - return true when requests are made to the STA (station mode) interface. - `ON_AP_FILTER` - return true when requests are made to the AP (access point) interface. -See the [Filters example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/Filters/Filters.ino). +See the [Filters example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/Filters/Filters.ino). ### Serve different site files in AP mode diff --git a/docs/middleware.md b/docs/middleware.md index 5bf7de781..b829ffbbd 100644 --- a/docs/middleware.md +++ b/docs/middleware.md @@ -40,7 +40,7 @@ AsyncMiddlewareFunction complexAuth([](AsyncWebServerRequest* request, ArMiddlew - `LoggerMiddleware`: to log requests globally or per handler with the same pattern as curl. Will also record request processing time - `AsyncRateLimitMiddleware`: to limit the number of requests on a windows of time globally or per handler -See the [Middleware example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/Middleware/Middleware.ino). +See the [Middleware example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/Middleware/Middleware.ino). ### CORS with AsyncCorsMiddleware @@ -114,7 +114,7 @@ server.addMiddleware(&authMiddleware); // globally add authentication to the ser myHandler.addMiddleware(&authMiddleware); // add authentication to a specific handler ``` -See the [Auth example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/Auth/Auth.ino). +See the [Auth example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/Auth/Auth.ino). ### Migration to Middleware to improve performance and memory usage diff --git a/docs/requests.md b/docs/requests.md index dc339476d..b58016ce5 100644 --- a/docs/requests.md +++ b/docs/requests.md @@ -44,7 +44,7 @@ if(request->hasHeader("MyHeader")){ } ``` -See the [Headers example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/Headers/Headers.ino). +See the [Headers example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/Headers/Headers.ino). ## Path Variable @@ -83,7 +83,7 @@ build_flags = _NOTE_: By enabling `ASYNCWEBSERVER_REGEX`, `` will be included. This will add an 100k to your binary. -See the [URIMatcher example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/URIMatcher/URIMatcher.ino) and [URIMatcherTest example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/URIMatcherTest/URIMatcherTest.ino). +See the [URIMatcher example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/URIMatcher/URIMatcher.ino) and [URIMatcherTest example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/URIMatcherTest/URIMatcherTest.ino). ### GET, POST and FILE parameters @@ -124,7 +124,7 @@ if(request->hasArg("download")) String arg = request->arg("download"); ``` -See the [Params example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/Params/Params.ino). +See the [Params example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/Params/Params.ino). ### FILE Upload handling @@ -142,7 +142,7 @@ void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, } ``` -See the [Upload example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/Upload/Upload.ino). +See the [Upload example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/Upload/Upload.ino). ### Body data handling @@ -177,7 +177,7 @@ AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/rest/en server.addHandler(handler); ``` -See the [Json example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/Json/Json.ino). +See the [Json example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/Json/Json.ino). ### MessagePack body handling @@ -194,4 +194,4 @@ AsyncCallbackMessagePackWebHandler* handler = new AsyncCallbackMessagePackWebHan server.addHandler(handler); ``` -See the [MessagePack example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/MessagePack/MessagePack.ino). +See the [MessagePack example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/MessagePack/MessagePack.ino). diff --git a/docs/responses.md b/docs/responses.md index da9494b49..869e235c5 100644 --- a/docs/responses.md +++ b/docs/responses.md @@ -15,7 +15,7 @@ This will send error 400 instead of 200. -See the [example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/Replace/Replace.ino). +See the [example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/Replace/Replace.ino). ## Request Continuation @@ -63,7 +63,7 @@ if (auto request = requestPtr.lock()) { } ``` -See the [RequestContinuation example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/RequestContinuation/RequestContinuation.ino) and [RequestContinuationComplete example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/RequestContinuationComplete/RequestContinuationComplete.ino). +See the [RequestContinuation example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/RequestContinuation/RequestContinuation.ino) and [RequestContinuationComplete example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/RequestContinuationComplete/RequestContinuationComplete.ino). ## Responses @@ -77,7 +77,7 @@ request->redirect("/login"); request->redirect("http://esp8266.com"); ``` -See the [Redirect example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/Redirect/Redirect.ino). +See the [Redirect example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/Redirect/Redirect.ino). ### Basic response with HTTP Code @@ -139,7 +139,7 @@ const char index_html[] PROGMEM = "..."; // large char array, tested with 14k request->send_P(200, "text/html", index_html, processor); ``` -See the [Templates example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/Templates/Templates.ino). +See the [Templates example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/Templates/Templates.ino). ### Send large webpage from PROGMEM containing templates and extra headers @@ -291,7 +291,7 @@ request->send(LittleFS, "/index.htm", "text/plain"); request->send(LittleFS, "/index.htm", String(), true); ``` -See the [StaticFile example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/StaticFile/StaticFile.ino). +See the [StaticFile example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/StaticFile/StaticFile.ino). ### Respond with content coming from a File and extra headers @@ -361,7 +361,7 @@ request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index }); ``` -See the [ChunkResponse example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/ChunkResponse/ChunkResponse.ino). +See the [ChunkResponse example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/ChunkResponse/ChunkResponse.ino). ### Respond with content using a callback and extra headers @@ -507,7 +507,7 @@ response->addHeader("Server","ESP Async Web Server"); request->send(response); ``` -See the [ChunkRequest example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/ChunkRequest/ChunkRequest.ino) and [ChunkRetryResponse example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/ChunkRetryResponse/ChunkRetryResponse.ino). +See the [ChunkRequest example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/ChunkRequest/ChunkRequest.ino) and [ChunkRetryResponse example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/ChunkRetryResponse/ChunkRetryResponse.ino). ### Chunked Response containing templates @@ -585,7 +585,7 @@ response->print(""); request->send(response); ``` -See the [AsyncResponseStream example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/AsyncResponseStream/AsyncResponseStream.ino). +See the [AsyncResponseStream example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/AsyncResponseStream/AsyncResponseStream.ino). ### ArduinoJson Basic Response @@ -624,7 +624,7 @@ response->setLength(); request->send(response); ``` -See the [Json example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/Json/Json.ino). +See the [Json example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/Json/Json.ino). ### MessagePack Response @@ -643,7 +643,7 @@ response->setLength(); request->send(response); ``` -See the [MessagePack example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/MessagePack/MessagePack.ino). +See the [MessagePack example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/MessagePack/MessagePack.ino). ## Adding Default Headers @@ -672,7 +672,7 @@ webServer.onNotFound([](AsyncWebServerRequest *request) { }); ``` -See the [CORS example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/CORS/CORS.ino). +See the [CORS example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/CORS/CORS.ino). ## Bad Responses diff --git a/docs/routing.md b/docs/routing.md index d562331b9..e254916f7 100644 --- a/docs/routing.md +++ b/docs/routing.md @@ -121,7 +121,7 @@ Usage: server.addRewrite( new OneParamRewrite("/radio/{frequence}", "/radio?f={frequence}") ); ``` -See the [Rewrite example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/Rewrite/Rewrite.ino). +See the [Rewrite example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/Rewrite/Rewrite.ino). ## Remove handlers and rewrites diff --git a/docs/websockets.md b/docs/websockets.md index 722762bec..ce1220986 100644 --- a/docs/websockets.md +++ b/docs/websockets.md @@ -40,7 +40,7 @@ I recommend to use the official API `AsyncWebSocketMessageBuffer` to retain furt The server includes a web socket plugin which lets you define different WebSocket locations to connect to without starting another listening service or using different port -See the [WebSocket example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/WebSocket/WebSocket.ino) and [WebSocketEasy example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/WebSocketEasy/WebSocketEasy.ino). +See the [WebSocket example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/WebSocket/WebSocket.ino) and [WebSocketEasy example here](https://github.com/ESP32Async/ESPAsyncWebServer/blob/master/examples/arduino/WebSocketEasy/WebSocketEasy.ino). ### Async WebSocket Event diff --git a/examples/AsyncResponseStream/AsyncResponseStream.ino b/examples/arduino/AsyncResponseStream/AsyncResponseStream.ino similarity index 100% rename from examples/AsyncResponseStream/AsyncResponseStream.ino rename to examples/arduino/AsyncResponseStream/AsyncResponseStream.ino diff --git a/examples/AsyncTunnel/AsyncTunnel.ino b/examples/arduino/AsyncTunnel/AsyncTunnel.ino similarity index 100% rename from examples/AsyncTunnel/AsyncTunnel.ino rename to examples/arduino/AsyncTunnel/AsyncTunnel.ino diff --git a/examples/Auth/Auth.ino b/examples/arduino/Auth/Auth.ino similarity index 100% rename from examples/Auth/Auth.ino rename to examples/arduino/Auth/Auth.ino diff --git a/examples/CORS/CORS.ino b/examples/arduino/CORS/CORS.ino similarity index 100% rename from examples/CORS/CORS.ino rename to examples/arduino/CORS/CORS.ino diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/arduino/CaptivePortal/CaptivePortal.ino similarity index 100% rename from examples/CaptivePortal/CaptivePortal.ino rename to examples/arduino/CaptivePortal/CaptivePortal.ino diff --git a/examples/CatchAllHandler/CatchAllHandler.ino b/examples/arduino/CatchAllHandler/CatchAllHandler.ino similarity index 100% rename from examples/CatchAllHandler/CatchAllHandler.ino rename to examples/arduino/CatchAllHandler/CatchAllHandler.ino diff --git a/examples/ChunkRequest/ChunkRequest.ino b/examples/arduino/ChunkRequest/ChunkRequest.ino similarity index 100% rename from examples/ChunkRequest/ChunkRequest.ino rename to examples/arduino/ChunkRequest/ChunkRequest.ino diff --git a/examples/ChunkResponse/ChunkResponse.ino b/examples/arduino/ChunkResponse/ChunkResponse.ino similarity index 100% rename from examples/ChunkResponse/ChunkResponse.ino rename to examples/arduino/ChunkResponse/ChunkResponse.ino diff --git a/examples/ChunkRetryResponse/ChunkRetryResponse.ino b/examples/arduino/ChunkRetryResponse/ChunkRetryResponse.ino similarity index 100% rename from examples/ChunkRetryResponse/ChunkRetryResponse.ino rename to examples/arduino/ChunkRetryResponse/ChunkRetryResponse.ino diff --git a/examples/EndBegin/EndBegin.ino b/examples/arduino/EndBegin/EndBegin.ino similarity index 100% rename from examples/EndBegin/EndBegin.ino rename to examples/arduino/EndBegin/EndBegin.ino diff --git a/examples/Filters/Filters.ino b/examples/arduino/Filters/Filters.ino similarity index 100% rename from examples/Filters/Filters.ino rename to examples/arduino/Filters/Filters.ino diff --git a/examples/FlashResponse/FlashResponse.ino b/examples/arduino/FlashResponse/FlashResponse.ino similarity index 100% rename from examples/FlashResponse/FlashResponse.ino rename to examples/arduino/FlashResponse/FlashResponse.ino diff --git a/examples/HTTPMethodsWithArduino/HTTPMethodsWithArduino.ino b/examples/arduino/HTTPMethodsWithArduino/HTTPMethodsWithArduino.ino similarity index 100% rename from examples/HTTPMethodsWithArduino/HTTPMethodsWithArduino.ino rename to examples/arduino/HTTPMethodsWithArduino/HTTPMethodsWithArduino.ino diff --git a/examples/HTTPMethodsWithESPIDF/HTTPMethodsWithESPIDF.ino b/examples/arduino/HTTPMethodsWithESPIDF/HTTPMethodsWithESPIDF.ino similarity index 100% rename from examples/HTTPMethodsWithESPIDF/HTTPMethodsWithESPIDF.ino rename to examples/arduino/HTTPMethodsWithESPIDF/HTTPMethodsWithESPIDF.ino diff --git a/examples/HeaderManipulation/HeaderManipulation.ino b/examples/arduino/HeaderManipulation/HeaderManipulation.ino similarity index 100% rename from examples/HeaderManipulation/HeaderManipulation.ino rename to examples/arduino/HeaderManipulation/HeaderManipulation.ino diff --git a/examples/Headers/Headers.ino b/examples/arduino/Headers/Headers.ino similarity index 100% rename from examples/Headers/Headers.ino rename to examples/arduino/Headers/Headers.ino diff --git a/examples/Json/Json.ino b/examples/arduino/Json/Json.ino similarity index 100% rename from examples/Json/Json.ino rename to examples/arduino/Json/Json.ino diff --git a/examples/LargeResponse/LargeResponse.ino b/examples/arduino/LargeResponse/LargeResponse.ino similarity index 100% rename from examples/LargeResponse/LargeResponse.ino rename to examples/arduino/LargeResponse/LargeResponse.ino diff --git a/examples/Logging/Logging.ino b/examples/arduino/Logging/Logging.ino similarity index 100% rename from examples/Logging/Logging.ino rename to examples/arduino/Logging/Logging.ino diff --git a/examples/MessagePack/MessagePack.ino b/examples/arduino/MessagePack/MessagePack.ino similarity index 100% rename from examples/MessagePack/MessagePack.ino rename to examples/arduino/MessagePack/MessagePack.ino diff --git a/examples/Middleware/Middleware.ino b/examples/arduino/Middleware/Middleware.ino similarity index 100% rename from examples/Middleware/Middleware.ino rename to examples/arduino/Middleware/Middleware.ino diff --git a/examples/Params/Params.ino b/examples/arduino/Params/Params.ino similarity index 100% rename from examples/Params/Params.ino rename to examples/arduino/Params/Params.ino diff --git a/examples/PartitionDownloader/PartitionDownloader.ino b/examples/arduino/PartitionDownloader/PartitionDownloader.ino similarity index 100% rename from examples/PartitionDownloader/PartitionDownloader.ino rename to examples/arduino/PartitionDownloader/PartitionDownloader.ino diff --git a/examples/PerfTests/PerfTests.ino b/examples/arduino/PerfTests/PerfTests.ino similarity index 100% rename from examples/PerfTests/PerfTests.ino rename to examples/arduino/PerfTests/PerfTests.ino diff --git a/examples/RateLimit/RateLimit.ino b/examples/arduino/RateLimit/RateLimit.ino similarity index 100% rename from examples/RateLimit/RateLimit.ino rename to examples/arduino/RateLimit/RateLimit.ino diff --git a/examples/Redirect/Redirect.ino b/examples/arduino/Redirect/Redirect.ino similarity index 100% rename from examples/Redirect/Redirect.ino rename to examples/arduino/Redirect/Redirect.ino diff --git a/examples/RequestContinuation/RequestContinuation.ino b/examples/arduino/RequestContinuation/RequestContinuation.ino similarity index 100% rename from examples/RequestContinuation/RequestContinuation.ino rename to examples/arduino/RequestContinuation/RequestContinuation.ino diff --git a/examples/RequestContinuationComplete/RequestContinuationComplete.ino b/examples/arduino/RequestContinuationComplete/RequestContinuationComplete.ino similarity index 100% rename from examples/RequestContinuationComplete/RequestContinuationComplete.ino rename to examples/arduino/RequestContinuationComplete/RequestContinuationComplete.ino diff --git a/examples/ResumableDownload/ResumableDownload.ino b/examples/arduino/ResumableDownload/ResumableDownload.ino similarity index 100% rename from examples/ResumableDownload/ResumableDownload.ino rename to examples/arduino/ResumableDownload/ResumableDownload.ino diff --git a/examples/Rewrite/Rewrite.ino b/examples/arduino/Rewrite/Rewrite.ino similarity index 100% rename from examples/Rewrite/Rewrite.ino rename to examples/arduino/Rewrite/Rewrite.ino diff --git a/examples/ServerSentEvents/ServerSentEvents.ino b/examples/arduino/ServerSentEvents/ServerSentEvents.ino similarity index 100% rename from examples/ServerSentEvents/ServerSentEvents.ino rename to examples/arduino/ServerSentEvents/ServerSentEvents.ino diff --git a/examples/ServerSentEvents_PR156/ServerSentEvents_PR156.ino b/examples/arduino/ServerSentEvents_PR156/ServerSentEvents_PR156.ino similarity index 100% rename from examples/ServerSentEvents_PR156/ServerSentEvents_PR156.ino rename to examples/arduino/ServerSentEvents_PR156/ServerSentEvents_PR156.ino diff --git a/examples/ServerState/ServerState.ino b/examples/arduino/ServerState/ServerState.ino similarity index 100% rename from examples/ServerState/ServerState.ino rename to examples/arduino/ServerState/ServerState.ino diff --git a/examples/SkipServerMiddleware/SkipServerMiddleware.ino b/examples/arduino/SkipServerMiddleware/SkipServerMiddleware.ino similarity index 100% rename from examples/SkipServerMiddleware/SkipServerMiddleware.ino rename to examples/arduino/SkipServerMiddleware/SkipServerMiddleware.ino diff --git a/examples/SlowChunkResponse/SlowChunkResponse.ino b/examples/arduino/SlowChunkResponse/SlowChunkResponse.ino similarity index 100% rename from examples/SlowChunkResponse/SlowChunkResponse.ino rename to examples/arduino/SlowChunkResponse/SlowChunkResponse.ino diff --git a/examples/StaticFile/StaticFile.ino b/examples/arduino/StaticFile/StaticFile.ino similarity index 100% rename from examples/StaticFile/StaticFile.ino rename to examples/arduino/StaticFile/StaticFile.ino diff --git a/examples/Templates/Templates.ino b/examples/arduino/Templates/Templates.ino similarity index 100% rename from examples/Templates/Templates.ino rename to examples/arduino/Templates/Templates.ino diff --git a/examples/URIMatcher/README.md b/examples/arduino/URIMatcher/README.md similarity index 100% rename from examples/URIMatcher/README.md rename to examples/arduino/URIMatcher/README.md diff --git a/examples/URIMatcher/URIMatcher.ino b/examples/arduino/URIMatcher/URIMatcher.ino similarity index 100% rename from examples/URIMatcher/URIMatcher.ino rename to examples/arduino/URIMatcher/URIMatcher.ino diff --git a/examples/URIMatcherTest/URIMatcherTest.ino b/examples/arduino/URIMatcherTest/URIMatcherTest.ino similarity index 100% rename from examples/URIMatcherTest/URIMatcherTest.ino rename to examples/arduino/URIMatcherTest/URIMatcherTest.ino diff --git a/examples/URIMatcherTest/test_routes.sh b/examples/arduino/URIMatcherTest/test_routes.sh similarity index 100% rename from examples/URIMatcherTest/test_routes.sh rename to examples/arduino/URIMatcherTest/test_routes.sh diff --git a/examples/Upload/Upload.ino b/examples/arduino/Upload/Upload.ino similarity index 100% rename from examples/Upload/Upload.ino rename to examples/arduino/Upload/Upload.ino diff --git a/examples/UploadFlash/UploadFlash.ino b/examples/arduino/UploadFlash/UploadFlash.ino similarity index 100% rename from examples/UploadFlash/UploadFlash.ino rename to examples/arduino/UploadFlash/UploadFlash.ino diff --git a/examples/WebDAVMethods/WebDAVMethods.ino b/examples/arduino/WebDAVMethods/WebDAVMethods.ino similarity index 100% rename from examples/WebDAVMethods/WebDAVMethods.ino rename to examples/arduino/WebDAVMethods/WebDAVMethods.ino diff --git a/examples/WebSocket/WebSocket.ino b/examples/arduino/WebSocket/WebSocket.ino similarity index 100% rename from examples/WebSocket/WebSocket.ino rename to examples/arduino/WebSocket/WebSocket.ino diff --git a/examples/WebSocketEasy/WebSocketEasy.ino b/examples/arduino/WebSocketEasy/WebSocketEasy.ino similarity index 100% rename from examples/WebSocketEasy/WebSocketEasy.ino rename to examples/arduino/WebSocketEasy/WebSocketEasy.ino diff --git a/idf_component_examples/catchall/CMakeLists.txt b/examples/idf_component/catchall/CMakeLists.txt similarity index 100% rename from idf_component_examples/catchall/CMakeLists.txt rename to examples/idf_component/catchall/CMakeLists.txt diff --git a/idf_component_examples/catchall/README.md b/examples/idf_component/catchall/README.md similarity index 100% rename from idf_component_examples/catchall/README.md rename to examples/idf_component/catchall/README.md diff --git a/idf_component_examples/catchall/main/CMakeLists.txt b/examples/idf_component/catchall/main/CMakeLists.txt similarity index 100% rename from idf_component_examples/catchall/main/CMakeLists.txt rename to examples/idf_component/catchall/main/CMakeLists.txt diff --git a/idf_component_examples/catchall/main/idf_component.yml b/examples/idf_component/catchall/main/idf_component.yml similarity index 78% rename from idf_component_examples/catchall/main/idf_component.yml rename to examples/idf_component/catchall/main/idf_component.yml index e2d1c657e..e3984e32c 100644 --- a/idf_component_examples/catchall/main/idf_component.yml +++ b/examples/idf_component/catchall/main/idf_component.yml @@ -2,5 +2,5 @@ dependencies: esp32async/espasyncwebserver: version: "*" - override_path: "../../../" + override_path: "../../../../" pre_release: true diff --git a/idf_component_examples/catchall/main/main.cpp b/examples/idf_component/catchall/main/main.cpp similarity index 100% rename from idf_component_examples/catchall/main/main.cpp rename to examples/idf_component/catchall/main/main.cpp diff --git a/idf_component_examples/catchall/sdkconfig.defaults b/examples/idf_component/catchall/sdkconfig.defaults similarity index 100% rename from idf_component_examples/catchall/sdkconfig.defaults rename to examples/idf_component/catchall/sdkconfig.defaults diff --git a/idf_component_examples/serversentevents/CMakeLists.txt b/examples/idf_component/serversentevents/CMakeLists.txt similarity index 100% rename from idf_component_examples/serversentevents/CMakeLists.txt rename to examples/idf_component/serversentevents/CMakeLists.txt diff --git a/idf_component_examples/serversentevents/README.md b/examples/idf_component/serversentevents/README.md similarity index 100% rename from idf_component_examples/serversentevents/README.md rename to examples/idf_component/serversentevents/README.md diff --git a/idf_component_examples/serversentevents/main/CMakeLists.txt b/examples/idf_component/serversentevents/main/CMakeLists.txt similarity index 100% rename from idf_component_examples/serversentevents/main/CMakeLists.txt rename to examples/idf_component/serversentevents/main/CMakeLists.txt diff --git a/idf_component_examples/serversentevents/main/idf_component.yml b/examples/idf_component/serversentevents/main/idf_component.yml similarity index 78% rename from idf_component_examples/serversentevents/main/idf_component.yml rename to examples/idf_component/serversentevents/main/idf_component.yml index e2d1c657e..e3984e32c 100644 --- a/idf_component_examples/serversentevents/main/idf_component.yml +++ b/examples/idf_component/serversentevents/main/idf_component.yml @@ -2,5 +2,5 @@ dependencies: esp32async/espasyncwebserver: version: "*" - override_path: "../../../" + override_path: "../../../../" pre_release: true diff --git a/idf_component_examples/serversentevents/main/main.cpp b/examples/idf_component/serversentevents/main/main.cpp similarity index 100% rename from idf_component_examples/serversentevents/main/main.cpp rename to examples/idf_component/serversentevents/main/main.cpp diff --git a/idf_component_examples/serversentevents/sdkconfig.defaults b/examples/idf_component/serversentevents/sdkconfig.defaults similarity index 100% rename from idf_component_examples/serversentevents/sdkconfig.defaults rename to examples/idf_component/serversentevents/sdkconfig.defaults diff --git a/idf_component_examples/websocket/CMakeLists.txt b/examples/idf_component/websocket/CMakeLists.txt similarity index 100% rename from idf_component_examples/websocket/CMakeLists.txt rename to examples/idf_component/websocket/CMakeLists.txt diff --git a/idf_component_examples/websocket/README.md b/examples/idf_component/websocket/README.md similarity index 100% rename from idf_component_examples/websocket/README.md rename to examples/idf_component/websocket/README.md diff --git a/idf_component_examples/websocket/main/CMakeLists.txt b/examples/idf_component/websocket/main/CMakeLists.txt similarity index 100% rename from idf_component_examples/websocket/main/CMakeLists.txt rename to examples/idf_component/websocket/main/CMakeLists.txt diff --git a/idf_component_examples/websocket/main/idf_component.yml b/examples/idf_component/websocket/main/idf_component.yml similarity index 78% rename from idf_component_examples/websocket/main/idf_component.yml rename to examples/idf_component/websocket/main/idf_component.yml index e2d1c657e..e3984e32c 100644 --- a/idf_component_examples/websocket/main/idf_component.yml +++ b/examples/idf_component/websocket/main/idf_component.yml @@ -2,5 +2,5 @@ dependencies: esp32async/espasyncwebserver: version: "*" - override_path: "../../../" + override_path: "../../../../" pre_release: true diff --git a/idf_component_examples/websocket/main/main.cpp b/examples/idf_component/websocket/main/main.cpp similarity index 100% rename from idf_component_examples/websocket/main/main.cpp rename to examples/idf_component/websocket/main/main.cpp diff --git a/idf_component_examples/websocket/sdkconfig.defaults b/examples/idf_component/websocket/sdkconfig.defaults similarity index 100% rename from idf_component_examples/websocket/sdkconfig.defaults rename to examples/idf_component/websocket/sdkconfig.defaults diff --git a/pioarduino_examples/IncreaseMaxSockets/.gitignore b/examples/pioarduino/IncreaseMaxSockets/.gitignore similarity index 100% rename from pioarduino_examples/IncreaseMaxSockets/.gitignore rename to examples/pioarduino/IncreaseMaxSockets/.gitignore diff --git a/pioarduino_examples/IncreaseMaxSockets/platformio.ini b/examples/pioarduino/IncreaseMaxSockets/platformio.ini similarity index 100% rename from pioarduino_examples/IncreaseMaxSockets/platformio.ini rename to examples/pioarduino/IncreaseMaxSockets/platformio.ini diff --git a/pioarduino_examples/IncreaseMaxSockets/src/main.cpp b/examples/pioarduino/IncreaseMaxSockets/src/main.cpp similarity index 100% rename from pioarduino_examples/IncreaseMaxSockets/src/main.cpp rename to examples/pioarduino/IncreaseMaxSockets/src/main.cpp diff --git a/idf_component.yml b/idf_component.yml index 651974547..ced46a162 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -5,8 +5,6 @@ tags: - arduino files: exclude: - - "idf_component_examples/" - - "idf_component_examples/**/*" - "docs/" - "docs/*" - "examples/" @@ -35,6 +33,6 @@ dependencies: version: "^7.4.3" require: public examples: - - path: ./idf_component_examples/catchall - - path: ./idf_component_examples/serversentevents - - path: ./idf_component_examples/websocket + - path: .examples/idf_component/catchall + - path: .examples/idf_component/serversentevents + - path: .examples/idf_component/websocket diff --git a/platformio.ini b/platformio.ini index 732058234..75393c637 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,49 +1,49 @@ [platformio] default_envs = arduino-2, arduino-3, esp8266, raspberrypi lib_dir = . -; src_dir = examples/AsyncResponseStream -; src_dir = examples/AsyncTunnel -; src_dir = examples/Auth -; src_dir = examples/CaptivePortal -; src_dir = examples/CatchAllHandler -; src_dir = examples/ChunkRequest -; src_dir = examples/ChunkResponse -; src_dir = examples/ChunkRetryResponse -; src_dir = examples/CORS -; src_dir = examples/EndBegin -; src_dir = examples/Filters -; src_dir = examples/FlashResponse -; src_dir = examples/HeaderManipulation -; src_dir = examples/Headers -; src_dir = examples/HTTPMethodsWithArduino -; src_dir = examples/HTTPMethodsWithESPIDF -; src_dir = examples/Json -; src_dir = examples/LargeResponse -; src_dir = examples/Logging -; src_dir = examples/MessagePack -; src_dir = examples/Middleware -; src_dir = examples/Params -; src_dir = examples/PartitionDownloader -src_dir = examples/PerfTests -; src_dir = examples/RateLimit -; src_dir = examples/Redirect -; src_dir = examples/RequestContinuation -; src_dir = examples/RequestContinuationComplete -; src_dir = examples/ResumableDownload -; src_dir = examples/Rewrite -; src_dir = examples/ServerSentEvents -; src_dir = examples/ServerState -; src_dir = examples/SkipServerMiddleware -; src_dir = examples/SlowChunkResponse -; src_dir = examples/StaticFile -; src_dir = examples/Templates -; src_dir = examples/Upload -; src_dir = examples/UploadFlash -; src_dir = examples/URIMatcher -; src_dir = examples/URIMatcherTest -; src_dir = examples/WebDAVMethods -; src_dir = examples/WebSocket -; src_dir = examples/WebSocketEasy +; src_dir = examples/arduino/AsyncResponseStream +; src_dir = examples/arduino/AsyncTunnel +; src_dir = examples/arduino/Auth +; src_dir = examples/arduino/CaptivePortal +; src_dir = examples/arduino/CatchAllHandler +; src_dir = examples/arduino/ChunkRequest +; src_dir = examples/arduino/ChunkResponse +; src_dir = examples/arduino/ChunkRetryResponse +; src_dir = examples/arduino/CORS +; src_dir = examples/arduino/EndBegin +; src_dir = examples/arduino/Filters +; src_dir = examples/arduino/FlashResponse +; src_dir = examples/arduino/HeaderManipulation +; src_dir = examples/arduino/Headers +; src_dir = examples/arduino/HTTPMethodsWithArduino +; src_dir = examples/arduino/HTTPMethodsWithESPIDF +; src_dir = examples/arduino/Json +; src_dir = examples/arduino/LargeResponse +; src_dir = examples/arduino/Logging +; src_dir = examples/arduino/MessagePack +; src_dir = examples/arduino/Middleware +; src_dir = examples/arduino/Params +; src_dir = examples/arduino/PartitionDownloader +src_dir = examples/arduino/PerfTests +; src_dir = examples/arduino/RateLimit +; src_dir = examples/arduino/Redirect +; src_dir = examples/arduino/RequestContinuation +; src_dir = examples/arduino/RequestContinuationComplete +; src_dir = examples/arduino/ResumableDownload +; src_dir = examples/arduino/Rewrite +; src_dir = examples/arduino/ServerSentEvents +; src_dir = examples/arduino/ServerState +; src_dir = examples/arduino/SkipServerMiddleware +; src_dir = examples/arduino/SlowChunkResponse +; src_dir = examples/arduino/StaticFile +; src_dir = examples/arduino/Templates +; src_dir = examples/arduino/Upload +; src_dir = examples/arduino/UploadFlash +; src_dir = examples/arduino/URIMatcher +; src_dir = examples/arduino/URIMatcherTest +; src_dir = examples/arduino/WebDAVMethods +; src_dir = examples/arduino/WebSocket +; src_dir = examples/arduino/WebSocketEasy [env] framework = arduino From c0619cb1793ce811e480123c144b1f554d41e02f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 8 Apr 2026 17:07:42 +0200 Subject: [PATCH 19/19] Move arduino_emulator to examples folder --- .github/workflows/build-arduino-emulator.yml | 2 +- arduino_emulator_example/CMakeLists.txt | 17 ----------------- examples/arduino_emulator/CMakeLists.txt | 17 +++++++++++++++++ .../host_config/freertos/semphr.h | 0 .../arduino_emulator}/host_config/lwipopts.h | 0 .../arduino_emulator}/host_config/sdkconfig.h | 0 6 files changed, 18 insertions(+), 18 deletions(-) delete mode 100644 arduino_emulator_example/CMakeLists.txt create mode 100644 examples/arduino_emulator/CMakeLists.txt rename {arduino_emulator_example => examples/arduino_emulator}/host_config/freertos/semphr.h (100%) rename {arduino_emulator_example => examples/arduino_emulator}/host_config/lwipopts.h (100%) rename {arduino_emulator_example => examples/arduino_emulator}/host_config/sdkconfig.h (100%) diff --git a/.github/workflows/build-arduino-emulator.yml b/.github/workflows/build-arduino-emulator.yml index 085ba6918..35931b707 100644 --- a/.github/workflows/build-arduino-emulator.yml +++ b/.github/workflows/build-arduino-emulator.yml @@ -48,5 +48,5 @@ jobs: - name: Build with Arduino-Emulator run: | - cmake -S arduino_emulator_example -B .ci/arduino-emulator-build/out -G Ninja + cmake -S examples/arduino_emulator -B .ci/arduino-emulator-build/out -G Ninja cmake --build .ci/arduino-emulator-build/out --target espasyncwebserver --parallel diff --git a/arduino_emulator_example/CMakeLists.txt b/arduino_emulator_example/CMakeLists.txt deleted file mode 100644 index 3156025cc..000000000 --- a/arduino_emulator_example/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -cmake_minimum_required(VERSION 3.11) -project(espasyncwebserver_host_compile LANGUAGES C CXX) - -add_subdirectory(${CMAKE_SOURCE_DIR}/../.ci/arduino-emulator ${CMAKE_BINARY_DIR}/arduino-emulator) -file(GLOB WEB_SRC "${CMAKE_SOURCE_DIR}/../src/*.cpp") -add_library(espasyncwebserver STATIC ${WEB_SRC}) - -target_compile_definitions(espasyncwebserver PUBLIC HOST ARDUINO=10813) -target_include_directories(espasyncwebserver PUBLIC - ${CMAKE_SOURCE_DIR}/../src - ${CMAKE_SOURCE_DIR}/../.ci/asynctcp/src - ${CMAKE_SOURCE_DIR}/../.ci/arduino-esp32/libraries/FS/src - ${CMAKE_SOURCE_DIR}/../.ci/lwip/src/include - ${CMAKE_SOURCE_DIR}/../.ci/lwip-contrib/ports/unix/port/include - ${CMAKE_SOURCE_DIR}/host_config -) -target_link_libraries(espasyncwebserver PUBLIC arduino_emulator) diff --git a/examples/arduino_emulator/CMakeLists.txt b/examples/arduino_emulator/CMakeLists.txt new file mode 100644 index 000000000..91ba9e625 --- /dev/null +++ b/examples/arduino_emulator/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.11) +project(espasyncwebserver_host_compile LANGUAGES C CXX) + +add_subdirectory(${CMAKE_SOURCE_DIR}/../../.ci/arduino-emulator ${CMAKE_BINARY_DIR}/arduino-emulator) +file(GLOB WEB_SRC "${CMAKE_SOURCE_DIR}/../../src/*.cpp") +add_library(espasyncwebserver STATIC ${WEB_SRC}) + +target_compile_definitions(espasyncwebserver PUBLIC HOST ARDUINO=10813) +target_include_directories(espasyncwebserver PUBLIC + ${CMAKE_SOURCE_DIR}/../../src + ${CMAKE_SOURCE_DIR}/../../.ci/asynctcp/src + ${CMAKE_SOURCE_DIR}/../../.ci/arduino-esp32/libraries/FS/src + ${CMAKE_SOURCE_DIR}/../../.ci/lwip/src/include + ${CMAKE_SOURCE_DIR}/../../.ci/lwip-contrib/ports/unix/port/include + ${CMAKE_SOURCE_DIR}/host_config +) +target_link_libraries(espasyncwebserver PUBLIC arduino_emulator) diff --git a/arduino_emulator_example/host_config/freertos/semphr.h b/examples/arduino_emulator/host_config/freertos/semphr.h similarity index 100% rename from arduino_emulator_example/host_config/freertos/semphr.h rename to examples/arduino_emulator/host_config/freertos/semphr.h diff --git a/arduino_emulator_example/host_config/lwipopts.h b/examples/arduino_emulator/host_config/lwipopts.h similarity index 100% rename from arduino_emulator_example/host_config/lwipopts.h rename to examples/arduino_emulator/host_config/lwipopts.h diff --git a/arduino_emulator_example/host_config/sdkconfig.h b/examples/arduino_emulator/host_config/sdkconfig.h similarity index 100% rename from arduino_emulator_example/host_config/sdkconfig.h rename to examples/arduino_emulator/host_config/sdkconfig.h