forked from khoih-prog/AsyncHTTPRequest_Generic
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
c2598c6f2f | |||
da9ee00a7a | |||
fd0d4c8dc8 | |||
1662bf5a4f | |||
14b7d18c29 | |||
183d14c18a | |||
6bed667169 | |||
9cd3c2c56e | |||
a614f53ac6 | |||
87c16f4485 |
18
library.json
18
library.json
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name":"AsyncHTTPRequest_Generic",
|
||||
"version": "1.0.0",
|
||||
"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",
|
||||
"description":"Simple Async HTTP Request library, supporting GET and POST, on top of AsyncTCP libraries, such as AsyncTCP, ESPAsyncTCP, etc... for ESP32, ESP8266.",
|
||||
"keywords":"async,tcp,http,ESP8266,ESP32,ESPAsyncTCP,AsyncTCP,ethernet,wifi,lan8742a",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bob Lemaire",
|
||||
@ -13,7 +13,7 @@
|
||||
"url": "https://github.com/khoih-prog",
|
||||
"email": "khoih.prog@gmail.com",
|
||||
"maintainer": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"repository":
|
||||
{
|
||||
@ -37,16 +37,8 @@
|
||||
"platforms": ["espressif8266", "espressif32"]
|
||||
},
|
||||
{
|
||||
"name": "STM32duino LwIP",
|
||||
"platforms": "ststm32"
|
||||
},
|
||||
{
|
||||
"name": "STM32duino STM32Ethernet",
|
||||
"platforms": "ststm32"
|
||||
},
|
||||
{
|
||||
"name": "STM32 AsyncTCP",
|
||||
"platforms": "ststm32"
|
||||
"name": "https://github.com/0xFEEDC0DE64/optional.git",
|
||||
"platforms": ["espressif8266", "espressif32"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ version=1.0.0
|
||||
author=Bob Lemaire,Khoi Hoang
|
||||
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.
|
||||
paragraph=This AsyncHTTPRequest_Generic Library, supporting GET and POST, for ESP32, ESP8266 and STM32 with built-in LAN8742A Ethernet, such as Nucleo-144 F767ZI, etc.
|
||||
sentence=Simple Async HTTP Request library, supporting GET and POST, on top of AsyncTCP libraries, such as AsyncTCP, ESPAsyncTCP, etc.. for ESP32, ESP8266
|
||||
paragraph=This AsyncHTTPRequest_Generic Library, supporting GET and POST, for ESP32, ESP8266.
|
||||
category=Communication,AsyncTCP,AsyncHTTP
|
||||
url=https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
architectures=*
|
||||
depends=AsyncTCP,ESP AsyncTCP,ESPAsync_WiFiManager,STM32duino LwIP,STM32duino STM32Ethernet,STM32 AsyncTCP
|
||||
depends=AsyncTCP,ESP AsyncTCP,ESPAsync_WiFiManager
|
||||
includes=AsyncHTTPRequest_Generic.h
|
||||
|
@ -15,13 +15,11 @@
|
||||
; ESP32
|
||||
; SAMD
|
||||
; NRF52
|
||||
; STM32
|
||||
; ============================================================
|
||||
;default_envs = ESP8266
|
||||
default_envs = ESP32
|
||||
;default_envs = SAMD
|
||||
;default_envs = NRF52
|
||||
;default_envs = STM32
|
||||
|
||||
[env]
|
||||
; ============================================================
|
||||
@ -33,22 +31,16 @@ upload_speed = 921600
|
||||
;monitor_speed = 9600
|
||||
;monitor_port = COM11
|
||||
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
; PlatformIO 4.x
|
||||
AsyncTCP@~1.1.1
|
||||
ESPAsyncTCP@~1.2.2
|
||||
STM32AsyncTCP@~1.0.0
|
||||
STM32duino LwIP@~2.1.2
|
||||
STM32duino STM32Ethernet@~1.2.0
|
||||
ESPAsync_WiFiManager@~1.1.2
|
||||
; PlatformIO 5.x
|
||||
; PlatformIO 5.x
|
||||
; me-no-dev/AsyncTCP@~1.1.1
|
||||
; me-no-dev/ESPAsyncTCP@~1.2.2
|
||||
; philbowles/STM32AsyncTCP@~1.0.0
|
||||
; stm32duino/STM32duino LwIP@~2.1.2
|
||||
; stm32duino/STM32duino STM32Ethernet@~1.2.0
|
||||
; khoih-prog/ESPAsync_WiFiManager@~1.1.2
|
||||
|
||||
|
||||
build_flags =
|
||||
; set your debug output (default=Serial)
|
||||
; -D DEBUG_ESP_PORT=Serial
|
||||
@ -234,115 +226,3 @@ board = feather52840
|
||||
;board = mdbt50qrx
|
||||
;board = ninab302
|
||||
;board = ninab112
|
||||
|
||||
[env:STM32]
|
||||
platform = ststm32
|
||||
framework = arduino
|
||||
|
||||
; ============================================================
|
||||
; Choose your board by uncommenting one of the following lines
|
||||
; ============================================================
|
||||
|
||||
; ============================================================
|
||||
; Board configuration Nucleo-144
|
||||
; ============================================================
|
||||
|
||||
;board = nucleo_f207zg
|
||||
;board = nucleo_f429zi
|
||||
;board = nucleo_f746zg
|
||||
;board = nucleo_f756zg
|
||||
;board = nucleo_f767zi
|
||||
;board = nucleo_h743zi
|
||||
;board = nucleo_l496zg
|
||||
;board = nucleo_l496zg-p
|
||||
;board = nucleo_l4r5zi
|
||||
;board = nucleo_l4r5zi-p
|
||||
|
||||
; ============================================================
|
||||
; Board configuration Nucleo-64
|
||||
; ============================================================
|
||||
|
||||
;board = nucleo_f030r8
|
||||
;board = nucleo_f072rb
|
||||
|
||||
;board = nucleo_f091rc
|
||||
;board = nucleo_f103rb
|
||||
;board = nucleo_f302r8
|
||||
;board = nucleo_f303re
|
||||
;board = nucleo_f401re
|
||||
;board = nucleo_f411re
|
||||
;board = nucleo_f446re
|
||||
;board = nucleo_g071rb
|
||||
;board = nucleo_g431rb
|
||||
;board = nucleo_g474re
|
||||
;board = nucleo_l053r8
|
||||
;board = nucleo_l073rz
|
||||
;board = nucleo_l152re
|
||||
;board = nucleo_l433rc_p
|
||||
;board = nucleo_l452re
|
||||
;board = nucleo_l452re-p
|
||||
;board = nucleo_l476rg
|
||||
;board = pnucleo_wb55rg
|
||||
|
||||
; ============================================================
|
||||
; Board configuration Nucleo-32
|
||||
; ============================================================
|
||||
|
||||
;board = nucleo_f031k6
|
||||
;board = nucleo_l031k6
|
||||
;board = nucleo_l412kb
|
||||
;board = nucleo_l432lc
|
||||
;board = nucleo_f303k8
|
||||
;board = nucleo_g431kb
|
||||
|
||||
; ============================================================
|
||||
; Board configuration Discovery Boards
|
||||
; ============================================================
|
||||
|
||||
;board = disco_f030r8
|
||||
;board = disco_f072rb
|
||||
;board = disco_f030r8
|
||||
;board = disco_f100rb
|
||||
;board = disco_f407vg
|
||||
;board = disco_f413zh
|
||||
;board = disco_f746ng
|
||||
;board = disco_g0316
|
||||
;board = disco_l475vg_iot
|
||||
;board = disco_f072cz-lrwan1
|
||||
|
||||
; ============================================================
|
||||
; Board configuration STM32MP1 Boards
|
||||
; ============================================================
|
||||
|
||||
;board = stm32mp157a-dk1
|
||||
;board = stm32mp157c-dk2
|
||||
|
||||
; ============================================================
|
||||
; Board configuration Generic Boards
|
||||
; ============================================================
|
||||
|
||||
;board = bluepill_f103c6
|
||||
;board = bluepill_f103c8
|
||||
;board = blackpill_f103c8
|
||||
;board = stm32f103cx
|
||||
;board = stm32f103rx
|
||||
;board = stm32f103tx
|
||||
;board = stm32f103vx
|
||||
;board = stm32f103zx
|
||||
;board = stm32f103zet6
|
||||
;board = maplemini_f103cb
|
||||
;board = blackpill_f303cc
|
||||
;board = black_f407ve
|
||||
;board = black_f407vg
|
||||
;board = black_f407ze
|
||||
;board = black_f407zg
|
||||
;board = blue_f407ve_mini
|
||||
;board = blackpill_f401cc
|
||||
;board = blackpill_f411ce
|
||||
;board = coreboard_f401rc
|
||||
;board = feather_f405
|
||||
|
||||
; ============================================================
|
||||
; Board configuration Many more Boards to be filled
|
||||
; ============================================================
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************************************************************
|
||||
AsyncHTTPRequest_Impl_Generic.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
AsyncHTTPRequest.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)
|
||||
|
||||
@ -23,37 +23,97 @@
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef AsyncHTTPRequest_Impl_Generic_h
|
||||
#define AsyncHTTPRequest_Impl_Generic_h
|
||||
#include "AsyncHTTPRequest.h"
|
||||
|
||||
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::AsyncHTTPRequest(): _readyState(readyStateUnsent), _HTTPcode(0), _chunked(false), _debug(DEBUG_IOTA_HTTP_SET)
|
||||
, _timeout(DEFAULT_RX_TIMEOUT), _lastActivity(0), _requestStartTime(0), _requestEndTime(0), _URL(nullptr)
|
||||
, _connectedHost(nullptr), _connectedPort(-1), _client(nullptr), _contentLength(0), _contentRead(0)
|
||||
, _readyStateChangeCB(nullptr), _readyStateChangeCBarg(nullptr), _onDataCB(nullptr), _onDataCBarg(nullptr)
|
||||
, _request(nullptr), _response(nullptr), _chunks(nullptr), _headers(nullptr)
|
||||
namespace {
|
||||
#if ESP32
|
||||
class LockHelper
|
||||
{
|
||||
#ifdef ESP32
|
||||
threadLock = xSemaphoreCreateRecursiveMutex();
|
||||
public:
|
||||
LockHelper(QueueHandle_t _xMutex) :
|
||||
xMutex{_xMutex}
|
||||
{
|
||||
xSemaphoreTakeRecursive(xMutex, portMAX_DELAY);
|
||||
}
|
||||
~LockHelper()
|
||||
{
|
||||
xSemaphoreGiveRecursive(xMutex);
|
||||
}
|
||||
|
||||
private:
|
||||
const QueueHandle_t xMutex;
|
||||
};
|
||||
#define _lock LockHelper lock{this->threadLock}
|
||||
#define _unlock
|
||||
#elif ESP8266
|
||||
#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) )
|
||||
#define _lock
|
||||
#define _unlock
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
std::optional<URL> parseURL(const String &url)
|
||||
{
|
||||
int hostBeg = 0;
|
||||
URL _URL;
|
||||
_URL.scheme = "HTTP://";
|
||||
|
||||
if (url.substring(0, 7).equalsIgnoreCase("HTTP://"))
|
||||
{
|
||||
hostBeg += 7;
|
||||
}
|
||||
else if (url.substring(0, 8).equalsIgnoreCase("HTTPS://"))
|
||||
return {};
|
||||
|
||||
int pathBeg = url.indexOf('/', hostBeg);
|
||||
|
||||
if (pathBeg < 0)
|
||||
return {};
|
||||
|
||||
int hostEnd = pathBeg;
|
||||
int portBeg = url.indexOf(':', hostBeg);
|
||||
|
||||
if (portBeg > 0 && portBeg < pathBeg)
|
||||
{
|
||||
_URL.port = url.substring(portBeg + 1, pathBeg).toInt();
|
||||
hostEnd = portBeg;
|
||||
}
|
||||
else
|
||||
_URL.port = 80;
|
||||
|
||||
_URL.host = url.substring(hostBeg, hostEnd);
|
||||
|
||||
int queryBeg = url.indexOf('?');
|
||||
|
||||
if (queryBeg < 0)
|
||||
queryBeg = url.length();
|
||||
|
||||
_URL.path = url.substring(pathBeg, queryBeg);
|
||||
_URL.query = url.substring(queryBeg);
|
||||
|
||||
AHTTP_LOGDEBUG2("_parseURL(): scheme+host", _URL.scheme, _URL.host);
|
||||
AHTTP_LOGDEBUG3("_parseURL(): port+path+query", _URL.port, _URL.path, _URL.query);
|
||||
|
||||
return _URL;
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::~AsyncHTTPRequest()
|
||||
{
|
||||
if (_client)
|
||||
_client->close(true);
|
||||
|
||||
delete _URL;
|
||||
delete _headers;
|
||||
delete _request;
|
||||
delete _response;
|
||||
delete _chunks;
|
||||
delete[] _connectedHost;
|
||||
|
||||
#ifdef ESP32
|
||||
vSemaphoreDelete(threadLock);
|
||||
@ -73,73 +133,67 @@ void AsyncHTTPRequest::setDebug(bool debug)
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
bool AsyncHTTPRequest::debug()
|
||||
bool AsyncHTTPRequest::debug() const
|
||||
{
|
||||
return (_debug);
|
||||
return _debug;
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
bool AsyncHTTPRequest::open(const char* method, const char* URL)
|
||||
bool AsyncHTTPRequest::open(const URL &url, HTTPmethod method)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("open(", method, ", url =", URL);
|
||||
AHTTP_LOGDEBUG3("open(url =", url.toString(), ", method =", toString<String>(method));
|
||||
|
||||
if (_readyState != readyStateUnsent && _readyState != readyStateDone)
|
||||
switch (_readyState)
|
||||
{
|
||||
case ReadyState::Idle:
|
||||
case ReadyState::Unsent:
|
||||
case ReadyState::Done:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
_requestStartTime = millis();
|
||||
|
||||
delete _URL;
|
||||
|
||||
delete _headers;
|
||||
delete _request;
|
||||
delete _response;
|
||||
delete _chunks;
|
||||
|
||||
_URL = nullptr;
|
||||
|
||||
_headers = nullptr;
|
||||
_response = nullptr;
|
||||
_request = nullptr;
|
||||
_chunks = nullptr;
|
||||
_chunked = false;
|
||||
_contentRead = 0;
|
||||
_readyState = readyStateUnsent;
|
||||
_readyState = ReadyState::Unsent;
|
||||
_HTTPmethod = method;
|
||||
|
||||
if (strcmp(method, "GET") == 0)
|
||||
{
|
||||
_HTTPmethod = HTTPmethodGET;
|
||||
}
|
||||
else if (strcmp(method, "POST") == 0)
|
||||
{
|
||||
_HTTPmethod = HTTPmethodPOST;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
_URL = url;
|
||||
|
||||
if (!_parseURL(URL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( _client && _client->connected() && (strcmp(_URL->host, _connectedHost) != 0 || _URL->port != _connectedPort))
|
||||
if ( _client && _client->connected() && (_URL.host != _connectedHost || _URL.port != _connectedPort))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char* hostName = new char[strlen(_URL->host) + 10];
|
||||
sprintf(hostName, "%s:%d", _URL->host, _URL->port);
|
||||
_addHeader("host", hostName);
|
||||
delete[] hostName;
|
||||
_addHeader("host", _URL.host + ':' + _URL.port);
|
||||
_lastActivity = millis();
|
||||
|
||||
return _connect();
|
||||
}
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::onReadyStateChange(readyStateChangeCB cb, void* arg)
|
||||
void AsyncHTTPRequest::onReadyStateChange(readyStateChangeCB cb, callback_arg_t arg)
|
||||
{
|
||||
_readyStateChangeCB = cb;
|
||||
_readyStateChangeCBarg = arg;
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::onReadyStateChangeArg(callback_arg_t arg)
|
||||
{
|
||||
_readyStateChangeCBarg = arg;
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::setTimeout(int seconds)
|
||||
{
|
||||
@ -155,7 +209,7 @@ bool AsyncHTTPRequest::send()
|
||||
|
||||
_lock;
|
||||
|
||||
if ( ! _buildRequest())
|
||||
if (!_buildRequest())
|
||||
return false;
|
||||
|
||||
_send();
|
||||
@ -265,13 +319,13 @@ void AsyncHTTPRequest::abort()
|
||||
_unlock;
|
||||
}
|
||||
//**************************************************************************************************************
|
||||
reqStates AsyncHTTPRequest::readyState()
|
||||
ReadyState AsyncHTTPRequest::readyState() const
|
||||
{
|
||||
return _readyState;
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
int AsyncHTTPRequest::responseHTTPcode()
|
||||
int AsyncHTTPRequest::responseHTTPcode() const
|
||||
{
|
||||
return _HTTPcode;
|
||||
}
|
||||
@ -283,7 +337,7 @@ String AsyncHTTPRequest::responseText()
|
||||
|
||||
_lock;
|
||||
|
||||
if ( ! _response || _readyState < readyStateLoading || ! available())
|
||||
if ( ! _response || _readyState < ReadyState::Loading || ! available())
|
||||
{
|
||||
AHTTP_LOGDEBUG("responseText() no data");
|
||||
|
||||
@ -299,7 +353,7 @@ String AsyncHTTPRequest::responseText()
|
||||
{
|
||||
AHTTP_LOGDEBUG("responseText() no buffer");
|
||||
|
||||
_HTTPcode = HTTPCODE_TOO_LESS_RAM;
|
||||
_HTTPcode = HttpCode::TOO_LESS_RAM;
|
||||
_client->abort();
|
||||
_unlock;
|
||||
|
||||
@ -319,7 +373,7 @@ String AsyncHTTPRequest::responseText()
|
||||
//**************************************************************************************************************
|
||||
size_t AsyncHTTPRequest::responseRead(uint8_t* buf, size_t len)
|
||||
{
|
||||
if ( ! _response || _readyState < readyStateLoading || ! available())
|
||||
if ( ! _response || _readyState < ReadyState::Loading || ! available())
|
||||
{
|
||||
//DEBUG_HTTP("responseRead() no data\r\n");
|
||||
AHTTP_LOGDEBUG("responseRead() no data");
|
||||
@ -340,9 +394,9 @@ size_t AsyncHTTPRequest::responseRead(uint8_t* buf, size_t len)
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
size_t AsyncHTTPRequest::available()
|
||||
size_t AsyncHTTPRequest::available() const
|
||||
{
|
||||
if (_readyState < readyStateLoading)
|
||||
if (_readyState < ReadyState::Loading)
|
||||
return 0;
|
||||
|
||||
if (_chunked && (_contentLength - _contentRead) < _response->available())
|
||||
@ -354,9 +408,9 @@ size_t AsyncHTTPRequest::available()
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
size_t AsyncHTTPRequest::responseLength()
|
||||
size_t AsyncHTTPRequest::responseLength() const
|
||||
{
|
||||
if (_readyState < readyStateLoading)
|
||||
if (_readyState < ReadyState::Loading)
|
||||
return 0;
|
||||
|
||||
return _contentLength;
|
||||
@ -372,12 +426,12 @@ void AsyncHTTPRequest::onData(onDataCB cb, void* arg)
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
uint32_t AsyncHTTPRequest::elapsedTime()
|
||||
uint32_t AsyncHTTPRequest::elapsedTime() const
|
||||
{
|
||||
if (_readyState <= readyStateOpened)
|
||||
if (_readyState <= ReadyState::Opened)
|
||||
return 0;
|
||||
|
||||
if (_readyState != readyStateDone)
|
||||
if (_readyState != ReadyState::Done)
|
||||
{
|
||||
return millis() - _requestStartTime;
|
||||
}
|
||||
@ -386,7 +440,7 @@ uint32_t AsyncHTTPRequest::elapsedTime()
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
String AsyncHTTPRequest::version()
|
||||
String AsyncHTTPRequest::version() const
|
||||
{
|
||||
return String(AsyncHTTPRequest_Generic_version);
|
||||
}
|
||||
@ -400,64 +454,6 @@ String AsyncHTTPRequest::version()
|
||||
P R R OOO T EEEEE CCC T EEEEE DDDD
|
||||
_______________________________________________________________________________________________________________*/
|
||||
|
||||
//**************************************************************************************************************
|
||||
bool AsyncHTTPRequest::_parseURL(const char* url)
|
||||
{
|
||||
return _parseURL(String(url));
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
bool AsyncHTTPRequest::_parseURL(String url)
|
||||
{
|
||||
delete _URL;
|
||||
|
||||
int hostBeg = 0;
|
||||
_URL = new URL;
|
||||
_URL->scheme = new char[8];
|
||||
strcpy(_URL->scheme, "HTTP://");
|
||||
|
||||
if (url.substring(0, 7).equalsIgnoreCase("HTTP://"))
|
||||
{
|
||||
hostBeg += 7;
|
||||
}
|
||||
else if (url.substring(0, 8).equalsIgnoreCase("HTTPS://"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int pathBeg = url.indexOf('/', hostBeg);
|
||||
|
||||
if (pathBeg < 0)
|
||||
return false;
|
||||
|
||||
int hostEnd = pathBeg;
|
||||
int portBeg = url.indexOf(':', hostBeg);
|
||||
|
||||
if (portBeg > 0 && portBeg < pathBeg)
|
||||
{
|
||||
_URL->port = url.substring(portBeg + 1, pathBeg).toInt();
|
||||
hostEnd = portBeg;
|
||||
}
|
||||
|
||||
_URL->host = new char[hostEnd - hostBeg + 1];
|
||||
strcpy(_URL->host, url.substring(hostBeg, hostEnd).c_str());
|
||||
|
||||
int queryBeg = url.indexOf('?');
|
||||
|
||||
if (queryBeg < 0)
|
||||
queryBeg = url.length();
|
||||
|
||||
_URL->path = new char[queryBeg - pathBeg + 1];
|
||||
strcpy(_URL->path, url.substring(pathBeg, queryBeg).c_str());
|
||||
_URL->query = new char[url.length() - queryBeg + 1];
|
||||
strcpy(_URL->query, url.substring(queryBeg).c_str());
|
||||
|
||||
AHTTP_LOGDEBUG2("_parseURL(): scheme+host", _URL->scheme, _URL->host);
|
||||
AHTTP_LOGDEBUG3("_parseURL(): port+path+query", _URL->port, _URL->path, _URL->query);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
bool AsyncHTTPRequest::_connect()
|
||||
{
|
||||
@ -468,11 +464,8 @@ bool AsyncHTTPRequest::_connect()
|
||||
_client = new AsyncClient();
|
||||
}
|
||||
|
||||
delete[] _connectedHost;
|
||||
|
||||
_connectedHost = new char[strlen(_URL->host) + 1];
|
||||
strcpy(_connectedHost, _URL->host);
|
||||
_connectedPort = _URL->port;
|
||||
_connectedHost = _URL.host;
|
||||
_connectedPort = _URL.port;
|
||||
|
||||
_client->onConnect([](void *obj, AsyncClient * client)
|
||||
{
|
||||
@ -496,12 +489,12 @@ bool AsyncHTTPRequest::_connect()
|
||||
|
||||
if ( ! _client->connected())
|
||||
{
|
||||
if ( ! _client->connect(_URL->host, _URL->port))
|
||||
if ( ! _client->connect(_URL.host.c_str(), _URL.port))
|
||||
{
|
||||
AHTTP_LOGDEBUG3("client.connect failed:", _URL->host, ",", _URL->port);
|
||||
AHTTP_LOGDEBUG3("client.connect failed:", _URL.host, ",", _URL.port);
|
||||
|
||||
_HTTPcode = HTTPCODE_NOT_CONNECTED;
|
||||
_setReadyState(readyStateDone);
|
||||
_HTTPcode = HttpCode::NOT_CONNECTED;
|
||||
_setReadyState(ReadyState::Done);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -525,14 +518,12 @@ bool AsyncHTTPRequest::_buildRequest()
|
||||
if ( ! _request)
|
||||
_request = new xbuf;
|
||||
|
||||
_request->write(_HTTPmethod == HTTPmethodGET ? "GET " : "POST ");
|
||||
_request->write(_URL->path);
|
||||
_request->write(_URL->query);
|
||||
_request->write(toString<String>(_HTTPmethod));
|
||||
_request->write(' ');
|
||||
_request->write(_URL.path);
|
||||
_request->write(_URL.query);
|
||||
_request->write(" HTTP/1.1\r\n");
|
||||
|
||||
delete _URL;
|
||||
|
||||
_URL = nullptr;
|
||||
header* hdr = _headers;
|
||||
|
||||
while (hdr)
|
||||
@ -546,6 +537,7 @@ bool AsyncHTTPRequest::_buildRequest()
|
||||
|
||||
delete _headers;
|
||||
_headers = nullptr;
|
||||
|
||||
_request->write("\r\n");
|
||||
|
||||
return true;
|
||||
@ -600,13 +592,13 @@ size_t AsyncHTTPRequest::_send()
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::_setReadyState(reqStates newState)
|
||||
void AsyncHTTPRequest::_setReadyState(ReadyState readyState)
|
||||
{
|
||||
if (_readyState != newState)
|
||||
if (_readyState != readyState)
|
||||
{
|
||||
_readyState = newState;
|
||||
_readyState = readyState;
|
||||
|
||||
AHTTP_LOGDEBUG1("_setReadyState :", _readyState);
|
||||
AHTTP_LOGDEBUG1("_setReadyState :", int(_readyState));
|
||||
|
||||
if (_readyStateChangeCB)
|
||||
{
|
||||
@ -639,9 +631,9 @@ void AsyncHTTPRequest::_processChunks()
|
||||
|
||||
if (chunkLength == 0)
|
||||
{
|
||||
char* connectionHdr = respHeaderValue("connection");
|
||||
const auto connectionHdr = respHeaderValue("connection");
|
||||
|
||||
if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("disconnect")) == 0))
|
||||
if (connectionHdr && connectionHdr == "disconnect")
|
||||
{
|
||||
AHTTP_LOGDEBUG("*all chunks received - closing TCP");
|
||||
|
||||
@ -655,7 +647,7 @@ void AsyncHTTPRequest::_processChunks()
|
||||
_requestEndTime = millis();
|
||||
_lastActivity = 0;
|
||||
_timeout = 0;
|
||||
_setReadyState(readyStateDone);
|
||||
_setReadyState(ReadyState::Done);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -678,7 +670,7 @@ void AsyncHTTPRequest::_onConnect(AsyncClient* client)
|
||||
|
||||
_lock;
|
||||
_client = client;
|
||||
_setReadyState(readyStateOpened);
|
||||
_setReadyState(ReadyState::Opened);
|
||||
_response = new xbuf;
|
||||
_contentLength = 0;
|
||||
_contentRead = 0;
|
||||
@ -711,7 +703,7 @@ void AsyncHTTPRequest::_onPoll(AsyncClient* client)
|
||||
if (_timeout && (millis() - _lastActivity) > (_timeout * 1000))
|
||||
{
|
||||
_client->close();
|
||||
_HTTPcode = HTTPCODE_TIMEOUT;
|
||||
_HTTPcode = HttpCode::TIMEOUT;
|
||||
|
||||
AHTTP_LOGDEBUG("_onPoll timeout");
|
||||
}
|
||||
@ -739,26 +731,25 @@ void AsyncHTTPRequest::_onDisconnect(AsyncClient* client)
|
||||
|
||||
_lock;
|
||||
|
||||
if (_readyState < readyStateOpened)
|
||||
if (_readyState < ReadyState::Opened)
|
||||
{
|
||||
_HTTPcode = HTTPCODE_NOT_CONNECTED;
|
||||
_HTTPcode = HttpCode::NOT_CONNECTED;
|
||||
}
|
||||
else if (_HTTPcode > 0 &&
|
||||
(_readyState < readyStateHdrsRecvd || (_contentRead + _response->available()) < _contentLength))
|
||||
(_readyState < ReadyState::HdrsRecvd || (_contentRead + _response->available()) < _contentLength))
|
||||
{
|
||||
_HTTPcode = HTTPCODE_CONNECTION_LOST;
|
||||
_HTTPcode = HttpCode::CONNECTION_LOST;
|
||||
}
|
||||
|
||||
delete _client;
|
||||
_client = nullptr;
|
||||
|
||||
delete[] _connectedHost;
|
||||
_connectedHost = nullptr;
|
||||
|
||||
_connectedHost = String{};
|
||||
_connectedPort = -1;
|
||||
|
||||
_requestEndTime = millis();
|
||||
_lastActivity = 0;
|
||||
_setReadyState(readyStateDone);
|
||||
_setReadyState(ReadyState::Done);
|
||||
_unlock;
|
||||
}
|
||||
|
||||
@ -781,24 +772,24 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len)
|
||||
}
|
||||
|
||||
// if headers not complete, collect them. If still not complete, just return.
|
||||
if (_readyState == readyStateOpened)
|
||||
if (_readyState == ReadyState::Opened)
|
||||
{
|
||||
if ( ! _collectHeaders())
|
||||
return;
|
||||
}
|
||||
|
||||
// If there's data in the buffer and not Done, advance readyState to Loading.
|
||||
if (_response->available() && _readyState != readyStateDone)
|
||||
if (_response->available() && _readyState != ReadyState::Done)
|
||||
{
|
||||
_setReadyState(readyStateLoading);
|
||||
_setReadyState(ReadyState::Loading);
|
||||
}
|
||||
|
||||
// If not chunked and all data read, close it up.
|
||||
if ( ! _chunked && (_response->available() + _contentRead) >= _contentLength)
|
||||
{
|
||||
char* connectionHdr = respHeaderValue("connection");
|
||||
const auto connectionHdr = respHeaderValue("connection");
|
||||
|
||||
if (connectionHdr && (strcasecmp_P(connectionHdr, PSTR("disconnect")) == 0))
|
||||
if (connectionHdr && connectionHdr == "disconnect")
|
||||
{
|
||||
AHTTP_LOGDEBUG("*all data received - closing TCP");
|
||||
|
||||
@ -812,7 +803,7 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len)
|
||||
_requestEndTime = millis();
|
||||
_lastActivity = 0;
|
||||
_timeout = 0;
|
||||
_setReadyState(readyStateDone);
|
||||
_setReadyState(ReadyState::Done);
|
||||
}
|
||||
|
||||
// If onData callback requested, do so.
|
||||
@ -844,7 +835,7 @@ bool AsyncHTTPRequest::_collectHeaders()
|
||||
// If empty line, all headers are in, advance readyState.
|
||||
if (headerLine.length() == 2)
|
||||
{
|
||||
_setReadyState(readyStateHdrsRecvd);
|
||||
_setReadyState(ReadyState::HdrsRecvd);
|
||||
}
|
||||
// If line is HTTP header, capture HTTPcode.
|
||||
else if (headerLine.substring(0, 7) == "HTTP/1.")
|
||||
@ -865,20 +856,20 @@ bool AsyncHTTPRequest::_collectHeaders()
|
||||
_addHeader(name.c_str(), value.c_str());
|
||||
}
|
||||
}
|
||||
} while (_readyState == readyStateOpened);
|
||||
} while (_readyState == ReadyState::Opened);
|
||||
|
||||
// If content-Length header, set _contentLength
|
||||
header *hdr = _getHeader("Content-Length");
|
||||
|
||||
if (hdr)
|
||||
{
|
||||
_contentLength = strtol(hdr->value, nullptr, 10);
|
||||
_contentLength = hdr->value.toInt();
|
||||
}
|
||||
|
||||
// If chunked specified, try to set _contentLength to size of first chunk
|
||||
hdr = _getHeader("Transfer-Encoding");
|
||||
|
||||
if (hdr && strcasecmp_P(hdr->value, PSTR("chunked")) == 0)
|
||||
if (hdr && hdr->value == "chunked")
|
||||
{
|
||||
AHTTP_LOGDEBUG("*transfer-encoding: chunked");
|
||||
|
||||
@ -905,7 +896,7 @@ bool AsyncHTTPRequest::_collectHeaders()
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::setReqHeader(const char* name, const char* value)
|
||||
{
|
||||
if (_readyState <= readyStateOpened && _headers)
|
||||
if (_readyState <= ReadyState::Opened && _headers)
|
||||
{
|
||||
_addHeader(name, value);
|
||||
}
|
||||
@ -914,7 +905,7 @@ void AsyncHTTPRequest::setReqHeader(const char* name, const char* value)
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::setReqHeader(const char* name, int32_t value)
|
||||
{
|
||||
if (_readyState <= readyStateOpened && _headers)
|
||||
if (_readyState <= ReadyState::Opened && _headers)
|
||||
{
|
||||
setReqHeader(name, String(value).c_str());
|
||||
}
|
||||
@ -925,7 +916,7 @@ void AsyncHTTPRequest::setReqHeader(const char* name, int32_t value)
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::setReqHeader(const char* name, const __FlashStringHelper* value)
|
||||
{
|
||||
if (_readyState <= readyStateOpened && _headers)
|
||||
if (_readyState <= ReadyState::Opened && _headers)
|
||||
{
|
||||
char* _value = _charstar(value);
|
||||
_addHeader(name, _value);
|
||||
@ -936,7 +927,7 @@ void AsyncHTTPRequest::setReqHeader(const char* name, const __FlashStringHelper*
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, const char* value)
|
||||
{
|
||||
if (_readyState <= readyStateOpened && _headers)
|
||||
if (_readyState <= ReadyState::Opened && _headers)
|
||||
{
|
||||
char* _name = _charstar(name);
|
||||
_addHeader(_name, value);
|
||||
@ -947,7 +938,7 @@ void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, const char*
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, const __FlashStringHelper* value)
|
||||
{
|
||||
if (_readyState <= readyStateOpened && _headers)
|
||||
if (_readyState <= ReadyState::Opened && _headers)
|
||||
{
|
||||
char* _name = _charstar(name);
|
||||
char* _value = _charstar(value);
|
||||
@ -960,7 +951,7 @@ void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, const __Fla
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, int32_t value)
|
||||
{
|
||||
if (_readyState <= readyStateOpened && _headers)
|
||||
if (_readyState <= ReadyState::Opened && _headers)
|
||||
{
|
||||
char* _name = _charstar(name);
|
||||
setReqHeader(_name, String(value).c_str());
|
||||
@ -973,7 +964,7 @@ void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, int32_t val
|
||||
//**************************************************************************************************************
|
||||
int AsyncHTTPRequest::respHeaderCount()
|
||||
{
|
||||
if (_readyState < readyStateHdrsRecvd)
|
||||
if (_readyState < ReadyState::HdrsRecvd)
|
||||
return 0;
|
||||
|
||||
int count = 0;
|
||||
@ -989,76 +980,69 @@ int AsyncHTTPRequest::respHeaderCount()
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
char* AsyncHTTPRequest::respHeaderName(int ndx)
|
||||
String AsyncHTTPRequest::respHeaderName(int ndx)
|
||||
{
|
||||
if (_readyState < readyStateHdrsRecvd)
|
||||
return nullptr;
|
||||
if (_readyState < ReadyState::HdrsRecvd)
|
||||
return {};
|
||||
|
||||
header* hdr = _getHeader(ndx);
|
||||
|
||||
if ( ! hdr)
|
||||
return nullptr;
|
||||
return {};
|
||||
|
||||
return hdr->name;
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
char* AsyncHTTPRequest::respHeaderValue(const char* name)
|
||||
String AsyncHTTPRequest::respHeaderValue(const String &name)
|
||||
{
|
||||
if (_readyState < readyStateHdrsRecvd)
|
||||
return nullptr;
|
||||
if (_readyState < ReadyState::HdrsRecvd)
|
||||
return {};
|
||||
|
||||
header* hdr = _getHeader(name);
|
||||
|
||||
if ( ! hdr)
|
||||
return nullptr;
|
||||
return {};
|
||||
|
||||
return hdr->value;
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
char* AsyncHTTPRequest::respHeaderValue(int ndx)
|
||||
String AsyncHTTPRequest::respHeaderValue(int ndx)
|
||||
{
|
||||
if (_readyState < readyStateHdrsRecvd)
|
||||
return nullptr;
|
||||
if (_readyState < ReadyState::HdrsRecvd)
|
||||
return {};
|
||||
|
||||
header* hdr = _getHeader(ndx);
|
||||
|
||||
if ( ! hdr)
|
||||
return nullptr;
|
||||
return {};
|
||||
|
||||
return hdr->value;
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
bool AsyncHTTPRequest::respHeaderExists(const char* name)
|
||||
bool AsyncHTTPRequest::respHeaderExists(const String &name)
|
||||
{
|
||||
if (_readyState < readyStateHdrsRecvd)
|
||||
if (_readyState < ReadyState::HdrsRecvd)
|
||||
return false;
|
||||
|
||||
header* hdr = _getHeader(name);
|
||||
|
||||
if ( ! hdr)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return _getHeader(name);
|
||||
}
|
||||
|
||||
|
||||
#if (ESP32 || ESP8266)
|
||||
|
||||
//**************************************************************************************************************
|
||||
char* AsyncHTTPRequest::respHeaderValue(const __FlashStringHelper *name)
|
||||
String AsyncHTTPRequest::respHeaderValue(const __FlashStringHelper *name)
|
||||
{
|
||||
if (_readyState < readyStateHdrsRecvd)
|
||||
return nullptr;
|
||||
if (_readyState < ReadyState::HdrsRecvd)
|
||||
return {};
|
||||
|
||||
char* _name = _charstar(name);
|
||||
header* hdr = _getHeader(_name);
|
||||
delete[] _name;
|
||||
header* hdr = _getHeader(name);
|
||||
|
||||
if ( ! hdr)
|
||||
return nullptr;
|
||||
return {};
|
||||
|
||||
return hdr->value;
|
||||
}
|
||||
@ -1066,17 +1050,10 @@ char* AsyncHTTPRequest::respHeaderValue(const __FlashStringHelper *name)
|
||||
//**************************************************************************************************************
|
||||
bool AsyncHTTPRequest::respHeaderExists(const __FlashStringHelper *name)
|
||||
{
|
||||
if (_readyState < readyStateHdrsRecvd)
|
||||
if (_readyState < ReadyState::HdrsRecvd)
|
||||
return false;
|
||||
|
||||
char* _name = _charstar(name);
|
||||
header* hdr = _getHeader(_name);
|
||||
delete[] _name;
|
||||
|
||||
if ( ! hdr)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return _getHeader(name);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1104,14 +1081,14 @@ String AsyncHTTPRequest::headers()
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_addHeader(const char* name, const char* value)
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_addHeader(const String &name, const String &value)
|
||||
{
|
||||
_lock;
|
||||
header* hdr = (header*) &_headers;
|
||||
|
||||
while (hdr->next)
|
||||
{
|
||||
if (strcasecmp(name, hdr->next->name) == 0)
|
||||
if (name.equalsIgnoreCase(hdr->next->name))
|
||||
{
|
||||
header* oldHdr = hdr->next;
|
||||
hdr->next = hdr->next->next;
|
||||
@ -1125,24 +1102,22 @@ 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);
|
||||
hdr->next->name = name;
|
||||
hdr->next->value = value;
|
||||
_unlock;
|
||||
|
||||
return hdr->next;
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_getHeader(const char* name)
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_getHeader(const String &name)
|
||||
{
|
||||
_lock;
|
||||
header* hdr = _headers;
|
||||
|
||||
while (hdr)
|
||||
{
|
||||
if (strcasecmp(name, hdr->name) == 0)
|
||||
if (name.equalsIgnoreCase(hdr->name))
|
||||
break;
|
||||
|
||||
hdr = hdr->next;
|
||||
@ -1187,5 +1162,3 @@ char* AsyncHTTPRequest::_charstar(const __FlashStringHelper * str)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // AsyncHTTPRequest_Impl_Generic_h
|
318
src/AsyncHTTPRequest.h
Normal file
318
src/AsyncHTTPRequest.h
Normal file
@ -0,0 +1,318 @@
|
||||
/****************************************************************************************************************************
|
||||
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.0
|
||||
|
||||
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).
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define AsyncHTTPRequest_Generic_version "1.0.0"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <WString.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "AsyncHTTPRequest_Debug.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
|
||||
|
||||
#if ESP32
|
||||
|
||||
#include <AsyncTCP.h>
|
||||
|
||||
#elif ESP8266
|
||||
|
||||
#include <ESPAsyncTCP.h>
|
||||
|
||||
#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"
|
||||
|
||||
#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
|
||||
|
||||
namespace HttpCode
|
||||
{
|
||||
enum
|
||||
{
|
||||
CONNECTION_REFUSED = -1,
|
||||
SEND_HEADER_FAILED = -2,
|
||||
SEND_PAYLOAD_FAILED = -3,
|
||||
NOT_CONNECTED = -4,
|
||||
CONNECTION_LOST = -5,
|
||||
NO_STREAM = -6,
|
||||
NO_HTTP_SERVER = -7,
|
||||
TOO_LESS_RAM = -8,
|
||||
ENCODING = -9,
|
||||
STREAM_WRITE = -10,
|
||||
TIMEOUT = -11,
|
||||
};
|
||||
|
||||
inline String toString(int code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case CONNECTION_REFUSED: return "CONNECTION_REFUSED";
|
||||
case SEND_HEADER_FAILED: return "SEND_HEADER_FAILED";
|
||||
case SEND_PAYLOAD_FAILED: return "SEND_PAYLOAD_FAILED";
|
||||
case NOT_CONNECTED: return "NOT_CONNECTED";
|
||||
case CONNECTION_LOST: return "CONNECTION_LOST";
|
||||
case NO_STREAM: return "NO_STREAM";
|
||||
case NO_HTTP_SERVER: return "NO_HTTP_SERVER";
|
||||
case TOO_LESS_RAM: return "TOO_LESS_RAM";
|
||||
case ENCODING: return "ENCODING";
|
||||
case STREAM_WRITE: return "STREAM_WRITE";
|
||||
case TIMEOUT: return "TIMEOUT";
|
||||
}
|
||||
|
||||
return String{code};
|
||||
}
|
||||
}
|
||||
|
||||
enum class ReadyState
|
||||
{
|
||||
Idle, // Client created, open not yet called
|
||||
Unsent, // open() has been called, not connected
|
||||
Opened, // open() has been called, connected
|
||||
HdrsRecvd, // send() called, response headers available
|
||||
Loading, // receiving, partial data available
|
||||
Done // Request complete, all data available.
|
||||
};
|
||||
|
||||
namespace {
|
||||
//! Helper utility to convert a ReadyState into a string
|
||||
//! String library agnostic, can be used with std::string or Arduino's WString
|
||||
template<typename T>
|
||||
T toString(ReadyState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case ReadyState::Idle: return "Idle";
|
||||
case ReadyState::Unsent: return "Unsent";
|
||||
case ReadyState::Opened: return "Opened";
|
||||
case ReadyState::HdrsRecvd: return "HdrsRecvd";
|
||||
case ReadyState::Loading: return "Loading";
|
||||
case ReadyState::Done: return "Done";
|
||||
}
|
||||
|
||||
return T{"Unknown ReadyState("} + int(state) + ')';
|
||||
}
|
||||
}
|
||||
|
||||
enum class HTTPmethod
|
||||
{
|
||||
GET,
|
||||
POST
|
||||
};
|
||||
|
||||
namespace {
|
||||
//! Helper utility to convert a HTTPmethod into a string
|
||||
//! String library agnostic, can be used with std::string or Arduino's WString
|
||||
template<typename T>
|
||||
T toString(HTTPmethod method)
|
||||
{
|
||||
switch (method)
|
||||
{
|
||||
case HTTPmethod::GET: return "GET";
|
||||
case HTTPmethod::POST: return "POST";
|
||||
}
|
||||
|
||||
return T{"Unknown HTTPmethod("} + int(method) + ')';
|
||||
}
|
||||
}
|
||||
|
||||
struct URL
|
||||
{
|
||||
String scheme;
|
||||
String user;
|
||||
String pwd;
|
||||
String host;
|
||||
int port;
|
||||
String path;
|
||||
String query;
|
||||
String fragment;
|
||||
|
||||
String toString() const
|
||||
{
|
||||
return scheme + user + pwd + host + ':' + port + path + query + fragment;
|
||||
}
|
||||
};
|
||||
|
||||
std::optional<URL> parseURL(const String &url);
|
||||
|
||||
class AsyncHTTPRequest
|
||||
{
|
||||
using callback_arg_t = void*;
|
||||
|
||||
struct header
|
||||
{
|
||||
header* next{};
|
||||
String name;
|
||||
String value;
|
||||
|
||||
~header()
|
||||
{
|
||||
delete next;
|
||||
}
|
||||
};
|
||||
|
||||
using readyStateChangeCB = std::function<void(callback_arg_t, AsyncHTTPRequest*, ReadyState readyState)>;
|
||||
using onDataCB = std::function<void(void*, AsyncHTTPRequest*, size_t available)>;
|
||||
|
||||
public:
|
||||
~AsyncHTTPRequest();
|
||||
|
||||
|
||||
//External functions in typical order of use:
|
||||
//__________________________________________________________________________________________________________*/
|
||||
void setDebug(bool); // Turn debug message on/off
|
||||
bool debug() const; // is debug on or off?
|
||||
|
||||
bool open(const URL &url, HTTPmethod method = HTTPmethod::GET); // Initiate a request
|
||||
void onReadyStateChange(readyStateChangeCB, callback_arg_t arg = 0); // Optional event handler for ready state change
|
||||
void onReadyStateChangeArg(callback_arg_t arg = 0); // set event handlers arg
|
||||
// or you can simply poll readyState()
|
||||
void setTimeout(int seconds); // 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
|
||||
|
||||
ReadyState readyState() const; // Return the ready state
|
||||
|
||||
int respHeaderCount(); // Retrieve count of response headers
|
||||
String respHeaderName(int index); // Return header name by index
|
||||
String respHeaderValue(int index); // Return header value by index
|
||||
String respHeaderValue(const String &name); // Return header value by name
|
||||
|
||||
bool respHeaderExists(const String &name); // Does header exist by name?
|
||||
|
||||
#if (ESP32 || ESP8266)
|
||||
String respHeaderValue(const __FlashStringHelper *name);
|
||||
bool respHeaderExists(const __FlashStringHelper *name);
|
||||
#endif
|
||||
|
||||
const URL &url() const { return _URL; }
|
||||
|
||||
String headers(); // Return all headers as String
|
||||
|
||||
void onData(onDataCB, void* arg = 0); // Notify when min data is available
|
||||
size_t available() const; // response available
|
||||
size_t responseLength() const; // indicated response length or sum of chunks to date
|
||||
int responseHTTPcode() const; // 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() const; // Elapsed time of in progress transaction or last completed (ms)
|
||||
String version() const; // Version of AsyncHTTPRequest
|
||||
//___________________________________________________________________________________________________________________________________
|
||||
|
||||
private:
|
||||
HTTPmethod _HTTPmethod;
|
||||
|
||||
ReadyState _readyState{ReadyState::Idle};
|
||||
|
||||
int16_t _HTTPcode{0}; // HTTP response code or (negative) exception code
|
||||
bool _chunked{false}; // Processing chunked response
|
||||
bool _debug{DEBUG_IOTA_HTTP_SET}; // Debug state
|
||||
uint32_t _timeout{DEFAULT_RX_TIMEOUT}; // Default or user overide RxTimeout in seconds
|
||||
uint32_t _lastActivity{0}; // Time of last activity
|
||||
uint32_t _requestStartTime{0}; // Time last open() issued
|
||||
uint32_t _requestEndTime{0}; // Time of last disconnect
|
||||
URL _URL{}; // -> URL data structure
|
||||
String _connectedHost; // Host when connected
|
||||
int _connectedPort{-1}; // Port when connected
|
||||
AsyncClient* _client{nullptr}; // ESPAsyncTCP AsyncClient instance
|
||||
size_t _contentLength{0}; // content-length header value or sum of chunk headers
|
||||
size_t _contentRead{0}; // number of bytes retrieved by user since last open()
|
||||
readyStateChangeCB _readyStateChangeCB{}; // optional callback for readyState change
|
||||
callback_arg_t _readyStateChangeCBarg{}; // associated user argument
|
||||
onDataCB _onDataCB{nullptr}; // optional callback when data received
|
||||
void* _onDataCBarg{nullptr}; // associated user argument
|
||||
|
||||
#ifdef ESP32
|
||||
SemaphoreHandle_t threadLock{xSemaphoreCreateRecursiveMutex()};
|
||||
#endif
|
||||
|
||||
// request and response String buffers and header list (same queue for request and response).
|
||||
|
||||
xbuf* _request{nullptr}; // Tx data buffer
|
||||
xbuf* _response{nullptr}; // Rx data buffer for headers
|
||||
xbuf* _chunks{nullptr}; // First stage for chunked response
|
||||
header* _headers{nullptr}; // request or (readyState > readyStateHdrsRcvd) response headers
|
||||
|
||||
// Protected functions
|
||||
|
||||
header* _addHeader(const String &name, const String &value);
|
||||
header* _getHeader(const String &name);
|
||||
header* _getHeader(int idx);
|
||||
bool _buildRequest();
|
||||
void _processChunks();
|
||||
bool _connect();
|
||||
size_t _send();
|
||||
void _setReadyState(ReadyState readyState);
|
||||
|
||||
#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();
|
||||
};
|
@ -24,8 +24,7 @@
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#ifndef AsyncHTTPRequest_Debug_STM32_H
|
||||
#define AsyncHTTPRequest_Debug_STM32_H
|
||||
#pragma once
|
||||
|
||||
#ifdef ASYNC_HTTP_DEBUG_PORT
|
||||
#define A_DBG_PORT ASYNC_HTTP_DEBUG_PORT
|
||||
@ -67,5 +66,3 @@
|
||||
#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); }
|
||||
|
||||
#endif // AsyncHTTPRequest_Debug_STM32_H
|
@ -1,269 +0,0 @@
|
||||
/****************************************************************************************************************************
|
||||
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.0
|
||||
|
||||
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).
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#ifndef AsyncHTTPRequest_Generic_h
|
||||
#define AsyncHTTPRequest_Generic_h
|
||||
|
||||
#define AsyncHTTPRequest_Generic_version "1.0.0"
|
||||
|
||||
#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
|
||||
|
||||
#if ESP32
|
||||
|
||||
#include <AsyncTCP.h>
|
||||
#define _lock xSemaphoreTakeRecursive(threadLock,portMAX_DELAY)
|
||||
#define _unlock xSemaphoreGiveRecursive(threadLock)
|
||||
|
||||
#elif ESP8266
|
||||
|
||||
#include <ESPAsyncTCP.h>
|
||||
#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 _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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
delete[] scheme;
|
||||
delete[] user;
|
||||
delete[] pwd;
|
||||
delete[] host;
|
||||
delete[] path;
|
||||
delete[] query;
|
||||
delete[] 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"
|
||||
|
||||
#endif // AsyncHTTPRequest_Generic_h
|
@ -27,7 +27,7 @@
|
||||
#ifndef xbuf_Impl_h
|
||||
#define xbuf_Impl_h
|
||||
|
||||
//#include "utility/xbuf.h"
|
||||
#include "utility/xbuf.h"
|
||||
|
||||
xbuf::xbuf(const uint16_t segSize) : _head(nullptr), _tail(nullptr), _used(0), _free(0), _offset(0)
|
||||
{
|
@ -148,6 +148,4 @@ class xbuf: public Print
|
||||
|
||||
};
|
||||
|
||||
#include "utility/xbuf_Impl.h"
|
||||
|
||||
#endif // xbuf_h
|
||||
|
Reference in New Issue
Block a user