mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-27 21:16:50 +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_DOWNLOAD_UNIT_SIZE 1460
|
||||||
#define HTTP_UPLOAD_BUFLEN 2048
|
#define HTTP_UPLOAD_BUFLEN 2048
|
||||||
#define HTTP_MAX_DATA_WAIT 1000 //ms to wait for the client to send the request
|
#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 HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection
|
||||||
|
|
||||||
#define CONTENT_LENGTH_UNKNOWN ((size_t) -1)
|
#define CONTENT_LENGTH_UNKNOWN ((size_t) -1)
|
||||||
|
@ -31,6 +31,38 @@
|
|||||||
#define DEBUG_OUTPUT Serial
|
#define DEBUG_OUTPUT Serial
|
||||||
#endif
|
#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) {
|
bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
|
||||||
// Read the first line of HTTP request
|
// Read the first line of HTTP request
|
||||||
String req = client.readStringUntil('\r');
|
String req = client.readStringUntil('\r');
|
||||||
@ -137,26 +169,9 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isForm){
|
if (!isForm){
|
||||||
if (searchStr != "") searchStr += '&';
|
size_t plainLength;
|
||||||
char *plainBuf = nullptr;
|
char* plainBuf = readBytesWithTimeout(client, contentLength, plainLength, HTTP_MAX_POST_WAIT);
|
||||||
size_t plainLen = 0;
|
if (plainLength < contentLength) {
|
||||||
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)
|
|
||||||
{
|
|
||||||
free(plainBuf);
|
free(plainBuf);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -164,14 +179,17 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
|
|||||||
DEBUG_OUTPUT.print("Plain: ");
|
DEBUG_OUTPUT.print("Plain: ");
|
||||||
DEBUG_OUTPUT.println(plainBuf);
|
DEBUG_OUTPUT.println(plainBuf);
|
||||||
#endif
|
#endif
|
||||||
if(plainBuf[0] == '{' || plainBuf[0] == '[' || strstr(plainBuf, "=") == NULL){
|
if (contentLength > 0) {
|
||||||
//plain post json or other data
|
if (searchStr != "") searchStr += '&';
|
||||||
searchStr += "plain=";
|
if(plainBuf[0] == '{' || plainBuf[0] == '[' || strstr(plainBuf, "=") == NULL){
|
||||||
searchStr += plainBuf;
|
//plain post json or other data
|
||||||
} else {
|
searchStr += "plain=";
|
||||||
searchStr += plainBuf;
|
searchStr += plainBuf;
|
||||||
|
} else {
|
||||||
|
searchStr += plainBuf;
|
||||||
|
}
|
||||||
|
free(plainBuf);
|
||||||
}
|
}
|
||||||
free(plainBuf);
|
|
||||||
}
|
}
|
||||||
_parseArguments(searchStr);
|
_parseArguments(searchStr);
|
||||||
if (isForm){
|
if (isForm){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user