mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 09:49:32 +02:00
Update ESPAsyncWebServer from 3.6.0 to 3.6.2
This commit is contained in:
parent
b9b14ded2f
commit
a91d02e62a
34 changed files with 640 additions and 79 deletions
|
@ -94,7 +94,7 @@ This code uses the following excellent libraries:
|
|||
- [eModbus/eModbus](https://github.com/eModbus/eModbus) MIT-License
|
||||
- [mackelec/SerialDataLink](https://github.com/mackelec/SerialDataLink)
|
||||
- [mathieucarbou/AsyncTCPsock](https://github.com/mathieucarbou/AsyncTCPSock) LGPL-3.0 license
|
||||
- [mathieucarbou/ESPAsyncWebServer](https://github.com/mathieucarbou/ESPAsyncWebServer) LGPL-3.0 license
|
||||
- [ESP32Async/ESPAsyncWebServer](https://github.com/ESP32Async/ESPAsyncWebServer) LGPL-3.0 license
|
||||
- [miwagner/ESP32-Arduino-CAN](https://github.com/miwagner/ESP32-Arduino-CAN/) MIT-License
|
||||
- [pierremolinaro/acan2515](https://github.com/pierremolinaro/acan2515) MIT-License
|
||||
- [pierremolinaro/acan2517FD](https://github.com/pierremolinaro/acan2517FD) MIT-License
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "../../datalayer/datalayer.h"
|
||||
#include "../../devboard/utils/events.h"
|
||||
#include "../../devboard/utils/value_mapping.h"
|
||||
#include "../../lib/mathieucarbou-ESPAsyncWebServer/src/ESPAsyncWebServer.h"
|
||||
#include "../../lib/ESP32Async-ESPAsyncWebServer/src/ESPAsyncWebServer.h"
|
||||
#include "../../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
|
||||
#ifdef CAN_ADDON
|
||||
#include "../../lib/pierremolinaro-acan2515/ACAN2515.h"
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
#include <Preferences.h>
|
||||
#include <WiFi.h>
|
||||
#include "../../include.h"
|
||||
#include "../../lib/ESP32Async-ESPAsyncWebServer/src/ESPAsyncWebServer.h"
|
||||
#include "../../lib/YiannisBourkelis-Uptime-Library/src/uptime_formatter.h"
|
||||
#include "../../lib/ayushsharma82-ElegantOTA/src/ElegantOTA.h"
|
||||
#include "../../lib/mathieucarbou-AsyncTCPSock/src/AsyncTCP.h"
|
||||
#include "../../lib/mathieucarbou-ESPAsyncWebServer/src/ESPAsyncWebServer.h"
|
||||
|
||||
extern const char* version_number; // The current software version, shown on webserver
|
||||
|
||||
|
|
129
Software/src/lib/ESP32Async-ESPAsyncWebServer/CODE_OF_CONDUCT.md
Normal file
129
Software/src/lib/ESP32Async-ESPAsyncWebServer/CODE_OF_CONDUCT.md
Normal file
|
@ -0,0 +1,129 @@
|
|||
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
https://sidweb.nl/cms3/en/contact.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
|
@ -1,21 +1,33 @@
|
|||

|
||||
|
||||
# ESPAsyncWebServer
|
||||
|
||||
[](https://GitHub.com/mathieucarbou/ESPAsyncWebServer/releases/)
|
||||
[](https://registry.platformio.org/libraries/mathieucarbou/ESPAsyncWebServer)
|
||||
[](https://GitHub.com/ESP32Async/ESPAsyncWebServer/releases/)
|
||||
[](https://registry.platformio.org/libraries/ESP32Async/ESPAsyncWebServer)
|
||||
|
||||
[](https://opensource.org/license/lgpl-3-0/)
|
||||
[](code_of_conduct.md)
|
||||
|
||||
[](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml)
|
||||
[](https://GitHub.com/mathieucarbou/ESPAsyncWebServer/commit/)
|
||||
[](https://gitpod.io/#https://github.com/mathieucarbou/ESPAsyncWebServer)
|
||||
[](https://github.com/ESP32Async/ESPAsyncWebServer/actions/workflows/ci.yml)
|
||||
[](https://GitHub.com/ESP32Async/ESPAsyncWebServer/commit/)
|
||||
[](https://gitpod.io/#https://github.com/ESP32Async/ESPAsyncWebServer)
|
||||
|
||||
Project moved to [ESP32Async](https://github.com/ESP32Async) organization at [https://github.com/ESP32Async/ESPAsyncWebServer](https://github.com/ESP32Async/ESPAsyncWebServer)
|
||||
|
||||
Discord Server: [https://discord.gg/X7zpGdyUcY](https://discord.gg/X7zpGdyUcY)
|
||||
|
||||
Please see the new links:
|
||||
|
||||
- `ESP32Async/ESPAsyncWebServer @ 3.6.2` (ESP32, ESP8266, RP2040)
|
||||
- `ESP32Async/AsyncTCP @ 3.3.2` (ESP32)
|
||||
- `ESP32Async/ESPAsyncTCP @ 2.0.0` (ESP8266)
|
||||
- `https://github.com/ESP32Async/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` (AsyncTCP alternative for ESP32)
|
||||
- `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (RP2040)
|
||||
|
||||
Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040
|
||||
Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.
|
||||
|
||||
This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes.
|
||||
|
||||
- [Changes in this fork](#changes-in-this-fork)
|
||||
- [Changes in this repository](#changes-in-this-repository)
|
||||
- [Dependencies](#dependencies)
|
||||
- [Performance](#performance)
|
||||
- [Important recommendations for build options](#important-recommendations-for-build-options)
|
||||
|
@ -26,7 +38,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo
|
|||
- [Migration to Middleware to improve performance and memory usage](#migration-to-middleware-to-improve-performance-and-memory-usage)
|
||||
- [Original Documentation](#original-documentation)
|
||||
|
||||
## Changes in this fork
|
||||
## Changes in this repository
|
||||
|
||||
- (bug) A lot of bug fixes
|
||||
- (ci) Better CI with a complete matrix of Arduino versions and boards
|
||||
|
@ -42,7 +54,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo
|
|||
- (feat) **Resumable download** support using HEAD and bytes range
|
||||
- (feat) `StreamConcat` example to show how to stream multiple files in one response
|
||||
- (feat) Removed ESPIDF Editor (this is not the role of a web server library to do that - get the source files from the original repos if required)
|
||||
- (perf) [AsyncTCPSock](https://github.com/mathieucarbou/AsyncTCPSock) support: AsyncTCP can be ignored and AsyncTCPSock used instead
|
||||
- (perf) [AsyncTCPSock](https://github.com/ESP32Async/AsyncTCPSock) support: AsyncTCP can be ignored and AsyncTCPSock used instead
|
||||
- (perf) `char*` overloads to avoid using `String`
|
||||
- (perf) `DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients
|
||||
- (perf) `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full
|
||||
|
@ -59,13 +71,19 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo
|
|||
|
||||
This ESPAsyncWebServer fork is now at version 3.x, where we try to keep the API compatibility with original project as much as possible.
|
||||
|
||||
Next version 4.x will:
|
||||
We plan on creating a next major 4.x version that will:
|
||||
|
||||
1. Drop support for ESP8266, which goes EOL in a few years. All ESP8266 boards can be replaced by equivalent ESP32 boards.
|
||||
2. Drop support for Arduino 2.x and ESP-IDF 4.x. The library will be compatible with Arduino 3.x and ESP-IDF 5.x.
|
||||
3. Drop support for ArduinoJson 5.x and 6.x. The library will be compatible with ArduinoJson 7.x.
|
||||
1. Drop support for ESP8266, which goes EOL in a few years
|
||||
2. Drop support for Arduino 2.x and ESP-IDF 4.x. The library will be compatible with latest Arduino and ESP-IDF
|
||||
3. Drop support for ArduinoJson 5.x and 6.x. The library will be compatible with latest ArduinoJson
|
||||
|
||||
So if you need one of these feature, you will have to stick with 3.x or another fork.
|
||||
So if you need one of these feature, you will have to stick with the current 3.x.
|
||||
All releases we do will not cease to exist: all 3.x releases will stay in the release page.
|
||||
That is why we have tags and a release cycle.
|
||||
|
||||
Maintaining a library for ESP8266 and RP2040 has a real cost and clearly what we see is that most users helping are on ESP32.
|
||||
|
||||
If you are an ESP8266 user and want to help improve current 3.x, you are more than welcomed to contribute to this community effort.
|
||||
|
||||
## Dependencies
|
||||
|
||||
|
@ -77,18 +95,18 @@ So if you need one of these feature, you will have to stick with 3.x or another
|
|||
```ini
|
||||
lib_compat_mode = strict
|
||||
lib_ldf_mode = chain
|
||||
lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.6.0
|
||||
lib_deps = ESP32Async/ESPAsyncWebServer @ 3.6.2
|
||||
```
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.3.2`
|
||||
Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.3.2](https://github.com/mathieucarbou/AsyncTCP/releases)
|
||||
- **ESP32 with AsyncTCP**: `ESP32Async/AsyncTCP @ 3.3.2`
|
||||
Arduino IDE: [https://github.com/ESP32Async/AsyncTCP#v3.3.2](https://github.com/ESP32Async/AsyncTCP/releases)
|
||||
|
||||
- **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip`
|
||||
- **ESP32 with AsyncTCPSock**: `https://github.com/ESP32Async/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip`
|
||||
|
||||
- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0`
|
||||
Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)
|
||||
- **ESP8266**: `ESP32Async/ESPAsyncTCP @ 2.0.0`
|
||||
Arduino IDE: [https://github.com/ESP32Async/ESPAsyncTCP#v2.0.0](https://github.com/ESP32Async/ESPAsyncTCP/releases/tag/v2.0.0)
|
||||
|
||||
- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0`
|
||||
Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)
|
||||
|
@ -101,30 +119,30 @@ AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the libr
|
|||
lib_compat_mode = strict
|
||||
lib_ldf_mode = chain
|
||||
lib_deps =
|
||||
; mathieucarbou/AsyncTCP @ 3.3.2
|
||||
https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip
|
||||
mathieucarbou/ESPAsyncWebServer @ 3.6.0
|
||||
; ESP32Async/AsyncTCP @ 3.3.2
|
||||
https://github.com/ESP32Async/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip
|
||||
ESP32Async/ESPAsyncWebServer @ 3.6.2
|
||||
lib_ignore =
|
||||
AsyncTCP
|
||||
mathieucarbou/AsyncTCP
|
||||
ESP32Async/AsyncTCP
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
Performance of `mathieucarbou/ESPAsyncWebServer @ 3.6.0`:
|
||||
Performance of `ESP32Async/ESPAsyncWebServer @ 3.6.2`:
|
||||
|
||||
```bash
|
||||
> brew install autocannon
|
||||
> autocannon -c 10 -w 10 -d 20 http://192.168.4.1
|
||||
```
|
||||
|
||||
With `mathieucarbou/AsyncTCP @ 3.3.2`
|
||||
With `ESP32Async/AsyncTCP @ 3.3.2`
|
||||
|
||||
[](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)
|
||||
<img width="629" alt="perf-c10" src="https://github.com/user-attachments/assets/b4b7f953-c24d-4e04-8d87-ba3f26805737" />
|
||||
|
||||
With `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip`:
|
||||
With `https://github.com/ESP32Async/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip`:
|
||||
|
||||
[](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)
|
||||
<img width="654" alt="perf-c10-asynctcpsock" src="https://github.com/user-attachments/assets/0dacf133-ca47-40be-939b-e6f60fc95b81" />
|
||||
|
||||
**SSE performance**
|
||||
|
||||
|
@ -190,6 +208,8 @@ I personally use the following configuration in my projects:
|
|||
-D CONFIG_ASYNC_TCP_STACK_SIZE=4096 // reduce the stack size (default is 16K)
|
||||
```
|
||||
|
||||
If you need to serve chunk requests with a really low buffer (which should be avoided), you can set `-D ASYNCWEBSERVER_USE_CHUNK_INFLIGHT=0` to disable the in-flight control.
|
||||
|
||||
## `AsyncWebSocketMessageBuffer` and `makeBuffer()`
|
||||
|
||||
The fork from [yubox-node-org](https://github.com/yubox-node-org/ESPAsyncWebServer) introduces some breaking API changes compared to the original library, especially regarding the use of `std::shared_ptr<std::vector<uint8_t>>` for WebSocket.
|
||||
|
@ -247,7 +267,7 @@ Middleware is a way to intercept requests to perform some operations on them, li
|
|||
Middleware can either be attached to individual handlers, attached at the server level (thus applied to all handlers), or both.
|
||||
They will be executed in the order they are attached, and they can stop the request processing by sending a response themselves.
|
||||
|
||||
You can have a look at the [SimpleServer.ino](https://github.com/mathieucarbou/ESPAsyncWebServer/blob/main/examples/SimpleServer/SimpleServer.ino) example for some use cases.
|
||||
You can have a look at the [SimpleServer.ino](https://github.com/ESP32Async/ESPAsyncWebServer/blob/main/examples/SimpleServer/SimpleServer.ino) example for some use cases.
|
||||
|
||||
For example, such middleware would handle authentication and set some attributes on the request to make them available for the next middleware and for the handler which will process the request.
|
||||
|
||||
|
@ -315,15 +335,6 @@ myHandler.addMiddleware(&authMiddleware); // add authentication to a specific ha
|
|||
These callbacks can be called multiple times during request parsing, so this is up to the user to now call the `AsyncAuthenticationMiddleware.allowed(request)` if needed and ideally when the method is called for the first time.
|
||||
These callbacks are also not triggering the whole middleware chain since they are not part of the request processing workflow (they are not the final handler).
|
||||
|
||||
|
||||
## Maintainers
|
||||
This fork of ESPAsyncWebServer and dependend libs are maintained as an opensource project at best effort level.
|
||||
- [Mathieu Carbou](https://github.com/mathieucarbou)
|
||||
- [Emil Muratov](https://github.com/vortigont)
|
||||
|
||||
Thanks to all who contributed by providing PRs, testing and reporting issues.
|
||||
|
||||
|
||||
## Original Documentation
|
||||
<!-- no toc -->
|
||||
- [Why should you care](#why-should-you-care)
|
|
@ -1,26 +1,18 @@
|
|||
{
|
||||
"name": "ESPAsyncWebServer",
|
||||
"version": "3.6.0",
|
||||
"version": "3.6.2",
|
||||
"description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.",
|
||||
"keywords": "http,async,websocket,webserver",
|
||||
"homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer",
|
||||
"homepage": "https://github.com/ESP32Async/ESPAsyncWebServer",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mathieucarbou/ESPAsyncWebServer.git"
|
||||
"url": "https://github.com/ESP32Async/ESPAsyncWebServer.git"
|
||||
},
|
||||
"authors":
|
||||
{
|
||||
"name": "ESP32Async",
|
||||
"maintainer": true
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Hristo Gochkov"
|
||||
},
|
||||
{
|
||||
"name": "Mathieu Carbou",
|
||||
"maintainer": true
|
||||
},
|
||||
{
|
||||
"name": "Emil Muratov",
|
||||
"maintainer": true
|
||||
}
|
||||
],
|
||||
"license": "LGPL-3.0",
|
||||
"frameworks": "arduino",
|
||||
"platforms": [
|
||||
|
@ -30,14 +22,14 @@
|
|||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"owner": "mathieucarbou",
|
||||
"owner": "ESP32Async",
|
||||
"name": "AsyncTCP",
|
||||
"version": "^3.3.2",
|
||||
"platforms": "espressif32"
|
||||
},
|
||||
{
|
||||
"owner": "esphome",
|
||||
"name": "ESPAsyncTCP-esphome",
|
||||
"owner": "ESP32Async",
|
||||
"name": "ESPAsyncTCP",
|
||||
"version": "^2.0.0",
|
||||
"platforms": "espressif8266"
|
||||
},
|
|
@ -1,11 +1,11 @@
|
|||
name=ESP Async WebServer
|
||||
includes=ESPAsyncWebServer.h
|
||||
version=3.6.0
|
||||
author=Me-No-Dev
|
||||
maintainer=Mathieu Carbou <mathieu.carbou@gmail.com>
|
||||
version=3.6.2
|
||||
author=ESP32Async
|
||||
maintainer=ESP32Async
|
||||
sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040
|
||||
paragraph=Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc
|
||||
category=Other
|
||||
url=https://github.com/mathieucarbou/ESPAsyncWebServer
|
||||
url=https://github.com/ESP32Async/ESPAsyncWebServer
|
||||
architectures=*
|
||||
license=LGPL-3.0
|
|
@ -18,7 +18,9 @@
|
|||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "Arduino.h"
|
||||
#include <rom/ets_sys.h>
|
||||
#if defined(ESP32)
|
||||
#include <rom/ets_sys.h>
|
||||
#endif
|
||||
#include "AsyncEventSource.h"
|
||||
|
||||
#define ASYNC_SSE_NEW_LINE_CHAR (char)0xa
|
||||
|
@ -174,19 +176,27 @@ AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest* request, A
|
|||
}
|
||||
|
||||
AsyncEventSourceClient::~AsyncEventSourceClient() {
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_lockmq);
|
||||
#endif
|
||||
_messageQueue.clear();
|
||||
close();
|
||||
}
|
||||
|
||||
bool AsyncEventSourceClient::_queueMessage(const char* message, size_t len) {
|
||||
if (_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES) {
|
||||
#ifdef ESP8266
|
||||
ets_printf(String(F("ERROR: Too many messages queued\n")).c_str());
|
||||
#elif defined(ESP32)
|
||||
log_e("Event message queue overflow: discard message");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
// length() is not thread-safe, thus acquiring the lock before this call..
|
||||
std::lock_guard<std::mutex> lock(_lockmq);
|
||||
#endif
|
||||
|
||||
_messageQueue.emplace_back(message, len);
|
||||
|
||||
|
@ -205,12 +215,18 @@ bool AsyncEventSourceClient::_queueMessage(const char* message, size_t len) {
|
|||
|
||||
bool AsyncEventSourceClient::_queueMessage(AsyncEvent_SharedData_t&& msg) {
|
||||
if (_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES) {
|
||||
#ifdef ESP8266
|
||||
ets_printf(String(F("ERROR: Too many messages queued\n")).c_str());
|
||||
#elif defined(ESP32)
|
||||
log_e("Event message queue overflow: discard message");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
// length() is not thread-safe, thus acquiring the lock before this call..
|
||||
std::lock_guard<std::mutex> lock(_lockmq);
|
||||
#endif
|
||||
|
||||
_messageQueue.emplace_back(std::move(msg));
|
||||
|
||||
|
@ -227,8 +243,10 @@ bool AsyncEventSourceClient::_queueMessage(AsyncEvent_SharedData_t&& msg) {
|
|||
}
|
||||
|
||||
void AsyncEventSourceClient::_onAck(size_t len __attribute__((unused)), uint32_t time __attribute__((unused))) {
|
||||
#ifdef ESP32
|
||||
// Same here, acquiring the lock early
|
||||
std::lock_guard<std::mutex> lock(_lockmq);
|
||||
#endif
|
||||
|
||||
// adjust in-flight len
|
||||
if (len < _inflight)
|
||||
|
@ -252,8 +270,10 @@ void AsyncEventSourceClient::_onAck(size_t len __attribute__((unused)), uint32_t
|
|||
|
||||
void AsyncEventSourceClient::_onPoll() {
|
||||
if (_messageQueue.size()) {
|
||||
#ifdef ESP32
|
||||
// Same here, acquiring the lock early
|
||||
std::lock_guard<std::mutex> lock(_lockmq);
|
||||
#endif
|
||||
_runQueue();
|
||||
}
|
||||
}
|
||||
|
@ -320,7 +340,9 @@ void AsyncEventSource::authorizeConnect(ArAuthorizeConnectHandler cb) {
|
|||
void AsyncEventSource::_addClient(AsyncEventSourceClient* client) {
|
||||
if (!client)
|
||||
return;
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_client_queue_lock);
|
||||
#endif
|
||||
_clients.emplace_back(client);
|
||||
if (_connectcb)
|
||||
_connectcb(client);
|
||||
|
@ -331,7 +353,9 @@ void AsyncEventSource::_addClient(AsyncEventSourceClient* client) {
|
|||
void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient* client) {
|
||||
if (_disconnectcb)
|
||||
_disconnectcb(client);
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_client_queue_lock);
|
||||
#endif
|
||||
for (auto i = _clients.begin(); i != _clients.end(); ++i) {
|
||||
if (i->get() == client)
|
||||
_clients.erase(i);
|
||||
|
@ -343,7 +367,9 @@ 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<std::mutex> lock(_client_queue_lock);
|
||||
#endif
|
||||
for (const auto& c : _clients) {
|
||||
if (c->connected())
|
||||
c->close();
|
||||
|
@ -354,7 +380,9 @@ void AsyncEventSource::close() {
|
|||
size_t AsyncEventSource::avgPacketsWaiting() const {
|
||||
size_t aql = 0;
|
||||
uint32_t nConnectedClients = 0;
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_client_queue_lock);
|
||||
#endif
|
||||
if (!_clients.size())
|
||||
return 0;
|
||||
|
||||
|
@ -370,7 +398,9 @@ 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<String>(generateEventMessage(message, event, id, reconnect));
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_client_queue_lock);
|
||||
#endif
|
||||
size_t hits = 0;
|
||||
size_t miss = 0;
|
||||
for (const auto& c : _clients) {
|
||||
|
@ -383,7 +413,9 @@ AsyncEventSource::SendStatus AsyncEventSource::send(
|
|||
}
|
||||
|
||||
size_t AsyncEventSource::count() const {
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_client_queue_lock);
|
||||
#endif
|
||||
size_t n_clients{0};
|
||||
for (const auto& i : _clients)
|
||||
if (i->connected())
|
|
@ -22,17 +22,39 @@
|
|||
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
#include "../../mathieucarbou-AsyncTCPSock/src/AsyncTCP.h"
|
||||
#ifdef ESP32
|
||||
#include "../../mathieucarbou-AsyncTCPSock/src/AsyncTCP.h"
|
||||
#include <mutex>
|
||||
#ifndef SSE_MAX_QUEUED_MESSAGES
|
||||
#define SSE_MAX_QUEUED_MESSAGES 32
|
||||
#endif
|
||||
#define SSE_MIN_INFLIGH 2 * 1460 // allow 2 MSS packets
|
||||
#define SSE_MAX_INFLIGH 16 * 1024 // but no more than 16k, no need to blow it, since same data is kept in local Q
|
||||
#elif defined(ESP8266)
|
||||
#include <ESPAsyncTCP.h>
|
||||
#ifndef SSE_MAX_QUEUED_MESSAGES
|
||||
#define SSE_MAX_QUEUED_MESSAGES 8
|
||||
#endif
|
||||
#define SSE_MIN_INFLIGH 2 * 1460 // allow 2 MSS packets
|
||||
#define SSE_MAX_INFLIGH 8 * 1024 // but no more than 8k, no need to blow it, since same data is kept in local Q
|
||||
#elif defined(TARGET_RP2040)
|
||||
#include <AsyncTCP_RP2040W.h>
|
||||
#ifndef SSE_MAX_QUEUED_MESSAGES
|
||||
#define SSE_MAX_QUEUED_MESSAGES 32
|
||||
#endif
|
||||
#define SSE_MIN_INFLIGH 2 * 1460 // allow 2 MSS packets
|
||||
#define SSE_MAX_INFLIGH 16 * 1024 // but no more than 16k, no need to blow it, since same data is kept in local Q
|
||||
#endif
|
||||
|
||||
#include "ESPAsyncWebServer.h"
|
||||
|
||||
#ifdef ESP8266
|
||||
#include <Hash.h>
|
||||
#ifdef CRYPTO_HASH_h // include Hash.h from espressif framework if the first include was from the crypto library
|
||||
#include <../src/Hash.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class AsyncEventSource;
|
||||
class AsyncEventSourceResponse;
|
||||
class AsyncEventSourceClient;
|
||||
|
@ -54,7 +76,12 @@ class AsyncEventSourceMessage {
|
|||
|
||||
public:
|
||||
AsyncEventSourceMessage(AsyncEvent_SharedData_t data) : _data(data) {};
|
||||
#ifdef ESP32
|
||||
AsyncEventSourceMessage(const char* data, size_t len) : _data(std::make_shared<String>(data, len)) {};
|
||||
#else
|
||||
// esp8266's String does not have constructor with data/length arguments. Use a concat method here
|
||||
AsyncEventSourceMessage(const char* data, size_t len) { _data->concat(data, len); };
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief acknowledge sending len bytes of data
|
||||
|
@ -105,7 +132,9 @@ 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<AsyncEventSourceMessage> _messageQueue;
|
||||
#ifdef ESP32
|
||||
mutable std::mutex _lockmq;
|
||||
#endif
|
||||
bool _queueMessage(const char* message, size_t len);
|
||||
bool _queueMessage(AsyncEvent_SharedData_t&& msg);
|
||||
void _runQueue();
|
||||
|
@ -184,9 +213,11 @@ class AsyncEventSource : public AsyncWebHandler {
|
|||
private:
|
||||
String _url;
|
||||
std::list<std::unique_ptr<AsyncEventSourceClient>> _clients;
|
||||
#ifdef ESP32
|
||||
// Same as for individual messages, protect mutations of _clients list
|
||||
// since simultaneous access from different tasks is possible
|
||||
mutable std::mutex _client_queue_lock;
|
||||
#endif
|
||||
ArEventHandlerFunction _connectcb = nullptr;
|
||||
ArEventHandlerFunction _disconnectcb = nullptr;
|
||||
|
|
@ -1,5 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
server.on("/msg_pack", HTTP_ANY, [](AsyncWebServerRequest * request) {
|
||||
AsyncMessagePackResponse * response = new AsyncMessagePackResponse();
|
||||
JsonObject& root = response->getRoot();
|
||||
root["key1"] = "key number one";
|
||||
JsonObject& nested = root.createNestedObject("nested");
|
||||
nested["key1"] = "key number one";
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
--------------------
|
||||
|
||||
AsyncCallbackMessagePackWebHandler* handler = new AsyncCallbackMessagePackWebHandler("/msg_pack/endpoint");
|
||||
handler->onRequest([](AsyncWebServerRequest *request, JsonVariant &json) {
|
||||
JsonObject jsonObj = json.as<JsonObject>();
|
||||
// ...
|
||||
});
|
||||
server.addHandler(handler);
|
||||
*/
|
||||
|
||||
#if __has_include("ArduinoJson.h")
|
||||
#include <ArduinoJson.h>
|
||||
#if ARDUINOJSON_VERSION_MAJOR >= 6
|
|
@ -293,7 +293,9 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest* request, Async
|
|||
|
||||
AsyncWebSocketClient::~AsyncWebSocketClient() {
|
||||
{
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_lock);
|
||||
#endif
|
||||
_messageQueue.clear();
|
||||
_controlQueue.clear();
|
||||
}
|
||||
|
@ -308,7 +310,9 @@ void AsyncWebSocketClient::_clearQueue() {
|
|||
void AsyncWebSocketClient::_onAck(size_t len, uint32_t time) {
|
||||
_lastMessageTime = millis();
|
||||
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_lock);
|
||||
#endif
|
||||
|
||||
if (!_controlQueue.empty()) {
|
||||
auto& head = _controlQueue.front();
|
||||
|
@ -338,11 +342,15 @@ void AsyncWebSocketClient::_onPoll() {
|
|||
if (!_client)
|
||||
return;
|
||||
|
||||
#ifdef ESP32
|
||||
std::unique_lock<std::mutex> lock(_lock);
|
||||
#endif
|
||||
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
|
||||
ping((uint8_t*)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN);
|
||||
}
|
||||
}
|
||||
|
@ -362,17 +370,23 @@ void AsyncWebSocketClient::_runQueue() {
|
|||
}
|
||||
|
||||
bool AsyncWebSocketClient::queueIsFull() const {
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_lock);
|
||||
#endif
|
||||
return (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED);
|
||||
}
|
||||
|
||||
size_t AsyncWebSocketClient::queueLen() const {
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_lock);
|
||||
#endif
|
||||
return _messageQueue.size();
|
||||
}
|
||||
|
||||
bool AsyncWebSocketClient::canSend() const {
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_lock);
|
||||
#endif
|
||||
return _messageQueue.size() < WS_MAX_QUEUED_MESSAGES;
|
||||
}
|
||||
|
||||
|
@ -380,7 +394,9 @@ bool AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t* data, si
|
|||
if (!_client)
|
||||
return false;
|
||||
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_lock);
|
||||
#endif
|
||||
|
||||
_controlQueue.emplace_back(opcode, data, len, mask);
|
||||
|
||||
|
@ -394,7 +410,9 @@ bool AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint
|
|||
if (!_client || buffer->size() == 0 || _status != WS_CONNECTED)
|
||||
return false;
|
||||
|
||||
#ifdef ESP32
|
||||
std::lock_guard<std::mutex> lock(_lock);
|
||||
#endif
|
||||
|
||||
if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) {
|
||||
if (closeWhenFull) {
|
||||
|
@ -402,10 +420,19 @@ bool AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint
|
|||
|
||||
if (_client)
|
||||
_client->close(true);
|
||||
|
||||
#ifdef ESP8266
|
||||
ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: closing connection\n");
|
||||
#elif defined(ESP32)
|
||||
log_e("Too many messages queued: closing connection");
|
||||
#endif
|
||||
|
||||
} else {
|
||||
#ifdef ESP8266
|
||||
ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: discarding new message\n");
|
||||
#elif defined(ESP32)
|
||||
log_e("Too many messages queued: discarding new message");
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -599,6 +626,30 @@ size_t AsyncWebSocketClient::printf(const char* format, ...) {
|
|||
return enqueued ? len : 0;
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) {
|
||||
va_list arg;
|
||||
va_start(arg, formatP);
|
||||
size_t len = vsnprintf_P(nullptr, 0, formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
char* buffer = new char[len + 1];
|
||||
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
va_start(arg, formatP);
|
||||
len = vsnprintf_P(buffer, len + 1, formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
bool enqueued = text(buffer, len);
|
||||
delete[] buffer;
|
||||
return enqueued ? len : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
AsyncWebSocketSharedBuffer makeSharedBuffer(const uint8_t* message, size_t len) {
|
||||
|
@ -637,6 +688,28 @@ bool AsyncWebSocketClient::text(const String& message) {
|
|||
return text(message.c_str(), message.length());
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
bool AsyncWebSocketClient::text(const __FlashStringHelper* data) {
|
||||
PGM_P p = reinterpret_cast<PGM_P>(data);
|
||||
|
||||
size_t n = 0;
|
||||
while (1) {
|
||||
if (pgm_read_byte(p + n) == 0)
|
||||
break;
|
||||
n += 1;
|
||||
}
|
||||
|
||||
char* message = (char*)malloc(n + 1);
|
||||
bool enqueued = false;
|
||||
if (message) {
|
||||
memcpy_P(message, p, n);
|
||||
message[n] = 0;
|
||||
enqueued = text(message, n);
|
||||
free(message);
|
||||
}
|
||||
return enqueued;
|
||||
}
|
||||
#endif // ESP8266
|
||||
|
||||
bool AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer* buffer) {
|
||||
bool enqueued = false;
|
||||
|
@ -667,6 +740,19 @@ bool AsyncWebSocketClient::binary(const String& message) {
|
|||
return binary(message.c_str(), message.length());
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
bool AsyncWebSocketClient::binary(const __FlashStringHelper* data, size_t len) {
|
||||
PGM_P p = reinterpret_cast<PGM_P>(data);
|
||||
char* message = (char*)malloc(len);
|
||||
bool enqueued = false;
|
||||
if (message) {
|
||||
memcpy_P(message, p, len);
|
||||
enqueued = binary(message, len);
|
||||
free(message);
|
||||
}
|
||||
return enqueued;
|
||||
}
|
||||
#endif
|
||||
|
||||
IPAddress AsyncWebSocketClient::remoteIP() const {
|
||||
if (!_client)
|
||||
|
@ -774,6 +860,29 @@ bool AsyncWebSocket::text(uint32_t id, const String& message) {
|
|||
return text(id, message.c_str(), message.length());
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
bool AsyncWebSocket::text(uint32_t id, const __FlashStringHelper* data) {
|
||||
PGM_P p = reinterpret_cast<PGM_P>(data);
|
||||
|
||||
size_t n = 0;
|
||||
while (true) {
|
||||
if (pgm_read_byte(p + n) == 0)
|
||||
break;
|
||||
n += 1;
|
||||
}
|
||||
|
||||
char* message = (char*)malloc(n + 1);
|
||||
bool enqueued = false;
|
||||
if (message) {
|
||||
memcpy_P(message, p, n);
|
||||
message[n] = 0;
|
||||
enqueued = text(id, message, n);
|
||||
free(message);
|
||||
}
|
||||
return enqueued;
|
||||
}
|
||||
#endif // ESP8266
|
||||
|
||||
bool AsyncWebSocket::text(uint32_t id, AsyncWebSocketMessageBuffer* buffer) {
|
||||
bool enqueued = false;
|
||||
if (buffer) {
|
||||
|
@ -799,6 +908,28 @@ AsyncWebSocket::SendStatus AsyncWebSocket::textAll(const char* message) {
|
|||
AsyncWebSocket::SendStatus AsyncWebSocket::textAll(const String& message) {
|
||||
return textAll(message.c_str(), message.length());
|
||||
}
|
||||
#ifdef ESP8266
|
||||
AsyncWebSocket::SendStatus AsyncWebSocket::textAll(const __FlashStringHelper* data) {
|
||||
PGM_P p = reinterpret_cast<PGM_P>(data);
|
||||
|
||||
size_t n = 0;
|
||||
while (1) {
|
||||
if (pgm_read_byte(p + n) == 0)
|
||||
break;
|
||||
n += 1;
|
||||
}
|
||||
|
||||
char* message = (char*)malloc(n + 1);
|
||||
AsyncWebSocket::SendStatus status = DISCARDED;
|
||||
if (message) {
|
||||
memcpy_P(message, p, n);
|
||||
message[n] = 0;
|
||||
status = textAll(message, n);
|
||||
free(message);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif // ESP8266
|
||||
AsyncWebSocket::SendStatus AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer* buffer) {
|
||||
AsyncWebSocket::SendStatus status = DISCARDED;
|
||||
if (buffer) {
|
||||
|
@ -833,6 +964,19 @@ bool AsyncWebSocket::binary(uint32_t id, const String& message) {
|
|||
return binary(id, message.c_str(), message.length());
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
bool AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper* data, size_t len) {
|
||||
PGM_P p = reinterpret_cast<PGM_P>(data);
|
||||
char* message = (char*)malloc(len);
|
||||
bool enqueued = false;
|
||||
if (message) {
|
||||
memcpy_P(message, p, len);
|
||||
enqueued = binary(id, message, len);
|
||||
free(message);
|
||||
}
|
||||
return enqueued;
|
||||
}
|
||||
#endif // ESP8266
|
||||
|
||||
bool AsyncWebSocket::binary(uint32_t id, AsyncWebSocketMessageBuffer* buffer) {
|
||||
bool enqueued = false;
|
||||
|
@ -860,6 +1004,20 @@ AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(const String& message) {
|
|||
return binaryAll(message.c_str(), message.length());
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(const __FlashStringHelper* data, size_t len) {
|
||||
PGM_P p = reinterpret_cast<PGM_P>(data);
|
||||
char* message = (char*)malloc(len);
|
||||
AsyncWebSocket::SendStatus status = DISCARDED;
|
||||
if (message) {
|
||||
memcpy_P(message, p, len);
|
||||
status = binaryAll(message, len);
|
||||
free(message);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif // ESP8266
|
||||
|
||||
AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer* buffer) {
|
||||
AsyncWebSocket::SendStatus status = DISCARDED;
|
||||
if (buffer) {
|
||||
|
@ -914,6 +1072,43 @@ size_t AsyncWebSocket::printfAll(const char* format, ...) {
|
|||
return status == DISCARDED ? 0 : len;
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...) {
|
||||
AsyncWebSocketClient* c = client(id);
|
||||
if (c != NULL) {
|
||||
va_list arg;
|
||||
va_start(arg, formatP);
|
||||
size_t len = c->printf_P(formatP, arg);
|
||||
va_end(arg);
|
||||
return len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) {
|
||||
va_list arg;
|
||||
va_start(arg, formatP);
|
||||
size_t len = vsnprintf_P(nullptr, 0, formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
char* buffer = new char[len + 1];
|
||||
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
va_start(arg, formatP);
|
||||
len = vsnprintf_P(buffer, len + 1, formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
AsyncWebSocket::SendStatus status = textAll(buffer, len);
|
||||
delete[] buffer;
|
||||
return status == DISCARDED ? 0 : len;
|
||||
}
|
||||
#endif
|
||||
|
||||
const char __WS_STR_CONNECTION[] PROGMEM = {"Connection"};
|
||||
const char __WS_STR_UPGRADE[] PROGMEM = {"Upgrade"};
|
||||
const char __WS_STR_ORIGIN[] PROGMEM = {"Origin"};
|
|
@ -22,18 +22,41 @@
|
|||
#define ASYNCWEBSOCKET_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "../../mathieucarbou-AsyncTCPSock/src/AsyncTCP.h"
|
||||
#ifdef ESP32
|
||||
#include "../../mathieucarbou-AsyncTCPSock/src/AsyncTCP.h"
|
||||
#include <mutex>
|
||||
#ifndef WS_MAX_QUEUED_MESSAGES
|
||||
#define WS_MAX_QUEUED_MESSAGES 32
|
||||
#endif
|
||||
#elif defined(ESP8266)
|
||||
#include <ESPAsyncTCP.h>
|
||||
#ifndef WS_MAX_QUEUED_MESSAGES
|
||||
#define WS_MAX_QUEUED_MESSAGES 8
|
||||
#endif
|
||||
#elif defined(TARGET_RP2040)
|
||||
#include <AsyncTCP_RP2040W.h>
|
||||
#ifndef WS_MAX_QUEUED_MESSAGES
|
||||
#define WS_MAX_QUEUED_MESSAGES 32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "ESPAsyncWebServer.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef ESP8266
|
||||
#include <Hash.h>
|
||||
#ifdef CRYPTO_HASH_h // include Hash.h from espressif framework if the first include was from the crypto library
|
||||
#include <../src/Hash.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_MAX_WS_CLIENTS
|
||||
#ifdef ESP32
|
||||
#define DEFAULT_MAX_WS_CLIENTS 8
|
||||
#else
|
||||
#define DEFAULT_MAX_WS_CLIENTS 4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using AsyncWebSocketSharedBuffer = std::shared_ptr<std::vector<uint8_t>>;
|
||||
|
@ -129,7 +152,9 @@ class AsyncWebSocketClient {
|
|||
AsyncWebSocket* _server;
|
||||
uint32_t _clientId;
|
||||
AwsClientStatus _status;
|
||||
#ifdef ESP32
|
||||
mutable std::mutex _lock;
|
||||
#endif
|
||||
std::deque<AsyncWebSocketControl> _controlQueue;
|
||||
std::deque<AsyncWebSocketMessage> _messageQueue;
|
||||
bool closeWhenFull = true;
|
||||
|
@ -229,6 +254,11 @@ class AsyncWebSocketClient {
|
|||
void _onDisconnect();
|
||||
void _onData(void* pbuf, size_t plen);
|
||||
|
||||
#ifdef ESP8266
|
||||
size_t printf_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3)));
|
||||
bool text(const __FlashStringHelper* message);
|
||||
bool binary(const __FlashStringHelper* message, size_t len);
|
||||
#endif
|
||||
};
|
||||
|
||||
using AwsHandshakeHandler = std::function<bool(AsyncWebServerRequest* request)>;
|
||||
|
@ -243,8 +273,9 @@ class AsyncWebSocket : public AsyncWebHandler {
|
|||
AwsEventHandler _eventHandler{nullptr};
|
||||
AwsHandshakeHandler _handshakeHandler;
|
||||
bool _enabled;
|
||||
#ifdef ESP32
|
||||
mutable std::mutex _lock;
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef enum {
|
||||
|
@ -304,6 +335,15 @@ class AsyncWebSocket : public AsyncWebHandler {
|
|||
size_t printf(uint32_t id, const char* format, ...) __attribute__((format(printf, 3, 4)));
|
||||
size_t printfAll(const char* format, ...) __attribute__((format(printf, 2, 3)));
|
||||
|
||||
#ifdef ESP8266
|
||||
bool text(uint32_t id, const __FlashStringHelper* message);
|
||||
SendStatus textAll(const __FlashStringHelper* message);
|
||||
bool binary(uint32_t id, const __FlashStringHelper* message, size_t len);
|
||||
SendStatus binaryAll(const __FlashStringHelper* message, size_t len);
|
||||
size_t printf_P(uint32_t id, PGM_P formatP, ...) __attribute__((format(printf, 3, 4)));
|
||||
size_t printfAll_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3)));
|
||||
#endif
|
||||
|
||||
void onEvent(AwsEventHandler handler) { _eventHandler = handler; }
|
||||
void handleHandshake(AwsHandshakeHandler handler) { _handshakeHandler = handler; }
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
#include <vector>
|
||||
|
||||
#ifdef ESP32
|
||||
#include "../../mathieucarbou-AsyncTCPSock/src/AsyncTCP.h"
|
||||
#include "../../mathieucarbou-AsyncTCPSock/src/AsyncTCP.h"
|
||||
#include <WiFi.h>
|
||||
#elif defined(ESP8266)
|
||||
#include <ESP8266WiFi.h>
|
||||
|
@ -48,11 +48,11 @@
|
|||
|
||||
#include "literals.h"
|
||||
|
||||
#define ASYNCWEBSERVER_VERSION "3.6.0"
|
||||
#define ASYNCWEBSERVER_VERSION "3.6.2"
|
||||
#define ASYNCWEBSERVER_VERSION_MAJOR 3
|
||||
#define ASYNCWEBSERVER_VERSION_MINOR 6
|
||||
#define ASYNCWEBSERVER_VERSION_REVISION 0
|
||||
#define ASYNCWEBSERVER_FORK_mathieucarbou
|
||||
#define ASYNCWEBSERVER_VERSION_REVISION 2
|
||||
#define ASYNCWEBSERVER_FORK_ESP32Async
|
||||
|
||||
#ifdef ASYNCWEBSERVER_REGEX
|
||||
#define ASYNCWEBSERVER_REGEX_ATTRIBUTE
|
||||
|
@ -60,6 +60,12 @@
|
|||
#define ASYNCWEBSERVER_REGEX_ATTRIBUTE __attribute__((warning("ASYNCWEBSERVER_REGEX not defined")))
|
||||
#endif
|
||||
|
||||
// See https://github.com/ESP32Async/ESPAsyncWebServer/commit/3d3456e9e81502a477f6498c44d0691499dda8f9#diff-646b25b11691c11dce25529e3abce843f0ba4bd07ab75ec9eee7e72b06dbf13fR388-R392
|
||||
// This setting slowdown chunk serving but avoids crashing or deadlocks in the case where slow chunk responses are created, like file serving form SD Card
|
||||
#ifndef ASYNCWEBSERVER_USE_CHUNK_INFLIGHT
|
||||
#define ASYNCWEBSERVER_USE_CHUNK_INFLIGHT 1
|
||||
#endif
|
||||
|
||||
class AsyncWebServer;
|
||||
class AsyncWebServerRequest;
|
||||
class AsyncWebServerResponse;
|
||||
|
@ -83,7 +89,6 @@ typedef enum {
|
|||
HTTP_ANY = 0b01111111,
|
||||
} WebRequestMethod;
|
||||
|
||||
|
||||
#ifndef HAVE_FS_FILE_OPEN_MODE
|
||||
namespace fs {
|
||||
class FileOpenMode {
|
||||
|
@ -398,6 +403,9 @@ class AsyncWebServerRequest {
|
|||
const AsyncWebParameter* getParam(const char* name, bool post = false, bool file = false) const;
|
||||
|
||||
const AsyncWebParameter* getParam(const String& name, bool post = false, bool file = false) const { return getParam(name.c_str(), post, file); };
|
||||
#ifdef ESP8266
|
||||
const AsyncWebParameter* getParam(const __FlashStringHelper* data, bool post, bool file) const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get request parameter by number
|
||||
|
@ -413,10 +421,16 @@ class AsyncWebServerRequest {
|
|||
const String& arg(const char* name) const;
|
||||
// get request argument value by name
|
||||
const String& arg(const String& name) const { return arg(name.c_str()); };
|
||||
#ifdef ESP8266
|
||||
const String& arg(const __FlashStringHelper* data) const; // get request argument value by F(name)
|
||||
#endif
|
||||
const String& arg(size_t i) const; // get request argument value by number
|
||||
const String& argName(size_t i) const; // get request argument name by number
|
||||
bool hasArg(const char* name) const; // check if argument exists
|
||||
bool hasArg(const String& name) const { return hasArg(name.c_str()); };
|
||||
#ifdef ESP8266
|
||||
bool hasArg(const __FlashStringHelper* data) const; // check if F(argument) exists
|
||||
#endif
|
||||
|
||||
const String& ASYNCWEBSERVER_REGEX_ATTRIBUTE pathArg(size_t i) const;
|
||||
|
||||
|
@ -424,6 +438,9 @@ class AsyncWebServerRequest {
|
|||
const String& header(const char* name) const;
|
||||
const String& header(const String& name) const { return header(name.c_str()); };
|
||||
|
||||
#ifdef ESP8266
|
||||
const String& header(const __FlashStringHelper* data) const; // get request header value by F(name)
|
||||
#endif
|
||||
|
||||
const String& header(size_t i) const; // get request header value by number
|
||||
const String& headerName(size_t i) const; // get request header name by number
|
||||
|
@ -433,9 +450,15 @@ class AsyncWebServerRequest {
|
|||
// check if header exists
|
||||
bool hasHeader(const char* name) const;
|
||||
bool hasHeader(const String& name) const { return hasHeader(name.c_str()); };
|
||||
#ifdef ESP8266
|
||||
bool hasHeader(const __FlashStringHelper* data) const; // check if header exists
|
||||
#endif
|
||||
|
||||
const AsyncWebHeader* getHeader(const char* name) const;
|
||||
const AsyncWebHeader* getHeader(const String& name) const { return getHeader(name.c_str()); };
|
||||
#ifdef ESP8266
|
||||
const AsyncWebHeader* getHeader(const __FlashStringHelper* data) const;
|
||||
#endif
|
||||
|
||||
const AsyncWebHeader* getHeader(size_t num) const;
|
||||
|
||||
|
@ -452,6 +475,9 @@ class AsyncWebServerRequest {
|
|||
size_t params() const; // get arguments count
|
||||
bool hasParam(const char* name, bool post = false, bool file = false) const;
|
||||
bool hasParam(const String& name, bool post = false, bool file = false) const { return hasParam(name.c_str(), post, file); };
|
||||
#ifdef ESP8266
|
||||
bool hasParam(const __FlashStringHelper* data, bool post = false, bool file = false) const { return hasParam(String(data).c_str(), post, file); };
|
||||
#endif
|
||||
|
||||
// REQUEST ATTRIBUTES
|
||||
|
|
@ -93,7 +93,11 @@ static bool getMD5(uint8_t* data, uint16_t len, char* output) { // 33 bytes or m
|
|||
}
|
||||
|
||||
String genRandomMD5() {
|
||||
#ifdef ESP8266
|
||||
uint32_t r = RANDOM_REG32;
|
||||
#else
|
||||
uint32_t r = rand();
|
||||
#endif
|
||||
char* out = (char*)malloc(33);
|
||||
if (out == NULL || !getMD5((uint8_t*)(&r), 4, out))
|
||||
return emptyString;
|
|
@ -86,7 +86,13 @@ AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(const char* last_m
|
|||
|
||||
AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(struct tm* last_modified) {
|
||||
char result[30];
|
||||
#ifdef ESP8266
|
||||
auto formatP = PSTR("%a, %d %b %Y %H:%M:%S GMT");
|
||||
char format[strlen_P(formatP) + 1];
|
||||
strcpy_P(format, formatP);
|
||||
#else
|
||||
static constexpr const char* format = "%a, %d %b %Y %H:%M:%S GMT";
|
||||
#endif
|
||||
|
||||
strftime(result, sizeof(result), format, last_modified);
|
||||
_last_modified = result;
|
||||
|
@ -133,7 +139,11 @@ bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest* request) const {
|
|||
return const_cast<AsyncStaticWebHandler*>(this)->_searchFile(request, path);
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
#define FILE_IS_REAL(f) (f == true && !f.isDirectory())
|
||||
#else
|
||||
#define FILE_IS_REAL(f) (f == true)
|
||||
#endif
|
||||
|
||||
bool AsyncStaticWebHandler::_searchFile(AsyncWebServerRequest* request, const String& path) {
|
||||
bool fileFound = false;
|
||||
|
@ -298,6 +308,7 @@ void AsyncCallbackWebHandler::handleUpload(AsyncWebServerRequest* request, const
|
|||
_onUpload(request, filename, index, data, len, final);
|
||||
}
|
||||
void AsyncCallbackWebHandler::handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) {
|
||||
// ESP_LOGD("AsyncWebServer", "AsyncCallbackWebHandler::handleBody");
|
||||
if (_onBody)
|
||||
_onBody(request, data, len, index, total);
|
||||
}
|
|
@ -70,7 +70,9 @@ void AsyncWebServerRequest::_onData(void* buf, size_t len) {
|
|||
// SSL/TLS handshake detection
|
||||
#ifndef ASYNC_TCP_SSL_ENABLED
|
||||
if (_parseState == PARSE_REQ_START && len && ((uint8_t*)buf)[0] == 0x16) { // 0x16 indicates a Handshake message (SSL/TLS).
|
||||
#ifdef ESP32
|
||||
log_d("SSL/TLS handshake detected: resetting connection");
|
||||
#endif
|
||||
_parseState = PARSE_REQ_FAIL;
|
||||
_client->abort();
|
||||
return;
|
||||
|
@ -139,6 +141,7 @@ void AsyncWebServerRequest::_onData(void* buf, size_t len) {
|
|||
}
|
||||
}
|
||||
if (!_isPlainPost) {
|
||||
// ESP_LOGD("AsyncWebServer", "_isPlainPost: %d, _handler: %p", _isPlainPost, _handler);
|
||||
if (_handler)
|
||||
_handler->handleBody(this, (uint8_t*)buf, len, _parsedLength, _contentLength);
|
||||
_parsedLength += len;
|
||||
|
@ -641,11 +644,32 @@ bool AsyncWebServerRequest::hasHeader(const char* name) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
bool AsyncWebServerRequest::hasHeader(const __FlashStringHelper* data) const {
|
||||
return hasHeader(String(data));
|
||||
}
|
||||
#endif
|
||||
|
||||
const AsyncWebHeader* AsyncWebServerRequest::getHeader(const char* name) const {
|
||||
auto iter = std::find_if(std::begin(_headers), std::end(_headers), [&name](const AsyncWebHeader& header) { return header.name().equalsIgnoreCase(name); });
|
||||
return (iter == std::end(_headers)) ? nullptr : &(*iter);
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
const AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper* data) const {
|
||||
PGM_P p = reinterpret_cast<PGM_P>(data);
|
||||
size_t n = strlen_P(p);
|
||||
char* name = (char*)malloc(n + 1);
|
||||
if (name) {
|
||||
strcpy_P(name, p);
|
||||
const AsyncWebHeader* result = getHeader(String(name));
|
||||
free(name);
|
||||
return result;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) const {
|
||||
if (num >= _headers.size())
|
||||
|
@ -690,6 +714,11 @@ const AsyncWebParameter* AsyncWebServerRequest::getParam(const char* name, bool
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
const AsyncWebParameter* AsyncWebServerRequest::getParam(const __FlashStringHelper* data, bool post, bool file) const {
|
||||
return getParam(String(data), post, file);
|
||||
}
|
||||
#endif
|
||||
|
||||
const AsyncWebParameter* AsyncWebServerRequest::getParam(size_t num) const {
|
||||
if (num >= _params.size())
|
||||
|
@ -858,6 +887,12 @@ bool AsyncWebServerRequest::hasArg(const char* name) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
bool AsyncWebServerRequest::hasArg(const __FlashStringHelper* data) const {
|
||||
return hasArg(String(data).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
const String& AsyncWebServerRequest::arg(const char* name) const {
|
||||
for (const auto& arg : _params) {
|
||||
if (arg.name() == name) {
|
||||
|
@ -867,6 +902,12 @@ const String& AsyncWebServerRequest::arg(const char* name) const {
|
|||
return emptyString;
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
const String& AsyncWebServerRequest::arg(const __FlashStringHelper* data) const {
|
||||
return arg(String(data).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
const String& AsyncWebServerRequest::arg(size_t i) const {
|
||||
return getParam(i)->value();
|
||||
}
|
||||
|
@ -884,6 +925,12 @@ const String& AsyncWebServerRequest::header(const char* name) const {
|
|||
return h ? h->value() : emptyString;
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
const String& AsyncWebServerRequest::header(const __FlashStringHelper* data) const {
|
||||
return header(String(data).c_str());
|
||||
};
|
||||
#endif
|
||||
|
||||
const String& AsyncWebServerRequest::header(size_t i) const {
|
||||
const AsyncWebHeader* h = getHeader(i);
|
||||
return h ? h->value() : emptyString;
|
|
@ -47,10 +47,12 @@ class AsyncBasicResponse : public AsyncWebServerResponse {
|
|||
|
||||
class AsyncAbstractResponse : public AsyncWebServerResponse {
|
||||
private:
|
||||
#if ASYNCWEBSERVER_USE_CHUNK_INFLIGHT
|
||||
// amount of responce data in-flight, i.e. sent, but not acked yet
|
||||
size_t _in_flight{0};
|
||||
// in-flight queue credits
|
||||
size_t _in_flight_credit{2};
|
||||
#endif
|
||||
String _head;
|
||||
// Data is inserted into cache at begin().
|
||||
// This is inefficient with vector, but if we use some other container,
|
|
@ -205,7 +205,11 @@ void AsyncWebServerResponse::_assembleHead(String& buffer, uint8_t version) {
|
|||
buffer.reserve(len);
|
||||
|
||||
// HTTP header
|
||||
#ifdef ESP8266
|
||||
buffer.concat(PSTR("HTTP/1."));
|
||||
#else
|
||||
buffer.concat("HTTP/1.");
|
||||
#endif
|
||||
buffer.concat(version);
|
||||
buffer.concat(' ');
|
||||
buffer.concat(_code);
|
||||
|
@ -216,7 +220,11 @@ void AsyncWebServerResponse::_assembleHead(String& buffer, uint8_t version) {
|
|||
// Add headers
|
||||
for (const auto& header : _headers) {
|
||||
buffer.concat(header.name());
|
||||
#ifdef ESP8266
|
||||
buffer.concat(PSTR(": "));
|
||||
#else
|
||||
buffer.concat(": ");
|
||||
#endif
|
||||
buffer.concat(header.value());
|
||||
buffer.concat(T_rn);
|
||||
}
|
||||
|
@ -344,19 +352,25 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest* request, size_t len, u
|
|||
request->client()->close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if ASYNCWEBSERVER_USE_CHUNK_INFLIGHT
|
||||
// return a credit for each chunk of acked data (polls does not give any credits)
|
||||
if (len)
|
||||
++_in_flight_credit;
|
||||
|
||||
// for chunked responses ignore acks if there are no _in_flight_credits left
|
||||
if (_chunked && !_in_flight_credit) {
|
||||
#ifdef ESP32
|
||||
log_d("(chunk) out of in-flight credits");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
_ackedLength += len;
|
||||
_in_flight -= (_in_flight > len) ? len : _in_flight;
|
||||
// get the size of available sock space
|
||||
#endif
|
||||
|
||||
_ackedLength += len;
|
||||
size_t space = request->client()->space();
|
||||
|
||||
size_t headLen = _head.length();
|
||||
|
@ -368,13 +382,16 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest* request, size_t len, u
|
|||
String out = _head.substring(0, space);
|
||||
_head = _head.substring(space);
|
||||
_writtenLength += request->client()->write(out.c_str(), out.length());
|
||||
#if ASYNCWEBSERVER_USE_CHUNK_INFLIGHT
|
||||
_in_flight += out.length();
|
||||
--_in_flight_credit; // take a credit
|
||||
#endif
|
||||
return out.length();
|
||||
}
|
||||
}
|
||||
|
||||
if (_state == RESPONSE_CONTENT) {
|
||||
#if ASYNCWEBSERVER_USE_CHUNK_INFLIGHT
|
||||
// for response data we need to control the queue and in-flight fragmentation. Sending small chunks could give low latency,
|
||||
// but flood asynctcp's queue and fragment socket buffer space for large responses.
|
||||
// Let's ignore polled acks and acks in case when we have more in-flight data then the available socket buff space.
|
||||
|
@ -386,6 +403,7 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest* request, size_t len, u
|
|||
--_in_flight_credit;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t outLen;
|
||||
if (_chunked) {
|
||||
|
@ -441,8 +459,10 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest* request, size_t len, u
|
|||
|
||||
if (outLen) {
|
||||
_writtenLength += request->client()->write((const char*)buf, outLen);
|
||||
#if ASYNCWEBSERVER_USE_CHUNK_INFLIGHT
|
||||
_in_flight += outLen;
|
||||
--_in_flight_credit; // take a credit
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_chunked) {
|
|
@ -153,7 +153,7 @@ void AsyncWebServer::_attachHandler(AsyncWebServerRequest* request) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ESP_LOGD("AsyncWebServer", "No handler found for %s, using _catchAllHandler pointer: %p", request->url().c_str(), _catchAllHandler);
|
||||
request->setHandler(_catchAllHandler);
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ _____ _ _ ___ _____ _
|
|||
#include "StreamString.h"
|
||||
#if ELEGANTOTA_USE_ASYNC_WEBSERVER == 1
|
||||
#include "../../mathieucarbou-AsyncTCPSock/src/AsyncTCP.h"
|
||||
#include "../../mathieucarbou-ESPAsyncWebServer/src/ESPAsyncWebServer.h"
|
||||
#include "../../ESP32Async-ESPAsyncWebServer/src/ESPAsyncWebServer.h"
|
||||
#define ELEGANTOTA_WEBSERVER AsyncWebServer
|
||||
#else
|
||||
#include "WiFi.h"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue