Giter Club home page Giter Club logo

khoih-prog / asynchttpsrequest_generic Goto Github PK

View Code? Open in Web Editor NEW
19.0 4.0 4.0 334 KB

Simple Async HTTPS Request library, supporting GET, POST, PUT, PATCH, DELETE and HEAD, on top of AsyncTCP_SSL library for ESP32 (including ESP32_S2, ESP32_S3 and ESP32_C3), WT32_ETH01 (ESP32 + LAN8720). Supporting in the future for RP2040W, ESP8266, Portenta_H7, STM32 with built-in LAN8742A Ethernet, etc. Now you can send HTTP / HTTPS requests to multiple addresses and receive responses from them

License: GNU General Public License v3.0

C++ 85.52% C 14.20% Shell 0.27%
tls ssl async https esp32 wifi-network https-client lan8720 esp32-s2 esp32-c3

asynchttpsrequest_generic's Introduction

AsyncHTTPSRequest_Generic Library

arduino-library-badge GitHub release contributions welcome GitHub issues

Donate to my libraries using BuyMeACoffee



Table of Contents



Important Change from v2.0.0

Breaking change to permit coexisting with AsyncHTTPRequest library. Now you can send HTTP / HTTPS requests to multiple addresses and receive responses from them.

Important Change from v1.3.0

Please have a look at HOWTO Fix Multiple Definitions Linker Error



Why do we need this Async AsyncHTTPSRequest_Generic library

Important notes for WT32_ETH01

ESP32 Core v2.0.0+ introduces new enum breaking almost all WT32_ETH01 codes written for core v1.0.6-.

It's really strange to define a breaking enum arduino_event_id_t in WiFiGeneric.h#L36-L78, compared to the old system_event_id_t, now placed in esp_event_legacy.h#L29-L63

It's better to preserve the old enum order and just adding new items to do no harm to pre-2.0.0 codes

To use with core v1.0.6-, just define in your sketch

#define USING_CORE_ESP32_CORE_V200_PLUS       false

Features

  1. Asynchronous HTTPS Request library for ESP32, ESP32_S2, ESP32_C3, ESP32_S3 using built-in WiFi, WT32_ETH01 using either WiFi of built-in LAN8720 Ethernet and ESP32 boards using LwIP ENC28J60 Ethernet
  2. Providing a subset of HTTPS.
  3. Relying on AsyncTCP_SSL library for ESP32
  4. Methods similar in format and usage to XmlHTTPrequest in Javascript.
  5. Coexist with AsyncHTTPRequest library to permit sending HTTP / HTTPS requests to multiple addresses and receive responses from them

Supports

  1. GET, POST, PUT, PATCH, DELETE and HEAD
  2. Request and response headers
  3. Chunked response
  4. Single String response for short (<~5K) responses (heap permitting).
  5. Optional onData callback.
  6. Optional onReadyStatechange callback.

Principles of operation

This library adds a simple HTTPS layer on top of the AsyncTCP_SSL library to facilitate REST communication from a Client to a Server. The paradigm is similar to the XMLHttpRequest in Javascript, employing the notion of a ready-state progression through the transaction request.

Synchronization can be accomplished using callbacks on ready-state change, a callback on data receipt, or simply polling for ready-state change. Data retrieval can be incremental as received, or bulk retrieved when the transaction completes provided there is enough heap to buffer the entire response.

The underlying buffering uses a new xbuf class. It handles both character and binary data. Class xbuf uses a chain of small (64 byte) segments that are allocated and added to the tail as data is added and deallocated from the head as data is read, achieving the same result as a dynamic circular buffer limited only by the size of heap. The xbuf implements indexOf and readUntil functions.

For short transactions, buffer space should not be an issue. In fact, it can be more economical than other methods that use larger fixed length buffers. Data is acked when retrieved by the caller, so there is some limited flow control to limit heap usage for larger transfers.

Request and response headers are handled in the typical fashion.

Chunked responses are recognized and handled transparently.

This library is based on, modified from:

  1. Bob Lemaire's asyncHTTPrequest Library
  2. Khoi Hoang's AsyncHTTPRequest_Generic Library

Currently Supported Boards

1. ESP32 including ESP32_S2 (ESP32_S2 Saola, AI-Thinker ESP-12K, etc.), ESP32_S3 and ESP32_C3

  1. ESP32-S2 (ESP32-S2 Saola, AI-Thinker ESP-12K, etc.) using EEPROM, SPIFFS or LittleFS.
  2. ESP32-C3 (ARDUINO_ESP32C3_DEV) using EEPROM, SPIFFS or LittleFS.
  3. ESP32-S3 (ESP32S3_DEV, ESP32_S3_BOX, UM TINYS3, UM PROS3, UM FEATHERS3, etc.) using EEPROM, SPIFFS or LittleFS.

2. WT32_ETH01 using ESP32-based boards and LAN8720 Ethernet

3. ESP32 boards using LwIP ENC28J60 Ethernet

4. ESP32 boards using LwIP W5500 Ethernet

5. ESP32 boards using LwIP W6100 Ethernet


To be supported boards in the future

  1. ESP8266 using either WiFi or W5x00/ENC28J60 Ethernet
  2. RP2040W using arduino-pico core
  3. STM32 using built-in LAN8742A
  4. Portenta_H7 using either Ethernet or built-in WiFi
  5. ESP32 using either LwIP W5x00, LAN83848, etc. Ethernet


