AsynHTTPRequest_Generic for ESP8266/ESP32, WT32_ETH01 and STM32 (builtin LAN8742A or LAN8720 Ethernet)

AsyncHTTPRequest_Generic Library

How To Install Using Arduino Library Manager

Why do we need this Async AsyncHTTPRequest_Generic Library

Features

  1. Asynchronous HTTP Request library for ESP8266, ESP32 using built-in WiFi, and STM32 boards using built-in LAN8742A Ethernet.
  2. Providing a subset of HTTP.
  3. Relying on on ESPAsyncTCP for ESP8266, AsyncTCP for ESP32 using built-in WiFi
  4. Relying on STM32duino LwIP/STM32duino STM32Ethernet/STM32AsyncTCP for STM32 using built-in LAN8742A Ethernet.
  5. Methods similar in format and usage to XmlHTTPrequest in Javascript.

Supports:

  1. GET and POST
  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 HTTP layer on top of the ESPAsyncTCP/AsyncTCP/STM32AsyncTCP 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

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 to report and make PR in Fixed linker errors when included in multiple .cpp files. Also check HOWTO Fix Multiple Definitions Linker Error

Initial Releases v1.0.0

  1. Initial coding to add support to STM32F/L/H/G/WB/MP1 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
  2. Add examples using STM32 boards.

Currently Supported Boards

  1. ESP32 and ESP8266

  2. STM32F/L/H/G/WB/MP1 with built-in LAN8742A Ethernet.

  3. Nucleo-144 (F429ZI, F746ZG, F756ZG, F767ZI)

  4. Discovery STM32F746G-DISCOVERY

  5. Any STM32 boards with enough flash/memory and already configured to run LAN8742A Ethernet.

Sample Code

This is the AsyncHTTPRequest_STM32 example

#include "defines.h"

// 600s = 10 minutes to not flooding
#define HTTP_REQUEST_INTERVAL_MS     600000

#include <AsyncHTTPRequest_Generic.h>         // https://github.com/khoih-prog/AsyncHTTPRequest_Generic

#include <Ticker.h>                           // https://github.com/sstaub/Ticker

AsyncHTTPRequest request;

void sendRequest(void);

// Repeat forever, millis() resolution
Ticker sendHTTPRequest(sendRequest, HTTP_REQUEST_INTERVAL_MS, 0, MILLIS); 

void sendRequest(void)
{
  if (request.readyState() == readyStateUnsent || request.readyState() == readyStateDone)
  {
    //request.open("GET", "http://worldtimeapi.org/api/timezone/Europe/London.txt");
    request.open("GET", "http://worldtimeapi.org/api/timezone/America/Toronto.txt");
    request.send();
  }
}

void requestCB(void* optParm, AsyncHTTPRequest* request, int readyState) 
{
  if (readyState == readyStateDone) 
  {
    Serial.println("\n**************************************");
    Serial.println(request->responseText());
    Serial.println("**************************************");
    
    request->setDebug(false);
  }
}

void setup(void) 
{
  Serial.begin(115200);
  while (!Serial);
  
  Serial.println("\nStart AsyncHTTPRequest_STM32 on " + String(BOARD_NAME));

  // start the ethernet connection and the server
  // Use random mac
  uint16_t index = millis() % NUMBER_OF_MAC;

  // Use Static IP
  //Ethernet.begin(mac[index], ip);
  // Use DHCP dynamic IP and random mac
  Ethernet.begin(mac[index]);

  Serial.print(F("AsyncHTTPRequest @ IP : "));
  Serial.println(Ethernet.localIP());
  Serial.println();

  request.setDebug(false);
  
  request.onReadyStateChange(requestCB);
  sendHTTPRequest.start(); //start the ticker.

  // Send first request now
  //delay(60);
  sendRequest();
}

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

Debug Termimal Output Samples

  1. This is terminal debug output when running AsyncHTTPRequest_STM32 example on STM32F7 Nucleo-144 NUCLEO_F767ZI using built-in LAN8742A.
Start AsyncHTTPRequest_STM32 on NUCLEO_F767ZI
AsyncHTTPRequest @ IP : 192.168.2.72

**************************************
abbreviation: EDT
client_ip: 216.154.52.212
datetime: 2020-09-13T18:22:59.555816-04:00
day_of_week: 0
day_of_year: 257
dst: true
dst_from: 2020-03-08T07:00:00+00:00
dst_offset: 3600
dst_until: 2020-11-01T06:00:00+00:00
raw_offset: -18000
timezone: America/Toronto
unixtime: 1600035779
utc_datetime: 2020-09-13T22:22:59.555816+00:00
utc_offset: -04:00
week_number: 37

Releases v1.1.0

  1. Add HTTP PUT, PATCH, DELETE and HEAD besides POST and GET methods.
  2. Add Table of Contents
  3. Add Version String

Releases v1.2.0

  1. Add support to LAN8720 Ethernet for many STM32F4 (F407xx, NUCLEO_F429ZI) and STM32F7 (DISCO_F746NG, NUCLEO_F746ZG, NUCLEO_F756ZG) boards.
  2. Add LAN8720 examples
  3. Add Packages’ Patches for STM32 to use LAN8720 with STM32Ethernet and LwIP libraries
  4. Update ESP_WiFiManager-related example to fix multiWiFi timings to work better with latest esp32 core v1.0.6

Releases v1.1.5

  1. Fix dependency on unpublished STM32AsyncTCP Library.

Releases v1.1.4

  1. Fix library.properties dependency

Releases v1.1.3

  1. Fix non-persistent Connection header bug.
  2. Add ESP32-S2 support
  3. Tested with Latest ESP32 Core 1.0.5 for ESP32-based boards.

Releases v1.1.2

  1. Rename _lock and _unlock to avoid conflict with ESP32/ESP8266 AsyncWebServer library.
  2. Fix compiler warnings.

Releases v1.1.1

  1. Prevent crash if request and/or method not correct.

Releases v1.3.0

  1. Add support to WT32_ETH01 (ESP32 + LAN8720) boards
  2. Add examples with new features

Debug Terminal Output

AsyncHTTPRequest_WT32_ETH01 on ESP32_DEV with ETH_PHY_LAN8720

Starting AsyncHTTPRequest_WT32_ETH01 on ESP32_DEV with ETH_PHY_LAN8720
WebServer_WT32_ETH01 v1.1.0
AsyncHTTPRequest_Generic v1.3.0
ETH MAC: A8:03:2A:A1:61:73, IPv4: 192.168.2.232, FULL_DUPLEX, 100Mbps
AsyncHTTPRequest @ IP : 192.168.2.232

**************************************
abbreviation: EDT
client_ip: 45.72.193.56
datetime: 2021-07-09T23:16:50.506413-04:00
day_of_week: 5
day_of_year: 190
dst: true
dst_from: 2021-03-14T07:00:00+00:00
dst_offset: 3600
dst_until: 2021-11-07T06:00:00+00:00
raw_offset: -18000
timezone: America/Toronto
unixtime: 1625887010
utc_datetime: 2021-07-10T03:16:50.506413+00:00
utc_offset: -04:00
week_number: 27
**************************************