forked from khoih-prog/AsyncHTTPRequest_Generic
v1.0.2
### Releases v1.0.2 1. Make Mutex Lock and delete more reliable and error-proof to prevent random crash.
This commit is contained in:
@ -1,21 +1,21 @@
|
||||
## Contributing to ESP_WiFiManager
|
||||
## Contributing to AsyncHTTPRequest_Generic
|
||||
|
||||
### Reporting Bugs
|
||||
|
||||
Please report bugs in ESP_WiFiManager if you find them.
|
||||
Please report bugs in [AsyncHTTPRequest_Generic](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues/new) if you find them.
|
||||
|
||||
However, before reporting a bug please check through the following:
|
||||
|
||||
* [Existing Open Issues](https://github.com/khoih-prog/ESP_WiFiManager/issues) - someone might have already encountered this.
|
||||
* [Existing Open Issues](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues) - someone might have already encountered this.
|
||||
|
||||
If you don't find anything, please [open a new issue](https://github.com/khoih-prog/ESP_WiFiManager/issues/new).
|
||||
If you don't find anything, please [open a new issue](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues/new).
|
||||
|
||||
### How to submit a bug report
|
||||
|
||||
Please ensure to specify the following:
|
||||
|
||||
* Arduino IDE version (e.g. 1.8.11) or Platform.io version
|
||||
* `ESP8266` or `ESP32` Core Version (e.g. ESP8266 core v2.6.3 or ESP32 v1.0.4)
|
||||
* 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)
|
||||
* 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:
|
||||
@ -26,10 +26,10 @@ Please ensure to specify the following:
|
||||
### Example
|
||||
|
||||
```
|
||||
Arduino IDE version: 1.8.11
|
||||
ESP8266 Core Version 2.6.3
|
||||
OS: Ubuntu 16.04 LTS
|
||||
Linux Inspiron 4.4.0-170-generic #199-Ubuntu SMP Thu Nov 14 01:45:04 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
|
||||
Arduino IDE version: 1.8.13
|
||||
ESP32 Core Version 1.0.4
|
||||
OS: Ubuntu 20.04 LTS
|
||||
Linux xy-Inspiron-3593 5.4.0-51-generic #56-Ubuntu SMP Mon Oct 5 14:28:49 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
|
||||
|
||||
Context:
|
||||
I encountered an endless loop while trying to connect to Local WiFi.
|
||||
@ -44,7 +44,7 @@ Steps to reproduce:
|
||||
|
||||
Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful.
|
||||
|
||||
There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/ESP_WiFiManager/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them.
|
||||
There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them.
|
||||
|
||||
### Sending Pull Requests
|
||||
|
||||
|
16
README.md
16
README.md
@ -45,6 +45,10 @@ Chunked responses are recognized and handled transparently.
|
||||
---
|
||||
---
|
||||
|
||||
### Releases v1.0.2
|
||||
|
||||
1. Make Mutex Lock and delete more reliable and error-proof to prevent random crash.
|
||||
|
||||
### Releases v1.0.1
|
||||
|
||||
1. Restore cpp code besides Impl.h code to use in case of `multiple definition` linker error. 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). See [**HOWTO Fix `Multiple Definitions` Linker Error**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic#HOWTO-Fix-Multiple-Definitions-Linker-Error)
|
||||
@ -293,12 +297,12 @@ Please take a look at other examples, as well.
|
||||
```cpp
|
||||
#include "defines.h"
|
||||
|
||||
// 600s = 10 minutes to not flooding
|
||||
#define HTTP_REQUEST_INTERVAL_MS 600000
|
||||
// 600s = 10 minutes to not flooding, 10s in testing
|
||||
#define HTTP_REQUEST_INTERVAL_MS 10000 // 600000
|
||||
|
||||
#include <AsyncHTTPRequest_Generic.h> // https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
#include <AsyncHTTPRequest_Generic.h> // https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
|
||||
#include <Ticker.h> // https://github.com/sstaub/Ticker
|
||||
#include <Ticker.h> // https://github.com/sstaub/Ticker
|
||||
|
||||
AsyncHTTPRequest request;
|
||||
|
||||
@ -748,6 +752,10 @@ Submit issues to: [AsyncHTTPRequest_Generic issues](https://github.com/khoih-pro
|
||||
---
|
||||
---
|
||||
|
||||
### Releases v1.0.2
|
||||
|
||||
1. Make Mutex Lock and delete more reliable and error-proof to prevent random crash.
|
||||
|
||||
### Releases v1.0.1
|
||||
|
||||
1. Restore cpp code besides Impl.h code to use in case of `multiple definition` linker error. 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). See [**HOWTO Fix `Multiple Definitions` Linker Error**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic#HOWTO-Fix-Multiple-Definitions-Linker-Error)
|
||||
|
@ -17,22 +17,23 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
// Select a test server address
|
||||
char GET_ServerAddress[] = "192.168.2.110/";
|
||||
//char GET_ServerAddress[] = "http://worldtimeapi.org/api/timezone/America/Toronto.txt";
|
||||
//char GET_ServerAddress[] = "192.168.2.110/";
|
||||
char GET_ServerAddress[] = "http://worldtimeapi.org/api/timezone/America/Toronto.txt";
|
||||
|
||||
// 600s = 10 minutes to not flooding
|
||||
#define HTTP_REQUEST_INTERVAL_MS 600000
|
||||
// 600s = 10 minutes to not flooding, 10s in testing
|
||||
#define HTTP_REQUEST_INTERVAL_MS 10000 //600000
|
||||
|
||||
#include <AsyncHTTPRequest_Generic.h> // https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
|
||||
@ -52,7 +53,7 @@ void sendRequest(void)
|
||||
Serial.println("\nSending GET Request to " + String(GET_ServerAddress));
|
||||
|
||||
request.open("GET", GET_ServerAddress);
|
||||
request.setReqHeader("X-CUSTOM-HEADER", "custom_value");
|
||||
//request.setReqHeader("X-CUSTOM-HEADER", "custom_value");
|
||||
request.send();
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
/*
|
||||
Currently support
|
||||
|
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
/**
|
||||
|
@ -19,11 +19,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
/*
|
||||
Currently support
|
||||
|
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
// Dweet.io POST client. Connects to dweet.io once every ten seconds, sends a POST request and a request body.
|
||||
|
@ -19,11 +19,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
/*
|
||||
Currently support
|
||||
|
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
//************************************************************************************************************
|
||||
//
|
||||
@ -56,7 +57,7 @@
|
||||
#define _ASYNC_HTTP_LOGLEVEL_ 1
|
||||
|
||||
// 300s = 5 minutes to not flooding
|
||||
#define HTTP_REQUEST_INTERVAL 300
|
||||
#define HTTP_REQUEST_INTERVAL 30 //300
|
||||
|
||||
// 10s
|
||||
#define HEARTBEAT_INTERVAL 10
|
||||
@ -77,6 +78,7 @@ const char* password = "your_pass";
|
||||
|
||||
AsyncHTTPRequest request;
|
||||
Ticker ticker;
|
||||
Ticker ticker1;
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
@ -106,6 +108,10 @@ void sendRequest()
|
||||
request.open("GET", "http://worldtimeapi.org/api/timezone/America/Toronto.txt");
|
||||
request.send();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Can't send request");
|
||||
}
|
||||
}
|
||||
|
||||
void requestCB(void* optParm, AsyncHTTPRequest* request, int readyState)
|
||||
@ -130,13 +136,6 @@ void setup()
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
if (WiFi.status() == WL_NO_SHIELD)
|
||||
{
|
||||
Serial.println(F("WiFi shield not present"));
|
||||
// don't continue
|
||||
while (true);
|
||||
}
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
Serial.println("Connecting to WiFi SSID: " + String(ssid));
|
||||
@ -155,7 +154,7 @@ void setup()
|
||||
request.onReadyStateChange(requestCB);
|
||||
ticker.attach(HTTP_REQUEST_INTERVAL, sendRequest);
|
||||
|
||||
ticker.attach(HEARTBEAT_INTERVAL, heartBeatPrint);
|
||||
ticker1.attach(HEARTBEAT_INTERVAL, heartBeatPrint);
|
||||
|
||||
// Send first request now
|
||||
sendRequest();
|
||||
|
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
//************************************************************************************************************
|
||||
//
|
||||
@ -55,8 +56,8 @@
|
||||
#define ASYNC_HTTP_DEBUG_PORT Serial
|
||||
#define _ASYNC_HTTP_LOGLEVEL_ 1
|
||||
|
||||
// 300s = 5 minutes to not flooding
|
||||
#define HTTP_REQUEST_INTERVAL 300
|
||||
// 300s = 5 minutes to not flooding, 10s in testing
|
||||
#define HTTP_REQUEST_INTERVAL 10 //300
|
||||
|
||||
//Ported to ESP32
|
||||
#ifdef ESP32
|
||||
|
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
//************************************************************************************************************
|
||||
//
|
||||
@ -49,8 +50,8 @@
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
// 600s = 10 minutes to not flooding
|
||||
#define HTTP_REQUEST_INTERVAL_MS 600000
|
||||
// 600s = 10 minutes to not flooding, 10s in testing
|
||||
#define HTTP_REQUEST_INTERVAL_MS 10000 //600000
|
||||
|
||||
#include <AsyncHTTPRequest_Generic.h> // https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
|
||||
|
@ -19,11 +19,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
/*
|
||||
Currently support
|
||||
|
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include "defines.h"
|
||||
@ -31,8 +32,8 @@
|
||||
//char GET_ServerAddress[] = "ipv4bot.whatismyipaddress.com/";
|
||||
char GET_ServerAddress[] = "http://worldtimeapi.org/api/timezone/America/Toronto.txt";
|
||||
|
||||
// 600s = 10 minutes to not flooding
|
||||
#define HTTP_REQUEST_INTERVAL_MS 600000
|
||||
// 600s = 10 minutes to not flooding, 10s in testing
|
||||
#define HTTP_REQUEST_INTERVAL_MS 10000 //600000
|
||||
|
||||
#include <AsyncHTTPRequest_Generic.h> // https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
|
||||
|
@ -19,11 +19,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
/*
|
||||
Currently support
|
||||
|
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include "defines.h"
|
||||
|
@ -19,11 +19,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
/*
|
||||
Currently support
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name":"AsyncHTTPRequest_Generic",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"description":"Simple Async HTTP Request library, supporting GET and POST, 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",
|
||||
"authors": [
|
||||
|
@ -1,6 +1,6 @@
|
||||
name=AsyncHTTPRequest_Generic
|
||||
version=1.0.1
|
||||
author=Bob Lemaire,Khoi Hoang
|
||||
version=1.0.2
|
||||
author=Bob Lemaire,Khoi Hoang <khoih.prog@gmail.com>
|
||||
maintainer=Khoi Hoang <khoih.prog@gmail.com>
|
||||
license=MIT
|
||||
sentence=Simple Async HTTP Request library, supporting GET and POST, on top of AsyncTCP libraries, such as AsyncTCP, ESPAsyncTCP, AsyncTCP_STM32, etc.. for ESP32, ESP8266 and currently STM32 with built-in LAN8742A Ethernet.
|
||||
|
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
@ -17,17 +17,18 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define AsyncHTTPRequest_Generic_version "1.0.0"
|
||||
#define ASYNC_HTTP_REQUEST_GENERIC_VERSION "1.0.2"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
@ -43,15 +44,29 @@
|
||||
#define DEBUG_IOTA_HTTP_SET false
|
||||
#endif
|
||||
|
||||
|
||||
// KH add
|
||||
#define SAFE_DELETE(object) if (object) { delete object;}
|
||||
#define SAFE_DELETE_ARRAY(object) if (object) { delete[] object;}
|
||||
|
||||
#if ESP32
|
||||
|
||||
#include <AsyncTCP.h>
|
||||
|
||||
// KH mod
|
||||
#define MUTEX_LOCK_NR if (xSemaphoreTakeRecursive(threadLock,portMAX_DELAY) != pdTRUE) { return;}
|
||||
#define MUTEX_LOCK(returnVal) if (xSemaphoreTakeRecursive(threadLock,portMAX_DELAY) != pdTRUE) { return returnVal;}
|
||||
|
||||
#define _lock xSemaphoreTakeRecursive(threadLock,portMAX_DELAY)
|
||||
#define _unlock xSemaphoreGiveRecursive(threadLock)
|
||||
|
||||
#elif ESP8266
|
||||
|
||||
#include <ESPAsyncTCP.h>
|
||||
|
||||
#define MUTEX_LOCK_NR
|
||||
#define MUTEX_LOCK(returnVal)
|
||||
|
||||
#define _lock
|
||||
#define _unlock
|
||||
|
||||
@ -60,6 +75,9 @@
|
||||
defined(STM32WB) || defined(STM32MP1) )
|
||||
|
||||
#include "STM32AsyncTCP.h"
|
||||
|
||||
#define MUTEX_LOCK_NR
|
||||
#define MUTEX_LOCK(returnVal)
|
||||
#define _lock
|
||||
#define _unlock
|
||||
|
||||
@ -108,9 +126,12 @@ class AsyncHTTPRequest
|
||||
|
||||
~header()
|
||||
{
|
||||
delete[] name;
|
||||
delete[] value;
|
||||
delete next;
|
||||
SAFE_DELETE_ARRAY(name)
|
||||
SAFE_DELETE_ARRAY(value)
|
||||
SAFE_DELETE(next)
|
||||
//delete[] name;
|
||||
//delete[] value;
|
||||
//delete next;
|
||||
}
|
||||
};
|
||||
|
||||
@ -131,13 +152,13 @@ class AsyncHTTPRequest
|
||||
|
||||
~URL()
|
||||
{
|
||||
delete[] scheme;
|
||||
delete[] user;
|
||||
delete[] pwd;
|
||||
delete[] host;
|
||||
delete[] path;
|
||||
delete[] query;
|
||||
delete[] fragment;
|
||||
SAFE_DELETE_ARRAY(scheme)
|
||||
SAFE_DELETE_ARRAY(user)
|
||||
SAFE_DELETE_ARRAY(pwd)
|
||||
SAFE_DELETE_ARRAY(host)
|
||||
SAFE_DELETE_ARRAY(path)
|
||||
SAFE_DELETE_ARRAY(query)
|
||||
SAFE_DELETE_ARRAY(fragment)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
@ -46,15 +47,20 @@ AsyncHTTPRequest::~AsyncHTTPRequest()
|
||||
if (_client)
|
||||
_client->close(true);
|
||||
|
||||
delete _URL;
|
||||
delete _headers;
|
||||
delete _request;
|
||||
delete _response;
|
||||
delete _chunks;
|
||||
delete[] _connectedHost;
|
||||
|
||||
SAFE_DELETE(_URL)
|
||||
SAFE_DELETE(_headers)
|
||||
SAFE_DELETE(_request)
|
||||
SAFE_DELETE(_response)
|
||||
SAFE_DELETE(_chunks)
|
||||
SAFE_DELETE_ARRAY(_connectedHost)
|
||||
|
||||
#ifdef ESP32
|
||||
vSemaphoreDelete(threadLock);
|
||||
// KH add
|
||||
if (threadLock)
|
||||
{
|
||||
vSemaphoreDelete(threadLock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -65,8 +71,9 @@ void AsyncHTTPRequest::setDebug(bool debug)
|
||||
{
|
||||
_debug = true;
|
||||
|
||||
AHTTP_LOGDEBUG3("setDebug(", debug ? "on" : "off", ") version", AsyncHTTPRequest_Generic_version);
|
||||
AHTTP_LOGDEBUG3("setDebug(", debug ? "on" : "off", ") version", ASYNC_HTTP_REQUEST_GENERIC_VERSION);
|
||||
}
|
||||
|
||||
_debug = debug;
|
||||
}
|
||||
|
||||
@ -88,13 +95,13 @@ bool AsyncHTTPRequest::open(const char* method, const char* URL)
|
||||
|
||||
_requestStartTime = millis();
|
||||
|
||||
delete _URL;
|
||||
delete _headers;
|
||||
delete _request;
|
||||
delete _response;
|
||||
delete _chunks;
|
||||
SAFE_DELETE(_URL)
|
||||
SAFE_DELETE(_headers)
|
||||
SAFE_DELETE(_request)
|
||||
SAFE_DELETE(_response)
|
||||
SAFE_DELETE(_chunks)
|
||||
|
||||
_URL = nullptr;
|
||||
_URL = nullptr;
|
||||
_headers = nullptr;
|
||||
_response = nullptr;
|
||||
_request = nullptr;
|
||||
@ -124,12 +131,20 @@ bool AsyncHTTPRequest::open(const char* method, const char* URL)
|
||||
}
|
||||
|
||||
char* hostName = new char[strlen(_URL->host) + 10];
|
||||
sprintf(hostName, "%s:%d", _URL->host, _URL->port);
|
||||
_addHeader("host", hostName);
|
||||
delete[] hostName;
|
||||
_lastActivity = millis();
|
||||
|
||||
if (hostName)
|
||||
{
|
||||
sprintf(hostName, "%s:%d", _URL->host, _URL->port);
|
||||
_addHeader("host", hostName);
|
||||
|
||||
SAFE_DELETE_ARRAY(hostName)
|
||||
|
||||
_lastActivity = millis();
|
||||
|
||||
return _connect();
|
||||
return _connect();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::onReadyStateChange(readyStateChangeCB cb, void* arg)
|
||||
@ -151,12 +166,13 @@ bool AsyncHTTPRequest::send()
|
||||
{
|
||||
AHTTP_LOGDEBUG("send()");
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
if ( ! _buildRequest())
|
||||
return false;
|
||||
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@ -167,17 +183,20 @@ bool AsyncHTTPRequest::send(String body)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("send(String)", body.substring(0, 16).c_str(), ", length =", body.length());
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
_addHeader("Content-Length", String(body.length()).c_str());
|
||||
|
||||
if ( ! _buildRequest())
|
||||
{
|
||||
_unlock;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_request->write(body);
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@ -188,7 +207,8 @@ bool AsyncHTTPRequest::send(const char* body)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("send(char)", body, ", length =", strlen(body));
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
_addHeader("Content-Length", String(strlen(body)).c_str());
|
||||
|
||||
if ( ! _buildRequest())
|
||||
@ -200,6 +220,7 @@ bool AsyncHTTPRequest::send(const char* body)
|
||||
|
||||
_request->write(body);
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@ -210,7 +231,8 @@ bool AsyncHTTPRequest::send(const uint8_t* body, size_t len)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("send(char)", (char*) body, ", length =", len);
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
_addHeader("Content-Length", String(len).c_str());
|
||||
|
||||
if ( ! _buildRequest())
|
||||
@ -222,6 +244,7 @@ bool AsyncHTTPRequest::send(const uint8_t* body, size_t len)
|
||||
|
||||
_request->write(body, len);
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@ -232,7 +255,8 @@ bool AsyncHTTPRequest::send(xbuf* body, size_t len)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("send(char)", body->peekString(16).c_str(), ", length =", len);
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
_addHeader("Content-Length", String(len).c_str());
|
||||
|
||||
if ( ! _buildRequest())
|
||||
@ -244,6 +268,7 @@ bool AsyncHTTPRequest::send(xbuf* body, size_t len)
|
||||
|
||||
_request->write(body, len);
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@ -254,12 +279,15 @@ void AsyncHTTPRequest::abort()
|
||||
{
|
||||
AHTTP_LOGDEBUG("abort()");
|
||||
|
||||
_lock;
|
||||
|
||||
if (! _client)
|
||||
if (! _client)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
_client->abort();
|
||||
|
||||
_unlock;
|
||||
}
|
||||
//**************************************************************************************************************
|
||||
@ -279,7 +307,7 @@ String AsyncHTTPRequest::responseText()
|
||||
{
|
||||
AHTTP_LOGDEBUG("responseText()");
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(String())
|
||||
|
||||
if ( ! _response || _readyState < readyStateLoading || ! available())
|
||||
{
|
||||
@ -299,12 +327,13 @@ String AsyncHTTPRequest::responseText()
|
||||
|
||||
_HTTPcode = HTTPCODE_TOO_LESS_RAM;
|
||||
_client->abort();
|
||||
|
||||
_unlock;
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
localString = _response->readString(avail);
|
||||
localString = _response->readString(avail);
|
||||
_contentRead += localString.length();
|
||||
|
||||
AHTTP_LOGDEBUG3("responseText(char)", localString.substring(0, 16).c_str(), ", avail =", avail);
|
||||
@ -319,19 +348,20 @@ size_t AsyncHTTPRequest::responseRead(uint8_t* buf, size_t len)
|
||||
{
|
||||
if ( ! _response || _readyState < readyStateLoading || ! available())
|
||||
{
|
||||
//DEBUG_HTTP("responseRead() no data\r\n");
|
||||
AHTTP_LOGDEBUG("responseRead() no data");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(0)
|
||||
|
||||
size_t avail = available() > len ? len : available();
|
||||
_response->read(buf, avail);
|
||||
|
||||
AHTTP_LOGDEBUG3("responseRead(char)", (char*) buf, ", avail =", avail);
|
||||
|
||||
_contentRead += avail;
|
||||
|
||||
_unlock;
|
||||
|
||||
return avail;
|
||||
@ -386,7 +416,7 @@ uint32_t AsyncHTTPRequest::elapsedTime()
|
||||
//**************************************************************************************************************
|
||||
String AsyncHTTPRequest::version()
|
||||
{
|
||||
return String(AsyncHTTPRequest_Generic_version);
|
||||
return String(ASYNC_HTTP_REQUEST_GENERIC_VERSION);
|
||||
}
|
||||
|
||||
/*______________________________________________________________________________________________________________
|
||||
@ -407,11 +437,22 @@ bool AsyncHTTPRequest::_parseURL(const char* url)
|
||||
//**************************************************************************************************************
|
||||
bool AsyncHTTPRequest::_parseURL(String url)
|
||||
{
|
||||
delete _URL;
|
||||
SAFE_DELETE(_URL)
|
||||
|
||||
int hostBeg = 0;
|
||||
|
||||
_URL = new URL;
|
||||
_URL->scheme = new char[8];
|
||||
|
||||
if (_URL)
|
||||
{
|
||||
_URL->scheme = new char[8];
|
||||
|
||||
if (! (_URL->scheme) )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
strcpy(_URL->scheme, "HTTP://");
|
||||
|
||||
if (url.substring(0, 7).equalsIgnoreCase("HTTP://"))
|
||||
@ -438,6 +479,10 @@ bool AsyncHTTPRequest::_parseURL(String url)
|
||||
}
|
||||
|
||||
_URL->host = new char[hostEnd - hostBeg + 1];
|
||||
|
||||
if (_URL->host == nullptr)
|
||||
return false;
|
||||
|
||||
strcpy(_URL->host, url.substring(hostBeg, hostEnd).c_str());
|
||||
|
||||
int queryBeg = url.indexOf('?');
|
||||
@ -446,8 +491,17 @@ bool AsyncHTTPRequest::_parseURL(String url)
|
||||
queryBeg = url.length();
|
||||
|
||||
_URL->path = new char[queryBeg - pathBeg + 1];
|
||||
|
||||
if (_URL->path == nullptr)
|
||||
return false;
|
||||
|
||||
strcpy(_URL->path, url.substring(pathBeg, queryBeg).c_str());
|
||||
|
||||
_URL->query = new char[url.length() - queryBeg + 1];
|
||||
|
||||
if (_URL->query == nullptr)
|
||||
return false;
|
||||
|
||||
strcpy(_URL->query, url.substring(queryBeg).c_str());
|
||||
|
||||
AHTTP_LOGDEBUG2("_parseURL(): scheme+host", _URL->scheme, _URL->host);
|
||||
@ -464,11 +518,18 @@ bool AsyncHTTPRequest::_connect()
|
||||
if ( ! _client)
|
||||
{
|
||||
_client = new AsyncClient();
|
||||
|
||||
if (! _client)
|
||||
return false;
|
||||
}
|
||||
|
||||
delete[] _connectedHost;
|
||||
SAFE_DELETE_ARRAY(_connectedHost)
|
||||
|
||||
_connectedHost = new char[strlen(_URL->host) + 1];
|
||||
|
||||
if (_connectedHost == nullptr)
|
||||
return false;
|
||||
|
||||
strcpy(_connectedHost, _URL->host);
|
||||
_connectedPort = _URL->port;
|
||||
|
||||
@ -521,7 +582,12 @@ bool AsyncHTTPRequest::_buildRequest()
|
||||
|
||||
// Build the header.
|
||||
if ( ! _request)
|
||||
{
|
||||
_request = new xbuf;
|
||||
|
||||
if ( ! _request)
|
||||
return false;
|
||||
}
|
||||
|
||||
_request->write(_HTTPmethod == HTTPmethodGET ? "GET " : "POST ");
|
||||
_request->write(_URL->path);
|
||||
@ -530,7 +596,7 @@ bool AsyncHTTPRequest::_buildRequest()
|
||||
|
||||
AHTTP_LOGDEBUG3(_HTTPmethod == HTTPmethodGET ? "GET " : "POST ", _URL->path, _URL->query, " HTTP/1.1\r\n" );
|
||||
|
||||
delete _URL;
|
||||
SAFE_DELETE(_URL)
|
||||
|
||||
_URL = nullptr;
|
||||
header* hdr = _headers;
|
||||
@ -547,7 +613,8 @@ bool AsyncHTTPRequest::_buildRequest()
|
||||
hdr = hdr->next;
|
||||
}
|
||||
|
||||
delete _headers;
|
||||
SAFE_DELETE(_headers)
|
||||
|
||||
_headers = nullptr;
|
||||
_request->write("\r\n");
|
||||
|
||||
@ -577,19 +644,26 @@ size_t AsyncHTTPRequest::_send()
|
||||
|
||||
size_t sent = 0;
|
||||
uint8_t* temp = new uint8_t[100];
|
||||
|
||||
if (!temp)
|
||||
return 0;
|
||||
|
||||
while (supply)
|
||||
{
|
||||
size_t chunk = supply < 100 ? supply : 100;
|
||||
supply -= _request->read(temp, chunk);
|
||||
sent += _client->add((char*)temp, chunk);
|
||||
|
||||
supply -= _request->read(temp, chunk);
|
||||
sent += _client->add((char*)temp, chunk);
|
||||
}
|
||||
|
||||
delete temp;
|
||||
// KH, Must be delete [] temp;
|
||||
SAFE_DELETE_ARRAY(temp)
|
||||
|
||||
if (_request->available() == 0)
|
||||
{
|
||||
delete _request;
|
||||
//delete _request;
|
||||
SAFE_DELETE(_request)
|
||||
|
||||
_request = nullptr;
|
||||
}
|
||||
|
||||
@ -679,10 +753,20 @@ void AsyncHTTPRequest::_onConnect(AsyncClient* client)
|
||||
{
|
||||
AHTTP_LOGDEBUG("_onConnect handler");
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
_client = client;
|
||||
_setReadyState(readyStateOpened);
|
||||
|
||||
_response = new xbuf;
|
||||
|
||||
if (!_response)
|
||||
{
|
||||
_unlock;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_contentLength = 0;
|
||||
_contentRead = 0;
|
||||
_chunked = false;
|
||||
@ -703,13 +787,14 @@ void AsyncHTTPRequest::_onConnect(AsyncClient* client)
|
||||
}
|
||||
|
||||
_lastActivity = millis();
|
||||
|
||||
_unlock;
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::_onPoll(AsyncClient* client)
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
if (_timeout && (millis() - _lastActivity) > (_timeout * 1000))
|
||||
{
|
||||
@ -740,7 +825,7 @@ void AsyncHTTPRequest::_onDisconnect(AsyncClient* client)
|
||||
{
|
||||
AHTTP_LOGDEBUG("\n_onDisconnect handler");
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
if (_readyState < readyStateOpened)
|
||||
{
|
||||
@ -752,16 +837,19 @@ void AsyncHTTPRequest::_onDisconnect(AsyncClient* client)
|
||||
_HTTPcode = HTTPCODE_CONNECTION_LOST;
|
||||
}
|
||||
|
||||
delete _client;
|
||||
SAFE_DELETE(_client)
|
||||
|
||||
_client = nullptr;
|
||||
|
||||
delete[] _connectedHost;
|
||||
SAFE_DELETE_ARRAY(_connectedHost)
|
||||
|
||||
_connectedHost = nullptr;
|
||||
|
||||
_connectedPort = -1;
|
||||
_connectedPort = -1;
|
||||
_requestEndTime = millis();
|
||||
_lastActivity = 0;
|
||||
_lastActivity = 0;
|
||||
_setReadyState(readyStateDone);
|
||||
|
||||
_unlock;
|
||||
}
|
||||
|
||||
@ -770,6 +858,8 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("_onData handler", (char*) Vbuf, ", len =", len);
|
||||
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
_lastActivity = millis();
|
||||
|
||||
// Transfer data to xbuf
|
||||
@ -786,8 +876,12 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len)
|
||||
// if headers not complete, collect them. If still not complete, just return.
|
||||
if (_readyState == readyStateOpened)
|
||||
{
|
||||
if ( ! _collectHeaders())
|
||||
if ( ! _collectHeaders())
|
||||
{
|
||||
_unlock;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If there's data in the buffer and not Done, advance readyState to Loading.
|
||||
@ -932,7 +1026,8 @@ void AsyncHTTPRequest::setReqHeader(const char* name, const __FlashStringHelper*
|
||||
{
|
||||
char* _value = _charstar(value);
|
||||
_addHeader(name, _value);
|
||||
delete[] _value;
|
||||
|
||||
SAFE_DELETE_ARRAY(_value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -943,7 +1038,8 @@ void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, const char*
|
||||
{
|
||||
char* _name = _charstar(name);
|
||||
_addHeader(_name, value);
|
||||
delete[] _name;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -955,8 +1051,9 @@ void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, const __Fla
|
||||
char* _name = _charstar(name);
|
||||
char* _value = _charstar(value);
|
||||
_addHeader(_name, _value);
|
||||
delete[] _name;
|
||||
delete[] _value;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
SAFE_DELETE_ARRAY(_value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -967,7 +1064,8 @@ void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, int32_t val
|
||||
{
|
||||
char* _name = _charstar(name);
|
||||
setReqHeader(_name, String(value).c_str());
|
||||
delete[] _name;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1058,7 +1156,8 @@ char* AsyncHTTPRequest::respHeaderValue(const __FlashStringHelper *name)
|
||||
|
||||
char* _name = _charstar(name);
|
||||
header* hdr = _getHeader(_name);
|
||||
delete[] _name;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
|
||||
if ( ! hdr)
|
||||
return nullptr;
|
||||
@ -1074,7 +1173,8 @@ bool AsyncHTTPRequest::respHeaderExists(const __FlashStringHelper *name)
|
||||
|
||||
char* _name = _charstar(name);
|
||||
header* hdr = _getHeader(_name);
|
||||
delete[] _name;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
|
||||
if ( ! hdr)
|
||||
return false;
|
||||
@ -1087,7 +1187,8 @@ bool AsyncHTTPRequest::respHeaderExists(const __FlashStringHelper *name)
|
||||
//**************************************************************************************************************
|
||||
String AsyncHTTPRequest::headers()
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK(String())
|
||||
|
||||
String _response = "";
|
||||
header* hdr = _headers;
|
||||
|
||||
@ -1101,6 +1202,7 @@ String AsyncHTTPRequest::headers()
|
||||
}
|
||||
|
||||
_response += "\r\n";
|
||||
|
||||
_unlock;
|
||||
|
||||
return _response;
|
||||
@ -1109,17 +1211,19 @@ String AsyncHTTPRequest::headers()
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_addHeader(const char* name, const char* value)
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK(nullptr)
|
||||
|
||||
header* hdr = (header*) &_headers;
|
||||
|
||||
while (hdr->next)
|
||||
{
|
||||
if (strcasecmp(name, hdr->next->name) == 0)
|
||||
{
|
||||
header* oldHdr = hdr->next;
|
||||
hdr->next = hdr->next->next;
|
||||
oldHdr->next = nullptr;
|
||||
delete oldHdr;
|
||||
header* oldHdr = hdr->next;
|
||||
hdr->next = hdr->next->next;
|
||||
oldHdr->next = nullptr;
|
||||
|
||||
SAFE_DELETE(oldHdr)
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1128,10 +1232,37 @@ AsyncHTTPRequest::header* AsyncHTTPRequest::_addHeader(const char* name, const
|
||||
}
|
||||
|
||||
hdr->next = new header;
|
||||
hdr->next->name = new char[strlen(name) + 1];
|
||||
strcpy(hdr->next->name, name);
|
||||
hdr->next->value = new char[strlen(value) + 1];
|
||||
strcpy(hdr->next->value, value);
|
||||
|
||||
if (hdr->next)
|
||||
{
|
||||
hdr->next->name = new char[strlen(name) + 1];
|
||||
|
||||
if (hdr->next->name)
|
||||
strcpy(hdr->next->name, name);
|
||||
else
|
||||
{
|
||||
SAFE_DELETE(hdr->next)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hdr->next->value = new char[strlen(value) + 1];
|
||||
|
||||
if (hdr->next->value)
|
||||
strcpy(hdr->next->value, value);
|
||||
else
|
||||
{
|
||||
SAFE_DELETE_ARRAY(hdr->next->name)
|
||||
SAFE_DELETE(hdr->next)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
_unlock;
|
||||
|
||||
return hdr->next;
|
||||
@ -1140,7 +1271,8 @@ AsyncHTTPRequest::header* AsyncHTTPRequest::_addHeader(const char* name, const
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_getHeader(const char* name)
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK(nullptr)
|
||||
|
||||
header* hdr = _headers;
|
||||
|
||||
while (hdr)
|
||||
@ -1159,7 +1291,8 @@ AsyncHTTPRequest::header* AsyncHTTPRequest::_getHeader(const char* name)
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_getHeader(int ndx)
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK(nullptr)
|
||||
|
||||
header* hdr = _headers;
|
||||
|
||||
while (hdr)
|
||||
@ -1184,8 +1317,13 @@ char* AsyncHTTPRequest::_charstar(const __FlashStringHelper * str)
|
||||
return nullptr;
|
||||
|
||||
char* ptr = new char[strlen_P((PGM_P)str) + 1];
|
||||
strcpy_P(ptr, (PGM_P)str);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
strcpy_P(ptr, (PGM_P)str);
|
||||
}
|
||||
|
||||
// Rturn good ptr or nullptr
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
|
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
@ -361,14 +362,20 @@ void xbuf::addSeg()
|
||||
if (_tail)
|
||||
{
|
||||
_tail->next = (xseg*) new uint32_t[_segSize / 4 + 1];
|
||||
|
||||
// KH, Must check NULL here
|
||||
_tail = _tail->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// KH, Must check NULL here
|
||||
_tail = _head = (xseg*) new uint32_t[_segSize / 4 + 1];
|
||||
}
|
||||
|
||||
_tail->next = nullptr;
|
||||
// KH, Must check NULL here
|
||||
if (_tail)
|
||||
_tail->next = nullptr;
|
||||
|
||||
_free += _segSize;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************************************************************
|
||||
src_cpp/AsyncHTTPRequest_Debug_Generic.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
AsyncHTTPRequest_Debug_Generic.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************************************************************
|
||||
src_cpp/AsyncHTTPRequest_Generic.cpp - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
AsyncHTTPRequest_Generic.cpp - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
@ -17,14 +17,16 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include "AsyncHTTPRequest_Debug_Generic.h"
|
||||
#include "AsyncHTTPRequest_Generic.h"
|
||||
|
||||
|
||||
@ -46,15 +48,20 @@ AsyncHTTPRequest::~AsyncHTTPRequest()
|
||||
if (_client)
|
||||
_client->close(true);
|
||||
|
||||
delete _URL;
|
||||
delete _headers;
|
||||
delete _request;
|
||||
delete _response;
|
||||
delete _chunks;
|
||||
delete[] _connectedHost;
|
||||
|
||||
SAFE_DELETE(_URL)
|
||||
SAFE_DELETE(_headers)
|
||||
SAFE_DELETE(_request)
|
||||
SAFE_DELETE(_response)
|
||||
SAFE_DELETE(_chunks)
|
||||
SAFE_DELETE_ARRAY(_connectedHost)
|
||||
|
||||
#ifdef ESP32
|
||||
vSemaphoreDelete(threadLock);
|
||||
// KH add
|
||||
if (threadLock)
|
||||
{
|
||||
vSemaphoreDelete(threadLock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -65,8 +72,9 @@ void AsyncHTTPRequest::setDebug(bool debug)
|
||||
{
|
||||
_debug = true;
|
||||
|
||||
AHTTP_LOGDEBUG3("setDebug(", debug ? "on" : "off", ") version", AsyncHTTPRequest_Generic_version);
|
||||
AHTTP_LOGDEBUG3("setDebug(", debug ? "on" : "off", ") version", ASYNC_HTTP_REQUEST_GENERIC_VERSION);
|
||||
}
|
||||
|
||||
_debug = debug;
|
||||
}
|
||||
|
||||
@ -88,13 +96,13 @@ bool AsyncHTTPRequest::open(const char* method, const char* URL)
|
||||
|
||||
_requestStartTime = millis();
|
||||
|
||||
delete _URL;
|
||||
delete _headers;
|
||||
delete _request;
|
||||
delete _response;
|
||||
delete _chunks;
|
||||
SAFE_DELETE(_URL)
|
||||
SAFE_DELETE(_headers)
|
||||
SAFE_DELETE(_request)
|
||||
SAFE_DELETE(_response)
|
||||
SAFE_DELETE(_chunks)
|
||||
|
||||
_URL = nullptr;
|
||||
_URL = nullptr;
|
||||
_headers = nullptr;
|
||||
_response = nullptr;
|
||||
_request = nullptr;
|
||||
@ -124,12 +132,20 @@ bool AsyncHTTPRequest::open(const char* method, const char* URL)
|
||||
}
|
||||
|
||||
char* hostName = new char[strlen(_URL->host) + 10];
|
||||
sprintf(hostName, "%s:%d", _URL->host, _URL->port);
|
||||
_addHeader("host", hostName);
|
||||
delete[] hostName;
|
||||
_lastActivity = millis();
|
||||
|
||||
if (hostName)
|
||||
{
|
||||
sprintf(hostName, "%s:%d", _URL->host, _URL->port);
|
||||
_addHeader("host", hostName);
|
||||
|
||||
SAFE_DELETE_ARRAY(hostName)
|
||||
|
||||
_lastActivity = millis();
|
||||
|
||||
return _connect();
|
||||
return _connect();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::onReadyStateChange(readyStateChangeCB cb, void* arg)
|
||||
@ -151,12 +167,13 @@ bool AsyncHTTPRequest::send()
|
||||
{
|
||||
AHTTP_LOGDEBUG("send()");
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
if ( ! _buildRequest())
|
||||
return false;
|
||||
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@ -167,17 +184,20 @@ bool AsyncHTTPRequest::send(String body)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("send(String)", body.substring(0, 16).c_str(), ", length =", body.length());
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
_addHeader("Content-Length", String(body.length()).c_str());
|
||||
|
||||
if ( ! _buildRequest())
|
||||
{
|
||||
_unlock;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_request->write(body);
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@ -188,7 +208,8 @@ bool AsyncHTTPRequest::send(const char* body)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("send(char)", body, ", length =", strlen(body));
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
_addHeader("Content-Length", String(strlen(body)).c_str());
|
||||
|
||||
if ( ! _buildRequest())
|
||||
@ -200,6 +221,7 @@ bool AsyncHTTPRequest::send(const char* body)
|
||||
|
||||
_request->write(body);
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@ -210,7 +232,8 @@ bool AsyncHTTPRequest::send(const uint8_t* body, size_t len)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("send(char)", (char*) body, ", length =", len);
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
_addHeader("Content-Length", String(len).c_str());
|
||||
|
||||
if ( ! _buildRequest())
|
||||
@ -222,6 +245,7 @@ bool AsyncHTTPRequest::send(const uint8_t* body, size_t len)
|
||||
|
||||
_request->write(body, len);
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@ -232,7 +256,8 @@ bool AsyncHTTPRequest::send(xbuf* body, size_t len)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("send(char)", body->peekString(16).c_str(), ", length =", len);
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
_addHeader("Content-Length", String(len).c_str());
|
||||
|
||||
if ( ! _buildRequest())
|
||||
@ -244,6 +269,7 @@ bool AsyncHTTPRequest::send(xbuf* body, size_t len)
|
||||
|
||||
_request->write(body, len);
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@ -254,12 +280,15 @@ void AsyncHTTPRequest::abort()
|
||||
{
|
||||
AHTTP_LOGDEBUG("abort()");
|
||||
|
||||
_lock;
|
||||
|
||||
if (! _client)
|
||||
if (! _client)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
_client->abort();
|
||||
|
||||
_unlock;
|
||||
}
|
||||
//**************************************************************************************************************
|
||||
@ -279,7 +308,7 @@ String AsyncHTTPRequest::responseText()
|
||||
{
|
||||
AHTTP_LOGDEBUG("responseText()");
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(String())
|
||||
|
||||
if ( ! _response || _readyState < readyStateLoading || ! available())
|
||||
{
|
||||
@ -299,12 +328,13 @@ String AsyncHTTPRequest::responseText()
|
||||
|
||||
_HTTPcode = HTTPCODE_TOO_LESS_RAM;
|
||||
_client->abort();
|
||||
|
||||
_unlock;
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
localString = _response->readString(avail);
|
||||
localString = _response->readString(avail);
|
||||
_contentRead += localString.length();
|
||||
|
||||
AHTTP_LOGDEBUG3("responseText(char)", localString.substring(0, 16).c_str(), ", avail =", avail);
|
||||
@ -319,19 +349,20 @@ size_t AsyncHTTPRequest::responseRead(uint8_t* buf, size_t len)
|
||||
{
|
||||
if ( ! _response || _readyState < readyStateLoading || ! available())
|
||||
{
|
||||
//DEBUG_HTTP("responseRead() no data\r\n");
|
||||
AHTTP_LOGDEBUG("responseRead() no data");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(0)
|
||||
|
||||
size_t avail = available() > len ? len : available();
|
||||
_response->read(buf, avail);
|
||||
|
||||
AHTTP_LOGDEBUG3("responseRead(char)", (char*) buf, ", avail =", avail);
|
||||
|
||||
_contentRead += avail;
|
||||
|
||||
_unlock;
|
||||
|
||||
return avail;
|
||||
@ -386,7 +417,7 @@ uint32_t AsyncHTTPRequest::elapsedTime()
|
||||
//**************************************************************************************************************
|
||||
String AsyncHTTPRequest::version()
|
||||
{
|
||||
return String(AsyncHTTPRequest_Generic_version);
|
||||
return String(ASYNC_HTTP_REQUEST_GENERIC_VERSION);
|
||||
}
|
||||
|
||||
/*______________________________________________________________________________________________________________
|
||||
@ -407,11 +438,22 @@ bool AsyncHTTPRequest::_parseURL(const char* url)
|
||||
//**************************************************************************************************************
|
||||
bool AsyncHTTPRequest::_parseURL(String url)
|
||||
{
|
||||
delete _URL;
|
||||
SAFE_DELETE(_URL)
|
||||
|
||||
int hostBeg = 0;
|
||||
|
||||
_URL = new URL;
|
||||
_URL->scheme = new char[8];
|
||||
|
||||
if (_URL)
|
||||
{
|
||||
_URL->scheme = new char[8];
|
||||
|
||||
if (! (_URL->scheme) )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
strcpy(_URL->scheme, "HTTP://");
|
||||
|
||||
if (url.substring(0, 7).equalsIgnoreCase("HTTP://"))
|
||||
@ -438,6 +480,10 @@ bool AsyncHTTPRequest::_parseURL(String url)
|
||||
}
|
||||
|
||||
_URL->host = new char[hostEnd - hostBeg + 1];
|
||||
|
||||
if (_URL->host == nullptr)
|
||||
return false;
|
||||
|
||||
strcpy(_URL->host, url.substring(hostBeg, hostEnd).c_str());
|
||||
|
||||
int queryBeg = url.indexOf('?');
|
||||
@ -446,8 +492,17 @@ bool AsyncHTTPRequest::_parseURL(String url)
|
||||
queryBeg = url.length();
|
||||
|
||||
_URL->path = new char[queryBeg - pathBeg + 1];
|
||||
|
||||
if (_URL->path == nullptr)
|
||||
return false;
|
||||
|
||||
strcpy(_URL->path, url.substring(pathBeg, queryBeg).c_str());
|
||||
|
||||
_URL->query = new char[url.length() - queryBeg + 1];
|
||||
|
||||
if (_URL->query == nullptr)
|
||||
return false;
|
||||
|
||||
strcpy(_URL->query, url.substring(queryBeg).c_str());
|
||||
|
||||
AHTTP_LOGDEBUG2("_parseURL(): scheme+host", _URL->scheme, _URL->host);
|
||||
@ -464,11 +519,18 @@ bool AsyncHTTPRequest::_connect()
|
||||
if ( ! _client)
|
||||
{
|
||||
_client = new AsyncClient();
|
||||
|
||||
if (! _client)
|
||||
return false;
|
||||
}
|
||||
|
||||
delete[] _connectedHost;
|
||||
SAFE_DELETE_ARRAY(_connectedHost)
|
||||
|
||||
_connectedHost = new char[strlen(_URL->host) + 1];
|
||||
|
||||
if (_connectedHost == nullptr)
|
||||
return false;
|
||||
|
||||
strcpy(_connectedHost, _URL->host);
|
||||
_connectedPort = _URL->port;
|
||||
|
||||
@ -521,7 +583,12 @@ bool AsyncHTTPRequest::_buildRequest()
|
||||
|
||||
// Build the header.
|
||||
if ( ! _request)
|
||||
{
|
||||
_request = new xbuf;
|
||||
|
||||
if ( ! _request)
|
||||
return false;
|
||||
}
|
||||
|
||||
_request->write(_HTTPmethod == HTTPmethodGET ? "GET " : "POST ");
|
||||
_request->write(_URL->path);
|
||||
@ -530,7 +597,7 @@ bool AsyncHTTPRequest::_buildRequest()
|
||||
|
||||
AHTTP_LOGDEBUG3(_HTTPmethod == HTTPmethodGET ? "GET " : "POST ", _URL->path, _URL->query, " HTTP/1.1\r\n" );
|
||||
|
||||
delete _URL;
|
||||
SAFE_DELETE(_URL)
|
||||
|
||||
_URL = nullptr;
|
||||
header* hdr = _headers;
|
||||
@ -547,7 +614,8 @@ bool AsyncHTTPRequest::_buildRequest()
|
||||
hdr = hdr->next;
|
||||
}
|
||||
|
||||
delete _headers;
|
||||
SAFE_DELETE(_headers)
|
||||
|
||||
_headers = nullptr;
|
||||
_request->write("\r\n");
|
||||
|
||||
@ -577,19 +645,26 @@ size_t AsyncHTTPRequest::_send()
|
||||
|
||||
size_t sent = 0;
|
||||
uint8_t* temp = new uint8_t[100];
|
||||
|
||||
if (!temp)
|
||||
return 0;
|
||||
|
||||
while (supply)
|
||||
{
|
||||
size_t chunk = supply < 100 ? supply : 100;
|
||||
supply -= _request->read(temp, chunk);
|
||||
sent += _client->add((char*)temp, chunk);
|
||||
|
||||
supply -= _request->read(temp, chunk);
|
||||
sent += _client->add((char*)temp, chunk);
|
||||
}
|
||||
|
||||
delete temp;
|
||||
// KH, Must be delete [] temp;
|
||||
SAFE_DELETE_ARRAY(temp)
|
||||
|
||||
if (_request->available() == 0)
|
||||
{
|
||||
delete _request;
|
||||
//delete _request;
|
||||
SAFE_DELETE(_request)
|
||||
|
||||
_request = nullptr;
|
||||
}
|
||||
|
||||
@ -679,10 +754,20 @@ void AsyncHTTPRequest::_onConnect(AsyncClient* client)
|
||||
{
|
||||
AHTTP_LOGDEBUG("_onConnect handler");
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
_client = client;
|
||||
_setReadyState(readyStateOpened);
|
||||
|
||||
_response = new xbuf;
|
||||
|
||||
if (!_response)
|
||||
{
|
||||
_unlock;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_contentLength = 0;
|
||||
_contentRead = 0;
|
||||
_chunked = false;
|
||||
@ -703,13 +788,14 @@ void AsyncHTTPRequest::_onConnect(AsyncClient* client)
|
||||
}
|
||||
|
||||
_lastActivity = millis();
|
||||
|
||||
_unlock;
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::_onPoll(AsyncClient* client)
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
if (_timeout && (millis() - _lastActivity) > (_timeout * 1000))
|
||||
{
|
||||
@ -740,7 +826,7 @@ void AsyncHTTPRequest::_onDisconnect(AsyncClient* client)
|
||||
{
|
||||
AHTTP_LOGDEBUG("\n_onDisconnect handler");
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
if (_readyState < readyStateOpened)
|
||||
{
|
||||
@ -752,16 +838,19 @@ void AsyncHTTPRequest::_onDisconnect(AsyncClient* client)
|
||||
_HTTPcode = HTTPCODE_CONNECTION_LOST;
|
||||
}
|
||||
|
||||
delete _client;
|
||||
SAFE_DELETE(_client)
|
||||
|
||||
_client = nullptr;
|
||||
|
||||
delete[] _connectedHost;
|
||||
SAFE_DELETE_ARRAY(_connectedHost)
|
||||
|
||||
_connectedHost = nullptr;
|
||||
|
||||
_connectedPort = -1;
|
||||
_connectedPort = -1;
|
||||
_requestEndTime = millis();
|
||||
_lastActivity = 0;
|
||||
_lastActivity = 0;
|
||||
_setReadyState(readyStateDone);
|
||||
|
||||
_unlock;
|
||||
}
|
||||
|
||||
@ -770,6 +859,8 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("_onData handler", (char*) Vbuf, ", len =", len);
|
||||
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
_lastActivity = millis();
|
||||
|
||||
// Transfer data to xbuf
|
||||
@ -786,8 +877,12 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len)
|
||||
// if headers not complete, collect them. If still not complete, just return.
|
||||
if (_readyState == readyStateOpened)
|
||||
{
|
||||
if ( ! _collectHeaders())
|
||||
if ( ! _collectHeaders())
|
||||
{
|
||||
_unlock;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If there's data in the buffer and not Done, advance readyState to Loading.
|
||||
@ -932,7 +1027,8 @@ void AsyncHTTPRequest::setReqHeader(const char* name, const __FlashStringHelper*
|
||||
{
|
||||
char* _value = _charstar(value);
|
||||
_addHeader(name, _value);
|
||||
delete[] _value;
|
||||
|
||||
SAFE_DELETE_ARRAY(_value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -943,7 +1039,8 @@ void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, const char*
|
||||
{
|
||||
char* _name = _charstar(name);
|
||||
_addHeader(_name, value);
|
||||
delete[] _name;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -955,8 +1052,9 @@ void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, const __Fla
|
||||
char* _name = _charstar(name);
|
||||
char* _value = _charstar(value);
|
||||
_addHeader(_name, _value);
|
||||
delete[] _name;
|
||||
delete[] _value;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
SAFE_DELETE_ARRAY(_value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -967,7 +1065,8 @@ void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, int32_t val
|
||||
{
|
||||
char* _name = _charstar(name);
|
||||
setReqHeader(_name, String(value).c_str());
|
||||
delete[] _name;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1058,7 +1157,8 @@ char* AsyncHTTPRequest::respHeaderValue(const __FlashStringHelper *name)
|
||||
|
||||
char* _name = _charstar(name);
|
||||
header* hdr = _getHeader(_name);
|
||||
delete[] _name;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
|
||||
if ( ! hdr)
|
||||
return nullptr;
|
||||
@ -1074,7 +1174,8 @@ bool AsyncHTTPRequest::respHeaderExists(const __FlashStringHelper *name)
|
||||
|
||||
char* _name = _charstar(name);
|
||||
header* hdr = _getHeader(_name);
|
||||
delete[] _name;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
|
||||
if ( ! hdr)
|
||||
return false;
|
||||
@ -1087,7 +1188,8 @@ bool AsyncHTTPRequest::respHeaderExists(const __FlashStringHelper *name)
|
||||
//**************************************************************************************************************
|
||||
String AsyncHTTPRequest::headers()
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK(String())
|
||||
|
||||
String _response = "";
|
||||
header* hdr = _headers;
|
||||
|
||||
@ -1101,6 +1203,7 @@ String AsyncHTTPRequest::headers()
|
||||
}
|
||||
|
||||
_response += "\r\n";
|
||||
|
||||
_unlock;
|
||||
|
||||
return _response;
|
||||
@ -1109,17 +1212,19 @@ String AsyncHTTPRequest::headers()
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_addHeader(const char* name, const char* value)
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK(nullptr)
|
||||
|
||||
header* hdr = (header*) &_headers;
|
||||
|
||||
while (hdr->next)
|
||||
{
|
||||
if (strcasecmp(name, hdr->next->name) == 0)
|
||||
{
|
||||
header* oldHdr = hdr->next;
|
||||
hdr->next = hdr->next->next;
|
||||
oldHdr->next = nullptr;
|
||||
delete oldHdr;
|
||||
header* oldHdr = hdr->next;
|
||||
hdr->next = hdr->next->next;
|
||||
oldHdr->next = nullptr;
|
||||
|
||||
SAFE_DELETE(oldHdr)
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1128,10 +1233,37 @@ AsyncHTTPRequest::header* AsyncHTTPRequest::_addHeader(const char* name, const
|
||||
}
|
||||
|
||||
hdr->next = new header;
|
||||
hdr->next->name = new char[strlen(name) + 1];
|
||||
strcpy(hdr->next->name, name);
|
||||
hdr->next->value = new char[strlen(value) + 1];
|
||||
strcpy(hdr->next->value, value);
|
||||
|
||||
if (hdr->next)
|
||||
{
|
||||
hdr->next->name = new char[strlen(name) + 1];
|
||||
|
||||
if (hdr->next->name)
|
||||
strcpy(hdr->next->name, name);
|
||||
else
|
||||
{
|
||||
SAFE_DELETE(hdr->next)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hdr->next->value = new char[strlen(value) + 1];
|
||||
|
||||
if (hdr->next->value)
|
||||
strcpy(hdr->next->value, value);
|
||||
else
|
||||
{
|
||||
SAFE_DELETE_ARRAY(hdr->next->name)
|
||||
SAFE_DELETE(hdr->next)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
_unlock;
|
||||
|
||||
return hdr->next;
|
||||
@ -1140,7 +1272,8 @@ AsyncHTTPRequest::header* AsyncHTTPRequest::_addHeader(const char* name, const
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_getHeader(const char* name)
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK(nullptr)
|
||||
|
||||
header* hdr = _headers;
|
||||
|
||||
while (hdr)
|
||||
@ -1159,7 +1292,8 @@ AsyncHTTPRequest::header* AsyncHTTPRequest::_getHeader(const char* name)
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_getHeader(int ndx)
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK(nullptr)
|
||||
|
||||
header* hdr = _headers;
|
||||
|
||||
while (hdr)
|
||||
@ -1184,8 +1318,13 @@ char* AsyncHTTPRequest::_charstar(const __FlashStringHelper * str)
|
||||
return nullptr;
|
||||
|
||||
char* ptr = new char[strlen_P((PGM_P)str) + 1];
|
||||
strcpy_P(ptr, (PGM_P)str);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
strcpy_P(ptr, (PGM_P)str);
|
||||
}
|
||||
|
||||
// Rturn good ptr or nullptr
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************************************************************
|
||||
src_cpp/AsyncHTTPRequest_Generic.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
AsyncHTTPRequest_Generic.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
@ -17,17 +17,18 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define AsyncHTTPRequest_Generic_version "1.0.0"
|
||||
#define ASYNC_HTTP_REQUEST_GENERIC_VERSION "1.0.2"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
@ -43,15 +44,29 @@
|
||||
#define DEBUG_IOTA_HTTP_SET false
|
||||
#endif
|
||||
|
||||
|
||||
// KH add
|
||||
#define SAFE_DELETE(object) if (object) { delete object;}
|
||||
#define SAFE_DELETE_ARRAY(object) if (object) { delete[] object;}
|
||||
|
||||
#if ESP32
|
||||
|
||||
#include <AsyncTCP.h>
|
||||
|
||||
// KH mod
|
||||
#define MUTEX_LOCK_NR if (xSemaphoreTakeRecursive(threadLock,portMAX_DELAY) != pdTRUE) { return;}
|
||||
#define MUTEX_LOCK(returnVal) if (xSemaphoreTakeRecursive(threadLock,portMAX_DELAY) != pdTRUE) { return returnVal;}
|
||||
|
||||
#define _lock xSemaphoreTakeRecursive(threadLock,portMAX_DELAY)
|
||||
#define _unlock xSemaphoreGiveRecursive(threadLock)
|
||||
|
||||
#elif ESP8266
|
||||
|
||||
#include <ESPAsyncTCP.h>
|
||||
|
||||
#define MUTEX_LOCK_NR
|
||||
#define MUTEX_LOCK(returnVal)
|
||||
|
||||
#define _lock
|
||||
#define _unlock
|
||||
|
||||
@ -60,6 +75,9 @@
|
||||
defined(STM32WB) || defined(STM32MP1) )
|
||||
|
||||
#include "STM32AsyncTCP.h"
|
||||
|
||||
#define MUTEX_LOCK_NR
|
||||
#define MUTEX_LOCK(returnVal)
|
||||
#define _lock
|
||||
#define _unlock
|
||||
|
||||
@ -108,9 +126,12 @@ class AsyncHTTPRequest
|
||||
|
||||
~header()
|
||||
{
|
||||
delete[] name;
|
||||
delete[] value;
|
||||
delete next;
|
||||
SAFE_DELETE_ARRAY(name)
|
||||
SAFE_DELETE_ARRAY(value)
|
||||
SAFE_DELETE(next)
|
||||
//delete[] name;
|
||||
//delete[] value;
|
||||
//delete next;
|
||||
}
|
||||
};
|
||||
|
||||
@ -131,13 +152,13 @@ class AsyncHTTPRequest
|
||||
|
||||
~URL()
|
||||
{
|
||||
delete[] scheme;
|
||||
delete[] user;
|
||||
delete[] pwd;
|
||||
delete[] host;
|
||||
delete[] path;
|
||||
delete[] query;
|
||||
delete[] fragment;
|
||||
SAFE_DELETE_ARRAY(scheme)
|
||||
SAFE_DELETE_ARRAY(user)
|
||||
SAFE_DELETE_ARRAY(pwd)
|
||||
SAFE_DELETE_ARRAY(host)
|
||||
SAFE_DELETE_ARRAY(path)
|
||||
SAFE_DELETE_ARRAY(query)
|
||||
SAFE_DELETE_ARRAY(fragment)
|
||||
}
|
||||
};
|
||||
|
||||
@ -263,3 +284,4 @@ class AsyncHTTPRequest
|
||||
void _onPoll(AsyncClient*);
|
||||
bool _collectHeaders();
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************************************************************
|
||||
src_cpp/utility/xbuf_Impl.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
xbuf_Impl.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include "utility/xbuf.h"
|
||||
@ -361,14 +362,20 @@ void xbuf::addSeg()
|
||||
if (_tail)
|
||||
{
|
||||
_tail->next = (xseg*) new uint32_t[_segSize / 4 + 1];
|
||||
|
||||
// KH, Must check NULL here
|
||||
_tail = _tail->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// KH, Must check NULL here
|
||||
_tail = _head = (xseg*) new uint32_t[_segSize / 4 + 1];
|
||||
}
|
||||
|
||||
_tail->next = nullptr;
|
||||
// KH, Must check NULL here
|
||||
if (_tail)
|
||||
_tail->next = nullptr;
|
||||
|
||||
_free += _segSize;
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,13 @@
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
@ -43,7 +44,6 @@
|
||||
It could be extended but didn't seem to be a practical consideration.
|
||||
|
||||
********************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
@ -144,5 +144,6 @@ class xbuf: public Print
|
||||
|
||||
void addSeg();
|
||||
void remSeg();
|
||||
|
||||
};
|
||||
|
||||
|
71
src_h/AsyncHTTPRequest_Debug_Generic.h
Normal file
71
src_h/AsyncHTTPRequest_Debug_Generic.h
Normal file
@ -0,0 +1,71 @@
|
||||
/****************************************************************************************************************************
|
||||
AsyncHTTPRequest_Debug_Generic.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
AsyncHTTPRequest_STM32 is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
|
||||
|
||||
Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
Licensed under MIT license
|
||||
|
||||
Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
This program 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 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef ASYNC_HTTP_DEBUG_PORT
|
||||
#define A_DBG_PORT ASYNC_HTTP_DEBUG_PORT
|
||||
#else
|
||||
#define A_DBG_PORT Serial
|
||||
#endif
|
||||
|
||||
// Change _ASYNC_HTTP_LOGLEVEL_ to set tracing and logging verbosity
|
||||
// 0: DISABLED: no logging
|
||||
// 1: ERROR: errors
|
||||
// 2: WARN: errors and warnings
|
||||
// 3: INFO: errors, warnings and informational (default)
|
||||
// 4: DEBUG: errors, warnings, informational and debug
|
||||
|
||||
#ifndef _ASYNC_HTTP_LOGLEVEL_
|
||||
#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); }
|
||||
|
288
src_h/AsyncHTTPRequest_Generic.h
Normal file
288
src_h/AsyncHTTPRequest_Generic.h
Normal file
@ -0,0 +1,288 @@
|
||||
/****************************************************************************************************************************
|
||||
AsyncHTTPRequest_Generic.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
AsyncHTTPRequest_STM32 is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
|
||||
|
||||
Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
Licensed under MIT license
|
||||
|
||||
Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
This program 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 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ASYNC_HTTP_REQUEST_GENERIC_VERSION "1.0.2"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "AsyncHTTPRequest_Debug_Generic.h"
|
||||
|
||||
#ifndef DEBUG_IOTA_PORT
|
||||
#define DEBUG_IOTA_PORT Serial
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_IOTA_HTTP
|
||||
#define DEBUG_IOTA_HTTP_SET true
|
||||
#else
|
||||
#define DEBUG_IOTA_HTTP_SET false
|
||||
#endif
|
||||
|
||||
|
||||
// KH add
|
||||
#define SAFE_DELETE(object) if (object) { delete object;}
|
||||
#define SAFE_DELETE_ARRAY(object) if (object) { delete[] object;}
|
||||
|
||||
#if ESP32
|
||||
|
||||
#include <AsyncTCP.h>
|
||||
|
||||
// KH mod
|
||||
#define MUTEX_LOCK_NR if (xSemaphoreTakeRecursive(threadLock,portMAX_DELAY) != pdTRUE) { return;}
|
||||
#define MUTEX_LOCK(returnVal) if (xSemaphoreTakeRecursive(threadLock,portMAX_DELAY) != pdTRUE) { return returnVal;}
|
||||
|
||||
#define _lock xSemaphoreTakeRecursive(threadLock,portMAX_DELAY)
|
||||
#define _unlock xSemaphoreGiveRecursive(threadLock)
|
||||
|
||||
#elif ESP8266
|
||||
|
||||
#include <ESPAsyncTCP.h>
|
||||
|
||||
#define MUTEX_LOCK_NR
|
||||
#define MUTEX_LOCK(returnVal)
|
||||
|
||||
#define _lock
|
||||
#define _unlock
|
||||
|
||||
#elif ( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) ||defined(STM32F4) || defined(STM32F7) || \
|
||||
defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7) ||defined(STM32G0) || defined(STM32G4) || \
|
||||
defined(STM32WB) || defined(STM32MP1) )
|
||||
|
||||
#include "STM32AsyncTCP.h"
|
||||
|
||||
#define MUTEX_LOCK_NR
|
||||
#define MUTEX_LOCK(returnVal)
|
||||
#define _lock
|
||||
#define _unlock
|
||||
|
||||
#endif
|
||||
|
||||
#include <pgmspace.h>
|
||||
#include <utility/xbuf.h>
|
||||
|
||||
#define DEBUG_HTTP(format,...) if(_debug){\
|
||||
DEBUG_IOTA_PORT.printf("Debug(%3ld): ", millis()-_requestStartTime);\
|
||||
DEBUG_IOTA_PORT.printf_P(PSTR(format),##__VA_ARGS__);}
|
||||
|
||||
#define DEFAULT_RX_TIMEOUT 3 // Seconds for timeout
|
||||
|
||||
#define HTTPCODE_CONNECTION_REFUSED (-1)
|
||||
#define HTTPCODE_SEND_HEADER_FAILED (-2)
|
||||
#define HTTPCODE_SEND_PAYLOAD_FAILED (-3)
|
||||
#define HTTPCODE_NOT_CONNECTED (-4)
|
||||
#define HTTPCODE_CONNECTION_LOST (-5)
|
||||
#define HTTPCODE_NO_STREAM (-6)
|
||||
#define HTTPCODE_NO_HTTP_SERVER (-7)
|
||||
#define HTTPCODE_TOO_LESS_RAM (-8)
|
||||
#define HTTPCODE_ENCODING (-9)
|
||||
#define HTTPCODE_STREAM_WRITE (-10)
|
||||
#define HTTPCODE_TIMEOUT (-11)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
readyStateUnsent = 0, // Client created, open not yet called
|
||||
readyStateOpened = 1, // open() has been called, connected
|
||||
readyStateHdrsRecvd = 2, // send() called, response headers available
|
||||
readyStateLoading = 3, // receiving, partial data available
|
||||
readyStateDone = 4 // Request complete, all data available.
|
||||
} reqStates;
|
||||
|
||||
class AsyncHTTPRequest
|
||||
{
|
||||
struct header
|
||||
{
|
||||
header* next;
|
||||
char* name;
|
||||
char* value;
|
||||
|
||||
header(): next(nullptr), name(nullptr), value(nullptr)
|
||||
{};
|
||||
|
||||
~header()
|
||||
{
|
||||
SAFE_DELETE_ARRAY(name)
|
||||
SAFE_DELETE_ARRAY(value)
|
||||
SAFE_DELETE(next)
|
||||
//delete[] name;
|
||||
//delete[] value;
|
||||
//delete next;
|
||||
}
|
||||
};
|
||||
|
||||
struct URL
|
||||
{
|
||||
char* scheme;
|
||||
char* user;
|
||||
char* pwd;
|
||||
char* host;
|
||||
int port;
|
||||
char* path;
|
||||
char* query;
|
||||
char* fragment;
|
||||
|
||||
URL(): scheme(nullptr), user(nullptr), pwd(nullptr), host(nullptr),
|
||||
port(80), path(nullptr), query(nullptr), fragment(nullptr)
|
||||
{};
|
||||
|
||||
~URL()
|
||||
{
|
||||
SAFE_DELETE_ARRAY(scheme)
|
||||
SAFE_DELETE_ARRAY(user)
|
||||
SAFE_DELETE_ARRAY(pwd)
|
||||
SAFE_DELETE_ARRAY(host)
|
||||
SAFE_DELETE_ARRAY(path)
|
||||
SAFE_DELETE_ARRAY(query)
|
||||
SAFE_DELETE_ARRAY(fragment)
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::function<void(void*, AsyncHTTPRequest*, int readyState)> readyStateChangeCB;
|
||||
typedef std::function<void(void*, AsyncHTTPRequest*, size_t available)> onDataCB;
|
||||
|
||||
public:
|
||||
AsyncHTTPRequest();
|
||||
~AsyncHTTPRequest();
|
||||
|
||||
|
||||
//External functions in typical order of use:
|
||||
//__________________________________________________________________________________________________________*/
|
||||
void setDebug(bool); // Turn debug message on/off
|
||||
bool debug(); // is debug on or off?
|
||||
|
||||
bool open(const char* /*GET/POST*/, const char* URL); // Initiate a request
|
||||
void onReadyStateChange(readyStateChangeCB, void* arg = 0); // Optional event handler for ready state change
|
||||
// or you can simply poll readyState()
|
||||
void setTimeout(int); // overide default timeout (seconds)
|
||||
|
||||
void setReqHeader(const char* name, const char* value); // add a request header
|
||||
void setReqHeader(const char* name, int32_t value); // overload to use integer value
|
||||
|
||||
#if (ESP32 || ESP8266)
|
||||
void setReqHeader(const char* name, const __FlashStringHelper* value);
|
||||
void setReqHeader(const __FlashStringHelper *name, const char* value);
|
||||
void setReqHeader(const __FlashStringHelper *name, const __FlashStringHelper* value);
|
||||
void setReqHeader(const __FlashStringHelper *name, int32_t value);
|
||||
#endif
|
||||
|
||||
bool send(); // Send the request (GET)
|
||||
bool send(String body); // Send the request (POST)
|
||||
bool send(const char* body); // Send the request (POST)
|
||||
bool send(const uint8_t* buffer, size_t len); // Send the request (POST) (binary data?)
|
||||
bool send(xbuf* body, size_t len); // Send the request (POST) data in an xbuf
|
||||
void abort(); // Abort the current operation
|
||||
|
||||
reqStates readyState(); // Return the ready state
|
||||
|
||||
int respHeaderCount(); // Retrieve count of response headers
|
||||
char* respHeaderName(int index); // Return header name by index
|
||||
char* respHeaderValue(int index); // Return header value by index
|
||||
char* respHeaderValue(const char* name); // Return header value by name
|
||||
|
||||
bool respHeaderExists(const char* name); // Does header exist by name?
|
||||
|
||||
#if (ESP32 || ESP8266)
|
||||
char* respHeaderValue(const __FlashStringHelper *name);
|
||||
bool respHeaderExists(const __FlashStringHelper *name);
|
||||
#endif
|
||||
|
||||
String headers(); // Return all headers as String
|
||||
|
||||
void onData(onDataCB, void* arg = 0); // Notify when min data is available
|
||||
size_t available(); // response available
|
||||
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)
|
||||
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)
|
||||
String version(); // Version of AsyncHTTPRequest
|
||||
//___________________________________________________________________________________________________________________________________
|
||||
|
||||
private:
|
||||
|
||||
enum {HTTPmethodGET, HTTPmethodPOST} _HTTPmethod;
|
||||
|
||||
reqStates _readyState;
|
||||
|
||||
int16_t _HTTPcode; // HTTP response code or (negative) exception code
|
||||
bool _chunked; // Processing chunked response
|
||||
bool _debug; // Debug state
|
||||
uint32_t _timeout; // Default or user overide RxTimeout in seconds
|
||||
uint32_t _lastActivity; // Time of last activity
|
||||
uint32_t _requestStartTime; // Time last open() issued
|
||||
uint32_t _requestEndTime; // Time of last disconnect
|
||||
URL* _URL; // -> URL data structure
|
||||
char* _connectedHost; // Host when connected
|
||||
int _connectedPort; // Port when connected
|
||||
AsyncClient* _client; // ESPAsyncTCP AsyncClient instance
|
||||
size_t _contentLength; // content-length header value or sum of chunk headers
|
||||
size_t _contentRead; // number of bytes retrieved by user since last open()
|
||||
readyStateChangeCB _readyStateChangeCB; // optional callback for readyState change
|
||||
void* _readyStateChangeCBarg; // associated user argument
|
||||
onDataCB _onDataCB; // optional callback when data received
|
||||
void* _onDataCBarg; // associated user argument
|
||||
|
||||
#ifdef ESP32
|
||||
SemaphoreHandle_t threadLock;
|
||||
#endif
|
||||
|
||||
// request and response String buffers and header list (same queue for request and response).
|
||||
|
||||
xbuf* _request; // Tx data buffer
|
||||
xbuf* _response; // Rx data buffer for headers
|
||||
xbuf* _chunks; // First stage for chunked response
|
||||
header* _headers; // request or (readyState > readyStateHdrsRcvd) response headers
|
||||
|
||||
// Protected functions
|
||||
|
||||
header* _addHeader(const char*, const char*);
|
||||
header* _getHeader(const char*);
|
||||
header* _getHeader(int);
|
||||
bool _buildRequest();
|
||||
bool _parseURL(const char*);
|
||||
bool _parseURL(String);
|
||||
void _processChunks();
|
||||
bool _connect();
|
||||
size_t _send();
|
||||
void _setReadyState(reqStates);
|
||||
|
||||
#if (ESP32 || ESP8266)
|
||||
char* _charstar(const __FlashStringHelper *str);
|
||||
#endif
|
||||
|
||||
// callbacks
|
||||
|
||||
void _onConnect(AsyncClient*);
|
||||
void _onDisconnect(AsyncClient*);
|
||||
void _onData(void*, size_t);
|
||||
void _onError(AsyncClient*, int8_t);
|
||||
void _onPoll(AsyncClient*);
|
||||
bool _collectHeaders();
|
||||
};
|
||||
|
||||
#include "AsyncHTTPRequest_Impl_Generic.h"
|
1330
src_h/AsyncHTTPRequest_Impl_Generic.h
Normal file
1330
src_h/AsyncHTTPRequest_Impl_Generic.h
Normal file
File diff suppressed because it is too large
Load Diff
151
src_h/utility/xbuf.h
Normal file
151
src_h/utility/xbuf.h
Normal file
@ -0,0 +1,151 @@
|
||||
/****************************************************************************************************************************
|
||||
xbuf.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
AsyncHTTPRequest_STM32 is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
|
||||
|
||||
Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
Licensed under MIT license
|
||||
|
||||
Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
This program 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 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
xbuf is a dynamic buffering system that supports reading and writing much like cbuf.
|
||||
The class has it's own provision for writing from buffers, Strings and other xbufs
|
||||
as well as the inherited Print functions.
|
||||
Rather than use a large contiguous heap allocation, xbuf uses a linked chain of segments
|
||||
to dynamically grow and shrink with the contents.
|
||||
There are other benefits as well to using smaller heap allocation units:
|
||||
1) A buffer can work fine in a fragmented heap environment (admittedly contributing to it)
|
||||
2) xbuf contents can be copied from one buffer to another without the need for
|
||||
2x heap during the copy.
|
||||
The segment size defaults to 64 but can be dynamically set in the constructor at creation.
|
||||
The inclusion of indexOf and read/peek until functions make it useful for handling
|
||||
data streams like HTTP, and in fact is why it was created.
|
||||
|
||||
NOTE: The size of the indexOf() search string is limited to the segment size.
|
||||
It could be extended but didn't seem to be a practical consideration.
|
||||
|
||||
********************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
struct xseg
|
||||
{
|
||||
xseg *next;
|
||||
uint8_t data[];
|
||||
};
|
||||
|
||||
class xbuf: public Print
|
||||
{
|
||||
public:
|
||||
|
||||
xbuf(const uint16_t segSize = 64);
|
||||
virtual ~xbuf();
|
||||
|
||||
size_t write(const uint8_t);
|
||||
size_t write(const char*);
|
||||
size_t write(const uint8_t*, const size_t);
|
||||
size_t write(xbuf*, const size_t);
|
||||
size_t write(String);
|
||||
size_t available();
|
||||
int indexOf(const char, const size_t begin = 0);
|
||||
int indexOf(const char*, const size_t begin = 0);
|
||||
uint8_t read();
|
||||
size_t read(uint8_t*, size_t);
|
||||
String readStringUntil(const char);
|
||||
String readStringUntil(const char*);
|
||||
String readString(int);
|
||||
|
||||
String readString()
|
||||
{
|
||||
return readString(available());
|
||||
}
|
||||
|
||||
void flush();
|
||||
|
||||
uint8_t peek();
|
||||
size_t peek(uint8_t*, const size_t);
|
||||
|
||||
String peekStringUntil(const char target)
|
||||
{
|
||||
return peekString(indexOf(target, 0));
|
||||
}
|
||||
|
||||
String peekStringUntil(const char* target)
|
||||
{
|
||||
return peekString(indexOf(target, 0));
|
||||
}
|
||||
|
||||
String peekString()
|
||||
{
|
||||
return peekString(_used);
|
||||
}
|
||||
|
||||
String peekString(int);
|
||||
|
||||
/* In addition to the above functions,
|
||||
the following inherited functions from the Print class are available.
|
||||
|
||||
size_t printf(const char * format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
size_t printf_P(PGM_P format, ...) __attribute__((format(printf, 2, 3)));
|
||||
size_t print(const __FlashStringHelper *);
|
||||
size_t print(const String &);
|
||||
size_t print(const char[]);
|
||||
size_t print(char);
|
||||
size_t print(unsigned char, int = DEC);
|
||||
size_t print(int, int = DEC);
|
||||
size_t print(unsigned int, int = DEC);
|
||||
size_t print(long, int = DEC);
|
||||
size_t print(unsigned long, int = DEC);
|
||||
size_t print(double, int = 2);
|
||||
size_t print(const Printable&);
|
||||
|
||||
size_t println(const __FlashStringHelper *);
|
||||
size_t println(const String &s);
|
||||
size_t println(const char[]);
|
||||
size_t println(char);
|
||||
size_t println(unsigned char, int = DEC);
|
||||
size_t println(int, int = DEC);
|
||||
size_t println(unsigned int, int = DEC);
|
||||
size_t println(long, int = DEC);
|
||||
size_t println(unsigned long, int = DEC);
|
||||
size_t println(double, int = 2);
|
||||
size_t println(const Printable&);
|
||||
size_t println(void);
|
||||
*/
|
||||
|
||||
protected:
|
||||
|
||||
xseg *_head;
|
||||
xseg *_tail;
|
||||
uint16_t _used;
|
||||
uint16_t _free;
|
||||
uint16_t _offset;
|
||||
uint16_t _segSize;
|
||||
|
||||
void addSeg();
|
||||
void remSeg();
|
||||
|
||||
};
|
||||
|
||||
#include "utility/xbuf_Impl.h"
|
||||
|
399
src_h/utility/xbuf_Impl.h
Normal file
399
src_h/utility/xbuf_Impl.h
Normal file
@ -0,0 +1,399 @@
|
||||
/****************************************************************************************************************************
|
||||
xbuf_Impl.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
AsyncHTTPRequest_STM32 is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
|
||||
|
||||
Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
Licensed under MIT license
|
||||
|
||||
Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
This program 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 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
xbuf::xbuf(const uint16_t segSize) : _head(nullptr), _tail(nullptr), _used(0), _free(0), _offset(0)
|
||||
{
|
||||
_segSize = (segSize + 3) & -4;//((segSize + 3) >> 2) << 2;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
xbuf::~xbuf()
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(const uint8_t byte)
|
||||
{
|
||||
return write((uint8_t*) &byte, 1);
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(const char* buf)
|
||||
{
|
||||
return write((uint8_t*)buf, strlen(buf));
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(String string)
|
||||
{
|
||||
return write((uint8_t*)string.c_str(), string.length());
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(const uint8_t* buf, const size_t len)
|
||||
{
|
||||
size_t supply = len;
|
||||
|
||||
while (supply)
|
||||
{
|
||||
if (!_free)
|
||||
{
|
||||
addSeg();
|
||||
}
|
||||
|
||||
size_t demand = _free < supply ? _free : supply;
|
||||
memcpy(_tail->data + ((_offset + _used) % _segSize), buf + (len - supply), demand);
|
||||
_free -= demand;
|
||||
_used += demand;
|
||||
supply -= demand;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(xbuf* buf, const size_t len)
|
||||
{
|
||||
size_t supply = len;
|
||||
|
||||
if (supply > buf->available())
|
||||
{
|
||||
supply = buf->available();
|
||||
}
|
||||
|
||||
size_t read = 0;
|
||||
|
||||
while (supply)
|
||||
{
|
||||
if (!_free)
|
||||
{
|
||||
addSeg();
|
||||
}
|
||||
|
||||
size_t demand = _free < supply ? _free : supply;
|
||||
read += buf->read(_tail->data + ((_offset + _used) % _segSize), demand);
|
||||
_free -= demand;
|
||||
_used += demand;
|
||||
supply -= demand;
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
uint8_t xbuf::read()
|
||||
{
|
||||
uint8_t byte = 0;
|
||||
read((uint8_t*) &byte, 1);
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
uint8_t xbuf::peek()
|
||||
{
|
||||
uint8_t byte = 0;
|
||||
peek((uint8_t*) &byte, 1);
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::read(uint8_t* buf, const size_t len)
|
||||
{
|
||||
size_t read = 0;
|
||||
|
||||
while (read < len && _used)
|
||||
{
|
||||
size_t supply = (_offset + _used) > _segSize ? _segSize - _offset : _used;
|
||||
size_t demand = len - read;
|
||||
size_t chunk = supply < demand ? supply : demand;
|
||||
memcpy(buf + read, _head->data + _offset, chunk);
|
||||
_offset += chunk;
|
||||
_used -= chunk;
|
||||
read += chunk;
|
||||
|
||||
if (_offset == _segSize)
|
||||
{
|
||||
remSeg();
|
||||
_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! _used)
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::peek(uint8_t* buf, const size_t len)
|
||||
{
|
||||
size_t read = 0;
|
||||
xseg* seg = _head;
|
||||
size_t offset = _offset;
|
||||
size_t used = _used;
|
||||
|
||||
while (read < len && used)
|
||||
{
|
||||
size_t supply = (offset + used) > _segSize ? _segSize - offset : used;
|
||||
size_t demand = len - read;
|
||||
size_t chunk = supply < demand ? supply : demand;
|
||||
|
||||
memcpy(buf + read, seg->data + offset, chunk);
|
||||
|
||||
offset += chunk;
|
||||
used -= chunk;
|
||||
read += chunk;
|
||||
|
||||
if (offset == _segSize)
|
||||
{
|
||||
seg = seg->next;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::available()
|
||||
{
|
||||
return _used;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
int xbuf::indexOf(const char target, const size_t begin)
|
||||
{
|
||||
char targetstr[2] = " ";
|
||||
targetstr[0] = target;
|
||||
|
||||
return indexOf(targetstr, begin);
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
int xbuf::indexOf(const char* target, const size_t begin)
|
||||
{
|
||||
size_t targetLen = strlen(target);
|
||||
|
||||
if (targetLen > _segSize || targetLen > _used)
|
||||
return -1;
|
||||
|
||||
size_t searchPos = _offset + begin;
|
||||
size_t searchEnd = _offset + _used - targetLen;
|
||||
|
||||
if (searchPos > searchEnd)
|
||||
return -1;
|
||||
|
||||
size_t searchSeg = searchPos / _segSize;
|
||||
xseg* seg = _head;
|
||||
|
||||
while (searchSeg)
|
||||
{
|
||||
seg = seg->next;
|
||||
searchSeg --;
|
||||
}
|
||||
|
||||
size_t segPos = searchPos % _segSize;
|
||||
|
||||
while (searchPos <= searchEnd)
|
||||
{
|
||||
size_t compLen = targetLen;
|
||||
|
||||
if (compLen <= (_segSize - segPos))
|
||||
{
|
||||
if (memcmp(target, seg->data + segPos, compLen) == 0)
|
||||
{
|
||||
return searchPos - _offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t compLen = _segSize - segPos;
|
||||
|
||||
if (memcmp(target, seg->data + segPos, compLen) == 0)
|
||||
{
|
||||
compLen = targetLen - compLen;
|
||||
|
||||
if (memcmp(target + targetLen - compLen, seg->next->data, compLen) == 0)
|
||||
{
|
||||
return searchPos - _offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
searchPos++;
|
||||
segPos++;
|
||||
|
||||
if (segPos == _segSize)
|
||||
{
|
||||
seg = seg->next;
|
||||
segPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
String xbuf::readStringUntil(const char target)
|
||||
{
|
||||
return readString(indexOf(target) + 1);
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
String xbuf::readStringUntil(const char* target)
|
||||
{
|
||||
int index = indexOf(target);
|
||||
|
||||
if (index < 0)
|
||||
return String();
|
||||
|
||||
return readString(index + strlen(target));
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
String xbuf::readString(int endPos)
|
||||
{
|
||||
String result;
|
||||
|
||||
if ( ! result.reserve(endPos + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (endPos > _used)
|
||||
{
|
||||
endPos = _used;
|
||||
}
|
||||
|
||||
if (endPos > 0 && result.reserve(endPos + 1))
|
||||
{
|
||||
while (endPos--)
|
||||
{
|
||||
result += (char)_head->data[_offset++];
|
||||
_used--;
|
||||
|
||||
if (_offset >= _segSize)
|
||||
{
|
||||
remSeg();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
String xbuf::peekString(int endPos)
|
||||
{
|
||||
String result;
|
||||
|
||||
xseg* seg = _head;
|
||||
size_t offset = _offset;
|
||||
|
||||
if (endPos > _used)
|
||||
{
|
||||
endPos = _used;
|
||||
}
|
||||
|
||||
if (endPos > 0 && result.reserve(endPos + 1))
|
||||
{
|
||||
while (endPos--)
|
||||
{
|
||||
result += (char)seg->data[offset++];
|
||||
|
||||
if ( offset >= _segSize)
|
||||
{
|
||||
seg = seg->next;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
void xbuf::flush()
|
||||
{
|
||||
while (_head)
|
||||
remSeg();
|
||||
|
||||
_tail = nullptr;
|
||||
_offset = 0;
|
||||
_used = 0;
|
||||
_free = 0;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
void xbuf::addSeg()
|
||||
{
|
||||
if (_tail)
|
||||
{
|
||||
_tail->next = (xseg*) new uint32_t[_segSize / 4 + 1];
|
||||
|
||||
// KH, Must check NULL here
|
||||
_tail = _tail->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// KH, Must check NULL here
|
||||
_tail = _head = (xseg*) new uint32_t[_segSize / 4 + 1];
|
||||
}
|
||||
|
||||
// KH, Must check NULL here
|
||||
if (_tail)
|
||||
_tail->next = nullptr;
|
||||
|
||||
_free += _segSize;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
void xbuf::remSeg()
|
||||
{
|
||||
if (_head)
|
||||
{
|
||||
xseg *next = _head->next;
|
||||
delete[] (uint32_t*) _head;
|
||||
_head = next;
|
||||
|
||||
if ( ! _head)
|
||||
{
|
||||
_tail = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
_offset = 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user