3#include "AudioConfig.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"
45 URLStream(
const char* network,
const char* password,
58#ifdef USE_WIFI_CLIENT_SECURE
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; }
89 const char*
reqData =
"")
override {
90 LOGI(
"%s: %s", LOG_METHOD, urlStr);
92 LOGE(
"preProcess failed");
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);
106#if USE_AUDIO_LOGGING && !defined(USE_IDF_LOGGER)
107 custom_log_level.reset();
116 LOGI(
"%s: %s", LOG_METHOD, urlStr);
118 LOGE(
"preProcess failed");
123 size = request.contentLength();
124 LOGI(
"size: %d", (
int)size);
125 if (size >= 0 && wait_for_data) {
130 active = result == 200;
131 LOGI(
"==> http status: %d", result);
132#if USE_AUDIO_LOGGING && !defined(USE_IDF_LOGGER)
133 custom_log_level.reset();
138 virtual void end()
override {
139 if (active) request.stop();
144 virtual int available()
override {
145 if (!active)
return 0;
147 int result = request.available();
148 LOGD(
"available: %d", result);
152 virtual size_t readBytes(uint8_t* data,
size_t len)
override {
153 if (!active)
return 0;
155 int read = request.read((uint8_t*)&data[0], len);
160 LOGD(
"readBytes %d -> %d", (
int)len, read);
164 virtual int read()
override {
165 if (!active)
return -1;
167 read_buffer.resize(read_buffer_size);
171 return isEOS() ? -1 : read_buffer[read_pos++];
174 virtual int peek()
override {
175 if (!active)
return -1;
177 read_buffer.resize(read_buffer_size);
180 return isEOS() ? -1 : read_buffer[read_pos];
183 virtual void flush()
override {}
185 virtual size_t write(uint8_t)
override {
return not_supported(0); }
187 virtual size_t write(
const uint8_t*,
size_t len)
override {
188 return not_supported(0);
194 operator bool() {
return active && request.
isReady(); }
210 httpRequest().setConnection(close ? CON_CLOSE : CON_KEEP_ALIVE);
217 read_buffer.resize(0);
224 request.
header().put(key, value);
228 return request.reply().get(key);
237 void setWaitForData(
bool flag) { wait_for_data =
flag; }
239 int contentLength() {
return size; }
241 size_t totalRead() {
return total_read; }
247 if (request.available() == 0) {
248 LOGI(
"Request written ... waiting for reply");
249 while (request.available() == 0) {
250 if (
millis() > end)
break;
252 if (request.reply().statusCode() >= 300) {
253 LOGE(
"Error code recieved ... stop waiting for reply");
259 LOGD(
"available: %d", request.available());
260 return request.available() > 0;
263#if USE_AUDIO_LOGGING && !defined(USE_IDF_LOGGER)
265 void setLogLevel(AudioLogger::LogLevel
level) { custom_log_level.set(
level); }
267 const char* urlStr() {
return url_str.
c_str(); }
271 #ifdef USE_WIFI_CLIENT_SECURE
278#if USE_AUDIO_LOGGING && !defined(USE_IDF_LOGGER)
287 uint16_t read_buffer_size = DEFAULT_BUFFER_SIZE;
291 bool wait_for_data =
true;
293 const char* network =
nullptr;
294 const char* password =
nullptr;
295 Client* client =
nullptr;
297 WiFiClient* clientInsecure =
nullptr;
299#ifdef USE_WIFI_CLIENT_SECURE
300 WiFiClientSecure* clientSecure =
nullptr;
302 int clientTimeout = URL_CLIENT_TIMEOUT;
303 unsigned long handshakeTimeout = URL_HANDSHAKE_TIMEOUT;
304 bool is_power_save =
false;
306 bool preProcess(
const char* urlStr,
const char* acceptMime) {
308#if USE_AUDIO_LOGGING && !defined(USE_IDF_LOGGER)
309 custom_log_level.set();
312 url.setUrl(url_str.
c_str());
320 if (client ==
nullptr){
322 LOGE(
"Not connected");
329 if (acceptMime !=
nullptr) {
330 request.setAcceptMime(acceptMime);
334 Client& client =
getClient(url.isSecure());
335 request.setClient(client);
338 client.setTimeout(clientTimeout / 1000);
341#if defined(ESP32) && defined(USE_WIFI_CLIENT_SECURE)
343 if (clientSecure !=
nullptr) {
344 clientSecure->setHandshakeTimeout(handshakeTimeout);
348 if (!is_power_save) {
349 esp_wifi_set_ps(WIFI_PS_NONE);
357 template <
typename T>
362 const char* icy = request.
header().get(
"Icy-MetaData");
366 while (request.reply().isRedirectStatus()) {
367 const char*
redirect_url = request.reply().get(LOCATION);
373 request.setClient(*p_client);
375 request.
header().put(
"Icy-MetaData", icy);
379 LOGE(
"Location is null");
388#ifdef USE_WIFI_CLIENT_SECURE
394 LOGI(
"WiFiClientSecure");
399 if (clientInsecure ==
nullptr) {
403 return *clientInsecure;
405 if (client ==
nullptr){
406 LOGE(
"Client not set");
413 inline void fillBuffer() {
416 read_size = readBytes(&read_buffer[0], read_buffer_size);
421 inline bool isEOS() {
return read_pos >= read_size; }
425 if (network !=
nullptr && password !=
nullptr &&
426 WiFi.status() != WL_CONNECTED) {
428 WiFi.begin(network, password);
429 while (WiFi.status() != WL_CONNECTED) {
435 return WiFi.status() == WL_CONNECTED;
437 return WiFi.status() == WL_CONNECTED;
444using ICYStream = ICYStreamT<URLStream>;
446#if defined(USE_CONCURRENCY)
447using URLStreamBuffered = URLStreamBufferedT<URLStream>;
448using ICYStreamBuffered = URLStreamBufferedT<ICYStream>;
void stop()
Public generic methods.
Definition AudioRuntime.h:28