11/* ***************************************************************************************************************************
22 Portenta_H7_AsyncWebResponses.cpp
3-
3+
44 For Portenta_H7 (STM32H7) with Vision-Shield Ethernet
5-
5+
66 Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet
7-
7+
88 Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer)
99 Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer
1010 Licensed under GPLv3 license
11-
11+
1212 Version: 1.4.0
13-
13+
1414 Version Modified By Date Comments
1515 ------- ----------- ---------- -----------
1616 1.0.0 K Hoang 06/10/2021 Initial coding for Portenta_H7 (STM32H7) with Vision-Shield Ethernet
@@ -248,7 +248,6 @@ size_t AsyncWebServerResponse::_ack(AsyncWebServerRequest *request, size_t len,
248248 return 0 ;
249249}
250250
251-
252251// RSMOD///////////////////////////////////////////////
253252
254253/*
@@ -260,6 +259,7 @@ AsyncBasicResponse::AsyncBasicResponse(int code, const String& contentType, cons
260259 _content = String (" " );
261260 _contentCstr = (char *)content; // RSMOD
262261 _contentType = contentType;
262+ _partialHeader = String ();
263263
264264 int iLen;
265265
@@ -285,6 +285,7 @@ AsyncBasicResponse::AsyncBasicResponse(int code, const String& contentType, cons
285285 _content = content;
286286 _contentCstr = nullptr ; // RSMOD
287287 _contentType = contentType;
288+ _partialHeader = String ();
288289
289290 if (_content.length ())
290291 {
@@ -306,7 +307,7 @@ void AsyncBasicResponse::_respond(AsyncWebServerRequest *request)
306307 size_t outLen = out.length ();
307308 size_t space = request->client ()->space ();
308309
309- AWS_LOGDEBUG3 (" AsyncAbstractResponse ::_respond : Pre_respond, _contentLength =" , _contentLength, " , out =" , out );
310+ AWS_LOGDEBUG3 (" AsyncBasicResponse ::_respond : Pre_respond, _contentLength =" , _contentLength, " , out =" , out );
310311 AWS_LOGDEBUG3 (" outLen =" , outLen, " , _contentCstr =" , _contentCstr);
311312
312313 if (!_contentLength && space >= outLen)
@@ -322,21 +323,13 @@ void AsyncBasicResponse::_respond(AsyncWebServerRequest *request)
322323
323324 if (_contentCstr)
324325 {
325- memmove (&_contentCstr[outLen], _contentCstr, _contentLength);
326- memcpy (_contentCstr, out.c_str (), outLen);
327- outLen += _contentLength;
328-
329- AWS_LOGDEBUG1 (" _contentCstr =" , _contentCstr);
330-
331- _writtenLength += request->client ()->write (_contentCstr, outLen);
332- }
333- else
334- {
335- out += _content;
336- outLen += _contentLength;
337- _writtenLength += request->client ()->write (out.c_str (), outLen);
326+ _content = String (_contentCstr); // short _contentCstr - so just send as Arduino String - not much of a penalty - fall into below
338327 }
339328
329+ out += _content;
330+ outLen += _contentLength;
331+ _writtenLength += request->client ()->write (out.c_str (), outLen);
332+
340333 _state = RESPONSE_WAIT_ACK;
341334 }
342335 else if (space && space < outLen)
@@ -347,21 +340,18 @@ void AsyncBasicResponse::_respond(AsyncWebServerRequest *request)
347340
348341 if (_contentCstr)
349342 {
350- int deltaLen = out.length () - partial.length ();
351-
352- memmove (&_contentCstr[deltaLen], _contentCstr, deltaLen);
353- memcpy (_contentCstr, out.substring (space).c_str (), deltaLen);
343+ _partialHeader = out.substring (space);
354344 }
355345 else
356346 {
357347 _content = out.substring (space) + _content;
348+ _contentLength += outLen - space;
358349 }
359350
360- _contentLength += outLen - space;
361-
362351 AWS_LOGDEBUG1 (" partial =" , partial);
363352
364353 _writtenLength += request->client ()->write (partial.c_str (), partial.length ());
354+
365355 _state = RESPONSE_CONTENT;
366356 }
367357 else if (space > outLen && space < (outLen + _contentLength))
@@ -377,12 +367,21 @@ void AsyncBasicResponse::_respond(AsyncWebServerRequest *request)
377367 {
378368 char *s = (char *)malloc (shift + 1 );
379369
380- strncpy (s, _contentCstr, shift);
381- s[shift] = ' \0 ' ;
382- out += String (s);
383- _contentCstr += shift;
370+ if (s != nullptr )
371+ {
372+ strncpy (s, _contentCstr, shift);
373+ s[shift] = ' \0 ' ;
374+ out += String (s);
375+ _contentCstr += shift;
376+
377+ free (s);
378+ }
379+ else
380+ {
381+ AWS_LOGERROR (" AsyncBasicResponse::_respond: Out of heap" );
384382
385- free (s);
383+ return ;
384+ }
386385 }
387386 else
388387 {
@@ -401,19 +400,18 @@ void AsyncBasicResponse::_respond(AsyncWebServerRequest *request)
401400
402401 if (_contentCstr)
403402 {
404- memmove (&_contentCstr[outLen], _contentCstr, _contentLength);
405- memcpy (_contentCstr, out.c_str (), outLen);
403+ _partialHeader = out;
406404 }
407405 else
408406 {
409407 _content = out + _content;
408+ _contentLength += outLen;
410409 }
411-
412- _contentLength += outLen;
410+
413411 _state = RESPONSE_CONTENT;
414412 }
415413
416- AWS_LOGDEBUG3 (" AsyncAbstractResponse ::_respond : Post_respond, _contentLength =" , _contentLength, " , out =" , out );
414+ AWS_LOGDEBUG3 (" AsyncBasicResponse ::_respond : Post_respond, _contentLength =" , _contentLength, " , out =" , out );
417415 AWS_LOGDEBUG3 (" outLen =" , outLen, " , _contentCstr =" , _contentCstr);
418416}
419417
@@ -433,12 +431,40 @@ size_t AsyncBasicResponse::_ack(AsyncWebServerRequest *request, size_t len, uint
433431 size_t available = _contentLength - _sentLength;
434432 size_t space = request->client ()->space ();
435433
434+ if (_partialHeader.length () > 0 )
435+ {
436+ if (_partialHeader.length () > space)
437+ {
438+ // Header longer than space - send a piece of it, and make the _partialHeader = to what remains
439+ String _subHeader;
440+ String tmpString;
441+
442+ _subHeader = _partialHeader.substring (0 , space);
443+ tmpString = _partialHeader.substring (space);
444+ _partialHeader = tmpString;
445+
446+ _writtenLength += request->client ()->write (_subHeader.c_str (), space);
447+
448+ return (_partialHeader.length ());
449+ }
450+ else
451+ {
452+ // _partialHeader is <= space length - therefore send the whole thing, and make the remaining length = to the _contrentLength
453+ _writtenLength += request->client ()->write (_partialHeader.c_str (), _partialHeader.length ());
454+
455+ _partialHeader = String ();
456+
457+ return (_contentLength);
458+ }
459+ }
460+
461+ // if we are here - there is no _partialHJeader to send
462+
436463 AWS_LOGDEBUG3 (" AsyncBasicResponse::_ack : available =" , available, " , space =" , space );
437464
438465 // we can fit in this packet
439466 if (space > available)
440467 {
441- // Serial.println("In space>available");
442468 AWS_LOGDEBUG1 (" AsyncBasicResponse::_ack : Pre_ack, _contentLength =" , _contentLength);
443469
444470 if (_contentCstr)
@@ -453,7 +479,7 @@ size_t AsyncBasicResponse::_ack(AsyncWebServerRequest *request, size_t len, uint
453479 _writtenLength += request->client ()->write (_content.c_str (), available);
454480 _content = String ();
455481 }
456-
482+
457483 _state = RESPONSE_WAIT_ACK;
458484
459485 return available;
@@ -463,11 +489,22 @@ size_t AsyncBasicResponse::_ack(AsyncWebServerRequest *request, size_t len, uint
463489 if (_contentCstr)
464490 {
465491 char *s = (char *)malloc (space + 1 );
466- strncpy (s, _contentCstr, space);
467- s[space] = ' \0 ' ;
468- out = String (s);
469- _contentCstr += space;
470- free (s);
492+
493+ if (s != nullptr )
494+ {
495+ strncpy (s, _contentCstr, space);
496+ s[space] = ' \0 ' ;
497+ out = String (s);
498+ _contentCstr += space;
499+
500+ free (s);
501+ }
502+ else
503+ {
504+ AWS_LOGERROR (" AsyncBasicResponse::_ack: Out of heap" );
505+
506+ return 0 ;
507+ }
471508 }
472509 else
473510 {
@@ -976,4 +1013,3 @@ size_t AsyncResponseStream::write(uint8_t data)
9761013}
9771014
9781015// ///////////////////////////////////////////////
979-
0 commit comments