Prerequisites

  1. Arduino IDE 1.8.19+ for Arduino. GitHub release
  2. ESP32 Core 2.0.6+ for ESP32-based boards. [Latest stable release Release Version
  3. AsyncTCP_SSL v1.3.1+ for ESP32. GitHub release
  4. WebServer_WT32_ETH01 v1.5.1+ for ESP32-based WT32_ETH01 using either ESP32 core v2.0.0+ or v1.0.6-. GitHub release
  5. WebServer_ESP32_ENC v1.5.3+ for ESP32 boards using LwIP ENC28J60 Ethernet. GitHub release
  6. WebServer_ESP32_W5500 v1.5.3+ for ESP32 boards using LwIP W5500 Ethernet. GitHub release
  7. WebServer_ESP32_W6100 v1.5.3+ for ESP32 boards using LwIP W6100 Ethernet. GitHub release
  8. ESPAsync_WiFiManager library v1.15.1+ for ESP32/ESP8266 using some examples. GitHub release
  9. AsyncHTTPRequest_Generic library v1.12.0+ for ESP32/ESP8266 using with AsyncHTTP_HTTPSRequest_ESP example. GitHub release


Installation

Use Arduino Library Manager

The best and easiest way is to use Arduino Library Manager. Search for AsyncHTTPSRequest_Generic, then select / install the latest version. You can also use this link arduino-library-badge for more detailed instructions.

Manual Install

  1. Navigate to AsyncHTTPSRequest_Generic page.
  2. Download the latest release AsyncHTTPSRequest_Generic-main.zip.
  3. Extract the zip file to AsyncHTTPSRequest_Generic-main directory
  4. Copy the whole AsyncHTTPSRequest_Generic-main folder to Arduino libraries' directory such as ~/Arduino/libraries/.

VS Code & PlatformIO

  1. Install VS Code
  2. Install PlatformIO
  3. Install AsyncHTTPSRequest_Generic library by using Library Manager. Search for AsyncHTTPSRequest_Generic in Platform.io Author's Libraries
  4. Use included platformio.ini file from examples to ensure that all dependent libraries will installed automatically. Please visit documentation for the other options and examples at Project Configuration File


Note for Platform IO using ESP32 LittleFS

In Platform IO, to fix the error when using LittleFS_esp32 v1.0 for ESP32-based boards with ESP32 core v1.0.4- (ESP-IDF v3.2-), uncomment the following line

from

//#define CONFIG_LITTLEFS_FOR_IDF_3_2   /* For old IDF - like in release 1.0.4 */

to

#define CONFIG_LITTLEFS_FOR_IDF_3_2   /* For old IDF - like in release 1.0.4 */

It's advisable to use the latest LittleFS_esp32 v1.0.5+ to avoid the issue.

Thanks to Roshan to report the issue in Error esp_littlefs.c 'utime_p'



HOWTO Fix Multiple Definitions Linker Error

The current library implementation, using xyz-Impl.h instead of standard xyz.cpp, possibly creates certain Multiple Definitions Linker error in certain use cases.

You can include this .hpp file

// Can be included as many times as necessary, without `Multiple Definitions` Linker Error
#include "AsyncHTTPSRequest_Generic.hpp"     //https://github.com/khoih-prog/AsyncHTTPSRequest_Generic

in many files. But be sure to use the following .h file in just 1 .h, .cpp or .ino file, which must not be included in any other file, to avoid Multiple Definitions Linker Error

// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "AsyncHTTPSRequest_Generic.h"           //https://github.com/khoih-prog/AsyncHTTPSRequest_Generic

Check the new multiFileProject example for a HOWTO demo.

Have a look at the discussion in Different behaviour using the src_cpp or src_h lib #80



Note for Platform IO using ESP32 LittleFS

In Platform IO, to fix the error when using LittleFS_esp32 v1.0 for ESP32-based boards with ESP32 core v1.0.4- (ESP-IDF v3.2-), uncomment the following line

from

//#define CONFIG_LITTLEFS_FOR_IDF_3_2   /* For old IDF - like in release 1.0.4 */

to

#define CONFIG_LITTLEFS_FOR_IDF_3_2   /* For old IDF - like in release 1.0.4 */

It's advisable to use the latest LittleFS_esp32 v1.0.5+ to avoid the issue.

Thanks to Roshan to report the issue in Error esp_littlefs.c 'utime_p'



HOWTO Use analogRead() with ESP32 running WiFi and/or BlueTooth (BT/BLE)

Please have a look at ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example to have more detailed description and solution of the issue.

1. ESP32 has 2 ADCs, named ADC1 and ADC2

2. ESP32 ADCs functions

  • ADC1 controls ADC function for pins GPIO32-GPIO39
  • ADC2 controls ADC function for pins GPIO0, 2, 4, 12-15, 25-27

3.. ESP32 WiFi uses ADC2 for WiFi functions

Look in file adc_common.c

In ADC2, there're two locks used for different cases:

  1. lock shared with app and Wi-Fi: ESP32: When Wi-Fi using the ADC2, we assume it will never stop, so app checks the lock and returns immediately if failed. ESP32S2: The controller's control over the ADC is determined by the arbiter. There is no need to control by lock.

  2. lock shared between tasks: when several tasks sharing the ADC2, we want to guarantee all the requests will be handled. Since conversions are short (about 31us), app returns the lock very soon, we use a spinlock to stand there waiting to do conversions one by one.

adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock.

  • In order to use ADC2 for other functions, we have to acquire complicated firmware locks and very difficult to do
  • So, it's not advisable to use ADC2 with WiFi/BlueTooth (BT/BLE).
  • Use ADC1, and pins GPIO32-GPIO39
  • If somehow it's a must to use those pins serviced by ADC2 (GPIO0, 2, 4, 12, 13, 14, 15, 25, 26 and 27), use the fix mentioned at the end of ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example to work with ESP32 WiFi/BlueTooth (BT/BLE).


HOWTO use ESP32 with LwIP W5500 or ENC28J60 Ethernet

1. ESP32 Wiring

This is the wiring for ESP8266 W5500, W6100 or ENC28J60 Ethernet when using SS = GPIO5

// Optional values to override default settings
// Don't change unless you know what you're doing
//#define ETH_SPI_HOST SPI3_HOST
//#define SPI_CLOCK_MHZ 25
// Must connect INT to GPIOxx or not working
//#define INT_GPIO 4
//#define MISO_GPIO 19
//#define MOSI_GPIO 23
//#define SCK_GPIO 18
//#define CS_GPIO 5

W5x00/W6100/ENC28J60 Ethernet <---> ESP32
MOSI <---> MOSI = GPIO23
MISO <---> MISO = GPIO19
SCK <---> SCK = GPIO18
SS <---> GPIO5
INT <---> GPIO4
GND <---> GND
VCC <---> +3.3V


Examples

For ESP32

  1. AsyncHTTPSRequest_ESP
  2. AsyncHTTPSRequest_ESP_WiFiManager
  3. AsyncHTTPSRequest_ESP_Multi New
  4. AsyncHTTP_HTTPSRequest_ESP New

For WT32_ETH01

  1. AsyncHTTPSRequest_WT32_ETH01

For ESP32_ENC

  1. AsyncHTTPSRequest_ESP32_ENC

For ESP32_W5500

  1. AsyncHTTPSRequest_ESP32_W5500

For ESP32_W6100

  1. AsyncHTTPSRequest_ESP32_W6100

For ESP32, WT32_ETH01, ESP32_ENC, ESP32_W5500 or ESP32_W6100

  1. multiFileProject

#if !( defined(ESP8266) || defined(ESP32) )
#error This code is intended to run on the ESP8266 or ESP32 platform! Please check your Tools->Board setting.
#endif
#define ASYNC_HTTP_REQUEST_GENERIC_VERSION_MIN_TARGET "AsyncHTTPRequest_Generic v1.10.2"
#define ASYNC_HTTP_REQUEST_GENERIC_VERSION_MIN 1010002
#define ASYNC_HTTPS_REQUEST_GENERIC_VERSION_MIN_TARGET "AsyncHTTPSRequest_Generic v2.2.1"
#define ASYNC_HTTPS_REQUEST_GENERIC_VERSION_MIN 2002001
/////////////////////////////////////////////////////////
// Uncomment for certain HTTP site to optimize
//#define NOT_SEND_HEADER_AFTER_CONNECTED true
// Level from 0-4
#define ASYNC_HTTPS_DEBUG_PORT Serial
#define _ASYNC_TCP_SSL_LOGLEVEL_ 1
#define _ASYNC_HTTPS_LOGLEVEL_ 1
// 300s = 5 minutes to not flooding
#define HTTPS_REQUEST_INTERVAL 120
// 10s
#define HEARTBEAT_INTERVAL 10
int status; // the Wifi radio's status
const char* ssid = "your_ssid";
const char* password = "your_pass";
#if (ESP8266)
#include <ESP8266WiFi.h>
#elif (ESP32)
#include <WiFi.h>
#endif
// Use larger queue size if necessary for large data transfer. Default is 512 bytes if not defined here
//#define ASYNC_QUEUE_LENGTH 512
// Use larger priority if necessary. Default is 10 if not defined here. Must be > 4 or adjusted to 4
//#define CONFIG_ASYNC_TCP_PRIORITY (12)
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
// If use both AsyncHTTPRequest_Generic and AsyncHTTPSRequest_Generic, include AsyncHTTPRequest_Generic first or error
// because many definitions of AsyncHTTPSRequest_Generic rely on those of AsyncHTTPRequest_Generic
#include <AsyncHTTPRequest_Generic.h> // https://github.com/khoih-prog/AsyncHTTPRequest_Generic
#include <AsyncHTTPSRequest_Generic.h> // https://github.com/khoih-prog/AsyncHTTPSRequest_Generic
#include <Ticker.h>
#define NUM_DIFFERENT_SITES 3
const char* addreses[][NUM_DIFFERENT_SITES] =
{
{"https://worldtimeapi.org/api/timezone/America/Toronto.txt", "https://worldtimeapi.org/api/timezone/Europe/Prague.txt"},
{"http://worldtimeapi.org/api/timezone/Europe/London.txt", "http://worldtimeapi.org/api/timezone/America/Vancouver.txt"},
{"http://www.myexternalip.com/raw"}
};
#define NUM_ENTRIES_SITE_0 2
#define NUM_ENTRIES_SITE_1 2
#define NUM_ENTRIES_SITE_2 1
byte reqCount[] = { NUM_ENTRIES_SITE_0, NUM_ENTRIES_SITE_1, NUM_ENTRIES_SITE_2 };
bool readySend[] = { true, true, true };
typedef enum
{
HTTP_REQUEST = 0,
HTTPS_REQUEST = 1,
} HTTP_Type;
AsyncHTTPSRequest request0;
AsyncHTTPRequest request1;
AsyncHTTPRequest request2;
typedef struct _AsyncHTTPRequestData
{
void* request; // (void*) for AsyncHTTPRequest* or AsyncHTTPSRequest*
HTTP_Type httpType;
} AsyncHTTPRequestData;
AsyncHTTPRequestData myAsyncHTTPRequestData[] =
{
{ (void*) &request0, HTTPS_REQUEST },
{ (void*) &request1, HTTP_REQUEST },
{ (void*) &request2, HTTP_REQUEST }
};
// This is for HTTPS and must use AsyncHTTPSRequest
void requestCB0(void* optParm, AsyncHTTPSRequest* thisRequest, int readyState);
// This is for HTTP and must use AsyncHTTPRequest
void requestCB1(void* optParm, AsyncHTTPRequest* thisRequest, int readyState);
// This is for HTTP and must use AsyncHTTPRequest
void requestCB2(void* optParm, AsyncHTTPRequest* thisRequest, int readyState);
void sendRequest0();
void sendRequest1();
void sendRequest2();
typedef void (*requestCallback0)(void* optParm, AsyncHTTPSRequest* thisRequest, int readyState);
typedef void (*requestCallback1)(void* optParm, AsyncHTTPRequest* thisRequest, int readyState);
typedef void (*sendCallback)();
void* requestCB [] = { (void*) requestCB0, (void*) requestCB1, (void*) requestCB2 };
sendCallback sendRequestCB [] = { sendRequest0, sendRequest1, sendRequest2 };
Ticker ticker;
Ticker ticker1;
void heartBeatPrint()
{
static int num = 1;
if (WiFi.status() == WL_CONNECTED)
Serial.print(F("H")); // H means connected to WiFi
else
Serial.print(F("F")); // F means not connected to WiFi
if (num == 80)
{
Serial.println();
num = 1;
}
else if (num++ % 10 == 0)
{
Serial.print(F(" "));
}
}
void sendRequest(uint16_t index)
{
static bool requestOpenResult;
reqCount[index]--;
readySend[index] = false;
if ( myAsyncHTTPRequestData[index].httpType == HTTPS_REQUEST )
{
requestOpenResult = ((AsyncHTTPSRequest *) myAsyncHTTPRequestData[index].request)->open("GET",
addreses[index][reqCount[index]]);
if (requestOpenResult)
{
// Only send() if open() returns true, or crash
Serial.print("\nSending HTTPS request: ");
((AsyncHTTPSRequest *) myAsyncHTTPRequestData[index].request)->send();
}
else
{
Serial.print("\nCan't send bad HTTPS request : ");
}
}
else if ( myAsyncHTTPRequestData[index].httpType == HTTP_REQUEST )
{
requestOpenResult = ((AsyncHTTPRequest *) myAsyncHTTPRequestData[index].request)->open("GET",
addreses[index][reqCount[index]]);
if (requestOpenResult)
{
// Only send() if open() returns true, or crash
Serial.print("\nSending HTTP request: ");
((AsyncHTTPRequest *) myAsyncHTTPRequestData[index].request)->send();
}
else
{
Serial.print("\nCan't send bad HTTP request : ");
}
}
Serial.println(addreses[index][reqCount[index]]);
}
void sendRequest0()
{
sendRequest(0);
}
void sendRequest1()
{
sendRequest(1);
}
void sendRequest2()
{
sendRequest(2);
}
void sendRequests()
{
for (int index = 0; index < NUM_DIFFERENT_SITES; index++)
{
reqCount[index] = 2;
}
reqCount[0] = NUM_ENTRIES_SITE_0;
reqCount[1] = NUM_ENTRIES_SITE_1;
reqCount[2] = NUM_ENTRIES_SITE_2;
}
// This is for HTTPS and must use AsyncHTTPSRequest
void requestCB0(void *optParm, AsyncHTTPSRequest *thisRequest, int readyState)
{
(void) optParm;
if (readyState == readyStateDone)
{
AHTTPS_LOGDEBUG0(F("\n**************************************\n"));
AHTTPS_LOGDEBUG1(F("Response Code = "), thisRequest->responseHTTPString());
if (thisRequest->responseHTTPcode() == 200)
{
Serial.println(F("\n**************************************"));
Serial.println(thisRequest->responseText());
Serial.println(F("**************************************"));
}
thisRequest->setDebug(false);
readySend[0] = true;
}
}
// This is for HTTP and must use AsyncHTTPRequest
void requestCB1(void *optParm, AsyncHTTPRequest *thisRequest, int readyState)
{
(void) optParm;
if (readyState == readyStateDone)
{
AHTTPS_LOGDEBUG0(F("\n**************************************\n"));
AHTTPS_LOGDEBUG1(F("Response Code = "), thisRequest->responseHTTPString());
if (thisRequest->responseHTTPcode() == 200)
{
Serial.println(F("\n**************************************"));
Serial.println(thisRequest->responseText());
Serial.println(F("**************************************"));
}
thisRequest->setDebug(false);
readySend[1] = true;
}
}
// This is for HTTP and must use AsyncHTTPRequest
void requestCB2(void *optParm, AsyncHTTPRequest *thisRequest, int readyState)
{
(void) optParm;
if (readyState == readyStateDone)
{
AHTTPS_LOGDEBUG0(F("\n**************************************\n"));
AHTTPS_LOGDEBUG1(F("Response Code = "), thisRequest->responseHTTPString());
if (thisRequest->responseHTTPcode() == 200)
{
Serial.println(F("\n**************************************"));
Serial.println(thisRequest->responseText());
Serial.println(F("**************************************"));
}
thisRequest->setDebug(false);
readySend[2] = true;
}
}
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
while (!Serial && millis() < 5000);
delay(200);
Serial.print("\nStarting AsyncHTTP_HTTPSRequest_ESP on ");
Serial.println(ARDUINO_BOARD);
#if defined(ESP32)
Serial.println(ASYNC_TCP_SSL_VERSION);
#else
//Serial.println(ESPASYNC_TCP_SSL_VERSION);
#endif
Serial.println(ASYNC_HTTPS_REQUEST_GENERIC_VERSION);
Serial.println(ASYNC_HTTP_REQUEST_GENERIC_VERSION);
#if defined(ASYNC_HTTPS_REQUEST_GENERIC_VERSION_MIN)
if (ASYNC_HTTPS_REQUEST_GENERIC_VERSION_INT < ASYNC_HTTPS_REQUEST_GENERIC_VERSION_MIN)
{
Serial.print(F("Warning. Must use this example on Version equal or later than : "));
Serial.println(ASYNC_HTTPS_REQUEST_GENERIC_VERSION_MIN_TARGET);
}
#endif
#if defined(ASYNC_HTTP_REQUEST_GENERIC_VERSION_MIN)
if (ASYNC_HTTP_REQUEST_GENERIC_VERSION_INT < ASYNC_HTTP_REQUEST_GENERIC_VERSION_MIN)
{
Serial.print(F("Warning. Must use this example on Version equal or later than : "));
Serial.println(ASYNC_HTTP_REQUEST_GENERIC_VERSION_MIN_TARGET);
}
#endif
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("Connecting to WiFi SSID: " + String(ssid));
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.print(F("\nAsyncHTTPSRequest @ IP : "));
Serial.println(WiFi.localIP());
for (int index = 0; index < NUM_DIFFERENT_SITES; index++)
{
if ( myAsyncHTTPRequestData[index].httpType == HTTPS_REQUEST )
{
((AsyncHTTPSRequest *) myAsyncHTTPRequestData[index].request)->setDebug(false);
((AsyncHTTPSRequest *) myAsyncHTTPRequestData[index].request)->onReadyStateChange( (requestCallback0) requestCB[index]);
}
else if ( myAsyncHTTPRequestData[index].httpType == HTTP_REQUEST )
{
((AsyncHTTPRequest *) myAsyncHTTPRequestData[index].request)->setDebug(false);
((AsyncHTTPRequest *) myAsyncHTTPRequestData[index].request)->onReadyStateChange((requestCallback1) requestCB[index]);
}
}
ticker.attach(HTTPS_REQUEST_INTERVAL, sendRequests);
ticker1.attach(HEARTBEAT_INTERVAL, heartBeatPrint);
}
void loop()
{
for (int index = 0; index < NUM_DIFFERENT_SITES; index++)
{
if ((reqCount[index] > 0) && readySend[index])
{
sendRequestCB[index]();
// Don't reduce this or possible crash. TLS needs long time to work.
delay(100);
}
}
}



