Skip to content

Commit d0c0ccb

Browse files
committed
unify AsyncBasicResponse::_ack code with AsyncAbstractResponse::_ack
1 parent 049ef28 commit d0c0ccb

File tree

2 files changed

+44
-50
lines changed

2 files changed

+44
-50
lines changed

src/WebResponseImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
class AsyncBasicResponse : public AsyncWebServerResponse {
2121
private:
2222
String _content;
23+
// buffer to accumulate all response headers
24+
String _assembled_headers;
25+
// amount of headers buffer writtent to sockbuff
26+
size_t _assembled_headers_written{0};
2327

2428
public:
2529
explicit AsyncBasicResponse(int code, const char *contentType = asyncsrv::empty, const char *content = asyncsrv::empty);

src/WebResponses.cpp

Lines changed: 40 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,6 @@ bool AsyncWebServerResponse::_sourceValid() const {
238238
}
239239
void AsyncWebServerResponse::_respond(AsyncWebServerRequest *request) {
240240
_state = RESPONSE_END;
241-
request->client()->close();
242241
}
243242
size_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

266265
void 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

301271
size_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

Comments
 (0)