Aktualizace na verzi 2.7.0

This commit is contained in:
Pavel Brychta 2024-02-06 17:39:53 +01:00
parent ab6ddd0f32
commit 5b5da8b117
10 changed files with 167 additions and 83 deletions

View File

@ -8,14 +8,18 @@ Async Web Server for ESP31B
This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and includes all the concurrency fixes. This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and includes all the concurrency fixes.
## Changes ## Changes in this fork
- SPIFFSEditor is removed - Removed SPIFFSEditor
- Arduino Json 7 compatibility
- Deployed in PlatformIO registry and Arduino IDE library manager - Deployed in PlatformIO registry and Arduino IDE library manager
- CI - CI
- Only supports ESP32 - Some code cleanup
- `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client
- `write()` function public in `AsyncEventSource.h`
- Arduino Json 7 compatibility and by default, still compatible with 6 (`AsyncJson.h`)
- `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client
- Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. - Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket.
- [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5): set real "Last-Modified" header based on file's LastWrite time ([@vortigont](https://github.com/vortigont))
## Documentation ## Documentation

View File

@ -8,13 +8,18 @@ Async Web Server for ESP31B
This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and includes all the concurrency fixes. This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and includes all the concurrency fixes.
## Changes ## Changes in this fork
- SPIFFSEditor is removed - Removed SPIFFSEditor
- Arduino Json 7 compatibility
- Deployed in PlatformIO registry and Arduino IDE library manager - Deployed in PlatformIO registry and Arduino IDE library manager
- CI - CI
- Only supports ESP32 - Some code cleanup
- `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client
- `write()` function public in `AsyncEventSource.h`
- Arduino Json 7 compatibility and by default, still compatible with 6 (`AsyncJson.h`)
- `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client
- Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket.
- [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5): set real "Last-Modified" header based on file's LastWrite time ([@vortigont](https://github.com/vortigont))
## Documentation ## Documentation
@ -23,13 +28,29 @@ Please look at the original libraries for more examples and documentation.
[https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) [https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer)
## Pitfalls ## `AsyncWebSocketMessageBuffer` and `makeBuffer()`
The fork from yubox introduces some breaking API changes compared to the original library, especially regarding the use of `std::shared_ptr<std::vector<uint8_t>>` for WebSocket. The fork from `yubox-node-org` introduces some breaking API changes compared to the original library, especially regarding the use of `std::shared_ptr<std::vector<uint8_t>>` for WebSocket.
Thanks to this fork, you can handle them by using `ASYNCWEBSERVER_FORK_mathieucarbou`.
Here is an example for serializing a Json document in a websocket message buffer directly. This fork is compatible with the original library from `me-no-dev` regarding WebSocket, and wraps the optimizations done by `yubox-node-org` in the `AsyncWebSocketMessageBuffer` class.
This code is compatible with both forks. So you have the choice of which API to use.
I strongly suggest to use the optimized API from `yubox-node-org` as it is much more efficient.
Here is an example for serializing a Json document in a websocket message buffer. This code is compatible with any forks, but not optimized:
```cpp
void send(JsonDocument& doc) {
const size_t len = measureJson(doc);
// original API from me-no-dev
AsyncWebSocketMessageBuffer* buffer = _ws->makeBuffer(len);
assert(buffer); // up to you to keep or remove this
serializeJson(doc, buffer->get(), len);
_ws->textAll(buffer);
}
```
Here is an example for serializing a Json document in a more optimized way, and compatible with both forks:
```cpp ```cpp
void send(JsonDocument& doc) { void send(JsonDocument& doc) {

View File

@ -1,41 +1,47 @@
#include "ESPAsyncWebServer.h"
#include <AsyncTCP.h>
#include <DNSServer.h> #include <DNSServer.h>
#ifdef ESP32
#include <WiFi.h> #include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include "ESPAsyncWebServer.h"
DNSServer dnsServer; DNSServer dnsServer;
AsyncWebServer server(80); AsyncWebServer server(80);
class CaptiveRequestHandler : public AsyncWebHandler { class CaptiveRequestHandler : public AsyncWebHandler {
public: public:
CaptiveRequestHandler() {} CaptiveRequestHandler() {}
virtual ~CaptiveRequestHandler() {} virtual ~CaptiveRequestHandler() {}
bool canHandle(AsyncWebServerRequest* request) { bool canHandle(AsyncWebServerRequest *request){
// request->addInterestingHeader("ANY"); //request->addInterestingHeader("ANY");
return true; return true;
} }
void handleRequest(AsyncWebServerRequest* request) { void handleRequest(AsyncWebServerRequest *request) {
AsyncResponseStream* response = request->beginResponseStream("text/html"); AsyncResponseStream *response = request->beginResponseStream("text/html");
response->print("<!DOCTYPE html><html><head><title>Captive Portal</title></head><body>"); response->print("<!DOCTYPE html><html><head><title>Captive Portal</title></head><body>");
response->print("<p>This is out captive portal front page.</p>"); response->print("<p>This is out captive portal front page.</p>");
response->printf("<p>You were trying to reach: http://%s%s</p>", request->host().c_str(), request->url().c_str()); response->printf("<p>You were trying to reach: http://%s%s</p>", request->host().c_str(), request->url().c_str());
response->printf("<p>Try opening <a href='http://%s'>this link</a> instead</p>", WiFi.softAPIP().toString().c_str()); response->printf("<p>Try opening <a href='http://%s'>this link</a> instead</p>", WiFi.softAPIP().toString().c_str());
response->print("</body></html>"); response->print("</body></html>");
request->send(response); request->send(response);
} }
}; };
void setup() {
// your other setup stuff... void setup(){
//your other setup stuff...
WiFi.softAP("esp-captive"); WiFi.softAP("esp-captive");
dnsServer.start(53, "*", WiFi.softAPIP()); dnsServer.start(53, "*", WiFi.softAPIP());
server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); // only when requested from AP server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER);//only when requested from AP
// more handlers... //more handlers...
server.begin(); server.begin();
} }
void loop() { void loop(){
dnsServer.processNextRequest(); dnsServer.processNextRequest();
} }