Debug Terminal Output Samples

1. AsyncHTTPSRequest_ESP on ESP32_DEV

Following is the debug terminal when running example AsyncHTTPSRequest_ESP on ESP32_DEV to demonstrate the operation of SSL Async HTTPS request, using AsyncTCP_SSL Library.

Starting AsyncHTTPSRequest_ESP using ESP32_DEV
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.5.0
Connecting to WiFi SSID: HueNet1
...
AsyncHTTPSRequest @ IP : 192.168.2.80
[AHTTPS] open: connecting to hostname = worldtimeapi.org:443    <====== New connect attempt
[AHTTPS] _client->connecting to worldtimeapi.org , 443
[AHTTPS] client.connect OK to worldtimeapi.org , 443

**************************************
[AHTTPS] Response Code =  HTTP OK

**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:01:30.472515-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224090
utc_datetime: 2023-02-01T04:01:30.472515+00:00
utc_offset: -05:00
week_number: 5
**************************************
HH[AHTTPS] open: already connected    <====== No more connect attempt. Optional
H
**************************************
[AHTTPS] Response Code =  HTTP OK

**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:02:24.463788-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224144
utc_datetime: 2023-02-01T04:02:24.463788+00:00
utc_offset: -05:00
week_number: 5
**************************************

2. AsyncHTTPSRequest_ESP on ESP32S2_DEV

Following is the debug terminal when running example AsyncHTTPSRequest_ESP on ESP32S2_DEV to demonstrate the operation of SSL Async HTTPS request, using AsyncTCP_SSL Library.

Starting AsyncHTTPSRequest_ESP using ESP32S2_DEV
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.5.0
Connecting to WiFi SSID: HueNet1
.......
AsyncHTTPSRequest @ IP : 192.168.2.79
[ATCP] _handle_async_event: LWIP_TCP_DNS = 0x3FFE4E24
[ATCP] _handle_async_event: LWIP_TCP_DNS, name = worldtimeapi.org , IP = 213.188.196.246
[ATCP] _handle_async_event: LWIP_TCP_CONNECTED = 0x3FFE4E24 0x3FFE5024
[ATCP] _handle_async_event: LWIP_TCP_CONNECTED =  0
[ATCP] _handle_async_event: LWIP_TCP_SENT = 0x3FFE5024
[ATCP] _sent: len = 305
[ATCP] _handle_async_event: LWIP_TCP_RECV = 0x3FFE5024
[ATCP] _recv: tot_len = 1436
[ATCP] _handle_async_event: LWIP_TCP_RECV = 0x3FFE5024
[ATCP] _recv: tot_len = 1436
[ATCP] _handle_async_event: LWIP_TCP_RECV = 0x3FFE5024
[ATCP] _recv: tot_len = 1242
[ATCP] _handle_async_event: LWIP_TCP_SENT = 0x3FFE5024
[ATCP] _sent: len = 107
[ATCP] _handle_async_event: LWIP_TCP_SENT = 0x3FFE5024
[ATCP] _sent: len = 6
[ATCP] _handle_async_event: LWIP_TCP_SENT = 0x3FFE5024
[ATCP] _sent: len = 45
[ATCP] _handle_async_event: LWIP_TCP_RECV = 0x3FFE5024
[ATCP] _recv: tot_len = 51
[ATCP] _handle_async_event: LWIP_TCP_SENT = 0x3FFE5024
[ATCP] _sent: len = 106
[ATCP] _handle_async_event: LWIP_TCP_RECV = 0x3FFE5024
[ATCP] _recv: tot_len = 1016
**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:02:24.463788-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224144
utc_datetime: 2023-02-01T04:02:24.463788+00:00
utc_offset: -05:00
week_number: 5
**************************************
HHHHHH
**************************************
[AHTTPS] Response Code =  HTTP OK

**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:03:24.464007-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224204
utc_datetime: 2023-02-01T04:03:24.464007+00:00
utc_offset: -05:00
week_number: 5
**************************************

3. AsyncHTTPSRequest_ESP on ESP32C3_DEV

Following is the debug terminal when running example AsyncHTTPSRequest_ESP on ESP32C3_DEV to demonstrate the operation of SSL Async HTTPS request, using AsyncTCP_SSL Library.

Starting AsyncHTTPSRequest_ESP using ESP32C3_DEV
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.5.0
Connecting to WiFi SSID: HueNet1
.........
AsyncHTTPSRequest @ IP : 192.168.2.80
**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:03:24.464007-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224204
utc_datetime: 2023-02-01T04:03:24.464007+00:00
utc_offset: -05:00
week_number: 5
**************************************
HHHHHH
**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:04:24.464088-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224264
utc_datetime: 2023-02-01T04:04:24.464088+00:00
utc_offset: -05:00
week_number: 5
**************************************

4. AsyncHTTPSRequest_ESP_WiFiManager on ESP32_DEV

Following is the debug terminal when running example AsyncHTTPSRequest_ESP_WiFiManager on ESP32_DEV to demonstrate the operation of SSL Async HTTPS request, using AsyncTCP_SSL Library, and ESPAsync_WiFiManager Library

Starting AsyncHTTPSRequest_ESP_WiFiManager using LittleFS on ESP32_DEV
ESPAsync_WiFiManager v1.15.1
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.5.0
Stored: SSID = HueNet1, Pass = 12345678
Got stored Credentials. Timeout 120s
ConnectMultiWiFi in setup
After waiting 11.38 secs more in setup(), connection result is connected. Local IP: 192.168.2.232
H
**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:05:24.465017-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224324
utc_datetime: 2023-02-01T04:05:24.465017+00:00
utc_offset: -05:00
week_number: 5
**************************************
H

5. AsyncHTTPSRequest_WT32_ETH01 on WT32_ETH01 using ESP32 core v2.0.0

Following is the debug terminal when running example AsyncHTTPSRequest_WT32_ETH01 on WT32_ETH01 to demonstrate the operation of SSL Async HTTPS request, using AsyncTCP_SSL Library and ESP32 core v2.0.0

Starting AsyncHTTPSRequest_WT32_ETH01 using ESP32_DEV with ETH_PHY_LAN8720
WebServer_WT32_ETH01 v1.5.1 for core v2.0.0+
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.5.0
ETH MAC: A8:03:2A:A1:61:73, IPv4: 192.168.2.82, FULL_DUPLEX, 100Mbps

HTTP WebClient is @ IP : 192.168.2.82

**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:06:24.463935-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224384
utc_datetime: 2023-02-01T04:06:24.463935+00:00
utc_offset: -05:00
week_number: 5
**************************************

6. AsyncHTTPSRequest_WT32_ETH01 on WT32_ETH01 using ESP32 core v1.0.6

Following is the debug terminal when running example AsyncHTTPSRequest_WT32_ETH01 on WT32_ETH01 to demonstrate the operation of SSL Async HTTPS request, using AsyncTCP_SSL Library and ESP32 core v1.0.6

