File: lib/websrv/websrv.h | Language: cpp
bool startsWith (const char* base, const char* str) {
//fb
char c;
while ( (c = *str++) != '\0' )
if (c != *base++) return false;
return true;
}
bool startsWith (const char* base, const char* str) {
//fb
char c;
while ( (c = *str++) != '\0' ) {
if (c != *base++) return false;
if (*(base-1) == '\0') return false; // base is shorter than str
}
return true;
}
File: src/index.h | Language: javascript
xhr.onreadystatechange = function () { // Call a function when the state changes.
if (xhr.readyState === 4) {
if (xhr.responseText === 'OK') alert(filename + ' successfully uploaded')
else alert(filename + ' successfully uploaded')
}
}
xhr.onreadystatechange = function () { // Call a function when the state changes.
if (xhr.readyState === 4) {
if (xhr.responseText === 'OK') alert(filename + ' successfully uploaded')
else alert(filename + ' not successfully uploaded. Response: ' + xhr.responseText)
}
}
File: src/main.cpp | Language: cpp
if(strcmp(cmd, "uploadfile") == 0){savefile(param, contentLength); return;}
if(strcmp(cmd, "uploadfile") == 0){savefile(param, contentLength);
if(strcmp(param, "/stations.json") == 0) staMgnt.updateStationsList();
return;}
File: src/index.js.h | Language: javascript
var theUrl = "SD_delete?" + encodeURIComponent(node.data.path) + '&version=' + Math.random().toString()
var xhr = new XMLHttpRequest()
xhr.timeout = 2000; // time in milliseconds
xhr.open('POST', theUrl, true)
var theUrl = "SD/?" + encodeURIComponent(node.data.path) + '&version=' + Math.random().toString()
var xhr = new XMLHttpRequest()
xhr.timeout = 2000; // time in milliseconds
xhr.open('DELETE', theUrl, true)
File: src/index.h | Language: javascript
xhr.onreadystatechange = function () { // Call a function when the state changes.
if (xhr.readyState === 4) {
if (xhr.responseText === 'OK') alert(filename + ' successfully uploaded')
else alert(filename + 'not successfully uploaded')
}
}
xhr.onreadystatechange = function () { // Call a function when the state changes.
if (xhr.readyState === 4) {
if (xhr.responseText === 'OK') alert(filename + ' successfully uploaded')
else alert(filename + ' not successfully uploaded')
}
}
File: lib/websrv/websrv.cpp | Language: C++
rhl[pos] = b;
pos++;
if(pos == 511) {
pos = 510;
continue;
}
if(pos == 510) {
rhl[pos] = '\0';
log_i("requestHeaderline overflow");
}
// This improved snippet assumes 'b' is the current character read from the client,
// and 'pos' is the current write index in 'rhl'.
// A boolean flag, e.g., 'current_line_truncated', should be initialized to false
// at the beginning of reading each new header line.
if (current_line_truncated) {
// If the line has already been marked as truncated,
// consume 'b' without storing it to prevent buffer overflow.
} else if (pos < sizeof(rhl) - 1) {
// If there's space for the current character 'b' AND a null terminator.
rhl[pos++] = b;
} else {
// Buffer is full. The current character 'b' cannot be stored.
// Ensure the buffer is null-terminated at the very end.
rhl[sizeof(rhl) - 1] = '\0';
log_i("requestHeaderline overflow, line truncated");
current_line_truncated = true; // Mark this line as truncated.
}
// Note: After the character-reading loop for the entire line finishes (e.g., on '\n'),
// if 'current_line_truncated' is still false (i.e., no overflow occurred),
// an explicit `rhl[pos] = '\0';` is required to null-terminate normally short lines.
File: lib/websrv/websrv.cpp | Language: cpp
// param between "?" and "&" or HTTP, if "?" exists
if(pos_question != -1){
int start_part2 = pos_question + 1;
int end_part2 = (pos_ampersand != -1) ? pos_ampersand : pos_http;
strncpy(http_param, rhl + start_part2, end_part2 - start_part2);
}
// param between "?" and "&" or HTTP, if "?" exists
if(pos_question != -1){
int start_part2 = pos_question + 1;
int end_part2 = (pos_ampersand != -1) ? pos_ampersand : pos_http;
int len = end_part2 - start_part2;
if(len > sizeof(http_param) - 1) len = sizeof(http_param) - 1;
strncpy(http_param, rhl + start_part2, len);
http_param[len] = '\0';
}
File: lib/websrv/websrv.cpp | Language: cpp
void WebSrv::url_decode_in_place(char* url) {
int length = strlen(url);
int write_pos = 0; // Die Position, an die das dekodierte Zeichen geschrieben wird
auto from_hex = [](char ch) {
return std::isdigit(ch) ? ch - '0' : std::tolower(ch) - 'a' + 10;
};
for (int i = 0; i < length; ++i) {
if (url[i] == '%') {
if (i + 2 < length) {
// Dekodiere die beiden folgenden Hex-Zeichen
int hex_value = from_hex(url[i + 1]) * 16 + from_hex(url[i + 2]);
url[write_pos++] = static_cast<char>(hex_value); // Schreibe dekodiertes Zeichen
i += 2; // Überspringe die beiden Hex-Zeichen
}
} else if (url[i] == '+') {
// Ersetze '+' durch ein Leerzeichen
url[write_pos++] = ' ';
} else {
// Normales Zeichen einfach kopieren
url[write_pos++] = url[i];
}
}
url[write_pos] = '\0'; // Add a null termination character to mark the end of the string
}
void WebSrv::url_decode_in_place(char* url) {
int length = strlen(url);
int write_pos = 0;
auto from_hex = [](char ch) {
ch = std::tolower(ch);
return std::isdigit(ch) ? ch - '0' : (ch >= 'a' && ch <= 'f' ? ch - 'a' + 10 : -1);
};
for (int i = 0; i < length; ++i) {
if (url[i] == '%' && i + 2 < length &&
from_hex(url[i + 1]) != -1 && from_hex(url[i + 2]) != -1) {
int hex_value = from_hex(url[i + 1]) * 16 + from_hex(url[i + 2]);
url[write_pos++] = static_cast<char>(hex_value);
i += 2;
} else if (url[i] == '+') {
url[write_pos++] = ' ';
} else {
url[write_pos++] = url[i];
}
}
url[write_pos] = '\0';
}
File: lib/websrv/websrv.cpp | Language: cpp
else if(startsWith(rhl, "DELETE /")){
method_DELETE = true;
int pos_http = indexOf(rhl, "HTTP/", 0);
int pos_question = indexOf(rhl, "?", 0); // questionmark
int pos_ampersand = indexOf(rhl, "&", 0); // ampersand
if(pos_http == -1) {log_w("GET without HTTP?"); goto exit;}
// cmd between "GET /" and "?" or "HTTP"
int start_part1 = 8; // after "GET /"
int end_part1 = (pos_question != -1) ? pos_question : pos_http;
strncpy(http_cmd, rhl + start_part1, end_part1 - start_part1);
// param between "?" and "&" or HTTP, if "?" exists
if(pos_question != -1){
int start_part2 = pos_question + 1;
int end_part2 = (pos_ampersand != -1) ? pos_ampersand : pos_http;
strncpy(http_param, rhl + start_part2, end_part2 - start_part2);
}
// arg between "&" and "HTTP" if "&" exists
if (pos_ampersand != -1) {
int start_part3 = pos_ampersand + 1;
strncpy(http_arg, rhl + start_part3, pos_http - start_part3);
}
}
else if(startsWith(rhl, "DELETE /")){
method_DELETE = true;
int pos_http = indexOf(rhl, "HTTP/", 0);
int pos_question = indexOf(rhl, "?", 0); // questionmark
int pos_ampersand = indexOf(rhl, "&", 0); // ampersand
if(pos_http == -1) {log_w("DELETE without HTTP?"); goto exit;}
// cmd between "DELETE /" and "?" or "HTTP"
int start_part1 = 8; // after "DELETE /"
int end_part1 = pos_http;
if (pos_question != -1 && pos_question > start_part1) end_part1 = pos_question;
if (end_part1 > start_part1 && end_part1 - start_part1 < (int)sizeof(http_cmd))
strncpy(http_cmd, rhl + start_part1, end_part1 - start_part1);
// param between "?" and "&" or HTTP, if "?" exists
if(pos_question != -1) {
int start_part2 = pos_question + 1;
int end_part2 = (pos_ampersand != -1 && pos_ampersand > start_part2) ? pos_ampersand : pos_http;
if (end_part2 > start_part2 && end_part2 - start_part2 < (int)sizeof(http_param))
strncpy(http_param, rhl + start_part2, end_part2 - start_part2);
}
// arg between "&" and "HTTP" if "&" exists
if (pos_ampersand != -1) {
int start_part3 = pos_ampersand + 1;
if (pos_http > start_part3 && pos_http - start_part3 < (int)sizeof(http_arg))
strncpy(http_arg, rhl + start_part3, pos_http - start_part3);
}
}
File: lib/websrv/websrv.cpp | Language: cpp
posColon = indexOf(rhl, ":", 0); // lowercase all letters up to the colon
if(posColon >= 0) {
for(int i = 0; i < posColon; i++) { rhl[i] = toLowerCase(rhl[i]); }
}
posColon = indexOf(rhl, ":", 0); // lowercase all letters up to the colon
if(posColon >= 0) {
for(int i = 0; i < posColon; i++) {
rhl[i] = tolower(static_cast<unsigned char>(rhl[i]));
}
}
File: lib/websrv/websrv.cpp | Language: cpp
while(cmdclient.available()) {
uint8_t b = cmdclient.read();
if(b == '\n') {
if(!pos) { // empty line received, is the last line of this responseHeader
goto lastToDo;
}
break;
}
...
} // inner while
while(cmdclient.available()) {
uint8_t b = cmdclient.read();
if(b == '\n') {
if(!pos) { // empty line received, is the last line of this responseHeader
goto lastToDo;
}
break;
}
...
} // inner while
rhl[pos] = '\0'; // ensure line is null-terminated
File: lib/websrv/websrv.cpp | Language: cpp
void WebSrv::url_decode_in_place(char* url) {
int length = strlen(url);
int write_pos = 0;
auto from_hex = [](char ch) {
return std::isdigit(ch) ? ch - '0' : std::tolower(ch) - 'a' + 10;
};
...
}
void WebSrv::url_decode_in_place(char* url) {
int length = strlen(url);
int write_pos = 0;
for (int i = 0; i < length; ++i) {
if (url[i] == '%') {
if (i + 2 < length) {
char c1 = url[i + 1];
char c2 = url[i + 2];
int hex1 = (c1 >= '0' && c1 <= '9') ? c1 - '0' : (c1 >= 'a' && c1 <= 'f') ? c1 - 'a' + 10 : (c1 >= 'A' && c1 <= 'F') ? c1 - 'A' + 10 : 0;
int hex2 = (c2 >= '0' && c2 <= '9') ? c2 - '0' : (c2 >= 'a' && c2 <= 'f') ? c2 - 'a' + 10 : (c2 >= 'A' && c2 <= 'F') ? c2 - 'A' + 10 : 0;
url[write_pos++] = static_cast<char>(hex1 * 16 + hex2);
i += 2;
}
} else if (url[i] == '+') {
url[write_pos++] = ' ';
} else {
url[write_pos++] = url[i];
}
}
url[write_pos] = '\0';
}
File: lib/websrv/websrv.cpp | Language: cpp
static uint32_t stime;
static bool f_time = false;
if(cmdclient.available() == 0) {
if(!f_time) {
stime = millis();
f_time = true;
}
if((millis() - stime) > timeout) {
log_e("timeout");
f_time = false;
return false;
}
}
f_time = false;
static uint32_t stime;
static bool f_time = false;
if(cmdclient.available() == 0) {
if(!f_time) {
stime = millis();
f_time = true;
}
if((millis() - stime) > timeout) {
log_e("timeout");
f_time = false;
return false;
}
} else {
f_time = false;
}
File: lib/websrv/websrv.h | Language: cpp
void trim(char *str) {
char *start = str;
char *end;
while (isspace((unsigned char)*start)) start++;
if (*start == 0) {
str[0] = '\0';
return;
}
end = start + strlen(start) - 1;
while (end > start && isspace((unsigned char)*end)) end--;
end[1] = '\0';
memmove(str, start, strlen(start) + 1);
}
void trim(char *str) {
char *start = str;
char *end;
while (isspace((unsigned char)*start)) start++;
if (*start == 0) {
str[0] = '\0';
return;
}
size_t len = strlen(start);
end = start + len - 1;
while (end > start && isspace((unsigned char)*end)) end--;
end[1] = '\0';
memmove(str, start, len - (end - start - len + 1) + 1);
}
File: lib/websrv/websrv.cpp | Language: cpp
strncpy(http_cmd, rhl + start_part1, end_part1 - start_part1);
// param between "?" and "&" or HTTP, if "?" exists
if(pos_question != -1){
int start_part2 = pos_question + 1;
int end_part2 = (pos_ampersand != -1) ? pos_ampersand : pos_http;
strncpy(http_param, rhl + start_part2, end_part2 - start_part2);
}
// arg between "&" and "HTTP" if "&" exists
if (pos_ampersand != -1) {
int start_part3 = pos_ampersand + 1;
strncpy(http_arg, rhl + start_part3, pos_http - start_part3);
}
int len_cmd = end_part1 - start_part1;
strncpy(http_cmd, rhl + start_part1, len_cmd);
http_cmd[len_cmd] = '\0';
// param between "?" and "&" or HTTP, if "?" exists
if(pos_question != -1){
int start_part2 = pos_question + 1;
int end_part2 = (pos_ampersand != -1) ? pos_ampersand : pos_http;
int len_param = end_part2 - start_part2;
strncpy(http_param, rhl + start_part2, len_param);
http_param[len_param] = '\0';
}
// arg between "&" and "HTTP" if "&" exists
if (pos_ampersand != -1) {
int start_part3 = pos_ampersand + 1;
int len_arg = pos_http - start_part3;
strncpy(http_arg, rhl + start_part3, len_arg);
http_arg[len_arg] = '\0';
}
File: lib/websrv/websrv.cpp | Language: cpp
if(posColon >= 0) {
for(int i = 0; i < posColon; i++) { rhl[i] = toLowerCase(rhl[i]); }
}
#include <cctype>
if(posColon >= 0) {
for(int i = 0; i < posColon; i++) {
rhl[i] = static_cast<char>(std::tolower(static_cast<unsigned char>(rhl[i])));
}
}
File: src/index.h | Language: javascript
xhr.onreadystatechange = function () { // Call a function when the state changes.
if (xhr.readyState === 4) {
if (xhr.responseText === 'OK') alert(filename + ' successfully uploaded')
else alert(filename + 'not successfully uploaded')
}
}
xhr.onreadystatechange = function () { // Call a function when the state changes.
if (xhr.readyState === 4) {
if (xhr.responseText === 'OK') alert(filename + ' successfully uploaded')
else alert(filename + ' not successfully uploaded')
}
}
File: lib/websrv/websrv.cpp | Language: cpp
while(true) { // outer while
uint16_t pos = 0;
if((millis() - ctime) > timeout) {
log_e("timeout");
goto exit;
}
while(cmdclient.available()) {
uint8_t b = cmdclient.read();
if(b == '\n') {
if(!pos) { // empty line received, is the last line of this responseHeader
goto lastToDo;
}
break;
}
if(b == '\r') rhl[pos] = 0;
if(b < 0x20) continue;
rhl[pos] = b;
pos++;
if(pos == 511) {
pos = 510;
continue;
}
if(pos == 510) {
rhl[pos] = '\0';
log_i("requestHeaderline overflow");
}
} // inner while
while(true) { // outer while
uint16_t pos = 0;
if((millis() - ctime) > timeout) {
log_e("timeout");
goto exit;
}
while(cmdclient.available()) {
uint8_t b = cmdclient.read();
if(b == '\n') {
if(!pos) { // empty line received, is the last line of this responseHeader
goto lastToDo;
}
break;
}
if(b == '\r') rhl[pos] = 0;
if(b < 0x20) continue;
if(pos >= 511) {
rhl[511] = '\0';
log_i("requestHeaderline overflow");
break;
}
rhl[pos] = b;
pos++;
} // inner while
File: src/index.h | Language: javascript
xhr.timeout = 4000; // time in milliseconds
xhr.timeout = 10000; // time in milliseconds
File: src/index.h | Language: javascript
if (xhr.responseText === 'OK') alert(filename + ' successfully uploaded')
else alert(filename + 'not successfully uploaded')
if (xhr.responseText === 'OK') alert(filename + ' successfully uploaded')
else alert(filename + ' not successfully uploaded')
File: lib/websrv/websrv.cpp | Language: cpp
int idx = str.indexOf("\n");
if(idx > 0){
if(str.startsWith("-----")){ // is WebKitFormBoundary header
len -= str.length() + idx + 2; // ------WebKitFormBoundaryEnlfueBZaFBBzAm7
}
else{
len -= str.length();
}
}
int idx = str.indexOf("\n");
if(idx >= 0){
if(str.startsWith("-----")){ // is WebKitFormBoundary header
len -= str.length() + idx + 2; // ------WebKitFormBoundaryEnlfueBZaFBBzAm7
}
else{
len -= str.length();
}
}
File: lib/websrv/websrv.cpp | Language: cpp
char http_cmd[512] = {0};
char http_param[512] = {0};
char http_arg[512] = {0};
...
strncpy(http_cmd, rhl + start_part1, end_part1 - start_part1);
...
strncpy(http_param, rhl + start_part2, end_part2 - start_part2);
...
strncpy(http_arg, rhl + start_part3, pos_http - start_part3);
char http_cmd[512] = {0};
char http_param[512] = {0};
char http_arg[512] = {0};
...
strncpy(http_cmd, rhl + start_part1, end_part1 - start_part1);
http_cmd[end_part1 - start_part1] = '\0';
...
strncpy(http_param, rhl + start_part2, end_part2 - start_part2);
http_param[end_part2 - start_part2] = '\0';
...
strncpy(http_arg, rhl + start_part3, pos_http - start_part3);
http_arg[pos_http - start_part3] = '\0';
File: lib/websrv/websrv.cpp | Language: cpp
// cmd between "GET /" and "?" or "HTTP"
int start_part1 = 6; // after "GET /"
int end_part1 = (pos_question != -1) ? pos_question : pos_http;
strncpy(http_cmd, rhl + start_part1, end_part1 - start_part1);
// cmd between "POST /" and "?" or "HTTP"
int start_part1 = 6; // after "POST /"
int end_part1 = (pos_question != -1) ? pos_question : pos_http;
strncpy(http_cmd, rhl + start_part1, end_part1 - start_part1);
File: lib/websrv/websrv.cpp | Language: cpp
char rhl[512] = {0}; // requestHeaderline
char http_cmd[512] = {0};
char http_param[512] = {0};
char http_arg[512] = {0};
char contentType[50] = {0};
...
while(true) { // outer while
...
while(cmdclient.available()) {
uint8_t b = cmdclient.read();
if(b == '\n') {
...
if(pos == 511) {
pos = 510;
continue;
}
if(pos == 510) {
rhl[pos] = '\0';
log_i("requestHeaderline overflow");
}
} // inner while
...
else if(startsWith(rhl, "GET /")){
...
strncpy(http_cmd, rhl + start_part1, end_part1 - start_part1);
...
strncpy(http_param, rhl + start_part2, end_part2 - start_part2);
...
strncpy(http_arg, rhl + start_part3, pos_http - start_part3);
...
// Example illustration (actual implementation may vary depending on desired approach)
// Use std::string for dynamic resizing
// std::string rhl;
// while (cmdclient.available()) { char b = cmdclient.read(); if (b == '\n') break; if (b != '\r') rhl += b; }
// ... parse rhl using string methods ...
//
// Or, with fixed buffers, add strict size checks before copying:
char rhl[512] = {0};
char http_cmd[512] = {0};
char http_param[512] = {0};
char http_arg[512] = {0};
char contentType[50] = {0};
...
// Add check before rhl write loop: while(cmdclient.available() && pos < sizeof(rhl) - 1) { ... }
...
else if(startsWith(rhl, "GET /")){
...
int len_cmd = end_part1 - start_part1;
if (len_cmd > 0 && len_cmd < sizeof(http_cmd)) { // Add bounds check
strncpy(http_cmd, rhl + start_part1, len_cmd);
http_cmd[len_cmd] = '\0'; // Ensure null termination
} else { http_cmd[0] = '\0'; /* Handle error or empty */ }
...
int len_param = end_part2 - start_part2;
if(pos_question != -1 && len_param > 0 && len_param < sizeof(http_param)){ // Add bounds check
strncpy(http_param, rhl + start_part2, len_param);
http_param[len_param] = '\0'; // Ensure null termination
} else { http_param[0] = '\0'; }
...
int len_arg = pos_http - start_part3;
if (pos_ampersand != -1 && len_arg > 0 && len_arg < sizeof(http_arg)) { // Add bounds check
strncpy(http_arg, rhl + start_part3, len_arg);
http_arg[len_arg] = '\0'; // Ensure null termination
} else { http_arg[0] = '\0'; }
...
File: lib/websrv/websrv.cpp | Language: cpp
else if(startsWith(rhl, "GET /")){
method_GET = true;
int pos_http = indexOf(rhl, "HTTP/", 0);
int pos_question = indexOf(rhl, "?", 0); // questionmark
int pos_ampersand = indexOf(rhl, "&", 0); // ampersand
if(pos_http == -1) {log_w("GET without HTTP?"); goto exit;}
// cmd between "GET /" and "?" or "HTTP"
int start_part1 = 5; // after "GET /"
int end_part1 = (pos_question != -1) ? pos_question : (pos_ampersand != -1) ? pos_ampersand : pos_http;
strncpy(http_cmd, rhl + start_part1, end_part1 - start_part1);
// param between "?" and "&" or HTTP, if "?" exists
if(pos_question != -1){
...
else if(startsWith(rhl, "GET /")){
method_GET = true;
int pos_http = indexOf(rhl, "HTTP/", 0);
int pos_question = indexOf(rhl, "?", 0); // questionmark
int pos_ampersand = indexOf(rhl, "&", 0); // ampersand
if(pos_http == -1) {log_w("GET without HTTP?"); goto exit;}
// cmd between "GET /" and "?" or "HTTP"
int start_part1 = 5; // after "GET /"
int end_part1 = (pos_question != -1) ? pos_question : (pos_ampersand != -1) ? pos_ampersand : pos_http;
int len_cmd = end_part1 - start_part1;
strncpy(http_cmd, rhl + start_part1, len_cmd);
http_cmd[len_cmd] = '\0'; // Explicit null termination
// param between "?" and "&" or HTTP, if "?" exists
if(pos_question != -1){
int start_part2 = pos_question + 1;
int end_part2 = (pos_ampersand != -1) ? pos_ampersand : pos_http;
int len_param = end_part2 - start_part2;
strncpy(http_param, rhl + start_part2, len_param);
http_param[len_param] = '\0'; // Explicit null termination
} else { http_param[0] = '\0'; } // Ensure empty string if no param
// arg between "&" and "HTTP" if "&" exists
if (pos_ampersand != -1) {
int start_part3 = pos_ampersand + 1;
int len_arg = pos_http - start_part3;
strncpy(http_arg, rhl + start_part3, len_arg);
http_arg[len_arg] = '\0'; // Explicit null termination
} else { http_arg[0] = '\0'; } // Ensure empty string if no arg
}
// Apply similar null termination after strncpy in POST and DELETE blocks
...
File: lib/websrv/websrv.cpp | Language: cpp
str = str + cmdclient.readStringUntil(','); // data:image/jpeg;base64,
int idx = str.indexOf("\n");
if(idx > 0){
if(str.startsWith("-----")){ // is WebKitFormBoundary header
len -= str.length() + idx + 2; // ------WebKitFormBoundaryEnlfueBZaFBBzAm7
}
else{
len -= str.length();
}
}
while(cmdclient.available()){
av=cmdclient.available();
...
// Example illustration (requires adapting to actual body format)
// int bytes_read_for_headers = 0;
// String header_line;
// while (cmdclient.connected() && cmdclient.available()) {
// header_line = cmdclient.readStringUntil('\n');
// bytes_read_for_headers += header_line.length() + 1; // +1 for '\n'
// if (header_line.length() <= 1) break; // Blank line indicates end of headers
// }
// uint32_t base64_data_length = contentLength - bytes_read_for_headers; // Assuming contentLength is total body size
// ... now read base64_data_length bytes ...
str = str + cmdclient.readStringUntil(','); // Reads up to the comma
// The calculation below is problematic for robustness
int idx = str.indexOf("\n");
if(idx > 0){
if(str.startsWith("-----")){
// This calculation is risky.
// len -= str.length() + idx + 2;
}
else{
// This calculation is also risky.
// len -= str.length();
}
}
// Instead of adjusting len based on partial reads, read until body starts.
// while (cmdclient.connected() && cmdclient.available() && cmdclient.read() != '\n'); // Simplified: read until first \n after ','
// Now the base64 data should start, use contentLength (or a derived value)
while(cmdclient.available()){
av=cmdclient.available();
...