diff --git a/README.md b/README.md new file mode 100644 index 0000000..1b2b8d4 --- /dev/null +++ b/README.md @@ -0,0 +1,2197 @@ +# AsyncWebServer_ESP32_SC_W6100 Library + +[![arduino-library-badge](https://www.ardu-badge.com/badge/AsyncWebServer_ESP32_SC_W6100.svg?)](https://www.ardu-badge.com/AsyncWebServer_ESP32_SC_W6100) +[![GitHub release](https://img.shields.io/github/release/khoih-prog/AsyncWebServer_ESP32_SC_W6100.svg)](https://github.com/khoih-prog/AsyncWebServer_ESP32_SC_W6100/releases) +[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing) +[![GitHub issues](https://img.shields.io/github/issues/khoih-prog/AsyncWebServer_ESP32_SC_W6100.svg)](http://github.com/khoih-prog/AsyncWebServer_ESP32_SC_W6100/issues) + + + + + + +--- +--- + +## Table of contents + +* [Important Note](#Important-Note) +* [Why do we need this AsyncWebServer_ESP32_SC_W6100 library](#why-do-we-need-this-AsyncWebServer_ESP32_SC_W6100-library) + * [Features](#features) + * [Why Async is better](#why-async-is-better) + * [Currently supported Boards](#currently-supported-boards) +* [Changelog](changelog.md) +* [Prerequisites](#prerequisites) +* [Installation](#installation) + * [Use Arduino Library Manager](#use-arduino-library-manager) + * [Manual Install](#manual-install) + * [VS Code & PlatformIO](#vs-code--platformio) +* [Important things to remember](#important-things-to-remember) +* [Principles of operation](#principles-of-operation) + * [The Async Web server](#the-async-web-server) + * [Request Life Cycle](#request-life-cycle) + * [Rewrites and how do they work](#rewrites-and-how-do-they-work) + * [Handlers and how do they work](#handlers-and-how-do-they-work) + * [Responses and how do they work](#responses-and-how-do-they-work) + * [Template processing](#template-processing) +* [Request Variables](#request-variables) + * [Common Variables](#common-variables) + * [Headers](#headers) + * [GET, POST and FILE parameters](#get-post-and-file-parameters) + * [JSON body handling with ArduinoJson](#json-body-handling-with-arduinojson) +* [Responses](#responses) + * [Redirect to another URL](#redirect-to-another-url) + * [Basic response with HTTP Code](#basic-response-with-http-code) + * [Basic response with HTTP Code and extra headers](#basic-response-with-http-code-and-extra-headers) + * [Basic response with string content](#basic-response-with-string-content) + * [Basic response with string content and extra headers](#basic-response-with-string-content-and-extra-headers) + * [Respond with content coming from a Stream](#respond-with-content-coming-from-a-stream) + * [Respond with content coming from a Stream and extra headers](#respond-with-content-coming-from-a-stream-and-extra-headers) + * [Respond with content coming from a Stream containing templates](#respond-with-content-coming-from-a-stream-containing-templates) + * [Respond with content coming from a Stream containing templates and extra headers](#respond-with-content-coming-from-a-stream-containing-templates-and-extra-headers) + * [Respond with content using a callback](#respond-with-content-using-a-callback) + * [Respond with content using a callback and extra headers](#respond-with-content-using-a-callback-and-extra-headers) + * [Respond with content using a callback containing templates](#respond-with-content-using-a-callback-containing-templates) + * [Respond with content using a callback containing templates and extra headers](#respond-with-content-using-a-callback-containing-templates-and-extra-headers) + * [Chunked Response](#chunked-response) + * [Chunked Response containing templates](#chunked-response-containing-templates) + * [Print to response](#print-to-response) + * [ArduinoJson Basic Response](#arduinojson-basic-response) + * [ArduinoJson Advanced Response](#arduinojson-advanced-response) +* [Param Rewrite With Matching](#param-rewrite-with-matching) +* [Using filters](#using-filters) +* [Bad Responses](#bad-responses) + * [Respond with content using a callback without content length to HTTP/1.0 clients](#respond-with-content-using-a-callback-without-content-length-to-http10-clients) +* [Async WebSocket Plugin](#async-websocket-plugin) + * [Async WebSocket Event](#async-websocket-event) + * [Methods for sending data to a socket client](#methods-for-sending-data-to-a-socket-client) + * [Direct access to web socket message buffer](#direct-access-to-web-socket-message-buffer) + * [Limiting the number of web socket clients](#limiting-the-number-of-web-socket-clients) +* [Async Event Source Plugin](#async-event-source-plugin) + * [Setup Event Source on the server](#setup-event-source-on-the-server) + * [Setup Event Source in the browser](#setup-event-source-in-the-browser) +* [Remove handlers and rewrites](#remove-handlers-and-rewrites) +* [Setting up the server](#setting-up-the-server) + * [Setup global and class functions as request handlers](#setup-global-and-class-functions-as-request-handlers) + * [Methods for controlling websocket connections](#methods-for-controlling-websocket-connections) + * [Adding Default Headers](#adding-default-headers) + * [Path variable](#path-variable) +* [How to connect W6100 to ESP32_S2/S3/C3](#How-to-connect-W6100-to-ESP32_S2S3C3) +* [Examples](#examples) + * [ 1. Async_AdvancedWebServer](examples/Async_AdvancedWebServer) + * [ 2. Async_AdvancedWebServer_MemoryIssues_SendArduinoString](examples/Async_AdvancedWebServer_MemoryIssues_SendArduinoString) + * [ 3. Async_AdvancedWebServer_MemoryIssues_Send_CString](examples/Async_AdvancedWebServer_MemoryIssues_Send_CString) + * [ 4. Async_AdvancedWebServer_SendChunked](examples/Async_AdvancedWebServer_SendChunked) + * [ 5. Async_HelloServer](examples/Async_HelloServer) + * [ 6. Async_HelloServer2](examples/Async_HelloServer2) + * [ 7. Async_HttpBasicAuth](examples/Async_HttpBasicAuth) + * [ 8. AsyncMultiWebServer_ESP32_W6100](examples/AsyncMultiWebServer_ESP32_W6100) + * [ 9. Async_PostServer](examples/Async_PostServer) + * [10. Async_RegexPatterns_ESP32_W6100](examples/Async_RegexPatterns_ESP32_W6100) + * [11. AsyncSimpleServer_ESP32_W6100](examples/AsyncSimpleServer_ESP32_W6100) + * [12. AsyncWebServer_SendChunked](examples/AsyncWebServer_SendChunked) + * [13. Async_WebSocketsServer](examples/Async_WebSocketsServer) + * [14. MQTTClient_Auth](examples/MQTTClient_Auth) + * [15. MQTTClient_Basic](examples/MQTTClient_Basic) + * [16. MQTT_ThingStream](examples/MQTT_ThingStream) +* [Example Async_AdvancedWebServer](#Example-Async_AdvancedWebServer) +* [Debug Terminal Output Samples](#debug-terminal-output-samples) + * [1. AsyncMultiWebServer_ESP32_W6100 on ESP32S3_DEV with ESP32_S3_W6100](#1-AsyncMultiWebServer_ESP32_W6100-on-ESP32S3_DEV-with-ESP32_S3_W6100) + * [2. Async_AdvancedWebServer_MemoryIssues_Send_CString on ESP32S3_DEV with ESP32_S3_W6100](#2-Async_AdvancedWebServer_MemoryIssues_Send_CString-on-ESP32S3_DEV-with-ESP32_S3_W6100) + * [3. Async_AdvancedWebServer_SendChunked on ESP32S3_DEV with ESP32_S3_W6100](#3-Async_AdvancedWebServer_SendChunked-on-ESP32S3_DEV-with-ESP32_S3_W6100) + * [4. AsyncWebServer_SendChunked on ESP32S3_DEV with ESP32_S3_W6100](#4-AsyncWebServer_SendChunked-on-ESP32S3_DEV-with-ESP32_S3_W6100) + * [5. Async_WebSocketsServer on ESP32S3_DEV with ESP32_S3_W6100](#5-Async_WebSocketsServer-on-ESP32S3_DEV-with-ESP32_S3_W6100) + * [6. Async_HTTPBasicAuth on ESP32S3_DEV with ESP32_S3_W6100](#6-Async_HTTPBasicAuth-on-ESP32S3_DEV-with-ESP32_S3_W6100) + * [7. Async_AdvancedWebServer_SendChunked on ESP32S2_DEV with ESP32_S2_W6100](#7-Async_AdvancedWebServer_SendChunked-on-ESP32S2_DEV-with-ESP32_S2_W6100) + * [8. Async_AdvancedWebServer_SendChunked on ESP32C3_DEV with ESP32_C3_W6100](#8-Async_AdvancedWebServer_SendChunked-on-ESP32C3_DEV-with-ESP32_C3_W6100) +* [Debug](#debug) +* [Troubleshooting](#troubleshooting) +* [Issues](#issues) +* [TO DO](#to-do) +* [DONE](#done) +* [Contributions and Thanks](#contributions-and-thanks) +* [Contributing](#contributing) +* [License](#license) +* [Copyright](#copyright) + +--- +--- + +### Important Note + +The library permits using `CString` to save heap to send `very large data`. + +Check the `marvelleous` PRs of **@salasidis** in [Portenta_H7_AsyncWebServer library](https://github.com/khoih-prog/Portenta_H7_AsyncWebServer) +- [request->send(200, textPlainStr, jsonChartDataCharStr); - Without using String Class - to save heap #8](https://github.com/khoih-prog/Portenta_H7_AsyncWebServer/pull/8) +- [All memmove() removed - string no longer destroyed #11](https://github.com/khoih-prog/Portenta_H7_AsyncWebServer/pull/11) + +and these new examples + +1. [Async_AdvancedWebServer_MemoryIssues_Send_CString](https://github.com/khoih-prog/AsyncWebServer_ESP32_SC_W6100/tree/main/examples/Async_AdvancedWebServer_MemoryIssues_Send_CString) +2. [Async_AdvancedWebServer_MemoryIssues_SendArduinoString](https://github.com/khoih-prog/AsyncWebServer_ESP32_SC_W6100/tree/main/examples/Async_AdvancedWebServer_MemoryIssues_SendArduinoString) + +If using Arduino String, to send a buffer around `30 KBytes`, the used `Max Heap` is around **142,972 bytes** + +If using CString in regular memory, with the same `30 KBytes`, the used `Max Heap` is around **113,396 bytes, saving around a buffer size (30 KBytes)** + +This is very critical in use-cases where sending `very large data` is necessary, without `heap-allocation-error`. + + +1. The traditional function used to send `Arduino String` is + + +```cpp +void send(int code, const String& contentType = String(), const String& content = String()); +``` + +such as + +```cpp +request->send(200, textPlainStr, ArduinoStr); +``` +The required additional HEAP is about **3 times of the String size** + + +2. To use `CString` with copying while sending. Use function + + +```cpp +void send(int code, const String& contentType, const char *content, bool nonDetructiveSend = true); // RSMOD +``` + +such as + +```cpp +request->send(200, textPlainStr, cStr); +``` + +The required additional HEAP is also about **2 times of the CString size** because of `unnecessary copies` of the CString in HEAP. Avoid this `unefficient` way. + + +3. To use `CString` without copying while sending. Use function + + +```cpp +void send(int code, const String& contentType, const char *content, bool nonDetructiveSend = true); // RSMOD +``` + +such as + +```cpp +request->send(200, textPlainStr, cStr, false); +``` + +The required additional HEAP is about **1 times of the CString size**. This way is the best and **most efficient way** to use by avoiding of `unnecessary copies` of the CString in HEAP + + +--- +--- + +### Why do we need this [AsyncWebServer_ESP32_SC_W6100 library](https://github.com/khoih-prog/AsyncWebServer_ESP32_SC_W6100) + + +#### Features + +This library is based on, modified from: + +1. [Hristo Gochkov's ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) + +to apply the better and faster **asynchronous** feature of the **powerful** [ESPAsyncWebServer Library](https://github.com/me-no-dev/ESPAsyncWebServer) into **(ESP32_S2/S3/C3 + LwIP W6100)**. + + +#### Why Async is better + +- Using asynchronous network means that you can handle **more than one connection at the same time** +- **You are called once the request is ready and parsed** +- When you send the response, you are **immediately ready** to handle other connections while the server is taking care of sending the response in the background +- **Speed is OMG** +- **Easy to use API, HTTP Basic and Digest MD5 Authentication (default), ChunkedResponse** +- Easily extensible to handle **any type of content** +- Supports Continue 100 +- **Async WebSocket plugin offering different locations without extra servers or ports** +- Async EventSource (Server-Sent Events) plugin to send events to the browser +- URL Rewrite plugin for conditional and permanent url rewrites +- ServeStatic plugin that supports cache, Last-Modified, default index and more +- Simple template processing engine to handle templates + + +--- + +#### Currently supported Boards + + + 1. **ESP32_S3 boards** using `LwIP W6100 Ethernet` + 2. **ESP32_S2 boards** using `LwIP W6100 Ethernet` + 3. **ESP32_C3 boards** using `LwIP W6100 Ethernet` + + +--- + +#### ESP32S2_DEV + +
+ +
+ + +#### ESP32S3_DEV + ++ +
+ + +#### ESP32C3_DEV + ++ +
+ +--- + +#### W6100 + ++ +
+ + +--- +--- + + +## Prerequisites + + 1. [`Arduino IDE 1.8.19+` for Arduino](https://github.com/arduino/Arduino). [![GitHub release](https://img.shields.io/github/release/arduino/Arduino.svg)](https://github.com/arduino/Arduino/releases/latest) + 2. [`ESP32 Core 2.0.6+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. ESP32 Latest Core [![Latest release](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/) + 3. [`AsyncTCP library v1.1.1+`](https://github.com/me-no-dev/AsyncTCP). + +--- + +## Installation + +### Use Arduino Library Manager + +The best and easiest way is to use `Arduino Library Manager`. Search for `AsyncWebServer_ESP32_SC_W6100`, then select / install the latest version. You can also use this link [![arduino-library-badge](https://www.ardu-badge.com/badge/AsyncWebServer_ESP32_SC_W6100.svg?)](https://www.ardu-badge.com/AsyncWebServer_ESP32_SC_W6100) for more detailed instructions. + +### Manual Install + +1. Navigate to [AsyncWebServer_ESP32_SC_W6100](https://github.com/khoih-prog/AsyncWebServer_ESP32_SC_W6100) page. +2. Download the latest release `AsyncWebServer_ESP32_SC_W6100-main.zip`. +3. Extract the zip file to `AsyncWebServer_ESP32_SC_W6100-main` directory +4. Copy the whole `AsyncWebServer_ESP32_SC_W6100-main` folder to Arduino libraries' directory such as `~/Arduino/libraries/`. + +### VS Code & PlatformIO: + +1. Install [VS Code](https://code.visualstudio.com/) +2. Install [PlatformIO](https://platformio.org/platformio-ide) +3. Install [**AsyncWebServer_ESP32_SC_W6100** library](https://registry.platformio.org/libraries/khoih-prog/AsyncWebServer_ESP32_SC_W6100) by using [Library Manager](https://registry.platformio.org/libraries/khoih-prog/AsyncWebServer_ESP32_SC_W6100/installation). Search for **AsyncWebServer_ESP32_SC_W6100** in [Platform.io Author's Libraries](https://platformio.org/lib/search?query=author:%22Khoi%20Hoang%22) +4. Use included [platformio.ini](platformio/platformio.ini) file from examples to ensure that all dependent libraries will installed automatically. Please visit documentation for the other options and examples at [Project Configuration File](https://docs.platformio.org/page/projectconf.html) + + +--- +--- + +## Important things to remember + +- This is **fully asynchronous server** and as such does not run on the `loop()` thread. +- You can not use `yield()` or `delay()` or any function that uses them inside the callbacks +- The server is smart enough to know when to close the connection and free resources +- You can not send more than one response to a single request + +--- + +## Principles of operation + +### The Async Web server + +- Listens for connections +- Wraps the new clients into `Request` +- Keeps track of clients and cleans memory +- Manages `Rewrites` and apply them on the request url +- Manages `Handlers` and attaches them to Requests + +### Request Life Cycle + +- TCP connection is received by the server +- The connection is wrapped inside `Request` object +- When the request head is received (type, url, get params, http version and host), + the server goes through all `Rewrites` (in the order they were added) to rewrite the url and inject query parameters, + next, it goes through all attached `Handlers` (in the order they were added) trying to find one + that `canHandle` the given request. If none are found, the default(catch-all) handler is attached. +- The rest of the request is received, calling the `handleUpload` or `handleBody` methods of the `Handler` if they are needed (POST+File/Body) +- When the whole request is parsed, the result is given to the `handleRequest` method of the `Handler` and is ready to be responded to +- In the `handleRequest` method, to the `Request` is attached a `Response` object (see below) that will serve the response data back to the client +- When the `Response` is sent, the client is closed and freed from the memory + +### Rewrites and how do they work + +- The `Rewrites` are used to rewrite the request url and/or inject get parameters for a specific request url path. +- All `Rewrites` are evaluated on the request in the order they have been added to the server. +- The `Rewrite` will change the request url only if the request url (excluding get parameters) is fully match + the rewrite url, and when the optional `Filter` callback return true. +- Setting a `Filter` to the `Rewrite` enables to control when to apply the rewrite, decision can be based on + request url, http version, request host/port/target host, get parameters or the request client's localIP or remoteIP. +- The `Rewrite` can specify a target url with optional get parameters, e.g. `/to-url?with=params` + +### Handlers and how do they work + +- The `Handlers` are used for executing specific actions to particular requests +- One `Handler` instance can be attached to any request and lives together with the server +- Setting a `Filter` to the `Handler` enables to control when to apply the handler, decision can be based on + request url, http version, request host/port/target host, get parameters or the request client's localIP or remoteIP. +- The `canHandle` method is used for handler specific control on whether the requests can be handled + and for declaring any interesting headers that the `Request` should parse. Decision can be based on request + method, request url, http version, request host/port/target host and get parameters +- Once a `Handler` is attached to given `Request` (`canHandle` returned true) + that `Handler` takes care to receive any file/data upload and attach a `Response` + once the `Request` has been fully parsed +- `Handlers` are evaluated in the order they are attached to the server. The `canHandle` is called only + if the `Filter` that was set to the `Handler` return true. +- The first `Handler` that can handle the request is selected, not further `Filter` and `canHandle` are called. + +### Responses and how do they work + +- The `Response` objects are used to send the response data back to the client +- The `Response` object lives with the `Request` and is freed on end or disconnect +- Different techniques are used depending on the response type to send the data in packets + returning back almost immediately and sending the next packet when this one is received. + Any time in between is spent to run the user loop and handle other network packets +- Responding asynchronously is probably the most difficult thing for most to understand +- Many different options exist for the user to make responding a background task + +### Template processing + +- `AsyncWebServer_ESP32_SC_W6100` contains simple template processing engine. +- Template processing can be added to most response types. +- Currently it supports only replacing template placeholders with actual values. No conditional processing, cycles, etc. +- Placeholders are delimited with `%` symbols. Like this: `%TEMPLATE_PLACEHOLDER%`. +- It works by extracting placeholder name from response text and passing it to user provided function which should return actual value to be used instead of placeholder. +- Since it's user provided function, it is possible for library users to implement conditional processing and cycles themselves. +- Since it's impossible to know the actual response size after template processing step in advance (and, therefore, to include it in response headers), the response becomes [chunked](#chunked-response). + +--- + +## Request Variables + +### Common Variables + +```cpp +request->version(); // uint8_t: 0 = HTTP/1.0, 1 = HTTP/1.1 +request->method(); // enum: HTTP_GET, HTTP_POST, HTTP_DELETE, HTTP_PUT, HTTP_PATCH, HTTP_HEAD, HTTP_OPTIONS +request->url(); // String: URL of the request (not including host, port or GET parameters) +request->host(); // String: The requested host (can be used for virtual hosting) +request->contentType(); // String: ContentType of the request (not available in Handler::canHandle) +request->contentLength(); // size_t: ContentLength of the request (not available in Handler::canHandle) +request->multipart(); // bool: True if the request has content type "multipart" +``` + +### Headers + +```cpp +//List all collected headers +int headers = request->headers(); +int i; + +for (i=0;i+ +
+ + +--- + + +#### ESP32S3_DEV + ++ +
+ + +|W6100|<--->|ESP32_S3| +|:-:|:-:|:-:| +|MOSI|<--->|GPIO11| +|MISO|<--->|GPIO13| +|SCK|<--->|GPIO12| +|SS|<--->|GPIO10| +|INT|<--->|GPIO4| +|RST|<--->|RST| +|GND|<--->|GND| +|3.3V|<--->|3.3V| + + +--- + +#### ESP32S2_DEV + ++ +
+ + +|ENC28J60|<--->|ESP32_S2| +|:-:|:-:|:-:| +|MOSI|<--->|GPIO35| +|MISO|<--->|GPIO37| +|SCK|<--->|GPIO36| +|SS|<--->|GPIO34| +|INT|<--->|GPIO4| +|RST|<--->|RST| +|GND|<--->|GND| +|3.3V|<--->|3.3V| + +--- + + +#### ESP32C3_DEV + ++ +
+ + +|W6100|<--->|ESP32_C3| +|:-:|:-:|:-:| +|MOSI|<--->|GPIO6| +|MISO|<--->|GPIO5| +|SCK|<--->|GPIO4| +|SS|<--->|GPIO7| +|INT|<--->|GPIO10| +|RST|<--->|RST| +|GND|<--->|GND| +|3.3V|<--->|3.3V| + + + + +--- +--- + +### Examples + + 1. [Async_AdvancedWebServer](examples/Async_AdvancedWebServer) + 2. [Async_AdvancedWebServer_MemoryIssues_SendArduinoString](examples/Async_AdvancedWebServer_MemoryIssues_SendArduinoString) + 3. [Async_AdvancedWebServer_MemoryIssues_Send_CString](examples/Async_AdvancedWebServer_MemoryIssues_Send_CString) + 4. [Async_AdvancedWebServer_SendChunked](examples/Async_AdvancedWebServer_SendChunked) + 5. [Async_HelloServer](examples/Async_HelloServer) + 6. [Async_HelloServer2](examples/Async_HelloServer2) + 7. [Async_HttpBasicAuth](examples/Async_HttpBasicAuth) + 8. [AsyncMultiWebServer_ESP32_W6100](examples/AsyncMultiWebServer_ESP32_W6100) + 9. [Async_PostServer](examples/Async_PostServer) +10. [Async_RegexPatterns_ESP32_W6100](examples/Async_RegexPatterns_ESP32_W6100) +11. [AsyncSimpleServer_ESP32_W6100](examples/AsyncSimpleServer_ESP32_W6100) +12. [AsyncWebServer_SendChunked](examples/AsyncWebServer_SendChunked) +13. [Async_WebSocketsServer](examples/Async_WebSocketsServer) +14. [MQTTClient_Auth](examples/MQTTClient_Auth) +15. [MQTTClient_Basic](examples/MQTTClient_Basic) +16. [MQTT_ThingStream](examples/MQTT_ThingStream) + + +--- +--- + +### Example [Async_AdvancedWebServer](examples/Async_AdvancedWebServer) + +https://github.com/khoih-prog/AsyncWebServer_ESP32_SC_W6100/blob/db52447927b42518ac0322e48d538d1811148a26/examples/Async_AdvancedWebServer/Async_AdvancedWebServer.ino#L40-L268 + + +You can access the Async Advanced WebServer @ the server IP + ++ +
+ ++ +
+ ++ +
+ +--- +--- + +### Debug Terminal Output Samples + +#### 1. AsyncMultiWebServer_ESP32_W6100 on ESP32S3_DEV with ESP32_S3_W6100 + +Following are debug terminal output and screen shots when running example [AsyncMultiWebServer_ESP32_W6100](examples/AsyncMultiWebServer_ESP32_W6100) on `ESP32S3_DEV with LwIP W6100`, using ESP32 core `v2.0.0+`, to demonstrate the operation of 3 independent AsyncWebServers on 3 different ports and how to handle the complicated AsyncMultiWebServers. + + +```cpp +Start AsyncMultiWebServer_ESP32_W6100 on ESP32S3_DEV with ESP32_S3_W6100 +AsyncWebServer_ESP32_SC_W6100 v1.8.1 for core v2.0.0+ +[AWS] Default SPI pinout: +[AWS] SPI_HOST: 2 +[AWS] MOSI: 11 +[AWS] MISO: 13 +[AWS] SCK: 12 +[AWS] CS: 10 +[AWS] INT: 4 +[AWS] SPI Clock (MHz): 25 +[AWS] ========================= + +ETH Started +ETH Connected +ETH MAC: FE:ED:DE:AD:BE:EF, IPv4: 192.168.2.92 +FULL_DUPLEX, 100Mbps + +Connected to network. IP = 192.168.2.92 +Initialize multiServer OK, serverIndex = 0, port = 8080 +HTTP server started at ports 8080 +Initialize multiServer OK, serverIndex = 1, port = 8081 +HTTP server started at ports 8081 +Initialize multiServer OK, serverIndex = 2, port = 8082 +HTTP server started at ports 8082 +``` + +You can access the Async Advanced WebServers @ the server IP and corresponding ports (8080, 8081 and 8082) + ++ +
+ ++ +
+ ++ +
+ +--- + +#### 2. Async_AdvancedWebServer_MemoryIssues_Send_CString on ESP32S3_DEV with ESP32_S3_W6100 + +Following is the debug terminal and screen shot when running example [Async_AdvancedWebServer_MemoryIssues_Send_CString](examples/Async_AdvancedWebServer_MemoryIssues_Send_CString), on `ESP32S3_DEV with LwIP W6100`, to demonstrate the new and powerful `HEAP-saving` feature + + +##### Using CString ===> smaller heap (113,396 bytes) + +```cpp +Start Async_AdvancedWebServer_MemoryIssues_Send_CString on ESP32S3_DEV with ESP32_S3_W6100 +AsyncWebServer_ESP32_SC_W6100 v1.8.1 for core v2.0.0+ +[AWS] Default SPI pinout: +[AWS] SPI_HOST: 2 +[AWS] MOSI: 11 +[AWS] MISO: 13 +[AWS] SCK: 12 +[AWS] CS: 10 +[AWS] INT: 4 +[AWS] SPI Clock (MHz): 25 +[AWS] ========================= + +ETH Started +ETH Connected +ETH MAC: FE:ED:DE:AD:BE:EF, IPv4: 192.168.2.92 +FULL_DUPLEX, 100Mbps +HTTP EthernetWebServer is @ IP : 192.168.2.92 + +HEAP DATA - Pre Create Arduino String Max heap: 352132 Free heap: 250428 Used heap: 101704 +... +HEAP DATA - Pre Send Max heap: 352132 Free heap: 245624 Used heap: 106508 + +HEAP DATA - Post Send Max heap: 352132 Free heap: 239164 Used heap: 112968 +.. +HEAP DATA - Post Send Max heap: 352132 Free heap: 238736 Used heap: 113396 +... +``` + +While using `Arduino String`, the HEAP usage is very large + + +#### Async_AdvancedWebServer_MemoryIssues_SendArduinoString ===> very large heap (142,972 bytes) + +```cpp +Start Async_AdvancedWebServer_MemoryIssues_SendArduinoString on ESP32S3_DEV with ESP32_S3_W6100 +AsyncWebServer_ESP32_SC_W6100 v1.8.1 for core v2.0.0+ +[AWS] Default SPI pinout: +[AWS] SPI_HOST: 2 +[AWS] MOSI: 11 +[AWS] MISO: 13 +[AWS] SCK: 12 +[AWS] CS: 10 +[AWS] INT: 4 +[AWS] SPI Clock (MHz): 25 +[AWS] ========================= + +ETH Started +ETH Connected +ETH MAC: FE:ED:DE:AD:BE:EF, IPv4: 192.168.2.92 +FULL_DUPLEX, 100Mbps +HTTP EthernetWebServer is @ IP : 192.168.2.92 + +HEAP DATA - Pre Create Arduino String Max heap: 359852 Free heap: 298532 Used heap: 61320 +. +HEAP DATA - Pre Send Max heap: 359852 Free heap: 254632 Used heap: 105220 + +HEAP DATA - Post Send Max heap: 359852 Free heap: 215352 Used heap: 142960 + +HEAP DATA - Post Send Max heap: 359852 Free heap: 215340 Used heap: 142972 +. +``` + + +You can access the Async Advanced WebServers at the displayed server IP, e.g. `192.168.2.92` + ++ +
+ +--- + +#### 3. Async_AdvancedWebServer_SendChunked on ESP32S3_DEV with ESP32_S3_W6100 + +Following is debug terminal output when running example [Async_AdvancedWebServer_SendChunked](examples/Async_AdvancedWebServer_SendChunked) on `ESP32S3_DEV with LwIP W6100`, using ESP32 core `v2.0.0+`, to demo how to use `beginChunkedResponse()` to send large `html` in chunks + +```cpp +Start Async_AdvancedWebServer_SendChunked on ESP32S3_DEV with ESP32_S3_W6100 +AsyncWebServer_ESP32_SC_W6100 v1.8.1 for core v2.0.0+ +[AWS] Default SPI pinout: +[AWS] SPI_HOST: 2 +[AWS] MOSI: 11 +[AWS] MISO: 13 +[AWS] SCK: 12 +[AWS] CS: 10 +[AWS] INT: 4 +[AWS] SPI Clock (MHz): 25 +[AWS] ========================= + +ETH Started +ETH Connected +ETH MAC: FE:ED:DE:AD:BE:EF, IPv4: 192.168.2.92 +FULL_DUPLEX, 100Mbps +AsyncWebServer is @ IP : 192.168.2.92 +.[AWS] Total length to send in chunks = 31259 +[AWS] Bytes sent in chunk = 5620 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 2775 +[AWS] Bytes sent in chunk = 0 +.[AWS] Total length to send in chunks = 31279 +[AWS] Bytes sent in chunk = 5620 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 4300 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 2795 +[AWS] Bytes sent in chunk = 0 +``` + +You can access the Async Advanced WebServers @ the server IP + ++ +
+ + +--- + +#### 4. AsyncWebServer_SendChunked on ESP32S3_DEV with ESP32_S3_W6100 + +Following is debug terminal output when running example [AsyncWebServer_SendChunked](examples/AsyncWebServer_SendChunked) on `ESP32S3_DEV with LwIP W6100`, using ESP32 core `v2.0.0+`, to demo how to use `beginChunkedResponse()` to send large `html` in chunks + + +```cpp +Start AsyncWebServer_SendChunked on ESP32S3_DEV with ESP32_S3_W6100 +AsyncWebServer_ESP32_SC_W6100 v1.8.1 for core v2.0.0+ +[AWS] Default SPI pinout: +[AWS] SPI_HOST: 2 +[AWS] MOSI: 11 +[AWS] MISO: 13 +[AWS] SCK: 12 +[AWS] CS: 10 +[AWS] INT: 4 +[AWS] SPI Clock (MHz): 25 +[AWS] ========================= + +ETH Started +ETH Connected +ETH MAC: FE:ED:DE:AD:BE:EF, IPv4: 192.168.2.92 +FULL_DUPLEX, 100Mbps +AsyncWebServer is @ IP : 192.168.2.92 +.[AWS] Total length to send in chunks = 47809 +[AWS] Bytes sent in chunk = 5624 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 4300 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2129 +[AWS] Bytes sent in chunk = 0 +``` + + +--- + +#### 5. Async_WebSocketsServer on ESP32S3_DEV with ESP32_S3_W6100 + +Following is debug terminal output when running example [Async_WebSocketsServer](examples/Async_WebSocketsServer) on `ESP32S3_DEV with LwIP W6100`, using ESP32 core `v2.0.0+`, to demo how to use `Async_WebSocketsServer` feature + + +```cpp +Starting Async_WebSocketsServer on ESP32S3_DEV with ESP32_S3_W6100 +AsyncWebServer_ESP32_SC_W6100 v1.8.1 for core v2.0.0+ +[AWS] Default SPI pinout: +[AWS] SPI_HOST: 2 +[AWS] MOSI: 11 +[AWS] MISO: 13 +[AWS] SCK: 12 +[AWS] CS: 10 +[AWS] INT: 4 +[AWS] SPI Clock (MHz): 25 +[AWS] ========================= + +ETH Started +ETH Connected +ETH MAC: FE:ED:DE:AD:BE:EF, IPv4: 192.168.2.92 +FULL_DUPLEX, 100Mbps +ws[Server: /ws][ClientID: 1] WSClient connected +ws[Server: /ws][ClientID: 1] WSClient disconnected +ws[Server: /ws][ClientID: 2] WSClient connected +ws[Server: /ws][ClientID: 3] WSClient connected +``` + +--- + +#### 6. Async_HTTPBasicAuth on ESP32S3_DEV with ESP32_S3_W6100 + +Following is debug terminal output when running example [Async_HTTPBasicAuth](examples/Async_HTTPBasicAuth) on `ESP32S3_DEV with LwIP W6100`, using ESP32 core `v2.0.0+`, to demo how to use `Async_Auth` feature + + +```cpp +Start Async_HTTPBasicAuth on ESP32S3_DEV with ESP32_S3_W6100 +AsyncWebServer_ESP32_SC_W6100 v1.8.1 for core v2.0.0+ +[AWS] Default SPI pinout: +[AWS] SPI_HOST: 2 +[AWS] MOSI: 11 +[AWS] MISO: 13 +[AWS] SCK: 12 +[AWS] CS: 10 +[AWS] INT: 4 +[AWS] SPI Clock (MHz): 25 +[AWS] ========================= + +ETH Started +ETH Connected +ETH MAC: FE:ED:DE:AD:BE:EF, IPv4: 192.168.2.92 +FULL_DUPLEX, 100Mbps +Async_HttpBasicAuth started @ IP : 192.168.2.92 +Open http://192.168.2.88/ in your browser to see it working +Login using username = admin and password = esp32_W6100 +``` + +--- + +#### 7. Async_AdvancedWebServer_SendChunked on ESP32S2_DEV with ESP32_S2_W6100 + +Following is debug terminal output when running example [Async_AdvancedWebServer_SendChunked](examples/Async_AdvancedWebServer_SendChunked) on `ESP32S2_DEV with LwIP W6100`, using ESP32 core `v2.0.0+`, to demo how to use `beginChunkedResponse()` to send large `html` in chunks. The `built-in MAC address` is now used instead of user-defined one. + +```cpp +Start Async_AdvancedWebServer_SendChunked on ESP32S2_DEV with ESP32_S2_W6100 +AsyncWebServer_ESP32_SC_W6100 v1.8.1 for core v2.0.0+ +[AWS] Default SPI pinout: +[AWS] SPI_HOST: 2 +[AWS] MOSI: 35 +[AWS] MISO: 37 +[AWS] SCK: 36 +[AWS] CS: 34 +[AWS] INT: 4 +[AWS] SPI Clock (MHz): 25 +[AWS] ========================= + +ETH Started +ETH Connected +ETH MAC: 7E:DF:A1:08:64:27, IPv4: 192.168.2.132 +FULL_DUPLEX, 100Mbps +AsyncWebServer is @ IP : 192.168.2.132 +.[AWS] Total length to send in chunks = 31259 +[AWS] Bytes sent in chunk = 5620 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 2775 +[AWS] Bytes sent in chunk = 0 +.[AWS] Total length to send in chunks = 31279 +[AWS] Bytes sent in chunk = 5620 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 4300 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 2795 +[AWS] Bytes sent in chunk = 0 +``` + +You can access the Async Advanced WebServers @ the server IP + ++ +
+ +--- + +#### 8. Async_AdvancedWebServer_SendChunked on ESP32C3_DEV with ESP32_C3_W6100 + +Following is debug terminal output when running example [Async_AdvancedWebServer_SendChunked](examples/Async_AdvancedWebServer_SendChunked) on `ESP32C3_DEV with LwIP W6100`, using ESP32 core `v2.0.0+`, to demo how to use `beginChunkedResponse()` to send large `html` in chunks. The `built-in MAC address` is now used instead of user-defined one. + +```cpp +Start AsyncWebServer_SendChunked on ESP32C3_DEV with ESP32_C3_W6100 +AsyncWebServer_ESP32_SC_W6100 v1.8.1 for core v2.0.0+ +[AWS] Default SPI pinout: +[AWS] SPI_HOST: 1 +[AWS] MOSI: 6 +[AWS] MISO: 5 +[AWS] SCK: 4 +[AWS] CS: 7 +[AWS] INT: 10 +[AWS] SPI Clock (MHz): 25 +[AWS] ========================= + +ETH Started +ETH Connected +ETH MAC: 7C:DF:A1:DA:68:BF, IPv4: 192.168.2.159 +FULL_DUPLEX, 100Mbps +AsyncWebServer is @ IP : 192.168.2.159 +.[AWS] Total length to send in chunks = 47809 +[AWS] Bytes sent in chunk = 5624 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 4300 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2129 +[AWS] Bytes sent in chunk = 0 +[AWS] Total length to send in chunks = 47809 +[AWS] Bytes sent in chunk = 5624 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 4300 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 1428 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2864 +[AWS] Bytes sent in chunk = 2129 +[AWS] Bytes sent in chunk = 0 +``` + +You can access the Async Advanced WebServers @ the server IP + ++ +
+ + + +--- +--- + +### Debug + +Debug is enabled by default on Serial. Debug Level from 0 to 4. To disable, change the _ETHERNET_WEBSERVER_LOGLEVEL_ to 0 + +```cpp +// Use this to output debug msgs to Serial +#define DEBUG_ASYNC_WEBSERVER_PORT Serial +// Use this to disable all output debug msgs +// Debug Level from 0 to 4 +#define _ASYNC_WEBSERVER_LOGLEVEL_ 0 +``` + +--- + +### Troubleshooting + +If you get compilation errors, more often than not, you may need to install a newer version of Arduino IDE, the Arduino `ESP32` core or depending libraries. + +Sometimes, the library will only work if you update the `ESP32` core to the latest version because I'm always using the latest cores /libraries. + +--- + +### Issues ### + +Submit issues to: [AsyncWebServer_ESP32_SC_W6100 issues](https://github.com/khoih-prog/AsyncWebServer_ESP32_SC_W6100/issues) + +--- +--- + +## TO DO + + 1. Fix bug. Add enhancement + 2. Add support to more Ethernet shields, such as **DP83848, TLK110, IP101, RTL8201, DM9051, KSZ8041, KSZ8081, etc.** + 3. Add `LittleFS` support to use with new cores + +--- + +## DONE + + 1. Initial port to `ESP32_S2/S3/C3` boards using `LwIP W6100` Ethernet. + 2. Add more examples. + 3. Add debugging features. + 4. Add Table-of-Contents and Version String + 5. Display compiler `#warning` only when `DEBUG_LEVEL` is 3+ + 6. Fix `AsyncWebSocket` bug + 7. Support using `CString` to save heap to send `very large data`. Check [request->send(200, textPlainStr, jsonChartDataCharStr); - Without using String Class - to save heap #8](https://github.com/khoih-prog/Portenta_H7_AsyncWebServer/pull/8) + 8. Add examples [Async_AdvancedWebServer_SendChunked](https://github.com/khoih-prog/AsyncWebServer_ESP32_SC_W6100/tree/main/examples/Async_AdvancedWebServer_SendChunked) and [AsyncWebServer_SendChunked](https://github.com/khoih-prog/AsyncWebServer_ESP32_SC_W6100/tree/main/examples/AsyncWebServer_SendChunked) to demo how to use `beginChunkedResponse()` to send large `html` in chunks + 9. Use `allman astyle` and add `utils` +10. Add `Async_WebSocketsServer`, `Async_HttpBasicAuth` and `MQTT` examples +11. Remove unused variable to avoid compiler warning and error + + +--- +--- + + +### Contributions and Thanks + +1. Based on and modified from [Hristo Gochkov's ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer). Many thanks to [Hristo Gochkov](https://github.com/me-no-dev) for great [ESPAsyncWebServer Library](https://github.com/me-no-dev/ESPAsyncWebServer) + + +⭐️⭐️ Hristo Gochkov |
+