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.
+
+
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