@@ -309,42 +309,14 @@ void WebServer::_uploadWriteByte(uint8_t b){
309
309
_currentUpload->buf [_currentUpload->currentSize ++] = b;
310
310
}
311
311
312
- int WebServer::_uploadReadByte (WiFiClient& client){
312
+ int WebServer::_uploadReadByte (WiFiClient& client) {
313
313
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
- }
326
314
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 ();
348
320
}
349
321
350
322
return res;
@@ -436,88 +408,59 @@ bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){
436
408
if (_currentHandler && _currentHandler->canUpload (_currentUri))
437
409
_currentHandler->upload (*this , _currentUri, *_currentUpload);
438
410
_currentUpload->status = UPLOAD_FILE_WRITE;
439
- int argByte = _uploadReadByte (client);
440
- readfile:
441
411
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 ();
502
421
}
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
+ }
512
443
}
513
- argByte = _uploadReadByte (client);
514
- goto readfile;
515
- }
516
- } else {
517
- _uploadWriteByte (0x0D );
518
- goto readfile;
519
444
}
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 ;
521
464
}
522
465
}
523
466
}
0 commit comments