Send as much as possible from the response with the headers

related to: https://github.com/me-no-dev/ESPAsyncWebServer/issues/15
This commit is contained in:
Me No Dev 2016-04-08 14:55:41 +03:00
parent c0fd47bbf9
commit ced8ac1c4c
1 changed files with 34 additions and 37 deletions

View File

@ -234,18 +234,7 @@ void AsyncAbstractResponse::_respond(AsyncWebServerRequest *request){
} }
_head = _assembleHead(request->version()); _head = _assembleHead(request->version());
_state = RESPONSE_HEADERS; _state = RESPONSE_HEADERS;
size_t outLen = _head.length(); _ack(request, 0, 0);
size_t space = request->client()->space();
if(space >= outLen){
request->client()->write(_head.c_str(), outLen);
_head = String();
_state = RESPONSE_CONTENT;
} else {
String out = _head.substring(0, space);
_head = _head.substring(space);
request->client()->write(out.c_str(), out.length());
out = String();
}
} }
size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){
@ -256,43 +245,64 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, u
} }
_ackedLength += len; _ackedLength += len;
size_t space = request->client()->space(); size_t space = request->client()->space();
size_t headLen = _head.length();
if(_state == RESPONSE_HEADERS){
if(space >= headLen){
_state = RESPONSE_CONTENT;
space -= headLen;
} else {
String out = _head.substring(0, space);
_head = _head.substring(space);
request->client()->write(out.c_str(), out.length());
return out.length();
}
}
if(_state == RESPONSE_CONTENT){ if(_state == RESPONSE_CONTENT){
size_t outLen; size_t outLen;
size_t readLen = 0;
if(_chunked || !_sendContentLength){ if(_chunked || !_sendContentLength){
outLen = space; outLen = space;
} else { } else {
size_t remaining = _contentLength - _sentLength; outLen = ((_contentLength - _sentLength) > space)?space:(_contentLength - _sentLength);
outLen = (remaining > space)?space:remaining;
} }
uint8_t *buf = (uint8_t *)malloc(outLen);
uint8_t *buf = (uint8_t *)malloc(outLen+headLen);
if (!buf) { if (!buf) {
// os_printf("_ack malloc %d failed\n", outLen); // os_printf("_ack malloc %d failed\n", outLen+headLen);
return 0; return 0;
} }
if(headLen){
sprintf((char*)buf, "%s", _head.c_str());
_head = String();
}
size_t readLen = 0;
if(_chunked){ if(_chunked){
readLen = _fillBuffer(buf, outLen - 8); readLen = _fillBuffer(buf+headLen, outLen - 8);
char pre[6]; char pre[6];
sprintf(pre, "%x\r\n", readLen); sprintf(pre, "%x\r\n", readLen);
size_t preLen = strlen(pre); size_t preLen = strlen(pre);
memmove(buf+preLen, buf, readLen); memmove(buf+headLen+preLen, buf+headLen, readLen);
for(size_t i=0; i<preLen; i++) for(size_t i=0; i<preLen; i++)
buf[i] = pre[i]; buf[i+headLen] = pre[i];
outLen = preLen + readLen; outLen = preLen + readLen + headLen;
buf[outLen++] = '\r'; buf[outLen++] = '\r';
buf[outLen++] = '\n'; buf[outLen++] = '\n';
} else { } else {
outLen = _fillBuffer(buf, outLen); outLen = _fillBuffer(buf+headLen, outLen) + headLen;
} }
if(outLen) if(outLen)
outLen = request->client()->write((const char*)buf, outLen); outLen = request->client()->write((const char*)buf, outLen);
if(_chunked) if(_chunked)
_sentLength += readLen; _sentLength += readLen;
else else
_sentLength += outLen; _sentLength += outLen - headLen;
free(buf); free(buf);
if((_chunked && readLen == 0) || (!_sendContentLength && outLen == 0) || _sentLength == _contentLength){ if((_chunked && readLen == 0) || (!_sendContentLength && outLen == 0) || _sentLength == _contentLength){
@ -300,19 +310,6 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, u
} }
return outLen; return outLen;
} else if(_state == RESPONSE_HEADERS){
size_t outLen = _head.length();
if(space >= outLen){
request->client()->write(_head.c_str(), outLen);
_head = String();
_state = RESPONSE_CONTENT;
return outLen;
} else {
String out = _head.substring(0, space);
_head = _head.substring(space);
request->client()->write(out.c_str(), out.length());
return out.length();
}
} else if(_state == RESPONSE_WAIT_ACK){ } else if(_state == RESPONSE_WAIT_ACK){
if(!_sendContentLength || _ackedLength >= (_headLength+_contentLength)){ if(!_sendContentLength || _ackedLength >= (_headLength+_contentLength)){
_state = RESPONSE_END; _state = RESPONSE_END;