3 #include "AudioConfig.h"
9 #include <WiFiClientSecure.h>
13 #include "AbstractURLStream.h"
14 #include "HttpRequest.h"
15 #include "AudioTools/CoreAudio/AudioBasic/Str.h"
28 URLStream(
int readBufferSize = DEFAULT_BUFFER_SIZE) {
30 setReadBufferSize(readBufferSize);
33 URLStream(
Client& clientPar,
int readBufferSize = DEFAULT_BUFFER_SIZE) {
35 setReadBufferSize(readBufferSize);
39 URLStream(
const char* network,
const char* password,
40 int readBufferSize = DEFAULT_BUFFER_SIZE) {
42 setReadBufferSize(readBufferSize);
52 #ifdef USE_WIFI_CLIENT_SECURE
53 if (clientSecure !=
nullptr) {
55 clientSecure =
nullptr;
59 if (clientInsecure !=
nullptr) {
60 delete clientInsecure;
61 clientInsecure =
nullptr;
70 void setSSID(
const char* ssid)
override { this->network = ssid; }
73 void setPassword(
const char* password)
override { this->password = password; }
75 void setReadBufferSize(
int readBufferSize) {
76 read_buffer_size = readBufferSize;
80 virtual bool begin(
const char* urlStr,
const char* acceptMime =
nullptr,
81 MethodID action = GET,
const char* reqMime =
"",
82 const char* reqData =
"")
override {
83 LOGI(
"%s: %s", LOG_METHOD, urlStr);
84 if (!preProcess(urlStr, acceptMime)) {
85 LOGE(
"preProcess failed");
88 int result = process<const char*>(action, url, reqMime, reqData);
90 size = request.contentLength();
91 LOGI(
"size: %d", (
int)size);
92 if (size >= 0 && wait_for_data) {
97 active = result == 200;
98 LOGI(
"==> http status: %d", result);
99 custom_log_level.reset();
105 virtual bool begin(
const char* urlStr,
const char* acceptMime,
106 MethodID action,
const char* reqMime,
Stream& reqData,
108 LOGI(
"%s: %s", LOG_METHOD, urlStr);
109 if (!preProcess(urlStr, acceptMime)) {
110 LOGE(
"preProcess failed");
113 int result = process<Stream&>(action, url, reqMime, reqData, len);
115 size = request.contentLength();
116 LOGI(
"size: %d", (
int)size);
117 if (size >= 0 && wait_for_data) {
122 active = result == 200;
123 LOGI(
"==> http status: %d", result);
124 custom_log_level.reset();
129 virtual void end()
override {
130 if (active) request.stop();
135 virtual int available()
override {
136 if (!active || !request)
return 0;
138 int result = request.available();
139 LOGD(
"available: %d", result);
143 virtual size_t readBytes(uint8_t* data,
size_t len)
override {
144 if (!active || !request)
return 0;
146 int read = request.read((uint8_t*)&data[0], len);
151 LOGD(
"readBytes %d -> %d", (
int)len, read);
155 virtual int read()
override {
156 if (!active)
return -1;
158 read_buffer.resize(read_buffer_size);
162 return isEOS() ? -1 : read_buffer[read_pos++];
165 virtual int peek()
override {
166 if (!active)
return -1;
168 read_buffer.resize(read_buffer_size);
171 return isEOS() ? -1 : read_buffer[read_pos];
174 virtual void flush()
override {}
176 virtual size_t write(uint8_t)
override {
return not_supported(0); }
178 virtual size_t write(
const uint8_t*,
size_t len)
override {
179 return not_supported(0);
185 operator bool() {
return active && request.
isReady(); }
201 httpRequest().setConnection(close ? CON_CLOSE : CON_KEEP_ALIVE);
208 read_buffer.resize(0);
215 request.
header().put(header, value);
224 void setWaitForData(
bool flag) { wait_for_data = flag; }
226 int contentLength() {
return size; }
228 size_t totalRead() {
return total_read; }
233 uint32_t end =
millis() + timeout;
234 if (request.available() == 0) {
235 LOGI(
"Request written ... waiting for reply");
236 while (request.available() == 0) {
237 if (
millis() > end)
break;
239 if (request.reply().statusCode() >= 300) {
240 LOGE(
"Error code recieved ... stop waiting for reply");
246 LOGD(
"available: %d", request.available());
247 return request.available() > 0;
251 void setLogLevel(AudioLogger::LogLevel level) { custom_log_level.set(level); }
253 const char* urlStr() {
return url_str.
c_str(); }
257 CustomLogLevel custom_log_level;
263 Vector<uint8_t> read_buffer{0};
264 uint16_t read_buffer_size = DEFAULT_BUFFER_SIZE;
268 bool wait_for_data =
true;
270 const char* network =
nullptr;
271 const char* password =
nullptr;
272 Client* client =
nullptr;
274 WiFiClient* clientInsecure =
nullptr;
276 #ifdef USE_WIFI_CLIENT_SECURE
277 WiFiClientSecure* clientSecure =
nullptr;
279 int clientTimeout = URL_CLIENT_TIMEOUT;
280 unsigned long handshakeTimeout = URL_HANDSHAKE_TIMEOUT;
281 bool is_power_save =
false;
283 bool preProcess(
const char* urlStr,
const char* acceptMime) {
285 custom_log_level.set();
287 url.setUrl(url_str.c_str());
295 if (client ==
nullptr){
297 LOGE(
"Not connected");
304 if (acceptMime !=
nullptr) {
305 request.setAcceptMime(acceptMime);
309 Client& client =
getClient(url.isSecure());
310 request.setClient(client);
313 client.setTimeout(clientTimeout / 1000);
314 request.setTimeout(clientTimeout);
318 if (clientSecure !=
nullptr) {
319 clientSecure->setHandshakeTimeout(handshakeTimeout);
323 if (!is_power_save) {
324 esp_wifi_set_ps(WIFI_PS_NONE);
331 template <
typename T>
332 int process(MethodID action,
Url& url,
const char* reqMime, T reqData,
336 const char* icy = request.header().get(
"Icy-MetaData");
338 int status_code = request.process(action, url, reqMime, reqData, len);
340 while (request.reply().isRedirectStatus()) {
341 const char* redirect_url = request.reply().get(LOCATION);
342 if (redirect_url !=
nullptr) {
343 LOGW(
"Redirected to: %s", redirect_url);
344 url.setUrl(redirect_url);
347 request.setClient(*p_client);
349 request.header().put(
"Icy-MetaData", icy);
351 status_code = request.process(action, url, reqMime, reqData, len);
353 LOGE(
"Location is null");
362 #ifdef USE_WIFI_CLIENT_SECURE
364 if (clientSecure ==
nullptr) {
365 clientSecure =
new WiFiClientSecure();
366 clientSecure->setInsecure();
368 LOGI(
"WiFiClientSecure");
369 return *clientSecure;
373 if (clientInsecure ==
nullptr) {
374 clientInsecure =
new WiFiClient();
377 return *clientInsecure;
379 if (client ==
nullptr){
380 LOGE(
"Client not set");
387 inline void fillBuffer() {
390 read_size = readBytes(&read_buffer[0], read_buffer_size);
395 inline bool isEOS() {
return read_pos >= read_size; }
399 if (network !=
nullptr && password !=
nullptr &&
400 WiFi.status() != WL_CONNECTED) {
402 WiFi.begin(network, password);
403 while (WiFi.status() != WL_CONNECTED) {
409 return WiFi.status() == WL_CONNECTED;
411 return WiFi.status() == WL_CONNECTED;
void stop()
Public generic methods.
Definition: AudioRuntime.h:27