11/* *
2- * 2025-01-25
2+ * 2025-01-26
33 *
44 * For MCU build target (CORE_ARDUINO_XXXX), see Options.h.
55 *
@@ -218,6 +218,8 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
218218
219219 void newCon (async_data *sData , const char *host, uint16_t port)
220220 {
221+ sData ->request .setClient (client_type, client, async_tcp_config);
222+ sData ->response .setClient (client_type, client, async_tcp_config);
221223
222224 if ((!sData ->sse && session_timeout_sec >= FIREBASE_SESSION_TIMEOUT_SEC && session_timer.remaining () == 0 ) || (sse && !sData ->sse ) || (!sse && sData ->sse ) || (sData ->auth_used && sData ->state == astate_undefined) ||
223225 strcmp (this ->host .c_str (), host) != 0 || this ->port != port)
@@ -403,7 +405,7 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
403405 {
404406 uint16_t toSend = len - sData ->request .dataIndex > FIREBASE_CHUNK_SIZE ? FIREBASE_CHUNK_SIZE : len - sData ->request .dataIndex ;
405407
406- size_t sent = sData ->request .tcpWrite (client_type, client, async_tcp_config, data + sData ->request .dataIndex , toSend);
408+ size_t sent = sData ->request .tcpWrite (data + sData ->request .dataIndex , toSend);
407409 sys_idle ();
408410
409411 if (sent == toSend)
@@ -716,7 +718,6 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
716718
717719 void returnResult (async_data *sData , bool setData)
718720 {
719-
720721 bool error_notify_timeout = false ;
721722 if (sData ->err_timer .remaining () == 0 )
722723 {
@@ -800,52 +801,14 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
800801 }
801802 }
802803
803- int readLine (async_data *sData , String &buf)
804- {
805- int p = 0 ;
806-
807- while (sData ->response .tcpAvailable (client_type, client, async_tcp_config))
808- {
809- int res = sData ->response .tcpRead (client_type, client, async_tcp_config);
810- if (res > -1 )
811- {
812- buf += (char )res;
813- p++;
814- if (res == ' \n ' )
815- return p;
816- }
817- }
818- return p;
819- }
820-
821- uint32_t hex2int (const char *hex)
822- {
823- uint32_t val = 0 ;
824- while (*hex)
825- {
826- // get current character then increment
827- uint8_t byte = *hex++;
828- // transform hex character to the 4bit equivalent number, using the ascii table indexes
829- if (byte >= ' 0' && byte <= ' 9' )
830- byte = byte - ' 0' ;
831- else if (byte >= ' a' && byte <= ' f' )
832- byte = byte - ' a' + 10 ;
833- else if (byte >= ' A' && byte <= ' F' )
834- byte = byte - ' A' + 10 ;
835- // shift 4 to make space for new digit, and add the 4 bits of the new digit
836- val = (val << 4 ) | (byte & 0xF );
837- }
838- return val;
839- }
840-
841804 void clear (String &str) { sut.clear (str); }
842805
843806 bool readResponse (async_data *sData )
844807 {
845808 if (!client || !sData )
846809 return false ;
847810
848- if (sData ->response .tcpAvailable (client_type, client, async_tcp_config ) > 0 )
811+ if (sData ->response .tcpAvailable () > 0 )
849812 {
850813 // status line or data?
851814 if (!readStatusLine (sData ))
@@ -885,7 +848,7 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
885848 // Prevent sse timeout due to large sse Stream playload
886849 feedSSETimer (&sData ->aResult .rtdbResult );
887850
888- if ((*payload)[payload->length () - 1 ] == ' \n ' && sData ->response .tcpAvailable (client_type, client, async_tcp_config ) == 0 )
851+ if ((*payload)[payload->length () - 1 ] == ' \n ' && sData ->response .tcpAvailable () == 0 )
889852 {
890853 setRefPayload (&sData ->aResult .rtdbResult , payload);
891854 parseSSE (&sData ->aResult .rtdbResult );
@@ -925,28 +888,16 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
925888 return true ;
926889 }
927890
928- int getStatusCode (const String &header)
929- {
930- String out;
931- int p1 = header.indexOf (" HTTP/1." );
932- if (p1 > -1 )
933- {
934- out = header.substring (p1 + 9 , header.indexOf (' ' , p1 + 9 ));
935- return atoi (out.c_str ());
936- }
937- return 0 ;
938- }
939-
940891 bool readStatusLine (async_data *sData )
941892 {
942893 if (sData ->response .httpCode > 0 )
943894 return false ;
944895
945896 sData ->response .val [resns::header].reserve (1024 );
946897
947- // the first chunk (line) can be http response status or already connected stream payload
948- readLine ( sData , sData ->response .val [resns::header] );
949- int status = getStatusCode ( sData ->response .val [resns::header] );
898+ // The first chunk (line) can be http response status or already connected stream payload
899+ sData ->response .readLine ( );
900+ int status = sData ->response .getStatusCode ( );
950901 if (status > 0 )
951902 {
952903 // http response status
@@ -960,56 +911,53 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
960911 {
961912 if (sData ->response .flags .header_remaining )
962913 {
963- int read = readLine ( sData , sData ->response .val [resns::header] );
914+ int read = sData ->response .readLine ( );
964915 if ((read == 1 && sData ->response .val [resns::header][sData ->response .val [resns::header].length () - 1 ] == ' \n ' ) ||
965916 (read == 2 && sData ->response .val [resns::header][sData ->response .val [resns::header].length () - 2 ] == ' \r ' && sData ->response .val [resns::header][sData ->response .val [resns::header].length () - 1 ] == ' \n ' ))
966917 {
967918 sData ->response .flags .http_response = true ;
968919 clear (sData ->response .val [resns::etag]);
969- String temp[ 5 ] ;
920+ String temp;
970921#if defined(ENABLE_CLOUD_STORAGE)
971922 if (sData ->upload )
972- parseRespHeader ( sData , sData ->response .val [resns::header], sData ->request .file_data .resumable .getLocationRef (), " Location" );
923+ sData ->response .parseRespHeader ( sData ->request .file_data .resumable .getLocationRef (), " Location" );
973924#else
974- parseRespHeader ( sData , sData ->response .val [resns::header], sData ->response .val [resns::location], " Location" );
925+ sData ->response .parseRespHeader ( sData ->response .val [resns::location], " Location" );
975926
976927#endif
977- parseRespHeader ( sData , sData ->response .val [resns::header], sData ->response .val [resns::etag], " ETag" );
928+ sData ->response .parseRespHeader ( sData ->response .val [resns::etag], " ETag" );
978929 resETag = sData ->response .val [resns::etag];
979930 sData ->aResult .val [ares_ns::res_etag] = sData ->response .val [resns::etag];
980931 sData ->aResult .val [ares_ns::data_path] = sData ->request .val [reqns::path];
981932#if defined(ENABLE_DATABASE)
982933 setNullETagOption (&sData ->aResult .rtdbResult , sData ->response .val [resns::etag].indexOf (" null_etag" ) > -1 );
983934#endif
984935
985- parseRespHeader (sData , sData ->response .val [resns::header], temp[0 ], " Content-Length" );
936+ sData ->response .parseRespHeader (temp, " Content-Length" );
937+ sData ->response .payloadLen = atoi (temp.c_str ());
986938
987- sData ->response .payloadLen = atoi (temp[0 ].c_str ());
939+ sData ->response .parseRespHeader (temp, " Connection" );
940+ sData ->response .flags .keep_alive = temp.length () && temp.indexOf (" keep-alive" ) > -1 ;
988941
989- parseRespHeader ( sData , sData ->response .val [resns::header], temp[ 1 ] , " Connection " );
990- sData ->response .flags .keep_alive = temp[ 1 ] .length () && temp[ 1 ] .indexOf (" keep-alive " ) > -1 ;
942+ sData ->response .parseRespHeader ( temp, " Transfer-Encoding " );
943+ sData ->response .flags .chunks = temp.length () && temp.indexOf (" chunked " ) > -1 ;
991944
992- parseRespHeader (sData , sData ->response .val [resns::header], temp[2 ], " Transfer-Encoding" );
993- sData ->response .flags .chunks = temp[2 ].length () && temp[2 ].indexOf (" chunked" ) > -1 ;
994-
995- parseRespHeader (sData , sData ->response .val [resns::header], temp[3 ], " Content-Type" );
996- sData ->response .flags .sse = temp[3 ].length () && temp[3 ].indexOf (" text/event-stream" ) > -1 ;
945+ sData ->response .parseRespHeader (temp, " Content-Type" );
946+ sData ->response .flags .sse = temp.length () && temp.indexOf (" text/event-stream" ) > -1 ;
997947
998948 if (sData ->upload )
999- parseRespHeader ( sData , sData ->response .val [resns::header], temp[ 4 ] , " Range" );
949+ sData ->response .parseRespHeader ( temp, " Range" );
1000950
1001951 clear (sData );
1002952
1003953#if defined(ENABLE_CLOUD_STORAGE)
1004954 if (sData ->upload && sData ->request .file_data .resumable .isEnabled ())
1005955 {
1006956 sData ->request .file_data .resumable .setHeaderState ();
1007- if (sData ->response .httpCode == FIREBASE_ERROR_HTTP_CODE_PERMANENT_REDIRECT && temp[ 4 ] .indexOf (" bytes=" ) > -1 )
957+ if (sData ->response .httpCode == FIREBASE_ERROR_HTTP_CODE_PERMANENT_REDIRECT && temp.indexOf (" bytes=" ) > -1 )
1008958 sData ->request .file_data .resumable .updateRange ();
1009959 }
1010960#endif
1011- for (size_t i = 0 ; i < 5 ; i++)
1012- sut.clear (temp[i]);
1013961
1014962 if (sData ->response .httpCode > 0 && sData ->response .httpCode != FIREBASE_ERROR_HTTP_CODE_NO_CONTENT)
1015963 sData ->response .flags .payload_remaining = true ;
@@ -1023,121 +971,6 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
1023971 }
1024972 }
1025973
1026- void parseRespHeader (async_data *sData , const String &src, String &out, const char *header)
1027- {
1028- if (sData ->response .httpCode > 0 )
1029- {
1030- int p1 = -1 , p2 = -1 , p3 = -1 ;
1031- p1 = src.indexOf (header);
1032- if (p1 > -1 )
1033- p2 = src.indexOf (' :' , p1);
1034-
1035- if (p2 > -1 )
1036- p3 = src.indexOf (" \r\n " , p2);
1037-
1038- if (p2 > -1 && p3 > -1 )
1039- out = src.substring (p2 + 1 , p3);
1040-
1041- out.trim ();
1042- }
1043- }
1044-
1045- int getChunkSize (async_data *sData , Client *client, String &line)
1046- {
1047- if (line.length () == 0 )
1048- readLine (sData , line);
1049-
1050- int p = line.indexOf (" ;" );
1051- if (p == -1 )
1052- p = line.indexOf (" \r\n " );
1053- if (p != -1 )
1054- sData ->response .chunkInfo .chunkSize = hex2int (line.substring (0 , p).c_str ());
1055-
1056- return sData ->response .chunkInfo .chunkSize ;
1057- }
1058-
1059- // Returns -1 when complete
1060- int decodeChunks (async_data *sData , Client *client, String *out)
1061- {
1062- if (!client || !sData || !out)
1063- return 0 ;
1064- int res = 0 , read = 0 ;
1065- String line;
1066-
1067- // because chunks might span multiple reads, we need to keep track of where we are in the chunk
1068- // chunkInfo.dataLen is our current position in the chunk
1069- // chunkInfo.chunkSize is the total size of the chunk
1070-
1071- // readline() only reads while there is data available, so it might return early
1072- // when available() is less than the remaining amount of data in the chunk
1073-
1074- // read chunk-size, chunk-extension (if any) and CRLF
1075- if (sData ->response .chunkInfo .phase == res_handler::READ_CHUNK_SIZE)
1076- {
1077- sData ->response .chunkInfo .phase = res_handler::READ_CHUNK_DATA;
1078- sData ->response .chunkInfo .chunkSize = -1 ;
1079- sData ->response .chunkInfo .dataLen = 0 ;
1080- res = getChunkSize (sData , client, line);
1081- sData ->response .payloadLen += res > -1 ? res : 0 ;
1082- }
1083- // read chunk-data and CRLF
1084- // append chunk-data to entity-body
1085- else
1086- {
1087- // if chunk-size is 0, it's the last chunk, and can be skipped
1088- if (sData ->response .chunkInfo .chunkSize > 0 )
1089- {
1090- read = readLine (sData , line);
1091-
1092- // if we read till a CRLF, we have a chunk (or the rest of it)
1093- // if the last two bytes are NOT CRLF, we have a partial chunk
1094- // if we read 0 bytes, read next chunk size
1095-
1096- // check for \n and \r, remove them if present (they're part of the protocol, not the data)
1097- if (read >= 2 && line[read - 2 ] == ' \r ' && line[read - 1 ] == ' \n ' )
1098- {
1099- // last chunk?
1100- if (line[0 ] == ' 0' )
1101- return -1 ;
1102-
1103- // remove the \r\n
1104- line.remove (line.length () - 2 );
1105- read -= 2 ;
1106- }
1107-
1108- // if we still have data, append it and update the chunkInfo
1109- if (read)
1110- {
1111- *out += line;
1112- sData ->response .chunkInfo .dataLen += read;
1113- sData ->response .payloadRead += read;
1114-
1115- // check if we're done reading this chunk
1116- if (sData ->response .chunkInfo .dataLen == sData ->response .chunkInfo .chunkSize )
1117- sData ->response .chunkInfo .phase = res_handler::READ_CHUNK_SIZE;
1118- }
1119- // if we read 0 bytes, read next chunk size
1120- else
1121- {
1122- sData ->response .chunkInfo .phase = res_handler::READ_CHUNK_SIZE;
1123- }
1124- }
1125- else
1126- {
1127-
1128- read = readLine (sData , line);
1129-
1130- // CRLF (end of chunked body)
1131- if (read == 2 && line[0 ] == ' \r ' && line[1 ] == ' \n ' )
1132- res = -1 ;
1133- else // another chunk?
1134- getChunkSize (sData , client, line);
1135- }
1136- }
1137-
1138- return res;
1139- }
1140-
1141974 bool readPayload (async_data *sData )
1142975 {
1143976 uint8_t *buf = nullptr ;
@@ -1154,7 +987,7 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
1154987 {
1155988 // Use temporary String buffer for decodeChunks
1156989 String temp;
1157- int res = decodeChunks (sData , client, &temp);
990+ int res = sData -> response . decodeChunks (&temp);
1158991 if (temp.length ())
1159992 {
1160993 reserveString (sData );
@@ -1216,7 +1049,7 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
12161049 ofs = sData ->request .base64 && sData ->response .payloadRead == 0 ? 1 : 0 ;
12171050 toRead = (int )(sData ->response .payloadLen - sData ->response .payloadRead ) > FIREBASE_CHUNK_SIZE + ofs ? FIREBASE_CHUNK_SIZE + ofs : sData ->response .payloadLen - sData ->response .payloadRead ;
12181051 buf = reinterpret_cast <uint8_t *>(mem.alloc (toRead));
1219- read = sData ->response .tcpRead (client_type, client, async_tcp_config, buf, toRead);
1052+ read = sData ->response .tcpRead (buf, toRead);
12201053 }
12211054
12221055 if (read > 0 )
@@ -1316,7 +1149,7 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
13161149 {
13171150 // Use temporary String buffer for readLine
13181151 String temp;
1319- size_t len = readLine (sData , temp);
1152+ size_t len = sData -> response . readLine (& temp);
13201153 sData ->response .payloadRead += len;
13211154 reserveString (sData );
13221155 sData ->response .val [resns::payload] += temp;
@@ -1329,7 +1162,7 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
13291162 if (buf)
13301163 mem.release (&buf);
13311164
1332- if (sData ->response .payloadLen > 0 && sData ->response .payloadRead >= sData ->response .payloadLen && sData ->response .tcpAvailable (client_type, client, async_tcp_config ) == 0 )
1165+ if (sData ->response .payloadLen > 0 && sData ->response .payloadRead >= sData ->response .payloadLen && sData ->response .tcpAvailable () == 0 )
13331166 {
13341167
13351168 // Async payload and header data collision workaround from session reusage.
@@ -1400,7 +1233,7 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
14001233 {
14011234 if (sData ->response .toFill && sData ->response .toFillLen )
14021235 {
1403- int currentRead = sData ->response .tcpRead (client_type, client, async_tcp_config, sData ->response .toFill + sData ->response .toFillIndex , sData ->response .toFillLen );
1236+ int currentRead = sData ->response .tcpRead (sData ->response .toFill + sData ->response .toFillIndex , sData ->response .toFillLen );
14041237 if (currentRead == sData ->response .toFillLen )
14051238 {
14061239 buf = reinterpret_cast <uint8_t *>(mem.alloc (sData ->response .toFillIndex + sData ->response .toFillLen ));
@@ -2374,7 +2207,7 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
23742207 if (sData ->return_type == ret_complete)
23752208 sData ->return_type = ret_continue;
23762209
2377- if (sData ->async && !sData ->response .tcpAvailable (client_type, client, async_tcp_config ))
2210+ if (sData ->async && !sData ->response .tcpAvailable ())
23782211 {
23792212 if (sData ->sse )
23802213 {
@@ -2388,7 +2221,7 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
23882221 }
23892222 else if (!sData ->async ) // wait for non async
23902223 {
2391- while (!sData ->response .tcpAvailable (client_type, client, async_tcp_config ) && networkConnect (sData ) == ret_complete)
2224+ while (!sData ->response .tcpAvailable () && networkConnect (sData ) == ret_complete)
23922225 {
23932226 sys_idle ();
23942227 if (handleReadTimeout (sData ))
0 commit comments