3#include "AudioToolsConfig.h"
9# include <WiFiClientSecure.h>
13#include "AudioTools/CoreAudio/AudioBasic/Str.h"
14#include "AudioTools/CoreAudio/AudioHttp/AbstractURLStream.h"
15#include "AudioTools/CoreAudio/AudioHttp/HttpRequest.h"
16#include "AudioTools/CoreAudio/AudioHttp/ICYStreamT.h"
17#include "AudioTools/CoreAudio/AudioHttp/URLStreamBufferedT.h"
34 URLStream(
int readBufferSize = DEFAULT_BUFFER_SIZE) {
39 URLStream(
Client& clientPar,
int readBufferSize = DEFAULT_BUFFER_SIZE) {
45 URLStream(
const char* network,
const char* password,
46 int readBufferSize = DEFAULT_BUFFER_SIZE) {
58#ifdef USE_WIFI_CLIENT_SECURE
59 if (clientSecure !=
nullptr) {
61 clientSecure =
nullptr;
65 if (clientInsecure !=
nullptr) {
66 delete clientInsecure;
67 clientInsecure =
nullptr;
76 void setSSID(
const char* ssid)
override { this->network = ssid; }
79 void setPassword(
const char* password)
override { this->password = password; }
83 read_buffer_size = readBufferSize;
87 virtual bool begin(
const char*
urlStr,
const char* acceptMime =
nullptr,
88 MethodID action = GET,
const char* reqMime =
"",
89 const char* reqData =
"")
override {
90 LOGI(
"%s: %s", LOG_METHOD,
urlStr);
91 if (!preProcess(
urlStr, acceptMime)) {
92 LOGE(
"preProcess failed");
95 int result = process<const char*>(action, url, reqMime, reqData);
97 size = request.contentLength();
98 LOGI(
"contentLength: %d", (
int)size);
99 if (size >= 0 && wait_for_data) {
104 active = result == 200;
105 LOGI(
"==> http status: %d", result);
87 virtual bool begin(
const char*
urlStr,
const char* acceptMime =
nullptr, {
…}
111 MethodID action,
const char* reqMime,
Stream& reqData,
113 LOGI(
"%s: %s", LOG_METHOD,
urlStr);
114 if (!preProcess(
urlStr, acceptMime)) {
115 LOGE(
"preProcess failed");
118 int result = process<Stream&>(action, url, reqMime, reqData, len);
120 size = request.contentLength();
121 LOGI(
"size: %d", (
int)size);
122 if (size >= 0 && wait_for_data) {
127 active = result == 200;
128 LOGI(
"==> http status: %d", result);
132 virtual void end()
override {
133 if (active) request.stop();
138 virtual int available()
override {
139 if (!active)
return 0;
141 int result = request.available();
142 LOGD(
"available: %d", result);
146 virtual size_t readBytes(uint8_t* data,
size_t len)
override {
147 if (!active)
return 0;
149 int read = request.read((uint8_t*)&data[0], len);
154 LOGD(
"readBytes %d -> %d", (
int)len, read);
158 virtual int read()
override {
159 if (!active)
return -1;
161 read_buffer.resize(read_buffer_size);
165 return isEOS() ? -1 : read_buffer[read_pos++];
168 virtual int peek()
override {
169 if (!active)
return -1;
171 read_buffer.resize(read_buffer_size);
174 return isEOS() ? -1 : read_buffer[read_pos];
177 virtual void flush()
override {}
179 virtual size_t write(uint8_t)
override {
return not_supported(0); }
181 virtual size_t write(
const uint8_t*,
size_t len)
override {
182 return not_supported(0);
188 operator bool()
override {
return active && request.
isReady(); }
204 httpRequest().setConnection(close ? CON_CLOSE : CON_KEEP_ALIVE);
211 read_buffer.resize(0);
218 request.
header().put(key, value);
222 return request.reply().get(key);
231 void setWaitForData(
bool flag) { wait_for_data = flag; }
239 uint32_t end =
millis() + timeout;
240 if (request.available() == 0) {
241 LOGI(
"Request written ... waiting for reply");
242 while (request.available() == 0) {
243 if (
millis() > end)
break;
245 if (request.reply().statusCode() >= 300) {
246 LOGE(
"Error code recieved ... stop waiting for reply");
252 LOGD(
"available: %d", request.available());
253 return request.available() > 0;
261 #ifdef USE_WIFI_CLIENT_SECURE
262 if (clientSecure!=
nullptr) clientSecure->setCACert(cert);
274 uint16_t read_buffer_size = DEFAULT_BUFFER_SIZE;
278 bool wait_for_data =
true;
280 const char* network =
nullptr;
281 const char* password =
nullptr;
282 Client* client =
nullptr;
284 WiFiClient* clientInsecure =
nullptr;
286#ifdef USE_WIFI_CLIENT_SECURE
287 WiFiClientSecure* clientSecure =
nullptr;
289 int clientTimeout = URL_CLIENT_TIMEOUT;
290 unsigned long handshakeTimeout = URL_HANDSHAKE_TIMEOUT;
291 bool is_power_save =
false;
293 bool preProcess(
const char*
urlStr,
const char* acceptMime) {
296 url.setUrl(url_str.
c_str());
304 if (client ==
nullptr){
306 LOGE(
"Not connected");
313 if (acceptMime !=
nullptr) {
314 request.setAcceptMime(acceptMime);
318 Client& client =
getClient(url.isSecure());
319 request.setClient(client);
322 client.setTimeout(clientTimeout / 1000);
325#if defined(ESP32) && defined(USE_WIFI_CLIENT_SECURE)
327 if (clientSecure !=
nullptr) {
328 clientSecure->setHandshakeTimeout(handshakeTimeout);
332 if (!is_power_save) {
333 esp_wifi_set_ps(WIFI_PS_NONE);
341 template <
typename T>
342 int process(MethodID action,
Url& url,
const char* reqMime, T reqData,
346 const char* icy = request.
header().get(
"Icy-MetaData");
348 int status_code = request.process(action, url, reqMime, reqData, len);
351 const char* redirect_url = request.reply().get(LOCATION);
352 if (redirect_url !=
nullptr) {
353 LOGW(
"Redirected to: %s", redirect_url);
354 url.setUrl(redirect_url);
357 request.setClient(*p_client);
359 request.
header().put(
"Icy-MetaData", icy);
361 status_code = request.process(action, url, reqMime, reqData, len);
363 LOGE(
"Location is null");
342 int process(MethodID action,
Url& url,
const char* reqMime, T reqData, {
…}
372#ifdef USE_WIFI_CLIENT_SECURE
374 if (clientSecure ==
nullptr) {
375 clientSecure =
new WiFiClientSecure();
376 clientSecure->setInsecure();
378 LOGI(
"WiFiClientSecure");
379 return *clientSecure;
383 if (clientInsecure ==
nullptr) {
384 clientInsecure =
new WiFiClient();
387 return *clientInsecure;
389 if (client ==
nullptr){
390 LOGE(
"Client not set");
397 inline void fillBuffer() {
400 read_size = readBytes(&read_buffer[0], read_buffer_size);
405 inline bool isEOS() {
return read_pos >= read_size; }
409 if (network !=
nullptr && password !=
nullptr &&
410 WiFi.status() != WL_CONNECTED) {
412 WiFi.begin(network, password);
413 while (WiFi.status() != WL_CONNECTED) {
419 return WiFi.status() == WL_CONNECTED;
421 return WiFi.status() == WL_CONNECTED;
428using ICYStream = ICYStreamT<URLStream>;
430#if defined(USE_CONCURRENCY)
431using URLStreamBuffered = URLStreamBufferedT<URLStream>;
432using ICYStreamBuffered = URLStreamBufferedT<ICYStream>;
void stop()
Public generic methods.
Definition AudioRuntime.h:14