37
37
#endif
38
38
39
39
static const char Content_Type[] PROGMEM = " Content-Type" ;
40
- static const char filename[] PROGMEM = " filename" ;
41
40
42
41
template <typename ServerType>
43
42
static bool readBytesWithTimeout (typename ServerType::ClientType& client, size_t maxLength, String& data, int timeout_ms)
@@ -62,216 +61,183 @@ static bool readBytesWithTimeout(typename ServerType::ClientType& client, size_t
62
61
63
62
template <typename ServerType>
64
63
bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
65
- // Read the first line of HTTP request
66
- String req = client.readStringUntil (' \r ' );
64
+ // Read the first line of HTTP request
65
+ String req = client.readStringUntil (' \r ' );
67
66
#ifdef DEBUG_ESP_HTTP_SERVER
68
67
DEBUG_OUTPUT.print (" request: " );
69
68
DEBUG_OUTPUT.println (req);
70
69
#endif
71
- client.readStringUntil (' \n ' );
72
- // reset header value
73
- for (int i = 0 ; i < _headerKeysCount; ++i) {
74
- _currentHeaders[i].value = String ();
75
- }
76
-
77
- // First line of HTTP request looks like "GET /path HTTP/1.1"
78
- // Retrieve the "/path" part by finding the spaces
79
- int addr_start = req.indexOf (' ' );
80
- int addr_end = req.indexOf (' ' , addr_start + 1 );
81
- if (addr_start == -1 || addr_end == -1 ) {
70
+ client.readStringUntil (' \n ' );
71
+ // reset header value
72
+ for (size_t i = 0 ; i < _headerKeysCount; ++i) {
73
+ _currentHeaders[i].value . clear ();
74
+ }
75
+
76
+ // First line of HTTP request looks like "GET /path HTTP/1.1"
77
+ // Retrieve the "/path" part by finding the spaces
78
+ int addr_start = req.indexOf (' ' );
79
+ int addr_end = req.indexOf (' ' , addr_start + 1 );
80
+ if (addr_start == -1 || addr_end == -1 ) {
82
81
#ifdef DEBUG_ESP_HTTP_SERVER
83
- DEBUG_OUTPUT.println (" Invalid request" );
82
+ DEBUG_OUTPUT.println (" Invalid request" );
84
83
#endif
85
- return false ;
86
- }
84
+ return false ;
85
+ }
87
86
88
- String methodStr = req.substring (0 , addr_start);
89
- String url = req.substring (addr_start + 1 , addr_end);
90
- String versionEnd = req.substring (addr_end + 8 );
91
- _currentVersion = atoi (versionEnd.c_str ());
92
- String searchStr;
93
- int hasSearch = url.indexOf (' ?' );
94
- if (hasSearch != -1 ){
95
- searchStr = url.substring (hasSearch + 1 );
96
- url = url.substring (0 , hasSearch);
97
- }
98
- _currentUri = url;
99
- _chunked = false ;
100
-
101
- HTTPMethod method = HTTP_GET;
102
- if (methodStr == F (" HEAD" )) {
103
- method = HTTP_HEAD;
104
- } else if (methodStr == F (" POST" )) {
105
- method = HTTP_POST;
106
- } else if (methodStr == F (" DELETE" )) {
107
- method = HTTP_DELETE;
108
- } else if (methodStr == F (" OPTIONS" )) {
109
- method = HTTP_OPTIONS;
110
- } else if (methodStr == F (" PUT" )) {
111
- method = HTTP_PUT;
112
- } else if (methodStr == F (" PATCH" )) {
113
- method = HTTP_PATCH;
114
- }
115
- _currentMethod = method;
87
+ String methodStr = req.substring (0 , addr_start);
88
+ String url = req.substring (addr_start + 1 , addr_end);
89
+ _currentVersion = req.substring (addr_end + 8 ).toInt ();
90
+ String searchStr;
91
+ int hasSearch = url.indexOf (' ?' );
92
+ if (hasSearch != -1 ) {
93
+ searchStr = url.substring (hasSearch + 1 );
94
+ url = url.substring (0 , hasSearch);
95
+ }
96
+ _currentUri = url;
97
+ _chunked = false ;
98
+
99
+ HTTPMethod method = HTTP_GET;
100
+ if (methodStr == F (" HEAD" )) {
101
+ method = HTTP_HEAD;
102
+ } else if (methodStr == F (" POST" )) {
103
+ method = HTTP_POST;
104
+ } else if (methodStr == F (" DELETE" )) {
105
+ method = HTTP_DELETE;
106
+ } else if (methodStr == F (" OPTIONS" )) {
107
+ method = HTTP_OPTIONS;
108
+ } else if (methodStr == F (" PUT" )) {
109
+ method = HTTP_PUT;
110
+ } else if (methodStr == F (" PATCH" )) {
111
+ method = HTTP_PATCH;
112
+ }
113
+ _currentMethod = method;
116
114
117
115
#ifdef DEBUG_ESP_HTTP_SERVER
118
- DEBUG_OUTPUT.print (" method: " );
119
- DEBUG_OUTPUT.print (methodStr);
120
- DEBUG_OUTPUT.print (" url: " );
121
- DEBUG_OUTPUT.print (url);
122
- DEBUG_OUTPUT.print (" search: " );
123
- DEBUG_OUTPUT.println (searchStr);
116
+ DEBUG_OUTPUT.print (" method: " );
117
+ DEBUG_OUTPUT.print (methodStr);
118
+ DEBUG_OUTPUT.print (" url: " );
119
+ DEBUG_OUTPUT.print (url);
120
+ DEBUG_OUTPUT.print (" search: " );
121
+ DEBUG_OUTPUT.println (searchStr);
124
122
#endif
125
123
126
- // attach handler
127
- RequestHandlerType* handler;
128
- for (handler = _firstHandler; handler; handler = handler->next ()) {
129
- if (handler->canHandle (_currentMethod, _currentUri))
130
- break ;
131
- }
132
- _currentHandler = handler;
124
+ // attach handler
125
+ RequestHandlerType* handler;
126
+ for (handler = _firstHandler; handler; handler = handler->next ()) {
127
+ if (handler->canHandle (_currentMethod, _currentUri))
128
+ break ;
129
+ }
130
+ _currentHandler = handler;
133
131
134
- String formData;
135
- // below is needed only when POST type request
136
- if (method == HTTP_POST || method == HTTP_PUT || method == HTTP_PATCH || method == HTTP_DELETE){
137
- String boundaryStr;
138
132
String headerName;
139
133
String headerValue;
134
+ String boundaryStr;
140
135
bool isForm = false ;
141
136
bool isEncoded = false ;
142
137
uint32_t contentLength = 0 ;
143
- // parse headers
144
- while (1 ){
145
- req = client.readStringUntil (' \r ' );
146
- client.readStringUntil (' \n ' );
147
- if (req.isEmpty ()) break ;// no moar headers
148
- int headerDiv = req.indexOf (' :' );
149
- if (headerDiv == -1 ){
150
- break ;
151
- }
152
- headerName = req.substring (0 , headerDiv);
153
- headerValue = req.substring (headerDiv + 1 );
154
- headerValue.trim ();
155
- _collectHeader (headerName.c_str (),headerValue.c_str ());
156
-
157
- #ifdef DEBUG_ESP_HTTP_SERVER
158
- DEBUG_OUTPUT.print (" headerName: " );
159
- DEBUG_OUTPUT.println (headerName);
160
- DEBUG_OUTPUT.print (" headerValue: " );
161
- DEBUG_OUTPUT.println (headerValue);
162
- #endif
163
-
164
- if (headerName.equalsIgnoreCase (FPSTR (Content_Type))){
165
- using namespace mime ;
166
- if (headerValue.startsWith (FPSTR (mimeTable[txt].mimeType ))){
167
- isForm = false ;
168
- } else if (headerValue.startsWith (F (" application/x-www-form-urlencoded" ))){
169
- isForm = false ;
170
- isEncoded = true ;
171
- } else if (headerValue.startsWith (F (" multipart/" ))){
172
- boundaryStr = headerValue.substring (headerValue.indexOf (' =' ) + 1 );
173
- boundaryStr.replace (" \" " ," " );
174
- isForm = true ;
175
- }
176
- } else if (headerName.equalsIgnoreCase (F (" Content-Length" ))){
177
- contentLength = headerValue.toInt ();
178
- } else if (headerName.equalsIgnoreCase (F (" Host" ))){
179
- _hostHeader = headerValue;
180
- }
181
- }
138
+ // parse headers
139
+ while (true ) {
140
+ req = client.readStringUntil (' \r ' );
141
+ client.readStringUntil (' \n ' );
182
142
183
- String plainBuf;
184
- if ( !isForm
185
- && // read content into plainBuf
186
- ( !readBytesWithTimeout<ServerType>(client, contentLength, plainBuf, HTTP_MAX_POST_WAIT)
187
- || (plainBuf.length () < contentLength)
188
- )
189
- )
190
- {
191
- return false ;
192
- }
143
+ int headerDiv = req.indexOf (' :' );
144
+ if (headerDiv < 0 ) {
145
+ break ;
146
+ }
147
+ headerName = req.substring (0 , headerDiv);
148
+ headerValue = req.substring (headerDiv + 1 );
149
+ headerValue.trim ();
150
+ _collectHeader (headerName, headerValue);
193
151
194
- if (isEncoded) {
195
- // isEncoded => !isForm => plainBuf is not empty
196
- // add plainBuf in search str
197
- if (searchStr.length ())
198
- searchStr += ' &' ;
199
- searchStr += plainBuf;
152
+ #ifdef DEBUG_ESP_HTTP_SERVER
153
+ DEBUG_OUTPUT.print (F (" headerName: " ));
154
+ DEBUG_OUTPUT.println (headerName);
155
+ DEBUG_OUTPUT.print (F (" headerValue: " ));
156
+ DEBUG_OUTPUT.println (headerValue);
157
+ #endif
158
+ if (headerName.equalsIgnoreCase (FPSTR (Content_Type))) {
159
+ if (headerValue.startsWith (FPSTR (::mime::mimeTable[::mime::txt].mimeType ))) {
160
+ isForm = false ;
161
+ } else if (headerValue.startsWith (F (" application/x-www-form-urlencoded" ))) {
162
+ isForm = false ;
163
+ isEncoded = true ;
164
+ } else if (headerValue.startsWith (F (" multipart/" ))) {
165
+ boundaryStr = headerValue.substring (headerValue.indexOf (' =' ) + 1 );
166
+ boundaryStr.replace (" \" " , " " );
167
+ isForm = true ;
168
+ }
169
+ } else if (headerName.equalsIgnoreCase (F (" Content-Length" ))) {
170
+ contentLength = headerValue.toInt ();
171
+ } else if (headerName.equalsIgnoreCase (F (" Host" ))) {
172
+ _hostHeader = headerValue;
173
+ }
200
174
}
201
-
202
- // parse searchStr for key/value pairs
203
175
_parseArguments (searchStr);
204
176
205
- if (!isForm) {
206
- if (contentLength) {
207
- // add key=value: plain={body} (post json or other data)
208
- RequestArgument& arg = _currentArgs[_currentArgCount++];
209
- arg.key = F (" plain" );
210
- arg.value = plainBuf;
211
- _currentArgsHavePlain = 1 ;
212
- }
213
- } else { // isForm is true
214
- // here: content is not yet read (plainBuf is still empty)
215
- if (!_parseForm (client, boundaryStr, contentLength)) {
216
- return false ;
217
- }
218
- }
219
- } else {
220
- String headerName;
221
- String headerValue;
222
- // parse headers
223
- while (1 ){
224
- req = client.readStringUntil (' \r ' );
225
- client.readStringUntil (' \n ' );
226
- if (req.isEmpty ()) break ;// no moar headers
227
- int headerDiv = req.indexOf (' :' );
228
- if (headerDiv == -1 ){
229
- break ;
230
- }
231
- headerName = req.substring (0 , headerDiv);
232
- headerValue = req.substring (headerDiv + 2 );
233
- _collectHeader (headerName.c_str (),headerValue.c_str ());
177
+ // below is needed only when POST type request
178
+ if (method == HTTP_POST || method == HTTP_PUT || method == HTTP_PATCH || method == HTTP_DELETE) {
179
+ String plainBuf;
180
+ if (!isForm &&
181
+ // read content into plainBuf
182
+ (!readBytesWithTimeout<ServerType>(client, contentLength, plainBuf, HTTP_MAX_POST_WAIT)
183
+ || (plainBuf.length () < contentLength)))
184
+ {
185
+ return false ;
186
+ }
234
187
235
- #ifdef DEBUG_ESP_HTTP_SERVER
236
- DEBUG_OUTPUT.print (F (" headerName: " ));
237
- DEBUG_OUTPUT.println (headerName);
238
- DEBUG_OUTPUT.print (F (" headerValue: " ));
239
- DEBUG_OUTPUT.println (headerValue);
240
- #endif
188
+ if (isEncoded) {
189
+ // isEncoded => !isForm => plainBuf is not empty
190
+ // add plainBuf in search str
191
+ if (searchStr.length ())
192
+ searchStr += ' &' ;
193
+ searchStr += plainBuf;
194
+ }
241
195
242
- if (headerName.equalsIgnoreCase (F (" Host" ))){
243
- _hostHeader = headerValue;
244
- }
196
+ // parse searchStr for key/value pairs
197
+ _parseArguments (searchStr);
198
+
199
+ if (!isForm) {
200
+ if (contentLength) {
201
+ // add key=value: plain={body} (post json or other data)
202
+ RequestArgument& arg = _currentArgs[_currentArgCount++];
203
+ arg.key = F (" plain" );
204
+ arg.value = plainBuf;
205
+ _currentArgsHavePlain = 1 ;
206
+ }
207
+ } else { // isForm is true
208
+ // here: content is not yet read (plainBuf is still empty)
209
+ if (!_parseForm (client, boundaryStr, contentLength)) {
210
+ return false ;
211
+ }
212
+ }
245
213
}
246
- _parseArguments (searchStr);
247
- }
248
- client.flush ();
214
+ client.flush ();
249
215
250
216
#ifdef DEBUG_ESP_HTTP_SERVER
251
- DEBUG_OUTPUT.print (F (" Request: " ));
252
- DEBUG_OUTPUT.println (url);
253
- DEBUG_OUTPUT.print (F (" Arguments: " ));
254
- DEBUG_OUTPUT.println (searchStr);
255
-
256
- DEBUG_OUTPUT.println (F (" final list of key/value pairs:" ));
257
- for (int i = 0 ; i < _currentArgCount; i++)
258
- DEBUG_OUTPUT.printf (" key:'%s' value:'%s'\r\n " ,
259
- _currentArgs[i].key .c_str (),
260
- _currentArgs[i].value .c_str ());
217
+ DEBUG_OUTPUT.print (F (" Request: " ));
218
+ DEBUG_OUTPUT.println (url);
219
+ DEBUG_OUTPUT.print (F (" Arguments: " ));
220
+ DEBUG_OUTPUT.println (searchStr);
221
+
222
+ DEBUG_OUTPUT.println (F (" final list of key/value pairs:" ));
223
+ for (int i = 0 ; i < _currentArgCount; i++)
224
+ DEBUG_OUTPUT.printf (" key:'%s' value:'%s'\r\n " ,
225
+ _currentArgs[i].key .c_str (),
226
+ _currentArgs[i].value .c_str ());
261
227
#endif
262
228
263
- return true ;
229
+ return true ;
264
230
}
265
231
266
232
template <typename ServerType>
267
- bool ESP8266WebServerTemplate<ServerType>::_collectHeader(const char * headerName, const char * headerValue) {
268
- for (int i = 0 ; i < _headerKeysCount; i++) {
269
- if (_currentHeaders[i].key .equalsIgnoreCase (headerName)) {
270
- _currentHeaders[i].value = headerValue;
233
+ bool ESP8266WebServerTemplate<ServerType>::_collectHeader(const String& headerName, const String& headerValue) {
234
+ for (int i = 0 ; i < _headerKeysCount; i++) {
235
+ if (_currentHeaders[i].key .equalsIgnoreCase (headerName)) {
236
+ _currentHeaders[i].value = headerValue;
271
237
return true ;
272
238
}
273
- }
274
- return false ;
239
+ }
240
+ return false ;
275
241
}
276
242
277
243
template <typename ServerType>
@@ -359,9 +325,9 @@ int ESP8266WebServerTemplate<ServerType>::_parseArgumentsPrivate(const String& d
359
325
}
360
326
361
327
template <typename ServerType>
362
- void ESP8266WebServerTemplate<ServerType>::_uploadWriteByte(uint8_t b){
363
- if (_currentUpload->currentSize == HTTP_UPLOAD_BUFLEN){
364
- if (_currentHandler && _currentHandler->canUpload (_currentUri))
328
+ void ESP8266WebServerTemplate<ServerType>::_uploadWriteByte(uint8_t b) {
329
+ if (_currentUpload->currentSize == HTTP_UPLOAD_BUFLEN) {
330
+ if (_currentHandler && _currentHandler->canUpload (_currentUri))
365
331
_currentHandler->upload (*this , _currentUri, *_currentUpload);
366
332
_currentUpload->totalSize += _currentUpload->currentSize ;
367
333
_currentUpload->currentSize = 0 ;
@@ -427,8 +393,9 @@ bool ESP8266WebServerTemplate<ServerType>::_parseForm(ClientType& client, const
427
393
DEBUG_OUTPUT.println (argFilename);
428
394
#endif
429
395
// use GET to set the filename if uploading using blob
430
- if (argFilename == F (" blob" ) && hasArg (FPSTR (filename)))
431
- argFilename = arg (FPSTR (filename));
396
+ String filenameArg = arg (F (" filename" ));
397
+ if (argFilename == F (" blob" ) && !filenameArg.isEmpty ())
398
+ argFilename = filenameArg;
432
399
}
433
400
#ifdef DEBUG_ESP_HTTP_SERVER
434
401
DEBUG_OUTPUT.print (" PostArg Name: " );
0 commit comments