esp32_https_server icon indicating copy to clipboard operation
esp32_https_server copied to clipboard

POST readBytes bytes limit

Open PabloASua opened this issue 4 years ago • 2 comments

Hi there! I was trying to send to my ESP32 some data using the POST method. Everything was ok until my data passed over 512 bytes. When my data gets 513 byte or more, the readByte function seems to overflow and overwrite the buffer regardless the buffer size.

My code:

byte buffer[1024]; size_t readLength = 0;

while(!(req->requestComplete())) { readLength = req->readBytes(buffer, 1024); } Serial.println(readLength);

When data is less or equal than 512 bytes readLenght match with the amount of byte sended, but over 513 bytes readLenght is equal to the the diference between 512 bytes and the sended bytes.

¿Is there any limit to change somewhere?

Regards!

PabloASua avatar Feb 25 '21 20:02 PabloASua

You override what is in your buffer already. This is how your code gets executed when you receive 513 bytes:

// Buffer gets allocated
byte buffer[1024];
// readLength is set to 0
size_t readLength = 0;

// First time the loop condition is checked. req->requestCompleted will return false, because 513 bytes are left
while(!(req->requestComplete())) {
  // This will read the first chunk of data
  // readLength will be 512
  // buffer[0] - buffer[511] contain the first 512 bytes of data
  readLength = req->readBytes(buffer, 1024);

// Second time the loop condition is checked. req->requestCompleted will return false, because 1 bytes is still left
while(!(req->requestComplete())) {
  // This will read the next chunk (the remaining byte in this case) of data and store it at the beginning of the array:
  // readLength is now 1
  // buffer[0] is the remaining byte
  // buffer[1] - buffer[511] are still data bytes from the previous chunk
  readLength = req->readBytes(buffer, 1024);


// Third (and last) time the loop condition is checked. req->requestCompleted will return true, the body has been consumed
while(!(req->requestComplete())) {
// Quit the loop
}

// Print the readLength=1 from the second iteration. That is what you call the difference between 512 and sent bytes
Serial.println(readLength);

So what you need to do is something like this to continue writing where you left of in the previous iteration of the loop (didn't test it, but you should get the gist):

#define BUFLEN 1024

uint8_t buffer[BUFLEN] = {0};
size_t idx = 0;
size_t readLength = 0;

do {
  // Don't read more than we have space left: BUFLEN-idx
  // Start writing at the offset where we stopped in the last iteration
  readLength = req->readBytes(buffer + idx, BUFLEN - idx);
} while (readLength > 0 && idx < BUFLEN);

if (idx == BUFLEN && readLength != 0) {
  // TODO: Handle error that the client sent more than 1024 bytes, which you cannot store
} else {
  // Process your data
}

Please also note that you cannot rely on getting chunks of 512 bytes, because that depends on how the data is transferred through the network.

fhessel avatar Feb 26 '21 23:02 fhessel

Hi Fhessel! First of all, thank you for taking the time to answer me. I've test your code but it seems like it doesn't work properly. idx value doesn't change in the loop, so the buffer is overwrited every time.

May I know how the readBytes function works? I don't understand how each parameter works.

Once more, thank you for your time, and by the way, your library was the only one that works properly with my server project, congrats.

Regads!

PabloASua avatar Feb 28 '21 14:02 PabloASua