11/* *
2- * Created January 14 , 2025
2+ * Created January 17 , 2025
33 *
44 * For MCU build target (CORE_ARDUINO_XXXX), see Options.h.
55 *
@@ -858,11 +858,14 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
858858 if (!readPayload (sData ))
859859 return false ;
860860
861+ String *payload = &sData ->response .val [res_hndlr_ns::payload];
862+
861863 if (sData ->response .flags .sse || !sData ->response .flags .payload_remaining )
862864 {
863865 if (!sData ->auth_used )
864866 {
865- sData ->aResult .setPayload (sData ->response .val [res_hndlr_ns::payload]);
867+ if (!sData ->response .flags .sse )
868+ sData ->aResult .setPayload (*payload);
866869
867870 if (sData ->aResult .download_data .total > 0 )
868871 clearAppData (sData ->aResult .app_data );
@@ -872,37 +875,43 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
872875 if (sData ->request .method == async_request_handler_t ::http_post)
873876 parseNodeName (&sData ->aResult .rtdbResult );
874877
875- // data available from sse event
876- if (sData ->response .flags .sse && sData -> response . val [res_hndlr_ns::payload]. length ())
878+ // Data available from sse event
879+ if (sData ->response .flags .sse && payload-> length ())
877880 {
878- // order of checking: event, data, newline
879- if (sData -> response . val [res_hndlr_ns::payload]. indexOf (" event: " ) > -1 && sData -> response . val [res_hndlr_ns::payload]. indexOf (" data: " ) > -1 && sData -> response . val [res_hndlr_ns::payload]. indexOf (" \n " ) > -1 )
881+
882+ if (payload-> indexOf (" event: " ) > -1 && payload-> indexOf (" data: " ) > -1 && payload-> indexOf (" \n " ) > -1 )
880883 {
884+ // Prevent sse timeout due to large sse Stream playload
885+ feedSSETimer (&sData ->aResult .rtdbResult );
881886
882- parseSSE (&sData ->aResult .rtdbResult );
883-
884- // Event filtering.
885- String event = sData ->aResult .rtdbResult .event ();
886- if (sse_events_filter.length () == 0 ||
887- (sData ->response .flags .http_response && sse_events_filter.indexOf (" get" ) > -1 && event.indexOf (" put" ) > -1 ) ||
888- (!sData ->response .flags .http_response && sse_events_filter.indexOf (" put" ) > -1 && event.indexOf (" put" ) > -1 ) ||
889- (sse_events_filter.indexOf (" patch" ) > -1 && event.indexOf (" patch" ) > -1 ) ||
890- (sse_events_filter.indexOf (" keep-alive" ) > -1 && event.indexOf (" keep-alive" ) > -1 ) ||
891- (sse_events_filter.indexOf (" cancel" ) > -1 && event.indexOf (" cancel" ) > -1 ) ||
892- (sse_events_filter.indexOf (" auth_revoked" ) > -1 && event.indexOf (" auth_revoked" ) > -1 ))
893- {
894- // save payload to slot result
895- sData ->aResult .setPayload (sData ->response .val [res_hndlr_ns::payload]);
896- clear (sData ->response .val [res_hndlr_ns::payload]);
897- sData ->response .flags .payload_available = true ;
898- returnResult (sData , true );
899- }
900- else
887+ if ((*payload)[payload->length () - 1 ] == ' \n ' && sData ->response .tcpAvailable (client_type, client, async_tcp_config) == 0 )
901888 {
902- clear (sData ->response .val [res_hndlr_ns::payload]);
903- }
889+ setRefPayload (&sData ->aResult .rtdbResult , payload);
890+ parseSSE (&sData ->aResult .rtdbResult );
891+
892+ // Event filtering.
893+ String event = sData ->aResult .rtdbResult .event ();
894+ if (sse_events_filter.length () == 0 ||
895+ (sData ->response .flags .http_response && sse_events_filter.indexOf (" get" ) > -1 && event.indexOf (" put" ) > -1 ) ||
896+ (!sData ->response .flags .http_response && sse_events_filter.indexOf (" put" ) > -1 && event.indexOf (" put" ) > -1 ) ||
897+ (sse_events_filter.indexOf (" patch" ) > -1 && event.indexOf (" patch" ) > -1 ) ||
898+ (sse_events_filter.indexOf (" keep-alive" ) > -1 && event.indexOf (" keep-alive" ) > -1 ) ||
899+ (sse_events_filter.indexOf (" cancel" ) > -1 && event.indexOf (" cancel" ) > -1 ) ||
900+ (sse_events_filter.indexOf (" auth_revoked" ) > -1 && event.indexOf (" auth_revoked" ) > -1 ))
901+ {
902+ // save payload to slot result
903+ sData ->aResult .setPayload (*payload);
904+ clear (*payload);
905+ sData ->response .flags .payload_available = true ;
906+ returnResult (sData , true );
907+ }
908+ else
909+ {
910+ clear (*payload);
911+ }
904912
905- sData ->response .flags .http_response = false ;
913+ sData ->response .flags .http_response = false ;
914+ }
906915 }
907916 }
908917#endif
@@ -1142,7 +1151,16 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
11421151
11431152 if (sData ->response .flags .chunks )
11441153 {
1145- if (decodeChunks (sData , client, &sData ->response .val [res_hndlr_ns::payload]) == -1 )
1154+ // Use temporary String buffer for decodeChunks
1155+ String temp;
1156+ int res = decodeChunks (sData , client, &temp);
1157+ if (temp.length ())
1158+ {
1159+ reserveString (sData );
1160+ sData ->response .val [res_hndlr_ns::payload] += temp;
1161+ }
1162+
1163+ if (res == -1 )
11461164 sData ->response .flags .payload_remaining = false ;
11471165 }
11481166 else
@@ -1294,7 +1312,14 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
12941312 }
12951313 }
12961314 else
1297- sData ->response .payloadRead += readLine (sData , sData ->response .val [res_hndlr_ns::payload]);
1315+ {
1316+ // Use temporary String buffer for readLine
1317+ String temp;
1318+ size_t len = readLine (sData , temp);
1319+ sData ->response .payloadRead += len;
1320+ reserveString (sData );
1321+ sData ->response .val [res_hndlr_ns::payload] += temp;
1322+ }
12981323 }
12991324 }
13001325 }
@@ -1354,6 +1379,17 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
13541379 return sData ->error .code == 0 ;
13551380 }
13561381
1382+ void reserveString (async_data_item_t *sData )
1383+ {
1384+ // String memory reservation is needed to hadle large data in external memory.
1385+ #if defined(ENABLE_PSRAM) && ((defined(ESP8266) && defined(MMU_EXTERNAL_HEAP)) || (defined(ESP32) && defined(BOARD_HAS_PSRAM)))
1386+ String old = sData ->response .val [res_hndlr_ns::payload];
1387+ sData ->response .val [res_hndlr_ns::payload].remove (0 , sData ->response .val [res_hndlr_ns::payload].length ());
1388+ sData ->response .val [res_hndlr_ns::payload].reserve (sData ->response .payloadRead + 1 );
1389+ sData ->response .val [res_hndlr_ns::payload] = old;
1390+ #endif
1391+ }
1392+
13571393 // non-block memory buffer for collecting the multiple of 4 data prepared for base64 decoding
13581394 uint8_t *asyncBase64Buffer (async_data_item_t *sData , Memory &mem, int &toRead, int &read)
13591395 {
0 commit comments