View File

@ -1,41 +1,74 @@
#include "ESPAsyncWebServer.h" //
#include <AsyncTCP.h> // A simple server implementation showing how to:
#include <DNSServer.h> // * serve static messages
#include <WiFi.h> // * read GET and POST parameters
// * handle missing pages / 404s
//
#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
DNSServer dnsServer;
AsyncWebServer server(80); AsyncWebServer server(80);
class CaptiveRequestHandler : public AsyncWebHandler { const char* ssid = "YOUR_SSID";
public: const char* password = "YOUR_PASSWORD";
CaptiveRequestHandler() {}
virtual ~CaptiveRequestHandler() {}
bool canHandle(AsyncWebServerRequest* request) { const char* PARAM_MESSAGE = "message";
// request->addInterestingHeader("ANY");
return true;
}
void handleRequest(AsyncWebServerRequest* request) { void notFound(AsyncWebServerRequest *request) {
AsyncResponseStream* response = request->beginResponseStream("text/html"); request->send(404, "text/plain", "Not found");
response->print("<!DOCTYPE html><html><head><title>Captive Portal</title></head><body>"); }
response->print("<p>This is out captive portal front page.</p>");
response->printf("<p>You were trying to reach: http://%s%s</p>", request->host().c_str(), request->url().c_str());
response->printf("<p>Try opening <a href='http://%s'>this link</a> instead</p>", WiFi.softAPIP().toString().c_str());
response->print("</body></html>");
request->send(response);
}
};
void setup() { void setup() {
// your other setup stuff...
WiFi.softAP("esp-captive"); Serial.begin(115200);
dnsServer.start(53, "*", WiFi.softAPIP()); WiFi.mode(WIFI_STA);
server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); // only when requested from AP WiFi.begin(ssid, password);
// more handlers... if (WiFi.waitForConnectResult() != WL_CONNECTED) {
server.begin(); Serial.printf("WiFi Failed!\n");
return;
}
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "Hello, world");
});
// Send a GET request to <IP>/get?message=<message>
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
String message;
if (request->hasParam(PARAM_MESSAGE)) {
message = request->getParam(PARAM_MESSAGE)->value();
} else {
message = "No message sent";
}
request->send(200, "text/plain", "Hello, GET: " + message);
});
// Send a POST request to <IP>/post with a form field message set to <message>
server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){
String message;
if (request->hasParam(PARAM_MESSAGE, true)) {
message = request->getParam(PARAM_MESSAGE, true)->value();
} else {
message = "No message sent";
}
request->send(200, "text/plain", "Hello, POST: " + message);
});
server.onNotFound(notFound);
server.begin();
} }
void loop() { void loop() {
dnsServer.processNextRequest();
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "ESP Async WebServer", "name": "ESP Async WebServer",
"version": "2.5.1", "version": "2.7.0",
"description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.",
"keywords": "http,async,websocket,webserver", "keywords": "http,async,websocket,webserver",
"homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer",
@ -28,6 +28,16 @@
"name": "AsyncTCP-esphome", "name": "AsyncTCP-esphome",
"version": "^2.1.1", "version": "^2.1.1",
"platforms": "espressif32" "platforms": "espressif32"
},
{
"owner": "esphome",
"name": "ESPAsyncTCP-esphome",
"version": "^2.0.0",
"platforms": "espressif8266"
},
{
"name": "Hash",
"platforms": "espressif8266"
} }
], ],
"export": { "export": {

View File

@ -1,5 +1,5 @@
name=ESP Async WebServer name=ESP Async WebServer
version=2.5.1 version=2.7.0
author=Me-No-Dev author=Me-No-Dev
maintainer=Mathieu Carbou <mathieu.carbou@gmail.com> maintainer=Mathieu Carbou <mathieu.carbou@gmail.com>
sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 sentence=Asynchronous HTTP and WebSocket Server Library for ESP32

View File

@ -1,7 +1,5 @@
[env] [env]
lib_deps = framework = arduino
bblanchon/ArduinoJson @ 7.0.2
esphome/AsyncTCP-esphome @ 2.1.1
build_flags = -Wall -Wextra build_flags = -Wall -Wextra
@ -13,11 +11,21 @@ monitor_speed = 115200
monitor_filters = esp32_exception_decoder, log2file monitor_filters = esp32_exception_decoder, log2file
[platformio] [platformio]
default_envs = esp8266
lib_dir = . lib_dir = .
src_dir = examples/CaptivePortal ; src_dir = examples/CaptivePortal
; src_dir = examples/SimpleServer src_dir = examples/SimpleServer
[env:esp32] [env:esp32]
platform = espressif32@6.5.0 platform = espressif32
board = esp32dev board = esp32dev
framework = arduino lib_deps =
bblanchon/ArduinoJson @ 7.0.2
esphome/AsyncTCP-esphome @ 2.1.1
[env:esp8266]
platform = espressif8266
board = huzzah
lib_deps =
bblanchon/ArduinoJson @ 7.0.2
esphome/ESPAsyncTCP-esphome @ 2.0.0

View File

@ -798,7 +798,7 @@ void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len)
IPAddress AsyncWebSocketClient::remoteIP() const IPAddress AsyncWebSocketClient::remoteIP() const
{ {
if (!_client) if (!_client)
return {}; // IPAddress(0U); return IPAddress((uint32_t)0U);
return _client->remoteIP(); return _client->remoteIP();
} }

View File

@ -40,10 +40,10 @@
#error Platform not supported #error Platform not supported
#endif #endif
#define ASYNCWEBSERVER_VERSION "2.5.1" #define ASYNCWEBSERVER_VERSION "2.7.0"
#define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MAJOR 2
#define ASYNCWEBSERVER_VERSION_MINOR 5 #define ASYNCWEBSERVER_VERSION_MINOR 7
#define ASYNCWEBSERVER_VERSION_REVISION 1 #define ASYNCWEBSERVER_VERSION_REVISION 0
#define ASYNCWEBSERVER_FORK_mathieucarbou #define ASYNCWEBSERVER_FORK_mathieucarbou
#ifdef ASYNCWEBSERVER_REGEX #ifdef ASYNCWEBSERVER_REGEX

View File

@ -58,7 +58,7 @@ AsyncStaticWebHandler& AsyncStaticWebHandler::setCacheControl(const char* cache_
} }
AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(const char* last_modified){ AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(const char* last_modified){
_last_modified = String(last_modified); _last_modified = last_modified;
return *this; return *this;
} }
@ -205,7 +205,9 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request)
return request->requestAuthentication(); return request->requestAuthentication();
if (request->_tempFile == true) { if (request->_tempFile == true) {
String etag = String(request->_tempFile.size()); time_t lw = request->_tempFile.getLastWrite(); // get last file mod time (if supported by FS)
if (lw) setLastModified(gmtime(&lw));
String etag(lw ? lw : request->_tempFile.size()); // set etag to lastmod timestamp if available, otherwise to size
if (_last_modified.length() && _last_modified == request->header(F("If-Modified-Since"))) { if (_last_modified.length() && _last_modified == request->header(F("If-Modified-Since"))) {
request->_tempFile.close(); request->_tempFile.close();
request->send(304); // Not modified request->send(304); // Not modified