diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a9dbe410..84c4df1b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ If you don't find anything, please [open a new issue](https://github.com/khoih-p Please ensure to specify the following: * Arduino IDE version (e.g. 1.8.13) or Platform.io version -* `ESP8266`,`ESP32` or `STM32` Core Version (e.g. ESP8266 core v2.7.4, ESP32 v1.0.4 or STM32 v1.9.0) +* `ESP8266`,`ESP32` or `STM32` Core Version (e.g. ESP8266 core v2.7.4, ESP32 v1.0.5 or STM32 v1.9.0) * Contextual information (e.g. what you were trying to achieve) * Simplest possible steps to reproduce * Anything that might be relevant in your opinion, such as: @@ -27,9 +27,9 @@ Please ensure to specify the following: ``` Arduino IDE version: 1.8.13 -ESP32 Core Version 1.0.4 +ESP32 Core Version 1.0.5 OS: Ubuntu 20.04 LTS -Linux xy-Inspiron-3593 5.4.0-65-generic #73-Ubuntu SMP Mon Jan 18 17:25:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux +Linux xy-Inspiron-3593 5.4.0-66-generic #74-Ubuntu SMP Wed Jan 27 22:54:38 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux Context: I encountered an endless loop while trying to connect to Local WiFi. diff --git a/Images/esp32_s2_Core_Unzipped.png b/Images/esp32_s2_Core_Unzipped.png new file mode 100644 index 00000000..76286a20 Binary files /dev/null and b/Images/esp32_s2_Core_Unzipped.png differ diff --git a/Images/esp32_s2_Toolchain.png b/Images/esp32_s2_Toolchain.png new file mode 100644 index 00000000..823c235a Binary files /dev/null and b/Images/esp32_s2_Toolchain.png differ diff --git a/Images/esp32_s2_esptool.png b/Images/esp32_s2_esptool.png new file mode 100644 index 00000000..a9075ebb Binary files /dev/null and b/Images/esp32_s2_esptool.png differ diff --git a/Images/esp32_s2_tools.png b/Images/esp32_s2_tools.png new file mode 100644 index 00000000..91339754 Binary files /dev/null and b/Images/esp32_s2_tools.png differ diff --git a/README.md b/README.md index fbe2ae71..537dd670 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,9 @@ * [Features](#features) * [Supports](#supports) * [Principles of operation](#principles-of-operation) + * [Currently supported Boards](#currently-supported-boards) * [Changelog](#changelog) + * [Releases v1.1.3](#releases-v113) * [Releases v1.1.2](#releases-v112) * [Releases v1.1.1](#releases-v111) * [Releases v1.1.0](#releases-v110) @@ -38,7 +40,22 @@ * [For core version v1.8.9-](#for-core-version-v189-) * [5. For Adafruit SAMD boards](#5-for-adafruit-samd-boards) * [6. For Seeeduino SAMD boards](#6-for-seeeduino-samd-boards) - * [7. For STM32 boards](#7-for-stm32-boards) + * [7. For STM32 boards](#7-for-stm32-boards) +* [HOWTO Install esp32-s2 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) boards into Arduino IDE)](#howto-install-esp32-s2-core-for-esp32-s2-saola-ai-thinker-esp-12k-boards-into-arduino-ide) + * [1. Save the original esp32 core](#1-save-the-original-esp32-core) + * [2. Download esp32-s2 core](#2-download-esp32-s2-core) + * [2.1 Download zip](#21-download-zip) + * [2.2 Unzip](#22-unzip) + * [2.3 Update esp32-s2 core directories](#23-update-esp32-s2-core-directories) + * [3. Download tools](#3-download-tools) + * [3.1 Download Toolchain for Xtensa (ESP32-S2) based on GCC](#31-download-toolchain-for-xtensa-esp32-s2-based-on-gcc) + * [3.2 Download esptool](#32-download-esptool) + * [3.3 Unzip](#33-unzip) + * [4. Update tools](#4-update-tools) + * [4.1 Update Toolchain](#41-update-toolchain) + * [4.2 Update esptool](#42-update-esptool) + * [5. esp32-s2 WebServer Library Patch](#5-esp32-s2-webserver-library-patch) +* [Note for Platform IO using ESP32 LittleFS](#note-for-platform-io-using-esp32-littlefs) * [HOWTO Fix `Multiple Definitions` Linker Error](#howto-fix-multiple-definitions-linker-error) * [Note for Platform IO using ESP32 LittleFS](#note-for-platform-io-using-esp32-littlefs) * [HOWTO Use analogRead() with ESP32 running WiFi and/or BlueTooth (BT/BLE)](#howto-use-analogread-with-esp32-running-wifi-andor-bluetooth-btble) @@ -79,15 +96,15 @@ ## Why do we need this Async [AsyncHTTPRequest_Generic library](https://github.com/khoih-prog/AsyncHTTPRequest_Generic) -#### Features +### Features -1. Asynchronous HTTP Request library for ESP8266, ESP32 using built-in WiFi, and STM32 boards using built-in LAN8742A Ethernet. +1. Asynchronous HTTP Request library for ESP8266, including ESP32-S2 (ESP32-S2 Saola, AI-Thinker ESP-12K, etc.) using built-in WiFi, and STM32 boards using built-in LAN8742A Ethernet. 2. Providing a subset of HTTP. 3. Relying on on **[`ESPAsyncTCP`](https://github.com/me-no-dev/ESPAsyncTCP) for ESP8266, [`AsyncTCP`](https://github.com/me-no-dev/AsyncTCP) for ESP32** using built-in WiFi 4. Relying on **[`STM32duino LwIP`](https://github.com/stm32duino/LwIP)/[`STM32duino STM32Ethernet`](https://github.com/stm32duino/STM32Ethernet)/[`STM32AsyncTCP`](https://github.com/philbowles/STM32AsyncTCP) for STM32 using built-in LAN8742A Ethernet.** 5. Methods similar in format and usage to XmlHTTPrequest in Javascript. -#### Supports +### Supports 1. **GET, POST, PUT, PATCH, DELETE and HEAD** 2. Request and response headers @@ -96,7 +113,7 @@ 5. Optional onData callback. 6. Optional onReadyStatechange callback. -#### Principles of operation +### Principles of operation This library adds a simple HTTP layer on top of the ESPAsyncTCP/AsyncTCP/STM32 AsyncTCP library to **facilitate REST communication from a Client to a Server**. The paradigm is similar to the XMLHttpRequest in Javascript, employing the notion of a ready-state progression through the transaction request. @@ -110,12 +127,37 @@ Request and response headers are handled in the typical fashion. Chunked responses are recognized and handled transparently. +This library is based on, modified from: + +1. [Bob Lemaire's asyncHTTPrequest Library](https://github.com/boblemaire/asyncHTTPrequest) + +--- + +### Currently Supported Boards + +#### 1. ESP32 including ESP32-S2 (ESP32-S2 Saola, AI-Thinker ESP-12K, etc.) + +#### 2. ESP8266 + +#### 3. STM32F/L/H/G/WB/MP1 with built-in LAN8742A Ethernet. + +1. Nucleo-144 (F429ZI, F746ZG, F756ZG, F767ZI) +2. Discovery STM32F746G-DISCOVERY +3. Any STM32 boards with enough flash/memory and already configured to run LAN8742A Ethernet. + + --- --- ## Changelog +### Releases v1.1.3 + +1. Fix non-persistent Connection header bug. Check [**'Connection' header expects 'disconnect' instead 'close' ? #13**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues/13) +2. Add ESP32-S2 support +3. Tested with [**Latest ESP32 Core 1.0.5**](https://github.com/espressif/arduino-esp32) for ESP32-based boards. + ### Releases v1.1.2 1. Rename _lock and _unlock to avoid conflict with [**ESP32/ESP8266 AsyncWebServer**](https://github.com/me-no-dev/ESPAsyncWebServer) library. Check [**compatibility with ESPAsyncWebServer #11**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues/11) @@ -147,24 +189,6 @@ Chunked responses are recognized and handled transparently. 1. Initial coding to add support to **STM32F/L/H/G/WB/MP1** using built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc). 2. Add examples using STM32 boards. -#### Currently Supported Boards - -#### 1. ESP32 and ESP8266 - -#### 2. STM32F/L/H/G/WB/MP1 with built-in LAN8742A Ethernet. - -1. Nucleo-144 (F429ZI, F746ZG, F756ZG, F767ZI) -2. Discovery STM32F746G-DISCOVERY -3. Any STM32 boards with enough flash/memory and already configured to run LAN8742A Ethernet. - ---- - -#### AsyncHTTPRequest_Generic for ESP32, ESP8266 using built-in WiFi and STM32 boards using built-in LAN8742A Ethernet - -This library is based on, modified from: - -1. [Bob Lemaire's asyncHTTPrequest Library](https://github.com/boblemaire/asyncHTTPrequest) - --- --- @@ -172,15 +196,17 @@ This library is based on, modified from: 1. [`Arduino IDE 1.8.13+` for Arduino](https://www.arduino.cc/en/Main/Software) 2. [`ESP8266 Core 2.7.4+`](https://github.com/esp8266/Arduino) for ESP8266-based boards. [![Latest release](https://img.shields.io/github/release/esp8266/Arduino.svg)](https://github.com/esp8266/Arduino/releases/latest/) - 3. [`ESP32 Core 1.0.4+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. [Latest stable release ![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32.svg?style=plastic) - 4. [`Arduino Core for STM32 1.9.0+`](https://github.com/stm32duino/Arduino_Core_STM32) for for STM32 using built-in Ethernet LAN8742A. [![GitHub release](https://img.shields.io/github/release/stm32duino/Arduino_Core_STM32.svg)](https://github.com/stm32duino/Arduino_Core_STM32/releases/latest) - 5. [`ESPAsyncTCP v1.2.2+`](https://github.com/me-no-dev/ESPAsyncTCP) for ESP8266. - 6. [`AsyncTCP v1.1.1+`](https://github.com/me-no-dev/AsyncTCP) for ESP32. - 7. [`STM32Ethernet library v1.2.0+`](https://github.com/stm32duino/STM32Ethernet) for STM32 using built-in Ethernet LAN8742A on (Nucleo-144, Discovery). [![GitHub release](https://img.shields.io/github/release/stm32duino/STM32Ethernet.svg)](https://github.com/stm32duino/STM32Ethernet/releases/latest) - 8. [`LwIP library v2.1.2+`](https://github.com/stm32duino/LwIP) for STM32 using built-in Ethernet LAN8742A on (Nucleo-144, Discovery). [![GitHub release](https://img.shields.io/github/release/stm32duino/LwIP.svg)](https://github.com/stm32duino/LwIP/releases/latest) - 9. [`STM32AsyncTCP library v1.0.0+`](https://github.com/philbowles/STM32AsyncTCP) for STM32 using built-in Ethernet LAN8742A on (Nucleo-144, Discovery). -10. [`ESPAsync_WiFiManager library v1.4.3+`](https://github.com/khoih-prog/ESPAsync_WiFiManager) for ESP32/ESP8266 using some examples. [![GitHub release](https://img.shields.io/github/release/khoih-prog/ESPAsync_WiFiManager.svg)](https://github.com/khoih-prog/ESPAsync_WiFiManager/releases) - + 3. [`ESP32 Core 1.0.5+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. [Latest stable release ![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32.svg?style=plastic) + 4. [`ESP32S2 Core 1.0.4+`](https://github.com/espressif/arduino-esp32/tree/esp32s2) for ESP32-S2-based boards. + 5. [`Arduino Core for STM32 1.9.0+`](https://github.com/stm32duino/Arduino_Core_STM32) for for STM32 using built-in Ethernet LAN8742A. [![GitHub release](https://img.shields.io/github/release/stm32duino/Arduino_Core_STM32.svg)](https://github.com/stm32duino/Arduino_Core_STM32/releases/latest) + 6. [`ESPAsyncTCP v1.2.2+`](https://github.com/me-no-dev/ESPAsyncTCP) for ESP8266. + 7. [`AsyncTCP v1.1.1+`](https://github.com/me-no-dev/AsyncTCP) for ESP32. + 8. [`STM32Ethernet library v1.2.0+`](https://github.com/stm32duino/STM32Ethernet) for STM32 using built-in Ethernet LAN8742A on (Nucleo-144, Discovery). [![GitHub release](https://img.shields.io/github/release/stm32duino/STM32Ethernet.svg)](https://github.com/stm32duino/STM32Ethernet/releases/latest) + 9. [`LwIP library v2.1.2+`](https://github.com/stm32duino/LwIP) for STM32 using built-in Ethernet LAN8742A on (Nucleo-144, Discovery). [![GitHub release](https://img.shields.io/github/release/stm32duino/LwIP.svg)](https://github.com/stm32duino/LwIP/releases/latest) +10. [`STM32AsyncTCP library v1.0.0+`](https://github.com/philbowles/STM32AsyncTCP) for STM32 using built-in Ethernet LAN8742A on (Nucleo-144, Discovery). +11. [`ESPAsync_WiFiManager library v1.6.0+`](https://github.com/khoih-prog/ESPAsync_WiFiManager) for ESP32/ESP8266 using some examples. [![GitHub release](https://img.shields.io/github/release/khoih-prog/ESPAsync_WiFiManager.svg)](https://github.com/khoih-prog/ESPAsync_WiFiManager/releases) +12. [`LittleFS_esp32 v1.0.5+`](https://github.com/lorol/LITTLEFS) for ESP32-based boards using LittleFS. To install, check [![arduino-library-badge](https://www.ardu-badge.com/badge/LittleFS_esp32.svg?)](https://www.ardu-badge.com/LittleFS_esp32). + --- ## Installation @@ -346,6 +372,136 @@ theses files must be copied into the corresponding directory: --- --- +## HOWTO Install esp32-s2 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) boards into Arduino IDE + + +These are instructions demonstrating the steps to install esp32-s2 core on Ubuntu machines. For Windows or other OS'es, just follow the the similar principles and steps. + +Assuming you already installed Arduino IDE ESP32 core and the installed directory is + +`/home/your_account/.arduino15/packages/esp32` + + +### 1. Save the original esp32 core + +First, copy the whole original esp32 core to another safe place. Then delete all the sub-directories of + +`/home/your_account/.arduino15/packages/esp32/hardware/esp32/1.0.4` + +--- + +### 2. Download esp32-s2 core + +#### 2.1 Download zip + +Download [**esp32-s2 core**](https://github.com/espressif/arduino-esp32/tree/esp32s2) in the `zip` format: + +`arduino-esp32-esp32s2.zip` + +#### 2.2 Unzip + +

+ +

+ +#### 2.3 Update esp32-s2 core directories + +Copy all subdirectories of esp32-s2 core into `/home/your_account/.arduino15/packages/esp32/hardware/esp32/1.0.4` + +--- + +### 3 Download tools + + +#### 3.1 Download Toolchain for Xtensa (ESP32-S2) based on GCC + +Download [**esp32-s2 Toolchain**](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-guides/tools/idf-tools.html#xtensa-esp32s2-elf) corresponding to your environment (linux-amd64, win64, etc.). + +For example `xtensa-esp32s2-elf-gcc8_4_0-esp-2020r3-linux-amd64.tar.gz`, then un-archive. + + +

+ +

+ +#### 3.2 Download esptool + + +Download [esptool](https://github.com/espressif/esptool/releases) int the `zip` format: + +`esptool-3.0.zip` + +#### 3.3 Unzip + +

+ +

+ +--- + +### 4. Update tools + +#### 4.1 Update Toolchain + +Copy whole `xtensa-esp32s2-elf` directory into `/home/your_account/.arduino15/packages/esp32/hardware/esp32/1.0.4/tools` + + +#### 4.2 Update esptool + +Rename `esptool-3.0` directory to `esptool` + + +Copy whole `esptool` directory into `/home/your_account/.arduino15/packages/esp32/hardware/esp32/1.0.4/tools` + + +

+ +

+ + +### 5. esp32-s2 WebServer Library Patch + +If you haven't installed a new version with [WebServer.handleClient delay PR #4350](https://github.com/espressif/arduino-esp32/pull/4350) or haven't applied the above mentioned PR, you have to use the following patch. + + +**To be able to run Config Portal on ESP32-S2 boards**, you have to copy the files in [esp32-s2 WebServer Patch](esp32s2_WebServer_Patch/) directory into esp32-s2 WebServer library directory (~/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/WebServer). + +Supposing the esp32-s2 version is 1.0.4, these files `WebServer.h/cpp` must be copied into the directory to replace: + +- `~/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/WebServer/src/WebServer.h` +- `~/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/WebServer/src/WebServer.cpp` + + +--- + +That's it. You're now ready to compile and test for ESP32-S2 now + +--- +--- + +### Note for Platform IO using ESP32 LittleFS + +In Platform IO, to fix the error when using [`LittleFS_esp32 v1.0`](https://github.com/lorol/LITTLEFS) for ESP32-based boards with ESP32 core v1.0.4- (ESP-IDF v3.2-), uncomment the following line + +from + +``` +//#define CONFIG_LITTLEFS_FOR_IDF_3_2 /* For old IDF - like in release 1.0.4 */ +``` + +to + +``` +#define CONFIG_LITTLEFS_FOR_IDF_3_2 /* For old IDF - like in release 1.0.4 */ +``` + +It's advisable to use the latest [`LittleFS_esp32 v1.0.5+`](https://github.com/lorol/LITTLEFS) to avoid the issue. + +Thanks to [Roshan](https://github.com/solroshan) to report the issue in [Error esp_littlefs.c 'utime_p'](https://github.com/khoih-prog/ESPAsync_WiFiManager/issues/28) + +--- +--- + ### HOWTO Fix `Multiple Definitions` Linker Error The current library implementation, using xyz-Impl.h instead of standard xyz.cpp, possibly creates certain `Multiple Definitions` Linker error in certain use cases. Although it's simple to just modify several lines of code, either in the library or in the application, the library is adding a separate source directory, named src_cpp, besides the standard src directory. @@ -444,8 +600,8 @@ Please take a look at other examples, as well. ```cpp #include "defines.h" -// 600s = 10 minutes to not flooding, 10s in testing -#define HTTP_REQUEST_INTERVAL_MS 10000 //600000 +// 600s = 10 minutes to not flooding, 60s in testing +#define HTTP_REQUEST_INTERVAL_MS 60000 //600000 #include // https://github.com/khoih-prog/AsyncHTTPRequest_Generic @@ -540,6 +696,17 @@ void loop(void) ```cpp +/* + Currently support + 1) STM32 boards with built-in Ethernet (to use USE_BUILTIN_ETHERNET = true) such as : + - Nucleo-144 (F429ZI, F767ZI) + - Discovery (STM32F746G-DISCOVERY) + - STM32 boards (STM32F/L/H/G/WB/MP1) with 32K+ Flash, with Built-in Ethernet, + - See How To Use Built-in Ethernet at (https://github.com/khoih-prog/EthernetWebServer_STM32/issues/1) + 2) STM32F/L/H/G/WB/MP1 boards (with 32+K Flash) running ENC28J60 shields (to use USE_BUILTIN_ETHERNET = false) + 3) STM32F/L/H/G/WB/MP1 boards (with 32+K Flash) running W5x00 shields +*/ + #ifndef defines_h #define defines_h @@ -653,7 +820,7 @@ IPAddress ip(192, 168, 2, 232); ``` Start AsyncHTTPRequest_STM32 on NUCLEO_F767ZI -AsyncHTTPRequest_Generic v1.1.2 +AsyncHTTPRequest_Generic v1.1.3 AsyncHTTPRequest @ IP : 192.168.2.72 ************************************** @@ -698,7 +865,7 @@ week_number: 37 ``` Starting AsyncHTTPRequest_ESP_WiFiManager using LittleFS on ESP8266_NODEMCU -AsyncHTTPRequest_Generic v1.1.2 +AsyncHTTPRequest_Generic v1.1.3 Stored: SSID = HueNet1, Pass = 12345678 Got stored Credentials. Timeout 120s ConnectMultiWiFi in setup @@ -731,7 +898,7 @@ HHHHHH ``` Starting AsyncHTTPRequest_ESP_WiFiManager using SPIFFS on ESP32_DEV -AsyncHTTPRequest_Generic v1.1.2 +AsyncHTTPRequest_Generic v1.1.3 Stored: SSID = HueNet1, Pass = 12345678 Got stored Credentials. Timeout 120s ConnectMultiWiFi in setup @@ -782,7 +949,7 @@ HHHHHHHHH HHHHHHHHHH HHHHHHHHHH ``` Starting AsyncHTTPRequest_ESP using ESP8266_NODEMCU -AsyncHTTPRequest_Generic v1.1.2 +AsyncHTTPRequest_Generic v1.1.3 Connecting to WiFi SSID: HueNet1 ........... HTTP WebServer is @ IP : 192.168.2.81 @@ -814,7 +981,7 @@ HHHHHHHHH HHHHHHHHHH HHHHHHHHHH H ``` Start AsyncWebClientRepeating_STM32 on NUCLEO_F767ZI -AsyncHTTPRequest_Generic v1.1.2 +AsyncHTTPRequest_Generic v1.1.3 AsyncHTTPRequest @ IP : 192.168.2.72 ************************************** @@ -913,6 +1080,12 @@ Submit issues to: [AsyncHTTPRequest_Generic issues](https://github.com/khoih-pro ## Releases +### Releases v1.1.3 + +1. Fix non-persistent Connection header bug. Check [**'Connection' header expects 'disconnect' instead 'close' ? #13**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues/13) +2. Add ESP32-S2 support +3. Tested with [**Latest ESP32 Core 1.0.5**](https://github.com/espressif/arduino-esp32) for ESP32-based boards. + ### Releases v1.1.2 1. Rename _lock and _unlock to avoid conflict with [**ESP32/ESP8266 AsyncWebServer**](https://github.com/me-no-dev/ESPAsyncWebServer) library. Check [**compatibility with ESPAsyncWebServer #11**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues/11) @@ -950,16 +1123,20 @@ This library is based on, modified, bug-fixed and improved from: 2. Thanks to [Daniel Brunner](https://github.com/0xFEEDC0DE64) to report and make PR in [Fixed linker errors when included in multiple .cpp files](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/pull/1) leading to v1.0.1. See [**HOWTO Fix `Multiple Definitions` Linker Error**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic#HOWTO-Fix-Multiple-Definitions-Linker-Error) -3. Thanks to [gleniat](https://github.com/gleniat) to make enhancement request in[Add support for sending PUT, PATCH, DELETE request](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues/5) leading to v1.1.0. +3. Thanks to [gleniat](https://github.com/gleniat) to make enhancement request in [Add support for sending PUT, PATCH, DELETE request](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues/5) leading to v1.1.0. 4. Thanks to [BadDwarf](https://github.com/baddwarf) to report [**compatibility with ESPAsyncWebServer #11**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues/11) leading to the enhancement in v1.1.2. +5. Thanks to [spdi](https://github.com/spdi) to report [**'Connection' header expects 'disconnect' instead 'close' ? #13**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues/13) leading to new release v1.1.3 to fix bug. + + +
boblemaire
⭐️ Bob Lemaire

0xFEEDC0DE64
Daniel Brunner

gleniat
gleniat

baddwarf
BadDwarf

spdi
spdi

diff --git a/esp32s2_WebServer_Patch/WebServer.cpp b/esp32s2_WebServer_Patch/WebServer.cpp new file mode 100644 index 00000000..5d8f313d --- /dev/null +++ b/esp32s2_WebServer_Patch/WebServer.cpp @@ -0,0 +1,705 @@ +/* + WebServer.cpp - Dead simple web-server. + Supports only one simultaneous client, knows how to handle GET and POST. + + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling) +*/ + +// KH, Using "WebServer.handleClient delay" (https://github.com/espressif/arduino-esp32/pull/4350) + +#include +#include +#include +#include "WiFiServer.h" +#include "WiFiClient.h" +#include "WebServer.h" +#include "FS.h" +#include "detail/RequestHandlersImpl.h" +#include "mbedtls/md5.h" + + +static const char AUTHORIZATION_HEADER[] = "Authorization"; +static const char qop_auth[] = "qop=\"auth\""; +static const char WWW_Authenticate[] = "WWW-Authenticate"; +static const char Content_Length[] = "Content-Length"; + + +WebServer::WebServer(IPAddress addr, int port) +: _corsEnabled(false) +, _server(addr, port) +, _currentMethod(HTTP_ANY) +, _currentVersion(0) +, _currentStatus(HC_NONE) +, _statusChange(0) +, _nullDelay(true) +, _currentHandler(nullptr) +, _firstHandler(nullptr) +, _lastHandler(nullptr) +, _currentArgCount(0) +, _currentArgs(nullptr) +, _postArgsLen(0) +, _postArgs(nullptr) +, _headerKeysCount(0) +, _currentHeaders(nullptr) +, _contentLength(0) +, _chunked(false) +{ +} + +WebServer::WebServer(int port) +: _corsEnabled(false) +, _server(port) +, _currentMethod(HTTP_ANY) +, _currentVersion(0) +, _currentStatus(HC_NONE) +, _statusChange(0) +, _nullDelay(true) +, _currentHandler(nullptr) +, _firstHandler(nullptr) +, _lastHandler(nullptr) +, _currentArgCount(0) +, _currentArgs(nullptr) +, _postArgsLen(0) +, _postArgs(nullptr) +, _headerKeysCount(0) +, _currentHeaders(nullptr) +, _contentLength(0) +, _chunked(false) +{ +} + +WebServer::~WebServer() { + _server.close(); + if (_currentHeaders) + delete[]_currentHeaders; + RequestHandler* handler = _firstHandler; + while (handler) { + RequestHandler* next = handler->next(); + delete handler; + handler = next; + } +} + +void WebServer::begin() { + close(); + _server.begin(); + _server.setNoDelay(true); +} + +void WebServer::begin(uint16_t port) { + close(); + _server.begin(port); + _server.setNoDelay(true); +} + +String WebServer::_extractParam(String& authReq,const String& param,const char delimit){ + int _begin = authReq.indexOf(param); + if (_begin == -1) + return ""; + return authReq.substring(_begin+param.length(),authReq.indexOf(delimit,_begin+param.length())); +} + +static String md5str(String &in){ + char out[33] = {0}; + mbedtls_md5_context _ctx; + uint8_t i; + uint8_t * _buf = (uint8_t*)malloc(16); + if(_buf == NULL) + return String(out); + memset(_buf, 0x00, 16); + mbedtls_md5_init(&_ctx); + mbedtls_md5_starts(&_ctx); + mbedtls_md5_update(&_ctx, (const uint8_t *)in.c_str(), in.length()); + mbedtls_md5_finish(&_ctx, _buf); + for(i = 0; i < 16; i++) { + sprintf(out + (i * 2), "%02x", _buf[i]); + } + out[32] = 0; + free(_buf); + return String(out); +} + +bool WebServer::authenticate(const char * username, const char * password){ + if(hasHeader(FPSTR(AUTHORIZATION_HEADER))) { + String authReq = header(FPSTR(AUTHORIZATION_HEADER)); + if(authReq.startsWith(F("Basic"))){ + authReq = authReq.substring(6); + authReq.trim(); + char toencodeLen = strlen(username)+strlen(password)+1; + char *toencode = new char[toencodeLen + 1]; + if(toencode == NULL){ + authReq = ""; + return false; + } + char *encoded = new char[base64_encode_expected_len(toencodeLen)+1]; + if(encoded == NULL){ + authReq = ""; + delete[] toencode; + return false; + } + sprintf(toencode, "%s:%s", username, password); + if(base64_encode_chars(toencode, toencodeLen, encoded) > 0 && authReq.equalsConstantTime(encoded)) { + authReq = ""; + delete[] toencode; + delete[] encoded; + return true; + } + delete[] toencode; + delete[] encoded; + } else if(authReq.startsWith(F("Digest"))) { + authReq = authReq.substring(7); + log_v("%s", authReq.c_str()); + String _username = _extractParam(authReq,F("username=\""),'\"'); + if(!_username.length() || _username != String(username)) { + authReq = ""; + return false; + } + // extracting required parameters for RFC 2069 simpler Digest + String _realm = _extractParam(authReq, F("realm=\""),'\"'); + String _nonce = _extractParam(authReq, F("nonce=\""),'\"'); + String _uri = _extractParam(authReq, F("uri=\""),'\"'); + String _response = _extractParam(authReq, F("response=\""),'\"'); + String _opaque = _extractParam(authReq, F("opaque=\""),'\"'); + + if((!_realm.length()) || (!_nonce.length()) || (!_uri.length()) || (!_response.length()) || (!_opaque.length())) { + authReq = ""; + return false; + } + if((_opaque != _sopaque) || (_nonce != _snonce) || (_realm != _srealm)) { + authReq = ""; + return false; + } + // parameters for the RFC 2617 newer Digest + String _nc,_cnonce; + if(authReq.indexOf(FPSTR(qop_auth)) != -1) { + _nc = _extractParam(authReq, F("nc="), ','); + _cnonce = _extractParam(authReq, F("cnonce=\""),'\"'); + } + String _H1 = md5str(String(username) + ':' + _realm + ':' + String(password)); + log_v("Hash of user:realm:pass=%s", _H1.c_str()); + String _H2 = ""; + if(_currentMethod == HTTP_GET){ + _H2 = md5str(String(F("GET:")) + _uri); + }else if(_currentMethod == HTTP_POST){ + _H2 = md5str(String(F("POST:")) + _uri); + }else if(_currentMethod == HTTP_PUT){ + _H2 = md5str(String(F("PUT:")) + _uri); + }else if(_currentMethod == HTTP_DELETE){ + _H2 = md5str(String(F("DELETE:")) + _uri); + }else{ + _H2 = md5str(String(F("GET:")) + _uri); + } + log_v("Hash of GET:uri=%s", _H2.c_str()); + String _responsecheck = ""; + if(authReq.indexOf(FPSTR(qop_auth)) != -1) { + _responsecheck = md5str(_H1 + ':' + _nonce + ':' + _nc + ':' + _cnonce + F(":auth:") + _H2); + } else { + _responsecheck = md5str(_H1 + ':' + _nonce + ':' + _H2); + } + log_v("The Proper response=%s", _responsecheck.c_str()); + if(_response == _responsecheck){ + authReq = ""; + return true; + } + } + authReq = ""; + } + return false; +} + +String WebServer::_getRandomHexString() { + char buffer[33]; // buffer to hold 32 Hex Digit + /0 + int i; + for(i = 0; i < 4; i++) { + sprintf (buffer + (i*8), "%08x", esp_random()); + } + return String(buffer); +} + +void WebServer::requestAuthentication(HTTPAuthMethod mode, const char* realm, const String& authFailMsg) { + if(realm == NULL) { + _srealm = String(F("Login Required")); + } else { + _srealm = String(realm); + } + if(mode == BASIC_AUTH) { + sendHeader(String(FPSTR(WWW_Authenticate)), String(F("Basic realm=\"")) + _srealm + String(F("\""))); + } else { + _snonce=_getRandomHexString(); + _sopaque=_getRandomHexString(); + sendHeader(String(FPSTR(WWW_Authenticate)), String(F("Digest realm=\"")) +_srealm + String(F("\", qop=\"auth\", nonce=\"")) + _snonce + String(F("\", opaque=\"")) + _sopaque + String(F("\""))); + } + using namespace mime; + send(401, String(FPSTR(mimeTable[html].mimeType)), authFailMsg); +} + +void WebServer::on(const Uri &uri, WebServer::THandlerFunction handler) { + on(uri, HTTP_ANY, handler); +} + +void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn) { + on(uri, method, fn, _fileUploadHandler); +} + +void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn, WebServer::THandlerFunction ufn) { + _addRequestHandler(new FunctionRequestHandler(fn, ufn, uri, method)); +} + +void WebServer::addHandler(RequestHandler* handler) { + _addRequestHandler(handler); +} + +void WebServer::_addRequestHandler(RequestHandler* handler) { + if (!_lastHandler) { + _firstHandler = handler; + _lastHandler = handler; + } + else { + _lastHandler->next(handler); + _lastHandler = handler; + } +} + +void WebServer::serveStatic(const char* uri, FS& fs, const char* path, const char* cache_header) { + _addRequestHandler(new StaticRequestHandler(fs, path, uri, cache_header)); +} + +void WebServer::handleClient() { + if (_currentStatus == HC_NONE) { + WiFiClient client = _server.available(); + if (!client) { + if (_nullDelay) { + delay(1); + } + return; + } + + log_v("New client"); + + _currentClient = client; + _currentStatus = HC_WAIT_READ; + _statusChange = millis(); + } + + bool keepCurrentClient = false; + bool callYield = false; + + if (_currentClient.connected()) { + switch (_currentStatus) { + case HC_NONE: + // No-op to avoid C++ compiler warning + break; + case HC_WAIT_READ: + // Wait for data from client to become available + if (_currentClient.available()) { + if (_parseRequest(_currentClient)) { + // because HTTP_MAX_SEND_WAIT is expressed in milliseconds, + // it must be divided by 1000 + _currentClient.setTimeout(HTTP_MAX_SEND_WAIT / 1000); + _contentLength = CONTENT_LENGTH_NOT_SET; + _handleRequest(); + +// Fix for issue with Chrome based browsers: https://github.com/espressif/arduino-esp32/issues/3652 +// if (_currentClient.connected()) { +// _currentStatus = HC_WAIT_CLOSE; +// _statusChange = millis(); +// keepCurrentClient = true; +// } + } + } else { // !_currentClient.available() + if (millis() - _statusChange <= HTTP_MAX_DATA_WAIT) { + keepCurrentClient = true; + } + callYield = true; + } + break; + case HC_WAIT_CLOSE: + // Wait for client to close the connection + if (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT) { + keepCurrentClient = true; + callYield = true; + } + } + } + + if (!keepCurrentClient) { + _currentClient = WiFiClient(); + _currentStatus = HC_NONE; + _currentUpload.reset(); + } + + if (callYield) { + yield(); + } +} + +void WebServer::close() { + _server.close(); + _currentStatus = HC_NONE; + if(!_headerKeysCount) + collectHeaders(0, 0); +} + +void WebServer::stop() { + close(); +} + +void WebServer::sendHeader(const String& name, const String& value, bool first) { + String headerLine = name; + headerLine += F(": "); + headerLine += value; + headerLine += "\r\n"; + + if (first) { + _responseHeaders = headerLine + _responseHeaders; + } + else { + _responseHeaders += headerLine; + } +} + +void WebServer::setContentLength(const size_t contentLength) { + _contentLength = contentLength; +} + +void WebServer::enableDelay(boolean value) { + _nullDelay = value; +} + +void WebServer::enableCORS(boolean value) { + _corsEnabled = value; +} + +void WebServer::enableCrossOrigin(boolean value) { + enableCORS(value); +} + +void WebServer::_prepareHeader(String& response, int code, const char* content_type, size_t contentLength) { + response = String(F("HTTP/1.")) + String(_currentVersion) + ' '; + response += String(code); + response += ' '; + response += _responseCodeToString(code); + response += "\r\n"; + + using namespace mime; + if (!content_type) + content_type = mimeTable[html].mimeType; + + sendHeader(String(F("Content-Type")), String(FPSTR(content_type)), true); + if (_contentLength == CONTENT_LENGTH_NOT_SET) { + sendHeader(String(FPSTR(Content_Length)), String(contentLength)); + } else if (_contentLength != CONTENT_LENGTH_UNKNOWN) { + sendHeader(String(FPSTR(Content_Length)), String(_contentLength)); + } else if(_contentLength == CONTENT_LENGTH_UNKNOWN && _currentVersion){ //HTTP/1.1 or above client + //let's do chunked + _chunked = true; + sendHeader(String(F("Accept-Ranges")),String(F("none"))); + sendHeader(String(F("Transfer-Encoding")),String(F("chunked"))); + } + if (_corsEnabled) { + sendHeader(String(FPSTR("Access-Control-Allow-Origin")), String("*")); + } + sendHeader(String(F("Connection")), String(F("close"))); + + response += _responseHeaders; + response += "\r\n"; + _responseHeaders = ""; +} + +void WebServer::send(int code, const char* content_type, const String& content) { + String header; + // Can we asume the following? + //if(code == 200 && content.length() == 0 && _contentLength == CONTENT_LENGTH_NOT_SET) + // _contentLength = CONTENT_LENGTH_UNKNOWN; + _prepareHeader(header, code, content_type, content.length()); + _currentClientWrite(header.c_str(), header.length()); + if(content.length()) + sendContent(content); +} + +void WebServer::send_P(int code, PGM_P content_type, PGM_P content) { + size_t contentLength = 0; + + if (content != NULL) { + contentLength = strlen_P(content); + } + + String header; + char type[64]; + memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type)); + _prepareHeader(header, code, (const char* )type, contentLength); + _currentClientWrite(header.c_str(), header.length()); + sendContent_P(content); +} + +void WebServer::send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength) { + String header; + char type[64]; + memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type)); + _prepareHeader(header, code, (const char* )type, contentLength); + sendContent(header); + sendContent_P(content, contentLength); +} + +void WebServer::send(int code, char* content_type, const String& content) { + send(code, (const char*)content_type, content); +} + +void WebServer::send(int code, const String& content_type, const String& content) { + send(code, (const char*)content_type.c_str(), content); +} + +void WebServer::sendContent(const String& content) { + sendContent(content.c_str(), content.length()); +} + +void WebServer::sendContent(const char* content, size_t contentLength) { + const char * footer = "\r\n"; + if(_chunked) { + char * chunkSize = (char *)malloc(11); + if(chunkSize){ + sprintf(chunkSize, "%x%s", contentLength, footer); + _currentClientWrite(chunkSize, strlen(chunkSize)); + free(chunkSize); + } + } + _currentClientWrite(content, contentLength); + if(_chunked){ + _currentClient.write(footer, 2); + if (contentLength == 0) { + _chunked = false; + } + } +} + +void WebServer::sendContent_P(PGM_P content) { + sendContent_P(content, strlen_P(content)); +} + +void WebServer::sendContent_P(PGM_P content, size_t size) { + const char * footer = "\r\n"; + if(_chunked) { + char * chunkSize = (char *)malloc(11); + if(chunkSize){ + sprintf(chunkSize, "%x%s", size, footer); + _currentClientWrite(chunkSize, strlen(chunkSize)); + free(chunkSize); + } + } + _currentClientWrite_P(content, size); + if(_chunked){ + _currentClient.write(footer, 2); + if (size == 0) { + _chunked = false; + } + } +} + + +void WebServer::_streamFileCore(const size_t fileSize, const String & fileName, const String & contentType) +{ + using namespace mime; + setContentLength(fileSize); + if (fileName.endsWith(String(FPSTR(mimeTable[gz].endsWith))) && + contentType != String(FPSTR(mimeTable[gz].mimeType)) && + contentType != String(FPSTR(mimeTable[none].mimeType))) { + sendHeader(F("Content-Encoding"), F("gzip")); + } + send(200, contentType, ""); +} + +String WebServer::pathArg(unsigned int i) { + if (_currentHandler != nullptr) + return _currentHandler->pathArg(i); + return ""; +} + +String WebServer::arg(String name) { + for (int j = 0; j < _postArgsLen; ++j) { + if ( _postArgs[j].key == name ) + return _postArgs[j].value; + } + for (int i = 0; i < _currentArgCount; ++i) { + if ( _currentArgs[i].key == name ) + return _currentArgs[i].value; + } + return ""; +} + +String WebServer::arg(int i) { + if (i < _currentArgCount) + return _currentArgs[i].value; + return ""; +} + +String WebServer::argName(int i) { + if (i < _currentArgCount) + return _currentArgs[i].key; + return ""; +} + +int WebServer::args() { + return _currentArgCount; +} + +bool WebServer::hasArg(String name) { + for (int j = 0; j < _postArgsLen; ++j) { + if (_postArgs[j].key == name) + return true; + } + for (int i = 0; i < _currentArgCount; ++i) { + if (_currentArgs[i].key == name) + return true; + } + return false; +} + + +String WebServer::header(String name) { + for (int i = 0; i < _headerKeysCount; ++i) { + if (_currentHeaders[i].key.equalsIgnoreCase(name)) + return _currentHeaders[i].value; + } + return ""; +} + +void WebServer::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) { + _headerKeysCount = headerKeysCount + 1; + if (_currentHeaders) + delete[]_currentHeaders; + _currentHeaders = new RequestArgument[_headerKeysCount]; + _currentHeaders[0].key = FPSTR(AUTHORIZATION_HEADER); + for (int i = 1; i < _headerKeysCount; i++){ + _currentHeaders[i].key = headerKeys[i-1]; + } +} + +String WebServer::header(int i) { + if (i < _headerKeysCount) + return _currentHeaders[i].value; + return ""; +} + +String WebServer::headerName(int i) { + if (i < _headerKeysCount) + return _currentHeaders[i].key; + return ""; +} + +int WebServer::headers() { + return _headerKeysCount; +} + +bool WebServer::hasHeader(String name) { + for (int i = 0; i < _headerKeysCount; ++i) { + if ((_currentHeaders[i].key.equalsIgnoreCase(name)) && (_currentHeaders[i].value.length() > 0)) + return true; + } + return false; +} + +String WebServer::hostHeader() { + return _hostHeader; +} + +void WebServer::onFileUpload(THandlerFunction fn) { + _fileUploadHandler = fn; +} + +void WebServer::onNotFound(THandlerFunction fn) { + _notFoundHandler = fn; +} + +void WebServer::_handleRequest() { + bool handled = false; + if (!_currentHandler){ + log_e("request handler not found"); + } + else { + handled = _currentHandler->handle(*this, _currentMethod, _currentUri); + if (!handled) { + log_e("request handler failed to handle request"); + } + } + if (!handled && _notFoundHandler) { + _notFoundHandler(); + handled = true; + } + if (!handled) { + using namespace mime; + send(404, String(FPSTR(mimeTable[html].mimeType)), String(F("Not found: ")) + _currentUri); + handled = true; + } + if (handled) { + _finalizeResponse(); + } + _currentUri = ""; +} + + +void WebServer::_finalizeResponse() { + if (_chunked) { + sendContent(""); + } +} + +String WebServer::_responseCodeToString(int code) { + switch (code) { + case 100: return F("Continue"); + case 101: return F("Switching Protocols"); + case 200: return F("OK"); + case 201: return F("Created"); + case 202: return F("Accepted"); + case 203: return F("Non-Authoritative Information"); + case 204: return F("No Content"); + case 205: return F("Reset Content"); + case 206: return F("Partial Content"); + case 300: return F("Multiple Choices"); + case 301: return F("Moved Permanently"); + case 302: return F("Found"); + case 303: return F("See Other"); + case 304: return F("Not Modified"); + case 305: return F("Use Proxy"); + case 307: return F("Temporary Redirect"); + case 400: return F("Bad Request"); + case 401: return F("Unauthorized"); + case 402: return F("Payment Required"); + case 403: return F("Forbidden"); + case 404: return F("Not Found"); + case 405: return F("Method Not Allowed"); + case 406: return F("Not Acceptable"); + case 407: return F("Proxy Authentication Required"); + case 408: return F("Request Time-out"); + case 409: return F("Conflict"); + case 410: return F("Gone"); + case 411: return F("Length Required"); + case 412: return F("Precondition Failed"); + case 413: return F("Request Entity Too Large"); + case 414: return F("Request-URI Too Large"); + case 415: return F("Unsupported Media Type"); + case 416: return F("Requested range not satisfiable"); + case 417: return F("Expectation Failed"); + case 500: return F("Internal Server Error"); + case 501: return F("Not Implemented"); + case 502: return F("Bad Gateway"); + case 503: return F("Service Unavailable"); + case 504: return F("Gateway Time-out"); + case 505: return F("HTTP Version not supported"); + default: return F(""); + } +} diff --git a/esp32s2_WebServer_Patch/WebServer.h b/esp32s2_WebServer_Patch/WebServer.h new file mode 100644 index 00000000..38c10167 --- /dev/null +++ b/esp32s2_WebServer_Patch/WebServer.h @@ -0,0 +1,211 @@ +/* + WebServer.h - Dead simple web-server. + Supports only one simultaneous client, knows how to handle GET and POST. + + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling) +*/ + + +#ifndef WEBSERVER_H +#define WEBSERVER_H + +#include +#include +#include +#include "HTTP_Method.h" +#include "Uri.h" + +enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END, + UPLOAD_FILE_ABORTED }; +enum HTTPClientStatus { HC_NONE, HC_WAIT_READ, HC_WAIT_CLOSE }; +enum HTTPAuthMethod { BASIC_AUTH, DIGEST_AUTH }; + +#define HTTP_DOWNLOAD_UNIT_SIZE 1436 + +#ifndef HTTP_UPLOAD_BUFLEN +#define HTTP_UPLOAD_BUFLEN 1436 +#endif + +#define HTTP_MAX_DATA_WAIT 5000 //ms to wait for the client to send the request +#define HTTP_MAX_POST_WAIT 5000 //ms to wait for POST data to arrive +#define HTTP_MAX_SEND_WAIT 5000 //ms to wait for data chunk to be ACKed +#define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection + +#define CONTENT_LENGTH_UNKNOWN ((size_t) -1) +#define CONTENT_LENGTH_NOT_SET ((size_t) -2) + +class WebServer; + +typedef struct { + HTTPUploadStatus status; + String filename; + String name; + String type; + size_t totalSize; // file size + size_t currentSize; // size of data currently in buf + uint8_t buf[HTTP_UPLOAD_BUFLEN]; +} HTTPUpload; + +#include "detail/RequestHandler.h" + +namespace fs { +class FS; +} + +class WebServer +{ +public: + WebServer(IPAddress addr, int port = 80); + WebServer(int port = 80); + virtual ~WebServer(); + + virtual void begin(); + virtual void begin(uint16_t port); + virtual void handleClient(); + + virtual void close(); + void stop(); + + bool authenticate(const char * username, const char * password); + void requestAuthentication(HTTPAuthMethod mode = BASIC_AUTH, const char* realm = NULL, const String& authFailMsg = String("") ); + + typedef std::function THandlerFunction; + void on(const Uri &uri, THandlerFunction handler); + void on(const Uri &uri, HTTPMethod method, THandlerFunction fn); + void on(const Uri &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn); + void addHandler(RequestHandler* handler); + void serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_header = NULL ); + void onNotFound(THandlerFunction fn); //called when handler is not assigned + void onFileUpload(THandlerFunction fn); //handle file uploads + + String uri() { return _currentUri; } + HTTPMethod method() { return _currentMethod; } + virtual WiFiClient client() { return _currentClient; } + HTTPUpload& upload() { return *_currentUpload; } + + String pathArg(unsigned int i); // get request path argument by number + String arg(String name); // get request argument value by name + String arg(int i); // get request argument value by number + String argName(int i); // get request argument name by number + int args(); // get arguments count + bool hasArg(String name); // check if argument exists + void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); // set the request headers to collect + String header(String name); // get request header value by name + String header(int i); // get request header value by number + String headerName(int i); // get request header name by number + int headers(); // get header count + bool hasHeader(String name); // check if header exists + + String hostHeader(); // get request host header if available or empty String if not + + // send response to the client + // code - HTTP response code, can be 200 or 404 + // content_type - HTTP content type, like "text/plain" or "image/png" + // content - actual content body + void send(int code, const char* content_type = NULL, const String& content = String("")); + void send(int code, char* content_type, const String& content); + void send(int code, const String& content_type, const String& content); + void send_P(int code, PGM_P content_type, PGM_P content); + void send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength); + + void enableDelay(boolean value); + void enableCORS(boolean value = true); + void enableCrossOrigin(boolean value = true); + + void setContentLength(const size_t contentLength); + void sendHeader(const String& name, const String& value, bool first = false); + void sendContent(const String& content); + void sendContent(const char* content, size_t contentLength); + void sendContent_P(PGM_P content); + void sendContent_P(PGM_P content, size_t size); + + static String urlDecode(const String& text); + + template + size_t streamFile(T &file, const String& contentType) { + _streamFileCore(file.size(), file.name(), contentType); + return _currentClient.write(file); + } + +protected: + virtual size_t _currentClientWrite(const char* b, size_t l) { return _currentClient.write( b, l ); } + virtual size_t _currentClientWrite_P(PGM_P b, size_t l) { return _currentClient.write_P( b, l ); } + void _addRequestHandler(RequestHandler* handler); + void _handleRequest(); + void _finalizeResponse(); + bool _parseRequest(WiFiClient& client); + void _parseArguments(String data); + static String _responseCodeToString(int code); + bool _parseForm(WiFiClient& client, String boundary, uint32_t len); + bool _parseFormUploadAborted(); + void _uploadWriteByte(uint8_t b); + int _uploadReadByte(WiFiClient& client); + void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength); + bool _collectHeader(const char* headerName, const char* headerValue); + + void _streamFileCore(const size_t fileSize, const String & fileName, const String & contentType); + + String _getRandomHexString(); + // for extracting Auth parameters + String _extractParam(String& authReq,const String& param,const char delimit = '"'); + + struct RequestArgument { + String key; + String value; + }; + + boolean _corsEnabled; + WiFiServer _server; + + WiFiClient _currentClient; + HTTPMethod _currentMethod; + String _currentUri; + uint8_t _currentVersion; + HTTPClientStatus _currentStatus; + unsigned long _statusChange; + bool _nullDelay; + + RequestHandler* _currentHandler; + RequestHandler* _firstHandler; + RequestHandler* _lastHandler; + THandlerFunction _notFoundHandler; + THandlerFunction _fileUploadHandler; + + int _currentArgCount; + RequestArgument* _currentArgs; + int _postArgsLen; + RequestArgument* _postArgs; + + std::unique_ptr _currentUpload; + + int _headerKeysCount; + RequestArgument* _currentHeaders; + size_t _contentLength; + String _responseHeaders; + + String _hostHeader; + bool _chunked; + + String _snonce; // Store noance and opaque for future comparison + String _sopaque; + String _srealm; // Store the Auth realm between Calls + +}; + + +#endif //ESP8266WEBSERVER_H diff --git a/examples/AsyncCustomHeader_STM32/AsyncCustomHeader_STM32.ino b/examples/AsyncCustomHeader_STM32/AsyncCustomHeader_STM32.ino index 37ab6b20..00f6978e 100644 --- a/examples/AsyncCustomHeader_STM32/AsyncCustomHeader_STM32.ino +++ b/examples/AsyncCustomHeader_STM32/AsyncCustomHeader_STM32.ino @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #include "defines.h" @@ -35,8 +36,8 @@ //char GET_ServerAddress[] = "192.168.2.110/"; char GET_ServerAddress[] = "http://worldtimeapi.org/api/timezone/America/Toronto.txt"; -// 600s = 10 minutes to not flooding, 10s in testing -#define HTTP_REQUEST_INTERVAL_MS 10000 //600000 +// 600s = 10 minutes to not flooding, 60s in testing +#define HTTP_REQUEST_INTERVAL_MS 60000 //600000 #include // https://github.com/khoih-prog/AsyncHTTPRequest_Generic diff --git a/examples/AsyncCustomHeader_STM32/defines.h b/examples/AsyncCustomHeader_STM32/defines.h index e8e5fa44..264966f9 100644 --- a/examples/AsyncCustomHeader_STM32/defines.h +++ b/examples/AsyncCustomHeader_STM32/defines.h @@ -19,7 +19,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -29,6 +29,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ /* Currently support diff --git a/examples/AsyncDweetGet_STM32/AsyncDweetGet_STM32.ino b/examples/AsyncDweetGet_STM32/AsyncDweetGet_STM32.ino index ff3b40bf..52d1b838 100644 --- a/examples/AsyncDweetGet_STM32/AsyncDweetGet_STM32.ino +++ b/examples/AsyncDweetGet_STM32/AsyncDweetGet_STM32.ino @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ /** @@ -46,8 +47,8 @@ const char GET_ServerAddress[] = "dweet.io"; // use your own thing name here String dweetName = "/dweet/for/currentSecond?second="; -// 10s = 10 seconds to not flooding the server -#define HTTP_REQUEST_INTERVAL_MS 10000 +// 60s = 60 seconds to not flooding the server +#define HTTP_REQUEST_INTERVAL_MS 60000 #include // https://github.com/khoih-prog/AsyncHTTPRequest_Generic diff --git a/examples/AsyncDweetGet_STM32/defines.h b/examples/AsyncDweetGet_STM32/defines.h index e8e5fa44..264966f9 100644 --- a/examples/AsyncDweetGet_STM32/defines.h +++ b/examples/AsyncDweetGet_STM32/defines.h @@ -19,7 +19,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -29,6 +29,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ /* Currently support diff --git a/examples/AsyncDweetPost_STM32/AsyncDweetPost_STM32.ino b/examples/AsyncDweetPost_STM32/AsyncDweetPost_STM32.ino index 09081869..f8686384 100644 --- a/examples/AsyncDweetPost_STM32/AsyncDweetPost_STM32.ino +++ b/examples/AsyncDweetPost_STM32/AsyncDweetPost_STM32.ino @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ // Dweet.io POST client. Connects to dweet.io once every ten seconds, sends a POST request and a request body. @@ -40,8 +41,8 @@ const char POST_ServerAddress[] = "dweet.io"; // use your own thing name here String dweetName = "/dweet/for/pinA0-Read?"; -// 10s = 10 seconds to not flooding the server -#define HTTP_REQUEST_INTERVAL_MS 10000 +// 60s = 60 seconds to not flooding the server +#define HTTP_REQUEST_INTERVAL_MS 60000 #include // https://github.com/khoih-prog/AsyncHTTPRequest_Generic diff --git a/examples/AsyncDweetPost_STM32/defines.h b/examples/AsyncDweetPost_STM32/defines.h index e8e5fa44..264966f9 100644 --- a/examples/AsyncDweetPost_STM32/defines.h +++ b/examples/AsyncDweetPost_STM32/defines.h @@ -19,7 +19,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -29,6 +29,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ /* Currently support diff --git a/examples/AsyncHTTPMultiRequests_ESP/AsyncHTTPMultiRequests_ESP.ino b/examples/AsyncHTTPMultiRequests_ESP/AsyncHTTPMultiRequests_ESP.ino index 61fa38e2..f90ba022 100644 --- a/examples/AsyncHTTPMultiRequests_ESP/AsyncHTTPMultiRequests_ESP.ino +++ b/examples/AsyncHTTPMultiRequests_ESP/AsyncHTTPMultiRequests_ESP.ino @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ //************************************************************************************************************ // @@ -60,7 +61,7 @@ #define _ASYNC_HTTP_LOGLEVEL_ 1 // 300s = 5 minutes to not flooding -#define HTTP_REQUEST_INTERVAL 30 //300 +#define HTTP_REQUEST_INTERVAL 60 //300 // 10s #define HEARTBEAT_INTERVAL 10 diff --git a/examples/AsyncHTTPRequest_ESP/AsyncHTTPRequest_ESP.ino b/examples/AsyncHTTPRequest_ESP/AsyncHTTPRequest_ESP.ino index 179ff4cf..c8ed46e9 100644 --- a/examples/AsyncHTTPRequest_ESP/AsyncHTTPRequest_ESP.ino +++ b/examples/AsyncHTTPRequest_ESP/AsyncHTTPRequest_ESP.ino @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ //************************************************************************************************************ // @@ -60,7 +61,7 @@ #define _ASYNC_HTTP_LOGLEVEL_ 1 // 300s = 5 minutes to not flooding -#define HTTP_REQUEST_INTERVAL 30 //300 +#define HTTP_REQUEST_INTERVAL 60 //300 // 10s #define HEARTBEAT_INTERVAL 10 diff --git a/examples/AsyncHTTPRequest_ESP_WiFiManager/AsyncHTTPRequest_ESP_WiFiManager.ino b/examples/AsyncHTTPRequest_ESP_WiFiManager/AsyncHTTPRequest_ESP_WiFiManager.ino index 28985c87..fb428f9c 100644 --- a/examples/AsyncHTTPRequest_ESP_WiFiManager/AsyncHTTPRequest_ESP_WiFiManager.ino +++ b/examples/AsyncHTTPRequest_ESP_WiFiManager/AsyncHTTPRequest_ESP_WiFiManager.ino @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ //************************************************************************************************************ // @@ -61,8 +62,8 @@ #define ASYNC_HTTP_DEBUG_PORT Serial #define _ASYNC_HTTP_LOGLEVEL_ 1 -// 300s = 5 minutes to not flooding, 10s in testing -#define HTTP_REQUEST_INTERVAL 10 //300 +// 300s = 5 minutes to not flooding, 60s in testing +#define HTTP_REQUEST_INTERVAL 60 //300 //Ported to ESP32 #ifdef ESP32 @@ -74,9 +75,22 @@ #include WiFiMulti wifiMulti; - #define USE_SPIFFS true + // LittleFS has higher priority than SPIFFS + #define USE_LITTLEFS true + #define USE_SPIFFS false - #if USE_SPIFFS + #if USE_LITTLEFS + // Use LittleFS + #include "FS.h" + + // The library will be depreciated after being merged to future major Arduino esp32 core release 2.x + // At that time, just remove this library inclusion + #include // https://github.com/lorol/LITTLEFS + + FS* filesystem = &LITTLEFS; + #define FileFS LITTLEFS + #define FS_Name "LittleFS" + #elif USE_SPIFFS #include FS* filesystem = &SPIFFS; #define FileFS SPIFFS diff --git a/examples/AsyncHTTPRequest_STM32/AsyncHTTPRequest_STM32.ino b/examples/AsyncHTTPRequest_STM32/AsyncHTTPRequest_STM32.ino index 8f87f5ab..08e171b1 100644 --- a/examples/AsyncHTTPRequest_STM32/AsyncHTTPRequest_STM32.ino +++ b/examples/AsyncHTTPRequest_STM32/AsyncHTTPRequest_STM32.ino @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ //************************************************************************************************************ // @@ -53,8 +54,8 @@ #include "defines.h" -// 600s = 10 minutes to not flooding, 10s in testing -#define HTTP_REQUEST_INTERVAL_MS 10000 //600000 +// 600s = 10 minutes to not flooding, 60s in testing +#define HTTP_REQUEST_INTERVAL_MS 60000 //600000 #include // https://github.com/khoih-prog/AsyncHTTPRequest_Generic diff --git a/examples/AsyncHTTPRequest_STM32/defines.h b/examples/AsyncHTTPRequest_STM32/defines.h index e8e5fa44..264966f9 100644 --- a/examples/AsyncHTTPRequest_STM32/defines.h +++ b/examples/AsyncHTTPRequest_STM32/defines.h @@ -19,7 +19,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -29,6 +29,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ /* Currently support diff --git a/examples/AsyncSimpleGET_STM32/AsyncSimpleGET_STM32.ino b/examples/AsyncSimpleGET_STM32/AsyncSimpleGET_STM32.ino index 4ce31b57..3373178c 100644 --- a/examples/AsyncSimpleGET_STM32/AsyncSimpleGET_STM32.ino +++ b/examples/AsyncSimpleGET_STM32/AsyncSimpleGET_STM32.ino @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #include "defines.h" @@ -35,8 +36,8 @@ //char GET_ServerAddress[] = "ipv4bot.whatismyipaddress.com/"; char GET_ServerAddress[] = "http://worldtimeapi.org/api/timezone/America/Toronto.txt"; -// 600s = 10 minutes to not flooding, 10s in testing -#define HTTP_REQUEST_INTERVAL_MS 10000 //600000 +// 600s = 10 minutes to not flooding, 60s in testing +#define HTTP_REQUEST_INTERVAL_MS 60000 //600000 #include // https://github.com/khoih-prog/AsyncHTTPRequest_Generic diff --git a/examples/AsyncSimpleGET_STM32/defines.h b/examples/AsyncSimpleGET_STM32/defines.h index 9a043716..a9f9fd3e 100644 --- a/examples/AsyncSimpleGET_STM32/defines.h +++ b/examples/AsyncSimpleGET_STM32/defines.h @@ -19,7 +19,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -29,6 +29,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ /* Currently support diff --git a/examples/AsyncWebClientRepeating_STM32/AsyncWebClientRepeating_STM32.ino b/examples/AsyncWebClientRepeating_STM32/AsyncWebClientRepeating_STM32.ino index d4b9f409..83fcc05d 100644 --- a/examples/AsyncWebClientRepeating_STM32/AsyncWebClientRepeating_STM32.ino +++ b/examples/AsyncWebClientRepeating_STM32/AsyncWebClientRepeating_STM32.ino @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #include "defines.h" @@ -37,8 +38,8 @@ const char GET_ServerAddress[] = "arduino.cc"; // GET location String GET_Location = "/asciilogo.txt"; -// 10s = 10 seconds to not flooding the server -#define HTTP_REQUEST_INTERVAL_MS 10000 +// 60s = 60 seconds to not flooding the server +#define HTTP_REQUEST_INTERVAL_MS 60000 #include // https://github.com/khoih-prog/AsyncHTTPRequest_Generic diff --git a/examples/AsyncWebClientRepeating_STM32/defines.h b/examples/AsyncWebClientRepeating_STM32/defines.h index e8e5fa44..264966f9 100644 --- a/examples/AsyncWebClientRepeating_STM32/defines.h +++ b/examples/AsyncWebClientRepeating_STM32/defines.h @@ -19,7 +19,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -29,6 +29,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ /* Currently support diff --git a/library.json b/library.json index 2de4045f..5a539039 100644 --- a/library.json +++ b/library.json @@ -1,8 +1,8 @@ { "name":"AsyncHTTPRequest_Generic", - "version": "1.1.2", - "description":"Simple Async HTTP Request library, supporting GET, POST, PUT, PATCH, DELETE and HEAD, on top of AsyncTCP libraries, such as AsyncTCP, ESPAsyncTCP, AsyncTCP_STM32, etc.. for ESP32, ESP8266 and currently STM32 with built-in LAN8742A Ethernet.", - "keywords":"async,tcp,http,ESP8266,ESP32,ESPAsyncTCP,AsyncTCP,stm32,ethernet,wifi,lan8742a", + "version": "1.1.3", + "description":"Simple Async HTTP Request library, supporting GET, POST, PUT, PATCH, DELETE and HEAD, on top of AsyncTCP libraries, such as AsyncTCP, ESPAsyncTCP, AsyncTCP_STM32, etc.. for ESP32 (including ESP32-S2), ESP8266 and currently STM32 with built-in LAN8742A Ethernet.", + "keywords":"async,tcp,http,ESP8266,ESP32,ESP32-S2,ESPAsyncTCP,AsyncTCP,stm32,ethernet,wifi,lan8742a", "authors": [ { "name": "Bob Lemaire", @@ -39,7 +39,7 @@ { "owner": "khoih.prog", "name": "ESPAsync_WiFiManager", - "version": ">=1.4.3", + "version": ">=1.6.0", "platforms": ["espressif8266", "espressif32"] }, { @@ -54,6 +54,12 @@ "version": ">=1.2.0", "platforms": "ststm32" }, + { + "owner": "lorol", + "name": "LittleFS_esp32", + "version": ">=1.0.5", + "platforms": ["espressif32"] + }, { "name": "external-repo", "version": "https://github.com/philbowles/STM32AsyncTCP" diff --git a/library.properties b/library.properties index 1594f173..3b356e94 100644 --- a/library.properties +++ b/library.properties @@ -1,12 +1,12 @@ name=AsyncHTTPRequest_Generic -version=1.1.2 +version=1.1.3 author=Bob Lemaire,Khoi Hoang maintainer=Khoi Hoang license=MIT -sentence=Simple Async HTTP Request library, supporting GET, POST, PUT, PATCH, DELETE and HEAD, on top of AsyncTCP libraries, such as AsyncTCP, ESPAsyncTCP, AsyncTCP_STM32, etc.. for ESP32, ESP8266 and currently STM32 with built-in LAN8742A Ethernet. -paragraph=This AsyncHTTPRequest_Generic Library, supporting GET and POST, for ESP32, ESP8266 and STM32 with built-in LAN8742A Ethernet, such as Nucleo-144 F767ZI, etc. +sentence=Simple Async HTTP Request library, supporting GET, POST, PUT, PATCH, DELETE and HEAD, on top of AsyncTCP libraries, such as AsyncTCP, ESPAsyncTCP, AsyncTCP_STM32, etc.. for ESP32 (including ESP32-S2), ESP8266 and currently STM32 with built-in LAN8742A Ethernet. +paragraph=This AsyncHTTPRequest_Generic Library, supporting GET, POST, PUT, PATCH, DELETE and HEAD, for ESP32 (including ESP32-S2), ESP8266 and STM32 with built-in LAN8742A Ethernet, such as Nucleo-144 F767ZI, etc. category=Communication,AsyncTCP,AsyncHTTP url=https://github.com/khoih-prog/AsyncHTTPRequest_Generic architectures=* -depends=AsyncTCP,ESP AsyncTCP,ESPAsync_WiFiManager,STM32duino LwIP,STM32duino STM32Ethernet,STM32 AsyncTCP +depends=AsyncTCP,ESP AsyncTCP,ESPAsync_WiFiManager,STM32duino LwIP,STM32duino STM32Ethernet,STM32 AsyncTCP,LittleFS_esp32 includes=AsyncHTTPRequest_Generic.h diff --git a/platformio/platformio.ini b/platformio/platformio.ini index 62dad808..cb5d2c7d 100644 --- a/platformio/platformio.ini +++ b/platformio/platformio.ini @@ -40,14 +40,16 @@ lib_deps = STM32AsyncTCP@>=1.0.0 STM32duino LwIP@>=2.1.2 STM32duino STM32Ethernet@>=1.2.0 - ESPAsync_WiFiManager@>=1.4.1 + ESPAsync_WiFiManager@>=1.6.0 + LittleFS_esp32@>=1.0.5 ; PlatformIO 5.x ; me-no-dev/AsyncTCP@>=1.1.1 ; me-no-dev/ESPAsyncTCP@>=1.2.2 ; philbowles/STM32AsyncTCP@>=1.0.0 ; stm32duino/STM32duino LwIP@>=2.1.2 ; stm32duino/STM32duino STM32Ethernet@>=1.2.0 -; khoih-prog/ESPAsync_WiFiManager@>=1.4.1 +; khoih-prog/ESPAsync_WiFiManager@>=1.6.0 +; lorol/LittleFS_esp32@>=1.0.5 build_flags = ; set your debug output (default=Serial) diff --git a/src/AsyncHTTPRequest_Debug_Generic.h b/src/AsyncHTTPRequest_Debug_Generic.h index 59d6e443..6396018e 100644 --- a/src/AsyncHTTPRequest_Debug_Generic.h +++ b/src/AsyncHTTPRequest_Debug_Generic.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #pragma once @@ -51,29 +52,49 @@ #define _ASYNC_HTTP_LOGLEVEL_ 0 #endif -#define AHTTP_LOGERROR(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); } -#define AHTTP_LOGERROR0(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print(x); } -#define AHTTP_LOGERROR1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); } -#define AHTTP_LOGERROR2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); } -#define AHTTP_LOGERROR3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); } - -#define AHTTP_LOGWARN(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); } -#define AHTTP_LOGWARN0(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print(x); } -#define AHTTP_LOGWARN1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); } -#define AHTTP_LOGWARN2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); } -#define AHTTP_LOGWARN3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); } - -#define AHTTP_LOGINFO(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); } -#define AHTTP_LOGINFO0(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print(x); } -#define AHTTP_LOGINFO1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); } -#define AHTTP_LOGINFO2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); } -#define AHTTP_LOGINFO3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); } - -#define AHTTP_LOGDEBUG(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); } -#define AHTTP_LOGDEBUG0(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print(x); } -#define AHTTP_LOGDEBUG1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); } -#define AHTTP_LOGDEBUG2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); } -#define AHTTP_LOGDEBUG3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); } +///////////////////////////////////////////////////////// + +const char AHTTP_MARK[] = "[AHTTP] "; + +#define AHTTP_PRINT_MARK AHTTP_PRINT(AHTTP_MARK) +#define AHTTP_PRINT_SP A_DBG_PORT.print(" ") + +#define AHTTP_PRINT A_DBG_PORT.print +#define AHTTP_PRINTLN A_DBG_PORT.println + +///////////////////////////////////////////////////////// + +#define AHTTP_LOGERROR(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT_MARK; AHTTP_PRINTLN(x); } +#define AHTTP_LOGERROR0(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT(x); } +#define AHTTP_LOGERROR1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINTLN(y); } +#define AHTTP_LOGERROR2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINTLN(z); } +#define AHTTP_LOGERROR3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINT(z); AHTTP_PRINT_SP; AHTTP_PRINTLN(w); } + +///////////////////////////////////////////////////////// + +#define AHTTP_LOGWARN(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT_MARK; AHTTP_PRINTLN(x); } +#define AHTTP_LOGWARN0(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT(x); } +#define AHTTP_LOGWARN1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINTLN(y); } +#define AHTTP_LOGWARN2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINTLN(z); } +#define AHTTP_LOGWARN3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINT(z); AHTTP_PRINT_SP; AHTTP_PRINTLN(w); } + +///////////////////////////////////////////////////////// + +#define AHTTP_LOGINFO(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT_MARK; AHTTP_PRINTLN(x); } +#define AHTTP_LOGINFO0(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT(x); } +#define AHTTP_LOGINFO1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINTLN(y); } +#define AHTTP_LOGINFO2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINTLN(z); } +#define AHTTP_LOGINFO3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINT(z); AHTTP_PRINT_SP; AHTTP_PRINTLN(w); } + +///////////////////////////////////////////////////////// + +#define AHTTP_LOGDEBUG(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT_MARK; AHTTP_PRINTLN(x); } +#define AHTTP_LOGDEBUG0(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT(x); } +#define AHTTP_LOGDEBUG1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINTLN(y); } +#define AHTTP_LOGDEBUG2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINTLN(z); } +#define AHTTP_LOGDEBUG3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINT(z); AHTTP_PRINT_SP; AHTTP_PRINTLN(w); } + +///////////////////////////////////////////////////////// #endif // ASYNC_HTTP_REQUEST_DEBUG_GENERIC_H diff --git a/src/AsyncHTTPRequest_Generic.h b/src/AsyncHTTPRequest_Generic.h index 001b9e55..644cf383 100644 --- a/src/AsyncHTTPRequest_Generic.h +++ b/src/AsyncHTTPRequest_Generic.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #pragma once @@ -34,7 +35,7 @@ #ifndef ASYNC_HTTP_REQUEST_GENERIC_H #define ASYNC_HTTP_REQUEST_GENERIC_H -#define ASYNC_HTTP_REQUEST_GENERIC_VERSION "AsyncHTTPRequest_Generic v1.1.2" +#define ASYNC_HTTP_REQUEST_GENERIC_VERSION "AsyncHTTPRequest_Generic v1.1.3" #include diff --git a/src/AsyncHTTPRequest_Impl_Generic.h b/src/AsyncHTTPRequest_Impl_Generic.h index 2d59a3c5..ae236f4a 100644 --- a/src/AsyncHTTPRequest_Impl_Generic.h +++ b/src/AsyncHTTPRequest_Impl_Generic.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #pragma once @@ -873,7 +874,7 @@ void AsyncHTTPRequest::_processChunks() { char* connectionHdr = respHeaderValue("connection"); - if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("disconnect")) == 0)) + if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("close")) == 0)) { AHTTP_LOGDEBUG("*all chunks received - closing TCP"); @@ -1078,7 +1079,7 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len) { char* connectionHdr = respHeaderValue("connection"); - if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("disconnect")) == 0)) + if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("close")) == 0)) { AHTTP_LOGDEBUG("*all data received - closing TCP"); diff --git a/src/utility/xbuf.h b/src/utility/xbuf.h index 48288470..1dd84937 100644 --- a/src/utility/xbuf.h +++ b/src/utility/xbuf.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ /******************************************************************************************** diff --git a/src/utility/xbuf_Impl.h b/src/utility/xbuf_Impl.h index b048979d..333c6e9f 100644 --- a/src/utility/xbuf_Impl.h +++ b/src/utility/xbuf_Impl.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #pragma once diff --git a/src_cpp/AsyncHTTPRequest_Debug_Generic.h b/src_cpp/AsyncHTTPRequest_Debug_Generic.h index 59d6e443..6396018e 100644 --- a/src_cpp/AsyncHTTPRequest_Debug_Generic.h +++ b/src_cpp/AsyncHTTPRequest_Debug_Generic.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #pragma once @@ -51,29 +52,49 @@ #define _ASYNC_HTTP_LOGLEVEL_ 0 #endif -#define AHTTP_LOGERROR(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); } -#define AHTTP_LOGERROR0(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print(x); } -#define AHTTP_LOGERROR1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); } -#define AHTTP_LOGERROR2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); } -#define AHTTP_LOGERROR3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); } - -#define AHTTP_LOGWARN(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); } -#define AHTTP_LOGWARN0(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print(x); } -#define AHTTP_LOGWARN1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); } -#define AHTTP_LOGWARN2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); } -#define AHTTP_LOGWARN3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); } - -#define AHTTP_LOGINFO(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); } -#define AHTTP_LOGINFO0(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print(x); } -#define AHTTP_LOGINFO1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); } -#define AHTTP_LOGINFO2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); } -#define AHTTP_LOGINFO3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); } - -#define AHTTP_LOGDEBUG(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); } -#define AHTTP_LOGDEBUG0(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print(x); } -#define AHTTP_LOGDEBUG1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); } -#define AHTTP_LOGDEBUG2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); } -#define AHTTP_LOGDEBUG3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); } +///////////////////////////////////////////////////////// + +const char AHTTP_MARK[] = "[AHTTP] "; + +#define AHTTP_PRINT_MARK AHTTP_PRINT(AHTTP_MARK) +#define AHTTP_PRINT_SP A_DBG_PORT.print(" ") + +#define AHTTP_PRINT A_DBG_PORT.print +#define AHTTP_PRINTLN A_DBG_PORT.println + +///////////////////////////////////////////////////////// + +#define AHTTP_LOGERROR(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT_MARK; AHTTP_PRINTLN(x); } +#define AHTTP_LOGERROR0(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT(x); } +#define AHTTP_LOGERROR1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINTLN(y); } +#define AHTTP_LOGERROR2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINTLN(z); } +#define AHTTP_LOGERROR3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINT(z); AHTTP_PRINT_SP; AHTTP_PRINTLN(w); } + +///////////////////////////////////////////////////////// + +#define AHTTP_LOGWARN(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT_MARK; AHTTP_PRINTLN(x); } +#define AHTTP_LOGWARN0(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT(x); } +#define AHTTP_LOGWARN1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINTLN(y); } +#define AHTTP_LOGWARN2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINTLN(z); } +#define AHTTP_LOGWARN3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINT(z); AHTTP_PRINT_SP; AHTTP_PRINTLN(w); } + +///////////////////////////////////////////////////////// + +#define AHTTP_LOGINFO(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT_MARK; AHTTP_PRINTLN(x); } +#define AHTTP_LOGINFO0(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT(x); } +#define AHTTP_LOGINFO1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINTLN(y); } +#define AHTTP_LOGINFO2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINTLN(z); } +#define AHTTP_LOGINFO3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINT(z); AHTTP_PRINT_SP; AHTTP_PRINTLN(w); } + +///////////////////////////////////////////////////////// + +#define AHTTP_LOGDEBUG(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT_MARK; AHTTP_PRINTLN(x); } +#define AHTTP_LOGDEBUG0(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT(x); } +#define AHTTP_LOGDEBUG1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINTLN(y); } +#define AHTTP_LOGDEBUG2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINTLN(z); } +#define AHTTP_LOGDEBUG3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINT(z); AHTTP_PRINT_SP; AHTTP_PRINTLN(w); } + +///////////////////////////////////////////////////////// #endif // ASYNC_HTTP_REQUEST_DEBUG_GENERIC_H diff --git a/src_cpp/AsyncHTTPRequest_Generic.cpp b/src_cpp/AsyncHTTPRequest_Generic.cpp index 9d586fd1..8281d3d8 100644 --- a/src_cpp/AsyncHTTPRequest_Generic.cpp +++ b/src_cpp/AsyncHTTPRequest_Generic.cpp @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #include "AsyncHTTPRequest_Debug_Generic.h" @@ -96,6 +97,8 @@ bool AsyncHTTPRequest::open(const char* method, const char* URL) if (_readyState != readyStateUnsent && _readyState != readyStateDone) { + AHTTP_LOGDEBUG("open: not ready"); + return false; } @@ -148,17 +151,23 @@ bool AsyncHTTPRequest::open(const char* method, const char* URL) ////// else { + AHTTP_LOGDEBUG("open: Bad method"); + return false; } if (!_parseURL(URL)) { + AHTTP_LOGDEBUG("open: error parsing URL"); + return false; } if ( _client && _client->connected() && (strcmp(_URL->host, _connectedHost) != 0 || _URL->port != _connectedPort)) { + AHTTP_LOGDEBUG("open: not connected"); + return false; } @@ -176,11 +185,17 @@ bool AsyncHTTPRequest::open(const char* method, const char* URL) // New in v1.1.1 _requestReadyToSend = true; ////// + + AHTTP_LOGDEBUG1("open: conneting to hostname =", hostName); return _connect(); } else + { + AHTTP_LOGDEBUG("open: error alloc"); + return false; + } } //************************************************************************************************************** void AsyncHTTPRequest::onReadyStateChange(readyStateChangeCB cb, void* arg) @@ -422,13 +437,61 @@ String AsyncHTTPRequest::responseText() localString = _response->readString(avail); _contentRead += localString.length(); - AHTTP_LOGDEBUG3("responseText(char)", localString.substring(0, 16).c_str(), ", avail =", avail); + //AHTTP_LOGDEBUG3("responseText(char)", localString.substring(0, 16).c_str(), ", avail =", avail); + AHTTP_LOGDEBUG3("responseText(char)", localString, ", avail =", avail); _AHTTP_unlock; return localString; } +//************************************************************************************************************** + +#if 1 + +#if (ESP32) + #define GLOBAL_STR_LEN (32 * 1024) +#elif (ESP8266) + #define GLOBAL_STR_LEN (16 * 1024) +#else + #define GLOBAL_STR_LEN (4 * 1024) +#endif + +char globalLongString[GLOBAL_STR_LEN + 1]; + +char* AsyncHTTPRequest::responseLongText() +{ + AHTTP_LOGDEBUG("responseLongText()"); + + MUTEX_LOCK(NULL) + + if ( ! _response || _readyState < readyStateLoading || ! available()) + { + AHTTP_LOGDEBUG("responseText() no data"); + + _AHTTP_unlock; + + //return String(); + return NULL; + } + + // String localString; + size_t avail = available(); + size_t lenToCopy = (avail <= GLOBAL_STR_LEN) ? avail : GLOBAL_STR_LEN; + + strncpy(globalLongString, _response->readString(avail).c_str(), lenToCopy ); + globalLongString[ lenToCopy + 1 ] = 0; + + _contentRead += _response->readString(avail).length(); + + AHTTP_LOGDEBUG3("responseLongText(char)", globalLongString, ", avail =", avail); + + _AHTTP_unlock; + + return globalLongString; +} +#endif + //************************************************************************************************************** size_t AsyncHTTPRequest::responseRead(uint8_t* buf, size_t len) { @@ -810,7 +873,7 @@ void AsyncHTTPRequest::_processChunks() { char* connectionHdr = respHeaderValue("connection"); - if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("disconnect")) == 0)) + if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("close")) == 0)) { AHTTP_LOGDEBUG("*all chunks received - closing TCP"); @@ -850,12 +913,19 @@ void AsyncHTTPRequest::_onConnect(AsyncClient* client) _client = client; _setReadyState(readyStateOpened); + // KH test _response = new xbuf; + //_response = new xbuf(256); + ////// if (!_response) { _AHTTP_unlock; + // KH, to remove + AHTTP_LOGDEBUG("_onConnect: Can't new _responser"); + /////// + return; } @@ -865,11 +935,17 @@ void AsyncHTTPRequest::_onConnect(AsyncClient* client) _client->onAck([](void* obj, AsyncClient * client, size_t len, uint32_t time) { + (void) client; + (void) len; + (void) time; + ((AsyncHTTPRequest*)(obj))->_send(); }, this); _client->onData([](void* obj, AsyncClient * client, void* data, size_t len) { + (void) client; + ((AsyncHTTPRequest*)(obj))->_onData(data, len); }, this); @@ -886,6 +962,8 @@ void AsyncHTTPRequest::_onConnect(AsyncClient* client) //************************************************************************************************************** void AsyncHTTPRequest::_onPoll(AsyncClient* client) { + (void) client; + MUTEX_LOCK_NR if (_timeout && (millis() - _lastActivity) > (_timeout * 1000)) @@ -907,6 +985,8 @@ void AsyncHTTPRequest::_onPoll(AsyncClient* client) //************************************************************************************************************** void AsyncHTTPRequest::_onError(AsyncClient* client, int8_t error) { + (void) client; + AHTTP_LOGDEBUG1("_onError handler error =", error); _HTTPcode = error; @@ -915,6 +995,8 @@ void AsyncHTTPRequest::_onError(AsyncClient* client, int8_t error) //************************************************************************************************************** void AsyncHTTPRequest::_onDisconnect(AsyncClient* client) { + (void) client; + AHTTP_LOGDEBUG("\n_onDisconnect handler"); MUTEX_LOCK_NR @@ -958,6 +1040,11 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len) if (_chunks) { _chunks->write((uint8_t*)Vbuf, len); + + // KH, to remove + AHTTP_LOGDEBUG("_onData: _processChunks"); + /////// + _processChunks(); } else @@ -972,6 +1059,10 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len) { _AHTTP_unlock; + // KH, to remove + AHTTP_LOGDEBUG("_onData: headers not complete"); + /////// + return; } } @@ -987,7 +1078,7 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len) { char* connectionHdr = respHeaderValue("connection"); - if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("disconnect")) == 0)) + if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("close")) == 0)) { AHTTP_LOGDEBUG("*all data received - closing TCP"); diff --git a/src_cpp/AsyncHTTPRequest_Generic.h b/src_cpp/AsyncHTTPRequest_Generic.h index 87000af4..e57f8da5 100644 --- a/src_cpp/AsyncHTTPRequest_Generic.h +++ b/src_cpp/AsyncHTTPRequest_Generic.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #pragma once @@ -34,7 +35,7 @@ #ifndef ASYNC_HTTP_REQUEST_GENERIC_H #define ASYNC_HTTP_REQUEST_GENERIC_H -#define ASYNC_HTTP_REQUEST_GENERIC_VERSION "AsyncHTTPRequest_Generic v1.1.2" +#define ASYNC_HTTP_REQUEST_GENERIC_VERSION "AsyncHTTPRequest_Generic v1.1.3" #include @@ -224,8 +225,11 @@ class AsyncHTTPRequest size_t responseLength(); // indicated response length or sum of chunks to date int responseHTTPcode(); // HTTP response code or (negative) error code String responseText(); // response (whole* or partial* as string) + + char* responseLongText(); // response long (whole* or partial* as string) + size_t responseRead(uint8_t* buffer, size_t len); // Read response into buffer - uint32_t elapsedTime(); // Elapsed time of in progress transaction or last completed (ms) + uint32_t elapsedTime(); // Elapsed time of in progress transaction or last completed (ms) String version(); // Version of AsyncHTTPRequest //___________________________________________________________________________________________________________________________________ diff --git a/src_cpp/utility/xbuf.cpp b/src_cpp/utility/xbuf.cpp index aefab95f..2217c92e 100644 --- a/src_cpp/utility/xbuf.cpp +++ b/src_cpp/utility/xbuf.cpp @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #include "utility/xbuf.h" diff --git a/src_cpp/utility/xbuf.h b/src_cpp/utility/xbuf.h index 9d6e9e87..bc77d0e4 100644 --- a/src_cpp/utility/xbuf.h +++ b/src_cpp/utility/xbuf.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ /******************************************************************************************** diff --git a/src_h/AsyncHTTPRequest_Debug_Generic.h b/src_h/AsyncHTTPRequest_Debug_Generic.h index 59d6e443..6396018e 100644 --- a/src_h/AsyncHTTPRequest_Debug_Generic.h +++ b/src_h/AsyncHTTPRequest_Debug_Generic.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #pragma once @@ -51,29 +52,49 @@ #define _ASYNC_HTTP_LOGLEVEL_ 0 #endif -#define AHTTP_LOGERROR(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); } -#define AHTTP_LOGERROR0(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print(x); } -#define AHTTP_LOGERROR1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); } -#define AHTTP_LOGERROR2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); } -#define AHTTP_LOGERROR3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); } - -#define AHTTP_LOGWARN(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); } -#define AHTTP_LOGWARN0(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print(x); } -#define AHTTP_LOGWARN1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); } -#define AHTTP_LOGWARN2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); } -#define AHTTP_LOGWARN3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); } - -#define AHTTP_LOGINFO(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); } -#define AHTTP_LOGINFO0(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print(x); } -#define AHTTP_LOGINFO1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); } -#define AHTTP_LOGINFO2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); } -#define AHTTP_LOGINFO3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); } - -#define AHTTP_LOGDEBUG(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); } -#define AHTTP_LOGDEBUG0(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print(x); } -#define AHTTP_LOGDEBUG1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); } -#define AHTTP_LOGDEBUG2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); } -#define AHTTP_LOGDEBUG3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); } +///////////////////////////////////////////////////////// + +const char AHTTP_MARK[] = "[AHTTP] "; + +#define AHTTP_PRINT_MARK AHTTP_PRINT(AHTTP_MARK) +#define AHTTP_PRINT_SP A_DBG_PORT.print(" ") + +#define AHTTP_PRINT A_DBG_PORT.print +#define AHTTP_PRINTLN A_DBG_PORT.println + +///////////////////////////////////////////////////////// + +#define AHTTP_LOGERROR(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT_MARK; AHTTP_PRINTLN(x); } +#define AHTTP_LOGERROR0(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT(x); } +#define AHTTP_LOGERROR1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINTLN(y); } +#define AHTTP_LOGERROR2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINTLN(z); } +#define AHTTP_LOGERROR3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>0) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINT(z); AHTTP_PRINT_SP; AHTTP_PRINTLN(w); } + +///////////////////////////////////////////////////////// + +#define AHTTP_LOGWARN(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT_MARK; AHTTP_PRINTLN(x); } +#define AHTTP_LOGWARN0(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT(x); } +#define AHTTP_LOGWARN1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINTLN(y); } +#define AHTTP_LOGWARN2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINTLN(z); } +#define AHTTP_LOGWARN3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>1) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINT(z); AHTTP_PRINT_SP; AHTTP_PRINTLN(w); } + +///////////////////////////////////////////////////////// + +#define AHTTP_LOGINFO(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT_MARK; AHTTP_PRINTLN(x); } +#define AHTTP_LOGINFO0(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT(x); } +#define AHTTP_LOGINFO1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINTLN(y); } +#define AHTTP_LOGINFO2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINTLN(z); } +#define AHTTP_LOGINFO3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>2) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINT(z); AHTTP_PRINT_SP; AHTTP_PRINTLN(w); } + +///////////////////////////////////////////////////////// + +#define AHTTP_LOGDEBUG(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT_MARK; AHTTP_PRINTLN(x); } +#define AHTTP_LOGDEBUG0(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT(x); } +#define AHTTP_LOGDEBUG1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINTLN(y); } +#define AHTTP_LOGDEBUG2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINTLN(z); } +#define AHTTP_LOGDEBUG3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>3) { AHTTP_PRINT_MARK; AHTTP_PRINT(x); AHTTP_PRINT_SP; AHTTP_PRINT(y); AHTTP_PRINT_SP; AHTTP_PRINT(z); AHTTP_PRINT_SP; AHTTP_PRINTLN(w); } + +///////////////////////////////////////////////////////// #endif // ASYNC_HTTP_REQUEST_DEBUG_GENERIC_H diff --git a/src_h/AsyncHTTPRequest_Generic.h b/src_h/AsyncHTTPRequest_Generic.h index 001b9e55..644cf383 100644 --- a/src_h/AsyncHTTPRequest_Generic.h +++ b/src_h/AsyncHTTPRequest_Generic.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #pragma once @@ -34,7 +35,7 @@ #ifndef ASYNC_HTTP_REQUEST_GENERIC_H #define ASYNC_HTTP_REQUEST_GENERIC_H -#define ASYNC_HTTP_REQUEST_GENERIC_VERSION "AsyncHTTPRequest_Generic v1.1.2" +#define ASYNC_HTTP_REQUEST_GENERIC_VERSION "AsyncHTTPRequest_Generic v1.1.3" #include diff --git a/src_h/AsyncHTTPRequest_Impl_Generic.h b/src_h/AsyncHTTPRequest_Impl_Generic.h index 2d59a3c5..ae236f4a 100644 --- a/src_h/AsyncHTTPRequest_Impl_Generic.h +++ b/src_h/AsyncHTTPRequest_Impl_Generic.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #pragma once @@ -873,7 +874,7 @@ void AsyncHTTPRequest::_processChunks() { char* connectionHdr = respHeaderValue("connection"); - if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("disconnect")) == 0)) + if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("close")) == 0)) { AHTTP_LOGDEBUG("*all chunks received - closing TCP"); @@ -1078,7 +1079,7 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len) { char* connectionHdr = respHeaderValue("connection"); - if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("disconnect")) == 0)) + if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("close")) == 0)) { AHTTP_LOGDEBUG("*all data received - closing TCP"); diff --git a/src_h/utility/xbuf.h b/src_h/utility/xbuf.h index 48288470..1dd84937 100644 --- a/src_h/utility/xbuf.h +++ b/src_h/utility/xbuf.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ /******************************************************************************************** diff --git a/src_h/utility/xbuf_Impl.h b/src_h/utility/xbuf_Impl.h index b048979d..333c6e9f 100644 --- a/src_h/utility/xbuf_Impl.h +++ b/src_h/utility/xbuf_Impl.h @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . - Version: 1.1.2 + Version: 1.1.3 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -27,6 +27,7 @@ 1.1.0 K Hoang 23/12/2020 Add HTTP PUT, PATCH, DELETE and HEAD methods 1.1.1 K Hoang 24/12/2020 Prevent crash if request and/or method not correct. 1.1.2 K Hoang 11/02/2021 Rename _lock and _unlock to avoid conflict with AsyncWebServer library + 1.1.3 K Hoang 25/02/2021 Fix non-persistent Connection header bug *****************************************************************************************************************************/ #pragma once