3535static const char Content_Type[] PROGMEM = " Content-Type" ;
3636static const char filename[] PROGMEM = " filename" ;
3737
38- static char * readBytesWithTimeout (WiFiClient& client, size_t maxLength, size_t & dataLength , int timeout_ms)
38+ static bool readBytesWithTimeout (WiFiClient& client, size_t maxLength, String& data , int timeout_ms)
3939{
40- char *buf = nullptr ;
41- dataLength = 0 ;
42- while (dataLength < maxLength) {
40+ if (!data.reserve (maxLength + 1 ))
41+ return false ;
42+ data[0 ] = 0 ; // data.clear()??
43+ while (data.length () < maxLength) {
4344 int tries = timeout_ms;
44- size_t newLength;
45- while (!(newLength = client.available ()) && tries--) delay (1 );
46- if (!newLength) {
45+ size_t avail;
46+ while (!(avail = client.available ()) && tries--)
47+ delay (1 );
48+ if (!avail)
4749 break ;
48- }
49- if (!buf) {
50- buf = (char *) malloc (newLength + 1 );
51- if (!buf) {
52- return nullptr ;
53- }
54- }
55- else {
56- char * newBuf = (char *) realloc (buf, dataLength + newLength + 1 );
57- if (!newBuf) {
58- free (buf);
59- return nullptr ;
60- }
61- buf = newBuf;
62- }
63- client.readBytes (buf + dataLength, newLength);
64- dataLength += newLength;
65- buf[dataLength] = ' \0 ' ;
50+ if (data.length () + avail > maxLength)
51+ avail = maxLength - data.length ();
52+ while (avail--)
53+ data += (char )client.read ();
6654 }
67- return buf ;
55+ return data. length () == maxLength ;
6856}
6957
7058bool ESP8266WebServer::_parseRequest (WiFiClient& client) {
7159 // Read the first line of HTTP request
7260 String req = client.readStringUntil (' \r ' );
61+ #ifdef DEBUG_ESP_HTTP_SERVER
62+ DEBUG_OUTPUT.print (" request: " );
63+ DEBUG_OUTPUT.println (req);
64+ #endif
7365 client.readStringUntil (' \n ' );
7466 // reset header value
7567 for (int i = 0 ; i < _headerKeysCount; ++i) {
@@ -82,8 +74,7 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
8274 int addr_end = req.indexOf (' ' , addr_start + 1 );
8375 if (addr_start == -1 || addr_end == -1 ) {
8476#ifdef DEBUG_ESP_HTTP_SERVER
85- DEBUG_OUTPUT.print (" Invalid request: " );
86- DEBUG_OUTPUT.println (req);
77+ DEBUG_OUTPUT.println (" Invalid request" );
8778#endif
8879 return false ;
8980 }
@@ -139,7 +130,7 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
139130 String headerName;
140131 String headerValue;
141132 bool isForm = false ;
142- // bool isEncoded = false;
133+ bool isEncoded = false ;
143134 uint32_t contentLength = 0 ;
144135 // parse headers
145136 while (1 ){
@@ -168,7 +159,7 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
168159 isForm = false ;
169160 } else if (headerValue.startsWith (F (" application/x-www-form-urlencoded" ))){
170161 isForm = false ;
171- // isEncoded = true;
162+ isEncoded = true ;
172163 } else if (headerValue.startsWith (F (" multipart/" ))){
173164 boundaryStr = headerValue.substring (headerValue.indexOf (' =' ) + 1 );
174165 boundaryStr.replace (" \" " ," " );
@@ -181,34 +172,40 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
181172 }
182173 }
183174
184- // always parse url for key/value pairs
175+ String plainBuf;
176+ if ( !isForm
177+ && // read content into plainBuf
178+ ( !readBytesWithTimeout (client, contentLength, plainBuf, HTTP_MAX_POST_WAIT)
179+ || (plainBuf.length () < contentLength)
180+ )
181+ )
182+ {
183+ return false ;
184+ }
185+
186+ if (isEncoded) {
187+ // isEncoded => !isForm => plainBuf is not empty
188+ // add plainBuf in search str
189+ if (searchStr.length ())
190+ searchStr += ' &' ;
191+ searchStr += plainBuf;
192+ }
193+
194+ // parse searchStr for key/value pairs
185195 _parseArguments (searchStr);
186196
187197 if (!isForm) {
188198 if (contentLength) {
189-
190199 // add key=value: plain={body} (post json or other data)
191-
192- size_t plainLength;
193- char * plainBuf = readBytesWithTimeout (client, contentLength, plainLength, HTTP_MAX_POST_WAIT);
194- if (plainLength < contentLength) {
195- free (plainBuf);
196- return false ;
197- }
198-
199200 RequestArgument& arg = _currentArgs[_currentArgCount++];
200201 arg.key = F (" plain" );
201- arg.value = String (plainBuf);
202-
203- free (plainBuf);
204-
202+ arg.value = plainBuf;
205203 }
206204 } else { // isForm is true
207-
205+ // here: content is not yet read (plainBuf is still empty)
208206 if (!_parseForm (client, boundaryStr, contentLength)) {
209207 return false ;
210208 }
211-
212209 }
213210 } else {
214211 String headerName;
@@ -368,7 +365,7 @@ uint8_t ESP8266WebServer::_uploadReadByte(WiFiClient& client){
368365 return (uint8_t )res;
369366}
370367
371- bool ESP8266WebServer::_parseForm (WiFiClient& client, String boundary, uint32_t len){
368+ bool ESP8266WebServer::_parseForm (WiFiClient& client, const String& boundary, uint32_t len){
372369 (void ) len;
373370#ifdef DEBUG_ESP_HTTP_SERVER
374371 DEBUG_OUTPUT.print (" Parse Form: Boundary: " );
0 commit comments