@@ -238,7 +238,6 @@ bool AsyncWebServerResponse::_sourceValid() const {
238238}
239239void AsyncWebServerResponse::_respond (AsyncWebServerRequest *request) {
240240 _state = RESPONSE_END;
241- request->client ()->close ();
242241}
243242size_t AsyncWebServerResponse::_ack (AsyncWebServerRequest *request, size_t len, uint32_t time) {
244243 (void )request;
@@ -265,64 +264,55 @@ AsyncBasicResponse::AsyncBasicResponse(int code, const char *contentType, const
265264
266265void AsyncBasicResponse::_respond (AsyncWebServerRequest *request) {
267266 _state = RESPONSE_HEADERS;
268- String out;
269- _assembleHead (out, request->version ());
270- size_t outLen = out.length ();
271- size_t space = request->client ()->space ();
272- if (!_contentLength && space >= outLen) {
273- _writtenLength += request->client ()->write (out.c_str (), outLen);
274- _state = RESPONSE_WAIT_ACK;
275- } else if (_contentLength && space >= outLen + _contentLength) {
276- out += _content;
277- outLen += _contentLength;
278- _writtenLength += request->client ()->write (out.c_str (), outLen);
279- _state = RESPONSE_WAIT_ACK;
280- } else if (space && space < outLen) {
281- String partial = out.substring (0 , space);
282- _content = out.substring (space) + _content;
283- _contentLength += outLen - space;
284- _writtenLength += request->client ()->write (partial.c_str (), partial.length ());
285- _state = RESPONSE_CONTENT;
286- } else if (space > outLen && space < (outLen + _contentLength)) {
287- size_t shift = space - outLen;
288- outLen += shift;
289- _sentLength += shift;
290- out += _content.substring (0 , shift);
291- _content = _content.substring (shift);
292- _writtenLength += request->client ()->write (out.c_str (), outLen);
293- _state = RESPONSE_CONTENT;
294- } else {
295- _content = out + _content;
296- _contentLength += outLen;
297- _state = RESPONSE_CONTENT;
298- }
267+ _assembleHead (_assembled_headers, request->version ());
268+ _ack (request, 0 , 0 );
299269}
300270
301271size_t AsyncBasicResponse::_ack (AsyncWebServerRequest *request, size_t len, uint32_t time) {
302272 (void )time;
273+
274+ // this is not functionally needed in AsyncBasicResponse itself, but kept for compatibility if some of the derived classes are rely on it somehow
303275 _ackedLength += len;
304- if (_state == RESPONSE_CONTENT) {
305- size_t available = _contentLength - _sentLength;
306- size_t space = request->client ()->space ();
307- // we can fit in this packet
308- if (space > available) {
309- _writtenLength += request->client ()->write (_content.c_str (), available);
310- _content = emptyString;
311- _state = RESPONSE_WAIT_ACK;
312- return available;
276+ size_t payloadlen{0 }; // amount of data to be written to tcp sockbuff during this call, used as return value of this method
277+
278+ // send http headers first
279+ if (_state == RESPONSE_HEADERS) {
280+ // copy headers buffer to sock buffer
281+ size_t const pcb_written = request->client ()->add (_assembled_headers.c_str () + _assembled_headers_written, _assembled_headers.length () - _assembled_headers_written);
282+ _writtenLength += pcb_written;
283+ _assembled_headers_written += pcb_written;
284+ if (_assembled_headers_written < _assembled_headers.length ()){
285+ // we were not able to fit all headers in current buff, send this part here and return later for the rest
286+ if (!request->client ()->send ()){
287+ // something is wrong, what should we do here?
288+ request->client ()->close ();
289+ return 0 ;
290+ }
291+ return pcb_written;
313292 }
314- // send some data, the rest on ack
315- String out = _content.substring (0 , space);
316- _content = _content.substring (space);
317- _sentLength += space;
318- _writtenLength += request->client ()->write (out.c_str (), space);
319- return space;
320- } else if (_state == RESPONSE_WAIT_ACK) {
321- if (_ackedLength >= _writtenLength) {
293+ // otherwise we've added all the (remainder) headers in current buff, go on with content
294+ _state = RESPONSE_CONTENT;
295+ payloadlen += pcb_written;
296+ _assembled_headers = String (); // clear
297+ }
298+
299+ if (_state == RESPONSE_CONTENT) {
300+ size_t const pcb_written = request->client ()->write (_content.c_str () + _sentLength, _content.length () - _sentLength);
301+ _writtenLength += pcb_written; // total written data (hdrs + body)
302+ _sentLength += pcb_written; // body written data
303+ payloadlen += pcb_written; // data writtent in current buff
304+ if (_sentLength >= _content.length ()){
305+ // we've just sent all the (remainder) data in current buff, complete the response
322306 _state = RESPONSE_END;
323307 }
324308 }
325- return 0 ;
309+
310+ // implicit complete
311+ if (_state == RESPONSE_WAIT_ACK) {
312+ _state = RESPONSE_END;
313+ }
314+
315+ return payloadlen;
326316}
327317
328318/*
0 commit comments