Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit de1774b

Browse filesBrowse files
authored
simplifying webserver file uploads via form POST (espressif#9211)
Backport of espressif#9167
1 parent 7c344cc commit de1774b
Copy full SHA for de1774b

File tree

Expand file treeCollapse file tree

1 file changed

+55
-112
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+55
-112
lines changed

‎libraries/WebServer/src/Parsing.cpp

Copy file name to clipboardExpand all lines: libraries/WebServer/src/Parsing.cpp
+55-112Lines changed: 55 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -309,42 +309,14 @@ void WebServer::_uploadWriteByte(uint8_t b){
309309
_currentUpload->buf[_currentUpload->currentSize++] = b;
310310
}
311311

312-
int WebServer::_uploadReadByte(WiFiClient& client){
312+
int WebServer::_uploadReadByte(WiFiClient& client) {
313313
int res = client.read();
314-
if(res < 0) {
315-
// keep trying until you either read a valid byte or timeout
316-
unsigned long startMillis = millis();
317-
long timeoutIntervalMillis = client.getTimeout();
318-
boolean timedOut = false;
319-
for(;;) {
320-
if (!client.connected()) return -1;
321-
// loosely modeled after blinkWithoutDelay pattern
322-
while(!timedOut && !client.available() && client.connected()){
323-
delay(2);
324-
timedOut = millis() - startMillis >= timeoutIntervalMillis;
325-
}
326314

327-
res = client.read();
328-
if(res >= 0) {
329-
return res; // exit on a valid read
330-
}
331-
// NOTE: it is possible to get here and have all of the following
332-
// assertions hold true
333-
//
334-
// -- client.available() > 0
335-
// -- client.connected == true
336-
// -- res == -1
337-
//
338-
// a simple retry strategy overcomes this which is to say the
339-
// assertion is not permanent, but the reason that this works
340-
// is elusive, and possibly indicative of a more subtle underlying
341-
// issue
342-
343-
timedOut = millis() - startMillis >= timeoutIntervalMillis;
344-
if(timedOut) {
345-
return res; // exit on a timeout
346-
}
347-
}
315+
if (res < 0) {
316+
while(!client.available() && client.connected())
317+
delay(2);
318+
319+
res = client.read();
348320
}
349321

350322
return res;
@@ -436,88 +408,59 @@ bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){
436408
if(_currentHandler && _currentHandler->canUpload(_currentUri))
437409
_currentHandler->upload(*this, _currentUri, *_currentUpload);
438410
_currentUpload->status = UPLOAD_FILE_WRITE;
439-
int argByte = _uploadReadByte(client);
440-
readfile:
441411

442-
while(argByte != 0x0D){
443-
if(argByte < 0) return _parseFormUploadAborted();
444-
_uploadWriteByte(argByte);
445-
argByte = _uploadReadByte(client);
446-
}
447-
448-
argByte = _uploadReadByte(client);
449-
if(argByte < 0) return _parseFormUploadAborted();
450-
if (argByte == 0x0A){
451-
argByte = _uploadReadByte(client);
452-
if(argByte < 0) return _parseFormUploadAborted();
453-
if ((char)argByte != '-'){
454-
//continue reading the file
455-
_uploadWriteByte(0x0D);
456-
_uploadWriteByte(0x0A);
457-
goto readfile;
458-
} else {
459-
argByte = _uploadReadByte(client);
460-
if(argByte < 0) return _parseFormUploadAborted();
461-
if ((char)argByte != '-'){
462-
//continue reading the file
463-
_uploadWriteByte(0x0D);
464-
_uploadWriteByte(0x0A);
465-
_uploadWriteByte((uint8_t)('-'));
466-
goto readfile;
467-
}
468-
}
469-
470-
uint8_t endBuf[boundary.length()];
471-
uint32_t i = 0;
472-
while(i < boundary.length()){
473-
argByte = _uploadReadByte(client);
474-
if(argByte < 0) return _parseFormUploadAborted();
475-
if ((char)argByte == 0x0D){
476-
_uploadWriteByte(0x0D);
477-
_uploadWriteByte(0x0A);
478-
_uploadWriteByte((uint8_t)('-'));
479-
_uploadWriteByte((uint8_t)('-'));
480-
uint32_t j = 0;
481-
while(j < i){
482-
_uploadWriteByte(endBuf[j++]);
483-
}
484-
goto readfile;
485-
}
486-
endBuf[i++] = (uint8_t)argByte;
487-
}
488-
489-
if (strstr((const char*)endBuf, boundary.c_str()) != NULL){
490-
if(_currentHandler && _currentHandler->canUpload(_currentUri))
491-
_currentHandler->upload(*this, _currentUri, *_currentUpload);
492-
_currentUpload->totalSize += _currentUpload->currentSize;
493-
_currentUpload->status = UPLOAD_FILE_END;
494-
if(_currentHandler && _currentHandler->canUpload(_currentUri))
495-
_currentHandler->upload(*this, _currentUri, *_currentUpload);
496-
log_v("End File: %s Type: %s Size: %d", _currentUpload->filename.c_str(), _currentUpload->type.c_str(), _currentUpload->totalSize);
497-
line = client.readStringUntil(0x0D);
498-
client.readStringUntil(0x0A);
499-
if (line == "--"){
500-
log_v("Done Parsing POST");
501-
break;
412+
int fastBoundaryLen = 4 /* \r\n-- */ + boundary.length() + 1 /* \0 */;
413+
char fastBoundary[ fastBoundaryLen ];
414+
snprintf(fastBoundary, fastBoundaryLen, "\r\n--%s", boundary.c_str());
415+
int boundaryPtr = 0;
416+
while ( true ) {
417+
int ret = _uploadReadByte(client);
418+
if (ret < 0) {
419+
// Unexpected, we should have had data available per above
420+
return _parseFormUploadAborted();
502421
}
503-
continue;
504-
} else {
505-
_uploadWriteByte(0x0D);
506-
_uploadWriteByte(0x0A);
507-
_uploadWriteByte((uint8_t)('-'));
508-
_uploadWriteByte((uint8_t)('-'));
509-
uint32_t i = 0;
510-
while(i < boundary.length()){
511-
_uploadWriteByte(endBuf[i++]);
422+
char in = (char) ret;
423+
if (in == fastBoundary[ boundaryPtr ]) {
424+
// The input matched the current expected character, advance and possibly exit this file
425+
boundaryPtr++;
426+
if (boundaryPtr == fastBoundaryLen - 1) {
427+
// We read the whole boundary line, we're done here!
428+
break;
429+
}
430+
} else {
431+
// The char doesn't match what we want, so dump whatever matches we had, the read in char, and reset ptr to start
432+
for (int i = 0; i < boundaryPtr; i++) {
433+
_uploadWriteByte( fastBoundary[ i ] );
434+
}
435+
if (in == fastBoundary[ 0 ]) {
436+
// This could be the start of the real end, mark it so and don't emit/skip it
437+
boundaryPtr = 1;
438+
} else {
439+
// Not the 1st char of our pattern, so emit and ignore
440+
_uploadWriteByte( in );
441+
boundaryPtr = 0;
442+
}
512443
}
513-
argByte = _uploadReadByte(client);
514-
goto readfile;
515-
}
516-
} else {
517-
_uploadWriteByte(0x0D);
518-
goto readfile;
519444
}
520-
break;
445+
// Found the boundary string, finish processing this file upload
446+
if (_currentHandler && _currentHandler->canUpload(_currentUri))
447+
_currentHandler->upload(*this, _currentUri, *_currentUpload);
448+
_currentUpload->totalSize += _currentUpload->currentSize;
449+
_currentUpload->status = UPLOAD_FILE_END;
450+
if (_currentHandler && _currentHandler->canUpload(_currentUri))
451+
_currentHandler->upload(*this, _currentUri, *_currentUpload);
452+
log_v("End File: %s Type: %s Size: %d",
453+
_currentUpload->filename.c_str(),
454+
_currentUpload->type.c_str(),
455+
(int)_currentUpload->totalSize);
456+
if (!client.connected()) return _parseFormUploadAborted();
457+
line = client.readStringUntil('\r');
458+
client.readStringUntil('\n');
459+
if (line == "--") { // extra two dashes mean we reached the end of all form fields
460+
log_v("Done Parsing POST");
461+
break;
462+
}
463+
continue;
521464
}
522465
}
523466
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.