35
35
static const char Content_Type[] PROGMEM = " Content-Type" ;
36
36
static const char filename[] PROGMEM = " filename" ;
37
37
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)
39
39
{
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) {
43
44
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)
47
49
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 ();
66
54
}
67
- return buf ;
55
+ return data. length () == maxLength ;
68
56
}
69
57
70
58
bool ESP8266WebServer::_parseRequest (WiFiClient& client) {
71
59
// Read the first line of HTTP request
72
60
String req = client.readStringUntil (' \r ' );
61
+ #ifdef DEBUG_ESP_HTTP_SERVER
62
+ DEBUG_OUTPUT.print (" request: " );
63
+ DEBUG_OUTPUT.println (req);
64
+ #endif
73
65
client.readStringUntil (' \n ' );
74
66
// reset header value
75
67
for (int i = 0 ; i < _headerKeysCount; ++i) {
@@ -82,8 +74,7 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
82
74
int addr_end = req.indexOf (' ' , addr_start + 1 );
83
75
if (addr_start == -1 || addr_end == -1 ) {
84
76
#ifdef DEBUG_ESP_HTTP_SERVER
85
- DEBUG_OUTPUT.print (" Invalid request: " );
86
- DEBUG_OUTPUT.println (req);
77
+ DEBUG_OUTPUT.println (" Invalid request" );
87
78
#endif
88
79
return false ;
89
80
}
@@ -139,7 +130,7 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
139
130
String headerName;
140
131
String headerValue;
141
132
bool isForm = false ;
142
- // bool isEncoded = false;
133
+ bool isEncoded = false ;
143
134
uint32_t contentLength = 0 ;
144
135
// parse headers
145
136
while (1 ){
@@ -168,7 +159,7 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
168
159
isForm = false ;
169
160
} else if (headerValue.startsWith (F (" application/x-www-form-urlencoded" ))){
170
161
isForm = false ;
171
- // isEncoded = true;
162
+ isEncoded = true ;
172
163
} else if (headerValue.startsWith (F (" multipart/" ))){
173
164
boundaryStr = headerValue.substring (headerValue.indexOf (' =' ) + 1 );
174
165
boundaryStr.replace (" \" " ," " );
@@ -181,34 +172,40 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
181
172
}
182
173
}
183
174
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
185
195
_parseArguments (searchStr);
186
196
187
197
if (!isForm) {
188
198
if (contentLength) {
189
-
190
199
// 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
-
199
200
RequestArgument& arg = _currentArgs[_currentArgCount++];
200
201
arg.key = F (" plain" );
201
- arg.value = String (plainBuf);
202
-
203
- free (plainBuf);
204
-
202
+ arg.value = plainBuf;
205
203
}
206
204
} else { // isForm is true
207
-
205
+ // here: content is not yet read (plainBuf is still empty)
208
206
if (!_parseForm (client, boundaryStr, contentLength)) {
209
207
return false ;
210
208
}
211
-
212
209
}
213
210
} else {
214
211
String headerName;
@@ -368,7 +365,7 @@ uint8_t ESP8266WebServer::_uploadReadByte(WiFiClient& client){
368
365
return (uint8_t )res;
369
366
}
370
367
371
- bool ESP8266WebServer::_parseForm (WiFiClient& client, String boundary, uint32_t len){
368
+ bool ESP8266WebServer::_parseForm (WiFiClient& client, const String& boundary, uint32_t len){
372
369
(void ) len;
373
370
#ifdef DEBUG_ESP_HTTP_SERVER
374
371
DEBUG_OUTPUT.print (" Parse Form: Boundary: " );
0 commit comments