Starting AsyncHTTPSRequest_WT32_ETH01 using ESP32_DEV with ETH_PHY_LAN8720
WebServer_WT32_ETH01 v1.5.1 for core v1.0.6-
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.5.0
ETH MAC: A8:03:2A:A1:61:73, IPv4: 192.168.2.232, FULL_DUPLEX, 100Mbps

HTTP WebClient is @ IP : 192.168.2.232
**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:08:24.467686-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224504
utc_datetime: 2023-02-01T04:08:24.467686+00:00
utc_offset: -05:00
week_number: 5
**************************************

7. AsyncHTTPSRequest_ESP_WiFiManager using LittleFS on ESP32C3_DEV

Following is the debug terminal when running example AsyncHTTPSRequest_ESP_WiFiManager on ESP32C3_DEV to demonstrate the operation of SSL Async HTTPS request, using AsyncTCP_SSL Library, and ESPAsync_WiFiManager Library

Starting AsyncHTTPSRequest_ESP_WiFiManager using LittleFS on ESP32C3_DEV
ESPAsync_WiFiManager v1.15.1
AsyncHTTPSRequest_Generic v2.5.0
Stored: SSID = HueNet1, Pass = password
Got stored Credentials. Timeout 120s
ConnectMultiWiFi in setup
After waiting 8.75 secs more in setup(), connection result is connected. Local IP: 192.168.2.85
H
**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:08:24.467686-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224504
utc_datetime: 2023-02-01T04:08:24.467686+00:00
utc_offset: -05:00
week_number: 5
**************************************
HHHHHH 
**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:09:24.464676-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224564
utc_datetime: 2023-02-01T04:09:24.464676+00:00
utc_offset: -05:00
week_number: 5
**************************************
HH

8. AsyncHTTPSRequest_ESP_WiFiManager using LittleFS on ESP32S3_DEV

Following is the debug terminal when running example AsyncHTTPSRequest_ESP_WiFiManager on ESP32S3_DEV to demonstrate the operation of SSL Async HTTPS request, using AsyncTCP_SSL Library, and ESPAsync_WiFiManager Library

Starting AsyncHTTPSRequest_ESP_WiFiManager using LittleFS on ESP32S3_DEV
ESPAsync_WiFiManager v1.15.1
AsyncHTTPSRequest_Generic v2.5.0
Stored: SSID = HueNet1, Pass = password
Got stored Credentials. Timeout 120s
ConnectMultiWiFi in setup
After waiting 8.26 secs more in setup(), connection result is connected. Local IP: 192.168.2.83
H
**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:10:24.464712-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224624
utc_datetime: 2023-02-01T04:10:24.464712+00:00
utc_offset: -05:00
week_number: 5
**************************************
HHHH

9. AsyncHTTPSRequest_ESP_Multi on ESP32_DEV

The terminal output of AsyncHTTPSRequest_ESP_Multi example running on ESP32_DEV to demonstrate how to send requests to multiple addresses and receive responses from them.

Starting AsyncHTTPSRequest_ESP_Multi on ESP32_DEV
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.5.0
Connecting to WiFi SSID: HueNet1
...
AsyncHTTPSRequest @ IP : 192.168.2.187

Sending request: https://worldtimeapi.org/api/timezone/Europe/Prague.txt

Sending request: https://www.myexternalip.com/raw
[AHTTPS] _onError handler SSL error = OK
[AHTTPS] _onError handler SSL error = OK

**************************************
[AHTTPS] Response Code =  HTTP OK

**************************************
aaa.bbb.ccc.ddd
**************************************

**************************************
[AHTTPS] Response Code =  HTTP OK

**************************************
abbreviation: CET
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-02-01T03:44:24.015957+01:00
day_of_week: 3
day_of_year: 32
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: 3600
timezone: Europe/Prague
unixtime: 1675219464
utc_datetime: 2023-02-01T02:44:24.015957+00:00
utc_offset: +01:00
week_number: 5
**************************************

Sending request: https://worldtimeapi.org/api/timezone/America/Toronto.txt

**************************************
[AHTTPS] Response Code =  HTTP OK

**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T21:44:24.210700-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675219464
utc_datetime: 2023-02-01T02:44:24.210700+00:00
utc_offset: -05:00
week_number: 5
**************************************
H

10. AsyncHTTP_HTTPSRequest_ESP on ESP32_DEV

The terminal output of AsyncHTTP_HTTPSRequest_ESP example running on ESP32_DEV to demonstrate how to send HTTP and HTTPS requests to multiple addresses and receive responses from them.

Starting AsyncHTTP_HTTPSRequest_ESP on ESP32_DEV
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.5.0
AsyncHTTPRequest_Generic v1.12.0
Connecting to WiFi SSID: HueNet1
...
AsyncHTTPSRequest @ IP : 192.168.2.80

Sending HTTPS request: https://worldtimeapi.org/api/timezone/Europe/Prague.txt

Sending HTTP request: http://worldtimeapi.org/api/timezone/America/Vancouver.txt

Sending HTTP request: http://www.myexternalip.com/raw

**************************************
aaa.bbb.ccc.ddd
**************************************

**************************************
abbreviation: PST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T18:44:24.061420-08:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -28800
timezone: America/Vancouver
unixtime: 1675219464
utc_datetime: 2023-02-01T02:44:24.061420+00:00
utc_offset: -08:00
week_number: 5
**************************************

**************************************
[AHTTPS] Response Code =  HTTP OK

**************************************
abbreviation: CET
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-02-01T03:44:24.015957+01:00
day_of_week: 3
day_of_year: 32
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: 3600
timezone: Europe/Prague
unixtime: 1675219464
utc_datetime: 2023-02-01T02:44:24.015957+00:00
utc_offset: +01:00
week_number: 5
**************************************

Sending HTTPS request: https://worldtimeapi.org/api/timezone/America/Toronto.txt

**************************************
[AHTTPS] Response Code =  HTTP OK

**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T21:44:24.210700-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675219464
utc_datetime: 2023-02-01T02:44:24.210700+00:00
utc_offset: -05:00
week_number: 5
**************************************

11. AsyncHTTPSRequest_ESP32_ENC using ESP32_DEV with ESP32_ENC28J60

Following is the debug terminal when running example AsyncHTTPSRequest_ESP32_ENC on ESP32_DEV boards using LwIP ENC28J60 Ethernet, to demonstrate the operation of SSL Async HTTPS request, using AsyncTCP_SSL Library

Starting AsyncHTTPSRequest_ESP32_ENC using ESP32_DEV with ESP32_ENC28J60
WebServer_ESP32_ENC v1.5.3 for core v2.0.0+
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.5.0
[AHTTPS] Default SPI pinout:
[AHTTPS] MOSI: 23
[AHTTPS] MISO: 19
[AHTTPS] SCK: 18
[AHTTPS] CS: 5
[AHTTPS] INT: 4
[AHTTPS] SPI Clock (MHz): 8
[AHTTPS] =========================

ETH Started
ETH Connected
ETH MAC: DE:AD:BE:EF:FE:01, IPv4: 192.168.2.95
FULL_DUPLEX, 10Mbps

HTTP WebClient is @ IP : 192.168.2.95

**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:14:24.465232-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224864
utc_datetime: 2023-02-01T04:14:24.465232+00:00
utc_offset: -05:00
week_number: 5
**************************************
HHHHHH
**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:15:24.464696-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224924
utc_datetime: 2023-02-01T04:15:24.464696+00:00
utc_offset: -05:00
week_number: 5
**************************************

12. AsyncHTTPSRequest_ESP32_W5500 using ESP32_DEV with ESP32_W5500

Following is the debug terminal when running example AsyncHTTPSRequest_ESP32_W5500 on ESP32_DEV boards using LwIP W5500 Ethernet, to demonstrate the operation of SSL Async HTTPS request, using AsyncTCP_SSL Library

Starting AsyncHTTPSRequest_ESP32_W5500 using ESP32_DEV with ESP32_W5500
WebServer_ESP32_W5500 v1.5.3 for core v2.0.0+
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.5.0
[AHTTPS] Default SPI pinout:
[AHTTPS] SPI_HOST: 2
[AHTTPS] MOSI: 23
[AHTTPS] MISO: 19
[AHTTPS] SCK: 18
[AHTTPS] CS: 5
[AHTTPS] INT: 4
[AHTTPS] SPI Clock (MHz): 25
[AHTTPS] =========================

ETH Started
ETH Connected
ETH MAC: DE:AD:BE:EF:BE:12, IPv4: 192.168.2.103
FULL_DUPLEX, 100Mbps

HTTP WebClient is @ IP : 192.168.2.103

**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:10:24.464712-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224624
utc_datetime: 2023-02-01T04:10:24.464712+00:00
utc_offset: -05:00
week_number: 5
**************************************
HHHHHH
**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:11:24.464025-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224684
utc_datetime: 2023-02-01T04:11:24.464025+00:00
utc_offset: -05:00
week_number: 5
**************************************
HHHH

13. AsyncHTTPSRequest_ESP32_W6100 using ESP32_DEV with ESP32_W6100

Following is the debug terminal when running example AsyncHTTPSRequest_ESP32_W6100 on ESP32_DEV boards using LwIP W6100 Ethernet, to demonstrate the operation of SSL Async HTTPS request, using AsyncTCP_SSL Library

Starting AsyncHTTPSRequest_ESP32_W6100 using ESP32_DEV with ESP32_W6100
WebServer_ESP32_W6100 v1.5.3 for core v2.0.0+
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.5.0
[AHTTPS] Default SPI pinout:
[AHTTPS] SPI_HOST: 2
[AHTTPS] MOSI: 23
[AHTTPS] MISO: 19
[AHTTPS] SCK: 18
[AHTTPS] CS: 5
[AHTTPS] INT: 4
[AHTTPS] SPI Clock (MHz): 25
[AHTTPS] =========================

ETH Started
ETH Connected
ETH MAC: 98:F4:AB:09:13:EB, IPv4: 192.168.2.154
FULL_DUPLEX, 100Mbps

HTTP WebClient is @ IP : 192.168.2.154

**************************************
abbreviation: EST
client_ip: aaa.bbb.ccc.ddd
datetime: 2023-01-31T23:01:30.472515-05:00
day_of_week: 2
day_of_year: 31
dst: false
dst_from: 
dst_offset: 0
dst_until: 
raw_offset: -18000
timezone: America/Toronto
unixtime: 1675224090
utc_datetime: 2023-02-01T04:01:30.472515+00:00
utc_offset: -05:00
week_number: 5
**************************************
H


