66#include " AudioTools/CoreAudio/AudioHttp/URLStreamBufferedT.h"
77#include " esp_crt_bundle.h"
88#include " esp_http_client.h"
9+ #include " esp_idf_version.h"
910#include " esp_system.h"
1011#include " esp_wifi.h"
1112#include " nvs_flash.h"
@@ -139,9 +140,8 @@ class WiFiESP32 {
139140
140141} static IDF_WIFI;
141142
142-
143143class URLStreamESP32 ;
144- static URLStreamESP32 * actualURLStreamESP32 = nullptr ;
144+ static URLStreamESP32* actualURLStreamESP32 = nullptr ;
145145
146146/* *
147147 * @brief URLStream using the ESP32 IDF API.
@@ -217,184 +217,190 @@ class URLStreamESP32 : public AbstractURLStream {
217217 http_config.cert_pem = (const char *)pem_cert;
218218 http_config.cert_len = pem_cert_len;
219219 } else {
220+ #if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 3, 7) && defined(ARDUINO)
221+ http_config.crt_bundle_attach = arduino_esp_crt_bundle_attach;
222+ #else
220223 http_config.crt_bundle_attach = esp_crt_bundle_attach;
221- }
222-
223- switch (action) {
224- case GET:
225- http_config.method = HTTP_METHOD_GET;
226- break ;
227- case POST:
228- http_config.method = HTTP_METHOD_POST;
229- break ;
230- case PUT:
231- http_config.method = HTTP_METHOD_PUT;
232- break ;
233- case DELETE:
234- http_config.method = HTTP_METHOD_DELETE;
235- break ;
236- default :
237- LOGE (" Unsupported action: %d" , action);
238- break ;
239- }
224+ #endif }
240225
241- // Init only the first time
242- if (client_handle == nullptr ) {
243- client_handle = esp_http_client_init (&http_config);
244- }
245-
246- // process header parameters
247- if (!StrView (acceptMime).isEmpty ()) addRequestHeader (ACCEPT, acceptMime);
248- if (!StrView (reqMime).isEmpty ()) addRequestHeader (CONTENT_TYPE, reqMime);
249- List<HttpHeaderLine*>& lines = request.header ().getHeaderLines ();
250- for (auto it = lines.begin (); it != lines.end (); ++it) {
251- if ((*it)->active ) {
252- esp_http_client_set_header (client_handle, (*it)->key .c_str (),
253- (*it)->value .c_str ());
226+ switch (action) {
227+ case GET:
228+ http_config.method = HTTP_METHOD_GET;
229+ break ;
230+ case POST:
231+ http_config.method = HTTP_METHOD_POST;
232+ break ;
233+ case PUT:
234+ http_config.method = HTTP_METHOD_PUT;
235+ break ;
236+ case DELETE:
237+ http_config.method = HTTP_METHOD_DELETE;
238+ break ;
239+ default :
240+ LOGE (" Unsupported action: %d" , action);
241+ break ;
254242 }
255- }
256-
257- // Open http
258- if (esp_http_client_open (client_handle, 0 ) != ESP_OK) {
259- LOGE (" esp_http_client_open" );
260- return false ;
261- }
262243
263- // Determine the result
264- int content_length = esp_http_client_fetch_headers (client_handle);
265- int status_code = esp_http_client_get_status_code (client_handle );
266- LOGI ( " status_code: %d / content_length: %d " , status_code, content_length);
244+ // Init only the first time
245+ if (client_handle == nullptr ) {
246+ client_handle = esp_http_client_init (&http_config );
247+ }
267248
268- // Process post/put data
269- StrView data (reqData);
270- if (!data.isEmpty ()) {
271- write ((const uint8_t *)reqData, data.length ());
272- }
249+ // process header parameters
250+ if (!StrView (acceptMime).isEmpty ()) addRequestHeader (ACCEPT, acceptMime);
251+ if (!StrView (reqMime).isEmpty ()) addRequestHeader (CONTENT_TYPE, reqMime);
252+ List<HttpHeaderLine*>& lines = request.header ().getHeaderLines ();
253+ for (auto it = lines.begin (); it != lines.end (); ++it) {
254+ if ((*it)->active ) {
255+ esp_http_client_set_header (client_handle, (*it)->key .c_str (),
256+ (*it)->value .c_str ());
257+ }
258+ }
273259
274- return status_code == 200 ;
275- }
276- // ends the request
277- virtual void end () override {
278- esp_http_client_close (client_handle);
279- esp_http_client_cleanup (client_handle);
280- }
260+ // Open http
261+ if (esp_http_client_open (client_handle, 0 ) != ESP_OK) {
262+ LOGE (" esp_http_client_open" );
263+ return false ;
264+ }
281265
282- // / Writes are not supported
283- int availableForWrite () override { return 1024 ; }
266+ // Determine the result
267+ int content_length = esp_http_client_fetch_headers (client_handle);
268+ int status_code = esp_http_client_get_status_code (client_handle);
269+ LOGI (" status_code: %d / content_length: %d" , status_code, content_length);
284270
285- // / Sets the ssid that will be used for logging in (when calling begin)
286- virtual void setSSID (const char * ssid) { this ->ssid = ssid; }
271+ // Process post/put data
272+ StrView data (reqData);
273+ if (!data.isEmpty ()) {
274+ write ((const uint8_t *)reqData, data.length ());
275+ }
287276
288- // / Sets the password that will be used for logging in (when calling begin)
289- virtual void setPassword (const char * password) { this ->password = password; }
277+ return status_code == 200 ;
278+ }
279+ // ends the request
280+ virtual void end () override {
281+ esp_http_client_close (client_handle);
282+ esp_http_client_cleanup (client_handle);
283+ }
290284
291- // / Sets the power save mode (default false)!
292- virtual void setPowerSave (bool ps) {
293- IDF_WIFI.setPowerSave (ps ? WIFI_PS_MAX_MODEM : WIFI_PS_NONE);
294- }
285+ // / Writes are not supported
286+ int availableForWrite () override { return 1024 ; }
295287
296- size_t write (const uint8_t * data, size_t len) override {
297- TRACED ();
298- return esp_http_client_write (client_handle, (const char *)data, len);
299- }
288+ // / Sets the ssid that will be used for logging in (when calling begin)
289+ virtual void setSSID (const char * ssid) { this ->ssid = ssid; }
300290
301- size_t readBytes ( uint8_t * data, size_t len) override {
302- TRACED ();
303- return esp_http_client_read (client_handle, ( char *)data, len) ;
304- }
291+ // / Sets the password that will be used for logging in (when calling begin)
292+ virtual void setPassword ( const char * password) {
293+ this -> password = password ;
294+ }
305295
306- // / Adds/Updates a request header
307- void addRequestHeader (const char * key, const char * value) override {
308- TRACED ();
309- request.addRequestHeader (key, value);
310- }
311- // / Provides a header entry
312- const char * getReplyHeader (const char * key) override {
313- return request.getReplyHeader (key);
314- }
296+ // / Sets the power save mode (default false)!
297+ virtual void setPowerSave (bool ps) {
298+ IDF_WIFI.setPowerSave (ps ? WIFI_PS_MAX_MODEM : WIFI_PS_NONE);
299+ }
315300
316- // / Define the Root PEM Certificate for SSL: Method compatible with Arduino
317- // / WiFiClientSecure API
318- void setCACert (const char * cert) override {
319- int len = strlen (cert);
320- setCACert ((const uint8_t *)cert, len + 1 );
321- }
301+ size_t write (const uint8_t * data, size_t len) override {
302+ TRACED ();
303+ return esp_http_client_write (client_handle, (const char *)data, len);
304+ }
322305
323- // / Defines the read buffer size
324- void setReadBufferSize (int size) { buffer_size = size; }
306+ size_t readBytes (uint8_t * data, size_t len) override {
307+ TRACED ();
308+ return esp_http_client_read (client_handle, (char *)data, len);
309+ }
325310
326- // / Used for request and reply header parameters
327- HttpRequest& httpRequest () override {
328- return request;
329- }
311+ // / Adds/Updates a request header
312+ void addRequestHeader (const char * key, const char * value) override {
313+ TRACED ();
314+ request.addRequestHeader (key, value);
315+ }
316+ // / Provides a header entry
317+ const char * getReplyHeader (const char * key) override {
318+ return request.getReplyHeader (key);
319+ }
330320
331- // / Does nothing
332- void setClient (Client& client) override {}
321+ // / Define the Root PEM Certificate for SSL: Method compatible with Arduino
322+ // / WiFiClientSecure API
323+ void setCACert (const char * cert) override {
324+ int len = strlen (cert);
325+ setCACert ((const uint8_t *)cert, len + 1 );
326+ }
333327
334- protected:
335- int id = 0 ;
336- HttpRequest request;
337- esp_http_client_handle_t client_handle = nullptr ;
338- bool is_power_save = false ;
339- const char * ssid = nullptr ;
340- const char * password = nullptr ;
341- int buffer_size = DEFAULT_BUFFER_SIZE;
342- const uint8_t * pem_cert = nullptr ;
343- int pem_cert_len = 0 ;
344-
345- // / Define the Root PEM Certificate for SSL: the last byte must be null, the
346- // / len is including the ending null
347- void setCACert (const uint8_t * cert, int len) {
348- pem_cert_len = len;
349- pem_cert = cert;
350- // certificate must end with traling null
351- assert (cert[len - 1 ] == 0 );
352- }
328+ // / Defines the read buffer size
329+ void setReadBufferSize (int size) { buffer_size = size; }
330+
331+ // / Used for request and reply header parameters
332+ HttpRequest& httpRequest () override { return request; }
333+
334+ // / Does nothing
335+ void setClient (Client & client) override {}
336+
337+ protected:
338+ int id = 0 ;
339+ HttpRequest request;
340+ esp_http_client_handle_t client_handle = nullptr ;
341+ bool is_power_save = false ;
342+ const char * ssid = nullptr ;
343+ const char * password = nullptr ;
344+ int buffer_size = DEFAULT_BUFFER_SIZE;
345+ const uint8_t * pem_cert = nullptr ;
346+ int pem_cert_len = 0 ;
347+
348+ // / Define the Root PEM Certificate for SSL: the last byte must be null, the
349+ // / len is including the ending null
350+ void setCACert (const uint8_t * cert, int len) {
351+ pem_cert_len = len;
352+ pem_cert = cert;
353+ // certificate must end with traling null
354+ assert (cert[len - 1 ] == 0 );
355+ }
353356
354- static esp_err_t http_event_handler (esp_http_client_event_t * evt) {
355- switch (evt->event_id ) {
356- case HTTP_EVENT_ERROR:
357- LOGI (" HTTP_EVENT_ERROR" );
358- break ;
359- case HTTP_EVENT_ON_CONNECTED:
360- LOGD (" HTTP_EVENT_ON_CONNECTED" );
361- break ;
362- case HTTP_EVENT_HEADER_SENT:
363- LOGD (" HTTP_EVENT_HEADER_SENT" );
364- break ;
365- case HTTP_EVENT_ON_HEADER:
366- LOGI (" HTTP_EVENT_ON_HEADER, key=%s, value=%s" , evt->header_key ,
367- evt->header_value );
368- // store reply headers
369- actualURLStreamESP32->request .reply ().put (evt->header_key ,evt->header_value );
370- break ;
371- case HTTP_EVENT_ON_DATA:
372- LOGD (" HTTP_EVENT_ON_DATA, len=%d" , evt->data_len );
373- break ;
374- case HTTP_EVENT_ON_FINISH:
375- LOGI (" HTTP_EVENT_ON_FINISH" );
376- break ;
377- case HTTP_EVENT_DISCONNECTED:
378- LOGI (" HTTP_EVENT_DISCONNECTED" );
379- break ;
380- case HTTP_EVENT_REDIRECT:
381- LOGI (" HTTP_EVENT_REDIRECT" );
382- break ;
357+ static esp_err_t http_event_handler (esp_http_client_event_t * evt) {
358+ switch (evt->event_id ) {
359+ case HTTP_EVENT_ERROR:
360+ LOGI (" HTTP_EVENT_ERROR" );
361+ break ;
362+ case HTTP_EVENT_ON_CONNECTED:
363+ LOGD (" HTTP_EVENT_ON_CONNECTED" );
364+ break ;
365+ case HTTP_EVENT_HEADER_SENT:
366+ LOGD (" HTTP_EVENT_HEADER_SENT" );
367+ break ;
368+ case HTTP_EVENT_ON_HEADER:
369+ LOGI (" HTTP_EVENT_ON_HEADER, key=%s, value=%s" , evt->header_key ,
370+ evt->header_value );
371+ // store reply headers
372+ actualURLStreamESP32->request .reply ().put (evt->header_key ,
373+ evt->header_value );
374+ break ;
375+ case HTTP_EVENT_ON_DATA:
376+ LOGD (" HTTP_EVENT_ON_DATA, len=%d" , evt->data_len );
377+ break ;
378+ case HTTP_EVENT_ON_FINISH:
379+ LOGI (" HTTP_EVENT_ON_FINISH" );
380+ break ;
381+ case HTTP_EVENT_DISCONNECTED:
382+ LOGI (" HTTP_EVENT_DISCONNECTED" );
383+ break ;
384+ #if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 3, 7)
385+ case HTTP_EVENT_REDIRECT:
386+ LOGI (" HTTP_EVENT_REDIRECT" );
387+ break ;
388+ #endif
389+ }
390+ return ESP_OK;
383391 }
384- return ESP_OK;
385- }
386- };
392+ };
387393
388- // / ICYStream
389- using ICYStreamESP32 = ICYStreamT<URLStreamESP32>;
390- using URLStreamBufferedESP32 = URLStreamBufferedT<URLStreamESP32>;
391- using ICYStreamBufferedESP32 = URLStreamBufferedT<ICYStreamESP32>;
394+ // / ICYStream
395+ using ICYStreamESP32 = ICYStreamT<URLStreamESP32>;
396+ using URLStreamBufferedESP32 = URLStreamBufferedT<URLStreamESP32>;
397+ using ICYStreamBufferedESP32 = URLStreamBufferedT<ICYStreamESP32>;
392398
393399// / Support URLStream w/o Arduino
394400#if !defined(ARDUINO)
395- using URLStream = URLStreamESP32;
396- using URLStreamBuffered = URLStreamBufferedESP32;
397- using ICYStreamBuffered = ICYStreamBufferedESP32;
401+ using URLStream = URLStreamESP32;
402+ using URLStreamBuffered = URLStreamBufferedESP32;
403+ using ICYStreamBuffered = ICYStreamBufferedESP32;
398404#endif
399405
400406} // namespace audio_tools
0 commit comments