mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-25 20:02:37 +03:00
ESP8266WebServer: fix handling of empty POST
Fix handling of case when Content-Length is 0. Change do {} while() loop into while(){} so that we don't wait 1000ms for data in case Content-Length is 0. Also fix handling of cases when malloc or realloc return null.
This commit is contained in:
parent
43d0989a3c
commit
f6516b004f
@ -34,6 +34,7 @@ enum HTTPClientStatus { HC_NONE, HC_WAIT_READ, HC_WAIT_CLOSE };
|
||||
#define HTTP_DOWNLOAD_UNIT_SIZE 1460
|
||||
#define HTTP_UPLOAD_BUFLEN 2048
|
||||
#define HTTP_MAX_DATA_WAIT 1000 //ms to wait for the client to send the request
|
||||
#define HTTP_MAX_POST_WAIT 1000 //ms to wait for POST data to arrive
|
||||
#define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection
|
||||
|
||||
#define CONTENT_LENGTH_UNKNOWN ((size_t) -1)
|
||||
|
@ -31,6 +31,38 @@
|
||||
#define DEBUG_OUTPUT Serial
|
||||
#endif
|
||||
|
||||
static char* readBytesWithTimeout(WiFiClient& client, size_t maxLength, size_t& dataLength, int timeout_ms)
|
||||
{
|
||||
char *buf = nullptr;
|
||||
dataLength = 0;
|
||||
while (dataLength < maxLength) {
|
||||
int tries = timeout_ms;
|
||||
size_t newLength;
|
||||
while (!(newLength = client.available()) && tries--) delay(1);
|
||||
if (!newLength) {
|
||||
break;
|
||||
}
|
||||
if (!buf) {
|
||||
buf = (char *) malloc(newLength + 1);
|
||||
if (!buf) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
char* newBuf = (char *) realloc(buf, dataLength + newLength + 1);
|
||||
if (!newBuf) {
|
||||
free(buf);
|
||||
return nullptr;
|
||||
}
|
||||
buf = newBuf;
|
||||
}
|
||||
client.readBytes(buf + dataLength, newLength);
|
||||
dataLength += newLength;
|
||||
buf[dataLength] = '\0';
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
|
||||
// Read the first line of HTTP request
|
||||
String req = client.readStringUntil('\r');
|
||||
@ -137,26 +169,9 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
|
||||
}
|
||||
|
||||
if (!isForm){
|
||||
if (searchStr != "") searchStr += '&';
|
||||
char *plainBuf = nullptr;
|
||||
size_t plainLen = 0;
|
||||
do
|
||||
{
|
||||
//some clients send headers first and data after (like we do)
|
||||
//give them a chance
|
||||
int tries = 1000;//1000ms max wait
|
||||
size_t newLen;
|
||||
while( !(newLen = client.available()) && tries--) delay(1);
|
||||
if (!newLen) break;
|
||||
plainBuf = (plainBuf == nullptr) ? (char *) malloc(newLen + 1) : (char *) realloc(plainBuf, plainLen + newLen + 1);
|
||||
client.readBytes(&plainBuf[plainLen], newLen);
|
||||
plainLen += newLen;
|
||||
plainBuf[plainLen] = '\0';
|
||||
} while (plainLen < contentLength);
|
||||
/* if data loss, exit */
|
||||
if (plainBuf == nullptr) return false;
|
||||
if (plainLen < contentLength)
|
||||
{
|
||||
size_t plainLength;
|
||||
char* plainBuf = readBytesWithTimeout(client, contentLength, plainLength, HTTP_MAX_POST_WAIT);
|
||||
if (plainLength < contentLength) {
|
||||
free(plainBuf);
|
||||
return false;
|
||||
}
|
||||
@ -164,14 +179,17 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
|
||||
DEBUG_OUTPUT.print("Plain: ");
|
||||
DEBUG_OUTPUT.println(plainBuf);
|
||||
#endif
|
||||
if(plainBuf[0] == '{' || plainBuf[0] == '[' || strstr(plainBuf, "=") == NULL){
|
||||
//plain post json or other data
|
||||
searchStr += "plain=";
|
||||
searchStr += plainBuf;
|
||||
} else {
|
||||
searchStr += plainBuf;
|
||||
if (contentLength > 0) {
|
||||
if (searchStr != "") searchStr += '&';
|
||||
if(plainBuf[0] == '{' || plainBuf[0] == '[' || strstr(plainBuf, "=") == NULL){
|
||||
//plain post json or other data
|
||||
searchStr += "plain=";
|
||||
searchStr += plainBuf;
|
||||
} else {
|
||||
searchStr += plainBuf;
|
||||
}
|
||||
free(plainBuf);
|
||||
}
|
||||
free(plainBuf);
|
||||
}
|
||||
_parseArguments(searchStr);
|
||||
if (isForm){
|
||||
|
Loading…
x
Reference in New Issue
Block a user