Debug

Debug is enabled by default on Serial.

You can also change the debugging level from 0 to 4

#define ASYNC_HTTP_DEBUG_PORT           Serial

// Use from 0 to 4. Higher number, more debugging messages and memory usage.
#define _ASYNC_TCP_SSL_LOGLEVEL_        1
#define _ASYNC_HTTPS_LOGLEVEL_          2

Troubleshooting

If you get compilation errors, more often than not, you may need to install a newer version of the ESP32 / ESP8266 / STM32 core for Arduino.

Sometimes, the library will only work if you update the ESP32 / ESP8266 / STM32 core to the latest version because I am using newly added functions.


Issues

Submit issues to: AsyncHTTPSRequest_Generic issues



TO DO

  1. Fix bug. Add enhancement
  2. Add support to more Ethernet / WiFi shields
  3. Add support to RP2040W, ESP8266, Portenta_H7, STM32 and many more boards
  4. Add many more examples.

DONE

  1. Initially add support to ESP32 using built-in WiFi
  2. Support breaking ESP32 core v2.0.0+ as well as v1.0.6-
  3. Auto detect ESP32 core v1.0.6- or v2.0.0+ to use correct settings
  4. Fix multiple-definitions linker error and weird bug related to src_cpp.
  5. Enable compatibility with old code to include only AsyncHTTPSRequest_Generic.h
  6. Modify to be compatible with AsyncTCP_SSL releases v1.2.0+
  7. Add complex example AsyncHTTPSRequest_ESP_WiFiManager
  8. Add support to ESP32-S3 (ESP32S3_DEV, ESP32_S3_BOX, UM TINYS3, UM PROS3, UM FEATHERS3, etc.) using EEPROM, SPIFFS or LittleFS
  9. Add LittleFS support to ESP32-C3
  10. Use ESP32-core's LittleFS library instead of Lorol's LITTLEFS library for ESP32 core v2.0.0+
  11. Add example AsyncHTTPSRequest_ESP_Multi to demonstrate how to send requests to multiple addresses and receive responses from them.
  12. Permit coexisting with AsyncHTTPRequest library to send and receive both HTTP and HTTPS
  13. Add example AsyncHTTP_HTTPSRequest_ESP to demonstrate how to send HTTP and HTTPS requests to multiple addresses and receive responses from them.
  14. Increase DEFAULT_RX_TIMEOUT to 30s from 3s for slower networks.
  15. Fix long timeout if using bad or unreachable IPAddress
  16. Display only successful responseText in examples
  17. Improve debug messages by adding functions to display error messages instead of cryptic error number
  18. Fix ESP32 chipID for exampleAsyncHTTPSRequest_ESP_WiFiManager
  19. Not try to reconnect to the same host:port after connected.
  20. Fix crash and memory leak
  21. Default to reconnect to the same host:port after connected for new HTTP sites.
  22. Use allman astyle
  23. Add support to ESP32 boards using LwIP ENC28J60 Ethernet
  24. Add support to ESP32 boards using LwIP W5500 Ethernet
  25. Fix "blank new line in chunk" bug #50
  26. Add support to ESP32 boards using LwIP W6100 Ethernet
  27. Fix bug of wrong reqStates. Check Callback behavior buggy #19
  28. Fix bug of _parseURL(). Check Bug with _parseURL() #21
  29. Improve README.md so that links can be used in other sites, such as PIO


Contributions and Thanks

This library is based on, modified, bug-fixed and improved from:

  1. Bob Lemaire's asyncHTTPrequest Library to use the better asynchronous features of the following Async SSL TCP Libraries : ( AsyncTCP_SSL ).
  2. Thanks to DavidAntonin
  1. Thanks to Glenn West
  1. Thanks to rjjrbatarao
  • to request enhancement in setReuse feature #12 leading to new release v2.1.3 to not try to reconnect to the same host:port after connected
  1. Thanks to Roeland Kluit
  1. Thanks to emmettprexus to report Getting 400 Bad Request on second call to same host #14 leading to new release v2.2.1
  2. Thanks to joaorolemberg to report Callback behavior buggy #19 leading to new release v2.5.0
  3. Thanks to redphx to report Bug with _parseURL() #21 leading to new release v2.5.0
boblemaire
โญ๏ธ Bob Lemaire

DavidAntonin
David Antonin

glennswest
Glenn West

rjjrbatarao
rjjrbatarao

roel80
Roeland Kluit

emmettprexus
emmettprexus

joaorolemberg
joaorolemberg

redphx
redphx


Contributing

If you want to contribute to this project:

  • Report bugs and errors
  • Ask for enhancements
  • Create issues and pull requests
  • Tell other people about this library

License and credits

  • The library is licensed under GPLv3

Copyright

Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>

Copyright (C) 2021- Khoi Hoang

asynchttpsrequest_generic's People

Contributors

khoih-prog avatar roelandkluit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

asynchttpsrequest_generic's Issues

Bug with _parseURL()

_parseURL() doesn't consider https://www.google.com a valid URL, but it does with https://www.google.com/.

"Connection: close" header from server causes ESP32 to crash

Describe the bug

ESP32 crashes with either "CORRUPT HEAP" or "Exception was unhandled" after receiving "Connection: close" header from target server following a POST request.

Similar issues did not happen when using the library AsyncHTTPRequest_Generic.

Steps to Reproduce

  1. Start a server that returns "Connection: close" as response header
  2. Make any POST request to the server
  3. ESP32 crashes

Expected behavior

Start a new TCP connection after closing the previous one.

Actual behavior

Crashes with either CORRUPT HEAP or "Exception was unhandled" as error message.

Debug and AT-command log (if applicable)

Logs are generated using esp32_exception_decoder with #define _ASYNC_HTTPS_LOGLEVEL_ 4, domain name of the server is removed

When Connection header of response is "keep-alive"

[AHTTPS] open( POST , url = 
[AHTTPS] _parseURL(): scheme+host HTTPS:// 
[AHTTPS] _parseURL(): port+path+query 443 
[AHTTPS] open: connecting to hostname = 
[AHTTPS] _connect()
[AHTTPS] _onConnect handler
[AHTTPS] _setReadyState : 1

[AHTTPS] send(String) {
  "floor": "L , length = 38
[AHTTPS] _buildRequest()
[AHTTPS] _HTTPmethod = 1
[AHTTPS] POST  /api/library/entrances  HTTP/1.1

[AHTTPS] write _HTTPmethodStringwithSpace :  POST 
[AHTTPS] write path :  /api/library/entrances
[AHTTPS] write query 
[AHTTPS] write HTTP/1.1
[AHTTPS] To write hdr
[AHTTPS] hdr->name
[AHTTPS] hdr->value
[AHTTPS] host : 

[AHTTPS] hdr->name
[AHTTPS] hdr->value
[AHTTPS] Content-Type : application/json 

[AHTTPS] hdr->name
[AHTTPS] hdr->value
[AHTTPS] Content-Length : 38 

[AHTTPS] Write hdr done
[AHTTPS] _buildRequest() done
[AHTTPS] Done supply
[AHTTPS] To send()
[AHTTPS] send 192
[AHTTPS] ========= _onData handler =======
[AHTTPS] Vbuf = HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: 
Content-Type: text/html; charset=utf-8
Content-Length: 8
**Connection: keep-alive**
X-Powered-By: Express

[AHTTPS] =================================
[AHTTPS] Vbuf len = 242
[AHTTPS] =================================
[AHTTPS] _collectHeaders()
[AHTTPS] xbuf::readString: Reserved size =  18
[AHTTPS] xbuf::readString: Reserved size =  32
[AHTTPS] xbuf::readString: Reserved size =  38
[AHTTPS] xbuf::readString: Reserved size =  41
[AHTTPS] xbuf::readString: Reserved size =  20
[AHTTPS] xbuf::readString: Reserved size =  25
[AHTTPS] xbuf::readString: Reserved size =  24
[AHTTPS] xbuf::readString: Reserved size =  42
[AHTTPS] xbuf::readString: Reserved size =  3
[AHTTPS] _setReadyState : 2
[AHTTPS] _setReadyState : 3
**[AHTTPS] *all data received - no disconnect**
[AHTTPS] _setReadyState : 4

[AHTTPS] responseText()
[AHTTPS] xbuf::readString: Reserved size =  9
[AHTTPS] ========= responseText(char) =======
[AHTTPS] localString = 
[AHTTPS] =================================
[AHTTPS] avail = 8
[AHTTPS] ====================================

When Connection header of response is "close" (Unhandled exception)

[AHTTPS] open( POST , url = 
[AHTTPS] _parseURL(): scheme+host HTTPS:// 
[AHTTPS] _parseURL(): port+path+query 443 
[AHTTPS] open: connecting to hostname = 
[AHTTPS] _connect()
[AHTTPS] _onConnect handler
[AHTTPS] _setReadyState : 1

[AHTTPS] send(String) {
  "floor": "L , length = 38
[AHTTPS] _buildRequest()
[AHTTPS] _HTTPmethod = 1
[AHTTPS] POST  /api/library/entrances  HTTP/1.1

[AHTTPS] write _HTTPmethodStringwithSpace :  POST 
[AHTTPS] write path :  
[AHTTPS] write query 
[AHTTPS] write HTTP/1.1
[AHTTPS] To write hdr
[AHTTPS] hdr->name
[AHTTPS] hdr->value
[AHTTPS] host : 

[AHTTPS] hdr->name
[AHTTPS] hdr->value
[AHTTPS] Content-Type : application/json 

[AHTTPS] hdr->name
[AHTTPS] hdr->value
[AHTTPS] Content-Length : 38 

[AHTTPS] Write hdr done
[AHTTPS] _buildRequest() done
[AHTTPS] Done supply
[AHTTPS] To send()
[AHTTPS] send 192

[AHTTPS] ========= _onData handler =======
[AHTTPS] Vbuf = HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Sun, 30 Jan 2022 13:48:21 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 8
**Connection: close**
X-Powered-By: Express

[AHTTPS] =================================
[AHTTPS] Vbuf len = 237
[AHTTPS] =================================
[AHTTPS] _collectHeaders()
[AHTTPS] xbuf::readString: Reserved size =  18
[AHTTPS] xbuf::readString: Reserved size =  32
[AHTTPS] xbuf::readString: Reserved size =  38
[AHTTPS] xbuf::readString: Reserved size =  41
[AHTTPS] xbuf::readString: Reserved size =  20
[AHTTPS] xbuf::readString: Reserved size =  20
[AHTTPS] xbuf::readString: Reserved size =  24
[AHTTPS] xbuf::readString: Reserved size =  42
[AHTTPS] xbuf::readString: Reserved size =  3
[AHTTPS] _setReadyState : 2
[AHTTPS] _setReadyState : 3
**[AHTTPS] *all data received - closing TCP**
[AHTTPS] _setReadyState : 4

[AHTTPS] responseText()
[AHTTPS] xbuf::readString: Reserved size =  9
[AHTTPS] ========= responseText(char) =======
[AHTTPS] localString = Received
[AHTTPS] =================================
[AHTTPS] avail = 8
[AHTTPS] ====================================
-----
Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC      : 0x4014ac74  PS      : 0x00060130  A0      : 0x80141e2e  A1      : 0x3ffb3e30  
A2      : 0x3ffd0108  A3      : 0x6e6f430a  A4      : 0x0000baaf  A5      : 0x00000000  
A6      : 0x3ffb3328  A7      : 0x00000000  A8      : 0x6bbd06da  A9      : 0xabba134a  
A10     : 0x3ffd0138  A11     : 0x00000116  A12     : 0xabba1234  A13     : 0x00000b38  
A14     : 0x00060720  A15     : 0x00000000  SAR     : 0x00000019  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000004  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  

ELF file SHA256: 0000000000000000

Backtrace: 0x4014ac74:0x3ffb3e30 0x40141e2b:0x3ffb3e60 0x400d1212:0x3ffb3e80 0x401414b4:0x3ffb3ea0 0x400897ea:0x3ffb3ed0
  #0  0x4014ac74:0x3ffb3e30 in tcp_output at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/tcp_out.c:1027
  #1  0x40141e2b:0x3ffb3e60 in tcp_recved at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/tcp.c:1765
  #2  0x400d1212:0x3ffb3e80 in _tcp_recved_api(tcpip_api_call_data*) at .pio/libdeps/esp32doit-devkit-v1/AsyncHTTPSRequest_Generic/src/AsyncHTTPSRequest_Impl_Generic.h:970
  #3  0x401414b4:0x3ffb3ea0 in tcpip_thread at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/api/tcpip.c:483
  #4  0x400897ea:0x3ffb3ed0 in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1)

When Connection header of response is "close" (Corrupt heap)

[AHTTPS] open( POST , url = 
[AHTTPS] _parseURL(): scheme+host HTTPS:// 
[AHTTPS] _parseURL(): port+path+query 443 
[AHTTPS] open: connecting to hostname = 
[AHTTPS] _connect()
[AHTTPS] _onConnect handler
[AHTTPS] _setReadyState : 1

[AHTTPS] send(String) {
  "floor": "L , length = 38
[AHTTPS] _buildRequest()
[AHTTPS] _HTTPmethod = 1
[AHTTPS] POST  /api/library/entrances  HTTP/1.1

[AHTTPS] write _HTTPmethodStringwithSpace :  POST 
[AHTTPS] write path :  /api/library/entrances
[AHTTPS] write query 
[AHTTPS] write HTTP/1.1
[AHTTPS] To write hdr
[AHTTPS] hdr->name
[AHTTPS] hdr->value
[AHTTPS] host :

[AHTTPS] hdr->name
[AHTTPS] hdr->value
[AHTTPS] Content-Type : application/json 

[AHTTPS] hdr->name
[AHTTPS] hdr->value
[AHTTPS] Content-Length : 38 

[AHTTPS] Write hdr done
[AHTTPS] _buildRequest() done
[AHTTPS] Done supply
[AHTTPS] To send()
[AHTTPS] send 192

[AHTTPS] ========= _onData handler =======
[AHTTPS] Vbuf = HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Sun, 30 Jan 2022 13:46:31 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 8
**Connection: close**
X-Powered-By: Express

[AHTTPS] =================================
[AHTTPS] Vbuf len = 237
[AHTTPS] =================================
[AHTTPS] _collectHeaders()
[AHTTPS] xbuf::readString: Reserved size =  18
[AHTTPS] xbuf::readString: Reserved size =  32
[AHTTPS] xbuf::readString: Reserved size =  38
[AHTTPS] xbuf::readString: Reserved size =  41
[AHTTPS] xbuf::readString: Reserved size =  20
[AHTTPS] xbuf::readString: Reserved size =  20
[AHTTPS] xbuf::readString: Reserved size =  24
[AHTTPS] xbuf::readString: Reserved size =  42
[AHTTPS] xbuf::readString: Reserved size =  3
[AHTTPS] _setReadyState : 2
[AHTTPS] _setReadyState : 3
**[AHTTPS] *all data received - closing TCP**
[AHTTPS] _setReadyState : 4

[AHTTPS] responseText()
[AHTTPS] xbuf::readString: Reserved size =  9
[AHTTPS] ========= responseText(char) =======
[AHTTPS] localString = Received
[AHTTPS] =================================
[AHTTPS] avail = 8
[AHTTPS] ====================================
[AHTTPS] 
_onDisconnect handler
[AHTTPS] open( POST , url =
CORRUPT HEAP: Bad tail at 0x3ffd00d3. Expected 0xbaad5678 got 0x70167078
abort() was called at PC 0x4008696d on core 1

ELF file SHA256: 0000000000000000

Backtrace: 0x4008855c:0x3ffb1900 0x400887d9:0x3ffb1920 0x4008696d:0x3ffb1940 0x40086a99:0x3ffb1970 0x40107c97:0x3ffb1990 0x40103f65:0x3ffb1c50 0x40103efd:0x3ffb1ca0 0x4008ceb5:0x3ffb1cd0 0x40081bba:0x3ffb1cf0 0x40086865:0x3ffb1d10 0x4000bec7:0x3ffb1d30 0x4016c98d:0x3ffb1d50 0x4016c6cd:0x3ffb1d70 0x400d523f:0x3ffb1d90 0x400d77bc:0x3ffb1dd0 0x400d7636:0x3ffb1df0 0x400da880:0x3ffb1fb0 0x400897ea:0x3ffb1fd0

Information

Platform.io version: Core 5.2.4, Home 3.4.0
ESP32 IDF version: v3.3.5-1-g85c43024c
ESP32 module: DEVKITV1
OS: Ubuntu 20.04 LTS
Linux focal 5.13.0-27-generic #29~20.04.1-Ubuntu SMP x86_64 x86_64 x86_64 GNU/Linux

Context:
Trying to make a POST request to a server through HTTPS.

Getting 400 Bad Request on second call to same host

400 Bad Request

First time I request data from my server it works. If I call it again, I get a 400 Bad Request.

The funny thing is it doesn't happen when connecting to the sample URLs.

Steps to Reproduce

Use your own examples but change the URL you are GET'ing from to https://yocal.dk/test.txt

Expected behavior

Same response both times

Actual behavior

First request returns 200, second request returns 400

Log

First request:

[AHTTPS] open( GET , url = https://yocal.dk/test.txt
[AHTTPS] open: connecting to hostname = yocal.dk:443
[AHTTPS] _client->connecting to yocal.dk , 443
[AHTTPS] client.connect OK to yocal.dk , 443
[AHTTPS] _onError handler SSL error = OK

**************************************
Response code: 200
Response text: Test :)
**************************************

Second request

[AHTTPS] open( GET , url = https://yocal.dk/test.txt
[AHTTPS] open: already connected

**************************************
Response code: 400
Response text: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Hostname</h2>
<hr><p>HTTP Error 400. The request hostname is invalid.</p>
</BODY></HTML>

**************************************

Information

Could it be related to: #12 ?

Doesn't work on M5Stack devices (M5Atom & M5StickC Plus)

Describe the bug

This library doesn't work on M5Stack devices (M5Atom & M5StickC Plus). Constantly crashing, throwing xQueueTakeMutexRecursive errors.
I don't have this problem when using AsyncTCP_SSL directly (on another project).

Steps to Reproduce

#define _ASYNC_HTTPS_LOGLEVEL_ 4

#include <WiFi.h>
#include <M5Atom.h>
#include <AsyncHTTPSRequest_Generic.h>

// Wifi Credentials
const char* WIFI_SSID = "wifi";
const char* WIFI_PASSWORD = "password";

void setup() {
  M5.begin(true, true, true);

  // WiFi Init
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("[WIFI] connecting to network " + String(WIFI_SSID) );
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("[WIFI] connected with Ip: " + WiFi.localIP().toString() );

  // divoom_client.LogIn();
  AsyncHTTPSRequest request;
  request.setDebug(true);
  static bool requestOpenResult;
  requestOpenResult = request.open("GET", "https://www.google.com/");
  request.send();
}

void loop() {
  M5.update();
}

Expected behavior

A clear and concise description of what you expected to happen.

Actual behavior

The script crashed the M5Atom constantly. It kept throwing these two errors:

assert failed: xQueueSemaphoreTake queue.c:1549 (pxQueue->uxItemSize == 0)


Backtrace: 0x40083dd5:0x3ffd6800 0x4008be49:0x3ffd6820 0x4009171d:0x3ffd6840 0x4008ce59:0x3ffd6970 0x4008d010:0x3ffd69b0 0x400d41b4:0x3ffd69d0 0x400d4221:0x3ffd6a00 0x400d3e0e:0x3ffd6a20 0x400d48e1:0x3ffd6a50 0x400d48f1:0x3ffd6a80 0x400d4b7b:0x3ffd6aa0
0x40083dd5: panic_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/panic.c line 402
0x4008be49: esp_system_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/esp_system.c line 128
0x4009171d: __assert_func at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/assert.c line 85
0x4008ce59: xQueueSemaphoreTake at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/freertos/queue.c line 1545
0x4008d010: xQueueTakeMutexRecursive at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/freertos/queue.c line 731
0x400d41b4: AsyncHTTPSRequest::_onPoll(AsyncSSLClient*) at /Users/redphx/Documents/Arduino/libraries/AsyncHTTPSRequest_Generic/src/AsyncHTTPSRequest_Impl_Generic.h line 1622
0x400d4221: std::_Function_handler   >::_M_invoke(const std::_Any_data &, void *&&, AsyncSSLClient *&&) at /Users/redphx/Documents/Arduino/libraries/AsyncHTTPSRequest_Generic/src/AsyncHTTPSRequest_Impl_Generic.h line 1321
0x400d3e0e: std::function ::operator()(void*, AsyncSSLClient*) const at /Users/redphx/Library/Arduino15/packages/m5stack/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/xtensa-esp32-elf/include/c++/8.4.0/bits/std_function.h line 260
0x400d48e1: AsyncSSLClient::_poll(tcp_pcb*) at /Users/redphx/Documents/Arduino/libraries/AsyncTCP_SSL/src/AsyncTCP_SSL_Impl.h line 1784
0x400d48f1: AsyncSSLClient::_s_poll(void*, tcp_pcb*) at /Users/redphx/Documents/Arduino/libraries/AsyncTCP_SSL/src/AsyncTCP_SSL_Impl.h line 2185
0x400d4b7b: _async_service_task(void*) at /Users/redphx/Documents/Arduino/libraries/AsyncTCP_SSL/src/AsyncTCP_SSL_Impl.h line 295


[AHTTPS] open( GET , url = https://www.google.com/
[AHTTPS] open: connecting to hostname = www.google.com:443
[AHTTPS] _client->connecting to www.google.com , 443
[AHTTPS] client.connect OK to www.google.com , 443
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x4008cff1  PS      : 0x00060e30  A0      : 0x800d41b7  A1      : 0x3ffd6990  
A2      : 0xa2413967  A3      : 0xffffffff  A4      : 0x00001004  A5      : 0x00000000  
A6      : 0x00000000  A7      : 0x3ffb6c68  A8      : 0x80084195  A9      : 0x3ffd6980  
A10     : 0x3ffd15a8  A11     : 0x0000000c  A12     : 0x3ffc8b18  A13     : 0x3ffb26e0  
A14     : 0x00000003  A15     : 0x00060023  SAR     : 0x0000000a  EXCCAUSE: 0x0000001c  
EXCVADDR: 0xa241396f  LBEG    : 0x40084bed  LEND    : 0x40084bf5  LCOUNT  : 0x00000027  


Backtrace: 0x4008cfee:0x3ffd6990 0x400d41b4:0x3ffd69b0 0x400d4221:0x3ffd69e0 0x400d3e0e:0x3ffd6a00 0x400d48e1:0x3ffd6a30 0x400d48f1:0x3ffd6a60 0x400d4b7b:0x3ffd6a80

PC: 0x4008cff1: xQueueTakeMutexRecursive at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/freertos/queue.c line 724
EXCVADDR: 0xa241396f

Decoding stack results
0x4008cfee: xQueueTakeMutexRecursive at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/freertos/queue.c line 717
0x400d41b4: AsyncHTTPSRequest::_onPoll(AsyncSSLClient*) at /Users/redphx/Documents/Arduino/libraries/AsyncHTTPSRequest_Generic/src/AsyncHTTPSRequest_Impl_Generic.h line 1622
0x400d4221: std::_Function_handler   >::_M_invoke(const std::_Any_data &, void *&&, AsyncSSLClient *&&) at /Users/redphx/Documents/Arduino/libraries/AsyncHTTPSRequest_Generic/src/AsyncHTTPSRequest_Impl_Generic.h line 1321
0x400d3e0e: std::function ::operator()(void*, AsyncSSLClient*) const at /Users/redphx/Library/Arduino15/packages/m5stack/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/xtensa-esp32-elf/include/c++/8.4.0/bits/std_function.h line 260
0x400d48e1: AsyncSSLClient::_poll(tcp_pcb*) at /Users/redphx/Documents/Arduino/libraries/AsyncTCP_SSL/src/AsyncTCP_SSL_Impl.h line 1784
0x400d48f1: AsyncSSLClient::_s_poll(void*, tcp_pcb*) at /Users/redphx/Documents/Arduino/libraries/AsyncTCP_SSL/src/AsyncTCP_SSL_Impl.h line 2185
0x400d4b7b: _async_service_task(void*) at /Users/redphx/Documents/Arduino/libraries/AsyncTCP_SSL/src/AsyncTCP_SSL_Impl.h line 295

Information

Arduino IDE version: 1.8.19
M5Stack Core Version 2.0.6
OS: macOS Catalina 10.15.7

Having problemen with AsyncHTTPS memory leak

Describe the bug

When utilizing the AsyncHTTPS library there is a decrease of the available heap space with about 100 to about 200 bytes per https request until it runs out of heap space and crashes.

Steps to Reproduce

I modified the included example slightly to demonstrate the problem;

https://github.com/khoih-prog/AsyncHTTPSRequest_Generic/blob/main/examples/AsyncHTTPSRequest_ESP/AsyncHTTPSRequest_ESP.ino
  1. Add a global variable;

uint previousHeapSize = ESP.getFreeHeap();

  1. Modified void sendRequest() function;
void sendRequest()
{
  static bool requestOpenResult;

///***Add this
  uint heapSize = ESP.getFreeHeap();
  Serial.print("Current HeapFree: "); Serial.print(heapSize);
  if(previousHeapSize > heapSize )
  {
    Serial.print(" decrease: ");
    Serial.println(previousHeapSize - heapSize);  
  }else{
    Serial.print(" increase: ");
    Serial.println(heapSize - previousHeapSize);      
  }
  previousHeapSize = heapSize;  
///***End Add this

  if (request.readyState() == readyStateUnsent || request.readyState() == readyStateDone)

  1. Commented out the Serial.print within requestCB to prevent printing of output
  if (readyState == readyStateDone)
  {
    /*Serial.println(F("\n**************************************"));
    Serial.println(request->responseText());
    Serial.println(F("**************************************"));*/

    request->setDebug(false);
  }

  1. Commented out the ticker1.attach within setup()
    //ticker1.attach(HEARTBEAT_INTERVAL, heartBeatPrint);

  2. Decreased the HTTPS_REQUEST_INTERVAL to 10 seconds to faster show the problem, although it also happens when you leave the interval to the example's default

// 300s = 5 minutes to not flooding
#define HTTPS_REQUEST_INTERVAL      10  //300

Expected behavior

Expected for the free heap size to be remain stable after initial initialization with minor variations both in increase and decrease of available free heap space.

Actual behavior

The modified demo shows an ongoing decrease of available heap space:

11:05:07.402 -> Starting AsyncHTTPSRequest_ESP using ESP32_DEV
11:05:07.402 -> AsyncTCP_SSL v1.2.0
11:05:07.448 -> AsyncHTTPSRequest_Generic v2.0.1
11:05:07.529 -> Connecting to WiFi SSID: Wireless
11:05:08.036 -> .....
11:05:10.006 -> AsyncHTTPSRequest @ IP : 172.16.16.241
11:05:10.053 -> Current HeapFree: 264648 increase: 102796
11:05:20.034 -> Current HeapFree: 199900 decrease: 64748
11:05:30.020 -> Current HeapFree: 199548 decrease: 352
11:05:40.037 -> Current HeapFree: 199376 decrease: 172
11:05:50.048 -> Current HeapFree: 199248 decrease: 128
11:06:00.037 -> Current HeapFree: 199060 decrease: 188
11:06:10.022 -> Current HeapFree: 198892 decrease: 168
11:06:20.021 -> Current HeapFree: 198764 decrease: 128
11:06:30.003 -> Current HeapFree: 198592 decrease: 172
11:06:40.039 -> Current HeapFree: 198408 decrease: 184
11:06:50.032 -> Current HeapFree: 198084 decrease: 324
11:07:00.034 -> Current HeapFree: 197932 decrease: 152
11:07:10.009 -> Current HeapFree: 197760 decrease: 172
11:07:20.017 -> Current HeapFree: 197604 decrease: 156
11:07:30.048 -> Current HeapFree: 197428 decrease: 176
11:07:40.021 -> Current HeapFree: 197272 decrease: 156
11:07:50.020 -> Current HeapFree: 197080 decrease: 192
11:08:00.015 -> Current HeapFree: 196956 decrease: 124
11:08:10.047 -> Current HeapFree: 196788 decrease: 168
11:08:20.016 -> Current HeapFree: 196612 decrease: 176
11:08:30.029 -> Current HeapFree: 196460 decrease: 152
11:08:40.022 -> Current HeapFree: 196300 decrease: 160
11:08:50.037 -> Current HeapFree: 196132 decrease: 168
11:09:00.032 -> Current HeapFree: 196016 decrease: 116
11:09:10.025 -> Current HeapFree: 195824 decrease: 192
11:09:20.011 -> Current HeapFree: 195656 decrease: 168
11:09:30.003 -> Current HeapFree: 195512 decrease: 144
11:09:40.040 -> Current HeapFree: 195320 decrease: 192
11:09:50.007 -> Current HeapFree: 195168 decrease: 152
11:10:00.013 -> Current HeapFree: 195008 decrease: 160
11:10:10.015 -> Current HeapFree: 194892 decrease: 116
11:10:20.002 -> Current HeapFree: 194700 decrease: 192
11:10:30.032 -> Current HeapFree: 194556 decrease: 144
11:10:40.003 -> Current HeapFree: 194380 decrease: 176
11:10:50.002 -> Current HeapFree: 194228 decrease: 152
11:11:00.011 -> Current HeapFree: 194056 decrease: 172
11:11:10.017 -> Current HeapFree: 193916 decrease: 140
11:11:20.025 -> Current HeapFree: 193744 decrease: 172
11:11:30.005 -> Current HeapFree: 193572 decrease: 172
11:11:40.001 -> Current HeapFree: 193424 decrease: 148
11:11:50.007 -> Current HeapFree: 193244 decrease: 180
11:12:00.002 -> Current HeapFree: 193108 decrease: 136
11:12:10.003 -> Current HeapFree: 192928 decrease: 180
11:12:20.018 -> Current HeapFree: 192796 decrease: 132
11:12:30.035 -> Current HeapFree: 192608 decrease: 188
11:12:40.003 -> Current HeapFree: 192452 decrease: 156
11:12:50.010 -> Current HeapFree: 192296 decrease: 156

Debug and AT-command log (if applicable)

N/A

Screenshots

N/A

Information

  • Arduino IDE version 1.8.16)
  • ESP32 Wrover device using Board manager: ESP32 v3.02
  • OS Windows 11

Delay on Done

Describe the bug

Doing automated update of web content on my board, and its working, but I see a consistent delay on the done state for the download.

Steps to Reproduce

Download a "list" of files, chaining next file off the complete of last. using datacb to handle any amount of data, see multi-second delay on the done after the last datacb. (About 6 seconds)

14:43:04.400 -> Starting download for: index.html
14:43:04.400 ->
14:43:05.031 -> Removing index.html
14:43:05.677 -> Remove done
14:43:06.321 -> Opening file
14:43:06.976 -> File Open
14:43:07.572 -> Send Download Request
14:43:08.214 -> sendDownloadReq
14:43:08.214 -> Sending request
14:43:08.214 -> https://raw.githubusercontent.com/glennswest/i2cgateha/main/contents/index.html
14:43:09.408 -> Download done callback index.html - state 1
14:43:09.620 -> Download done callback index.html - state 2
14:43:09.620 -> Download done callback index.html - state 3
14:43:15.393 -> Download done callback index.html - state 4
14:43:15.393 -> Download complete: index.html - Remainer: 0
14:43:15.393 -> No Downloads

Source: https://github.com/glennswest/i2cgateha/blob/main/I2CGateHa.ino

Expected behavior

Done immediate after data complete

Actual behavior

Multi-second delay

Debug and AT-command log (if applicable)

https://gist.github.com/glennswest/2911ae27fa427a9176382c5cf390b01b

Please ensure to specify the following:
M5Stack ESP32
Arduino 1.8.16

Conflict with ESP32-HUB75-MatrixPanel-I2S-DMA

I found a problem when using the this library and ESP32-HUB75-MatrixPanel-I2S-DMA. If I activate that library, responses to requests from AsyncHTTPSRequest_Generic come significantly later than without it.
Is there any workaround?

setReuse feature

This library is great, one problem though when connecting twice on the same host takes a long time, I was wondering if theres a feature you could add to reuse the connection to avoid doing ssl handshake again, this could reduce the request time significantly on second request.

Cannot send requests to different addresses

Could not send requests to different addresses in quick succession - to the same address works. In the example below it says "Can't send bad request"
After a while it ends with an error and ESP32 restarts
CORRUPT HEAP: Bad tail at 0x3ffcefb8. Expected 0xbaad5678 got 0xbaad5600

assert failed: multi_heap_free multi_heap_poisoning.c:253 (head != NULL)

  • Arduino IDE version 1.8.19
    ESP32 Core Version 2.0.2
    Windows 10 64b
/****************************************************************************************************************************
  AsyncHTTPSRequest_ESP.ino - Dead simple AsyncHTTPSRequest 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)

  AsyncHTTPSRequest_Generic is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer

  Based on and modified from AsyncHTTPSRequest Library (https://github.com/boblemaire/AsyncHTTPSRequest)

  Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPSRequest_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/>.
 *****************************************************************************************************************************/
//************************************************************************************************************
//
// There are scores of ways to use AsyncHTTPSRequest.  The important thing to keep in mind is that
// it is asynchronous and just like in JavaScript, everything is event driven.  You will have some
// reason to initiate an asynchronous HTTP request in your program, but then sending the request
// headers and payload, gathering the response headers and any payload, and processing
// of that response, can (and probably should) all be done asynchronously.
//
// In this example, a Ticker function is setup to fire every 300 seconds to initiate a request.
// Everything is handled in AsyncHTTPSRequest without blocking.
// The callback onReadyStateChange is made progressively and like most JS scripts, we look for
// readyState == 4 (complete) here.  At that time the response is retrieved and printed.
//
// Note that there is no code in loop().  A code entered into loop would run oblivious to
// the ongoing HTTP requests.  The Ticker could be removed and periodic calls to sendRequest()
// could be made in loop(), resulting in the same asynchronous handling.
//
// For demo purposes, debug is turned on for handling of the first request.  These are the
// events that are being handled in AsyncHTTPSRequest.  They all begin with Debug(nnn) where
// nnn is the elapsed time in milliseconds since the transaction was started.
//
//*************************************************************************************************************

#if !( defined(ESP8266) ||  defined(ESP32) )
#error This code is intended to run on the ESP8266 or ESP32 platform! Please check your Tools->Board setting.
#endif

#define ASYNC_HTTPS_REQUEST_GENERIC_VERSION_MIN_TARGET      "AsyncHTTPSRequest_Generic v1.3.0"
#define ASYNC_HTTPS_REQUEST_GENERIC_VERSION_MIN             1003000

// Level from 0-4
#define ASYNC_HTTPS_DEBUG_PORT      Serial

#define _ASYNC_TCP_SSL_LOGLEVEL_    1
#define _ASYNC_HTTPS_LOGLEVEL_      1

// 300s = 5 minutes to not flooding
#define HTTPS_REQUEST_INTERVAL      60  //300

// 10s
#define HEARTBEAT_INTERVAL          10

int status;     // the Wifi radio's status

const char* ssid        = "******";
const char* password    = "*******";
byte reqCount = 3;
bool readySend = true;
const char* addresesOK[] = {"https://worldtimeapi.org/api/timezone/Europe/Prague.txt", "https://worldtimeapi.org/api/timezone/America/Toronto.txt", "https://worldtimeapi.org/api/timezone/Europe/London.txt"};
const char* addreses[] =   {"https://worldtimeapi.org/api/timezone/America/Toronto.txt", "https://worldtimeapi.org/api/timezone/Europe/Prague.txt", "https://www.myexternalip.com/raw"};

#if (ESP8266)
#include <ESP8266WiFi.h>
#elif (ESP32)
#include <WiFi.h>
#endif

// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include <AsyncHTTPSRequest_Generic.h>            // https://github.com/khoih-prog/AsyncHTTPSRequest_Generic

#include <Ticker.h>

AsyncHTTPSRequest request;
Ticker ticker;
Ticker ticker1;

void heartBeatPrint()
{
  static int num = 1;

  if (WiFi.status() == WL_CONNECTED)
    Serial.print(F("H"));        // H means connected to WiFi
  else
    Serial.print(F("F"));        // F means not connected to WiFi

  if (num == 80)
  {
    Serial.println();
    num = 1;
  }
  else if (num++ % 10 == 0)
  {
    Serial.print(F(" "));
  }
}

void sendRequest()
{
  static bool requestOpenResult;

  if (request.readyState() == readyStateUnsent || request.readyState() == readyStateDone)
  {
    reqCount--;
    readySend = false;
    //requestOpenResult = request.open("GET", "https://worldtimeapi.org/api/timezone/Europe/London.txt");
    //requestOpenResult = request.open("GET", "https://worldtimeapi.org/api/timezone/America/Toronto.txt");
    requestOpenResult = request.open("GET", addreses[reqCount]);

    if (requestOpenResult)
    {
      // Only send() if open() returns true, or crash
      Serial.print("sending request: "); Serial.println(addreses[reqCount]);
      request.send();
    }
    else
    {
      Serial.println("Can't send bad request");
    }
  }
  else
  {
    Serial.println("Can't send request");
  }
}
void sendRequests()
{
  reqCount = 3;

}

void requestCB(void* optParm, AsyncHTTPSRequest* request, int readyState)
{
  (void) optParm;

  if (readyState == readyStateDone)
  {
    Serial.println("\n**************************************");
    Serial.println(request->responseText());
    Serial.println("**************************************");

    request->setDebug(false);
    readySend = true;

  }
}

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  while (!Serial);

  Serial.println("\nStarting AsyncHTTPSRequest_ESP using " + String(ARDUINO_BOARD));

#if defined(ESP32)
  Serial.println(ASYNC_TCP_SSL_VERSION);
#else
  //Serial.println(ESPASYNC_TCP_SSL_VERSION);
#endif

  Serial.println(ASYNC_HTTPS_REQUEST_GENERIC_VERSION);

#if defined(ASYNC_HTTPS_REQUEST_GENERIC_VERSION_MIN)
  if (ASYNC_HTTPS_REQUEST_GENERIC_VERSION_INT < ASYNC_HTTPS_REQUEST_GENERIC_VERSION_MIN)
  {
    Serial.print("Warning. Must use this example on Version equal or later than : ");
    Serial.println(ASYNC_HTTPS_REQUEST_GENERIC_VERSION_MIN_TARGET);
  }
#endif

  WiFi.mode(WIFI_STA);

  WiFi.begin(ssid, password);

  Serial.println("Connecting to WiFi SSID: " + String(ssid));

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.print(F("\nAsyncHTTPSRequest @ IP : "));
  Serial.println(WiFi.localIP());

  request.setDebug(false);

  request.onReadyStateChange(requestCB);

  ticker.attach(HTTPS_REQUEST_INTERVAL, sendRequests);

  ticker1.attach(HEARTBEAT_INTERVAL, heartBeatPrint);

  // Send first request now
}

void loop()
{
  //delay(1);
  if ((reqCount > 0) && readySend) sendRequest();
}

No result from github https query

Describe the bug

Doing a query to a github api endpoint (Publically available, and works from curl), and get no response.

Steps to Reproduce

Run app(i2cgateha) on m5stack esp32 (Which has working mqttasync and webserver), query returns no result.
App github: https://github.com/glennswest/i2cgateha
Debug Text: https://raw.githubusercontent.com/glennswest/i2cgateha/main/problem.txt

Steps to reproduce the behavior. Including the MRE sketches
Run above program

Expected behavior

Returns:
Print something like:
[
{
"name": "index.html",
"path": "contents/index.html",
"sha": "9e52837f62962c18c7e214a7e1a0d70882a1c726",
"size": 11,
"url": "https://api.github.com/repos/glennswest/i2cgateha/contents/contents/index.html?ref=main",
"html_url": "https://github.com/glennswest/i2cgateha/blob/main/contents/index.html",
"git_url": "https://api.github.com/repos/glennswest/i2cgateha/git/blobs/9e52837f62962c18c7e214a7e1a0d70882a1c726",
"download_url": "https://raw.githubusercontent.com/glennswest/i2cgateha/main/contents/index.html",
"type": "file",
"_links": {
"self": "https://api.github.com/repos/glennswest/i2cgateha/contents/contents/index.html?ref=main",
"git": "https://api.github.com/repos/glennswest/i2cgateha/git/blobs/9e52837f62962c18c7e214a7e1a0d70882a1c726",
"html": "https://github.com/glennswest/i2cgateha/blob/main/contents/index.html"
}
}
]

Actual behavior

Returns no data

Debug and AT-command log (if applicable)

See serial log:
https://raw.githubusercontent.com/glennswest/i2cgateha/main/problem.txt

Information

Please ensure to specify the following:
Arduino 1.18.16
Hardware: M5Stack-Paper ESP32

  • Contextual information (e.g. what you were trying to achieve)
    Pull a list of files on the directory on github
  • Simplest possible steps to reproduce
    Use the supplied url to test with your example code

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.