better up responses
This commit is contained in:
parent
010c311469
commit
457db5e7f5
|
@ -17,37 +17,44 @@ class AsyncBasicResponse: public AsyncWebServerResponse {
|
||||||
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
||||||
};
|
};
|
||||||
|
|
||||||
class AsyncFileResponse: public AsyncWebServerResponse {
|
class AsyncAbstractResponse: public AsyncWebServerResponse {
|
||||||
|
private:
|
||||||
|
String _head;
|
||||||
|
public:
|
||||||
|
void _respond(AsyncWebServerRequest *request);
|
||||||
|
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
||||||
|
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen){ return 0; }
|
||||||
|
virtual bool _sourceValid(){ return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class AsyncFileResponse: public AsyncAbstractResponse {
|
||||||
private:
|
private:
|
||||||
File _content;
|
File _content;
|
||||||
String _path;
|
String _path;
|
||||||
String _head;
|
|
||||||
void _setContentType(String path);
|
void _setContentType(String path);
|
||||||
public:
|
public:
|
||||||
AsyncFileResponse(FS &fs, String path, String contentType=String(), bool download=false);
|
AsyncFileResponse(FS &fs, String path, String contentType=String(), bool download=false);
|
||||||
~AsyncFileResponse();
|
~AsyncFileResponse();
|
||||||
void _respond(AsyncWebServerRequest *request);
|
bool _sourceValid(){ return !!(_content); }
|
||||||
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
|
||||||
};
|
};
|
||||||
|
|
||||||
class AsyncStreamResponse: public AsyncWebServerResponse {
|
class AsyncStreamResponse: public AsyncAbstractResponse {
|
||||||
private:
|
private:
|
||||||
Stream *_content;
|
Stream *_content;
|
||||||
String _head;
|
|
||||||
public:
|
public:
|
||||||
AsyncStreamResponse(Stream &stream, String contentType, size_t len);
|
AsyncStreamResponse(Stream &stream, String contentType, size_t len);
|
||||||
void _respond(AsyncWebServerRequest *request);
|
bool _sourceValid(){ return !!(_content); }
|
||||||
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
|
||||||
};
|
};
|
||||||
|
|
||||||
class AsyncCallbackResponse: public AsyncWebServerResponse {
|
class AsyncCallbackResponse: public AsyncAbstractResponse {
|
||||||
private:
|
private:
|
||||||
AwsResponseFiller _content;
|
AwsResponseFiller _content;
|
||||||
String _head;
|
|
||||||
public:
|
public:
|
||||||
AsyncCallbackResponse(String contentType, size_t len, AwsResponseFiller callback);
|
AsyncCallbackResponse(String contentType, size_t len, AwsResponseFiller callback);
|
||||||
void _respond(AsyncWebServerRequest *request);
|
bool _sourceValid(){ return !!(_content); }
|
||||||
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ASYNCWEBSERVERRESPONSEIMPL_H_ */
|
#endif /* ASYNCWEBSERVERRESPONSEIMPL_H_ */
|
||||||
|
|
|
@ -72,7 +72,7 @@ class AsyncWebHeader {
|
||||||
* REQUEST :: Each incoming Client is wrapped inside a Request and both live together until disconnect
|
* REQUEST :: Each incoming Client is wrapped inside a Request and both live together until disconnect
|
||||||
* */
|
* */
|
||||||
|
|
||||||
typedef std::function<size_t(uint8_t*, size_t, size_t)> AwsResponseFiller;
|
typedef std::function<size_t(uint8_t*, size_t)> AwsResponseFiller;
|
||||||
|
|
||||||
class AsyncWebServerRequest {
|
class AsyncWebServerRequest {
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -180,6 +180,77 @@ size_t AsyncBasicResponse::_ack(AsyncWebServerRequest *request, size_t len, uint
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Abstract Response
|
||||||
|
* */
|
||||||
|
|
||||||
|
void AsyncAbstractResponse::_respond(AsyncWebServerRequest *request){
|
||||||
|
if(!_sourceValid()){
|
||||||
|
_state = RESPONSE_FAILED;
|
||||||
|
request->send(500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_head = _assembleHead();
|
||||||
|
_state = RESPONSE_HEADERS;
|
||||||
|
size_t outLen = _head.length();
|
||||||
|
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){
|
||||||
|
if(!_sourceValid()){
|
||||||
|
_state = RESPONSE_FAILED;
|
||||||
|
request->client()->close();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ackedLength += len;
|
||||||
|
size_t space = request->client()->space();
|
||||||
|
if(_state == RESPONSE_CONTENT){
|
||||||
|
size_t remaining = _contentLength - _sentLength;
|
||||||
|
size_t outLen = (remaining > space)?space:remaining;
|
||||||
|
uint8_t *buf = (uint8_t *)os_malloc(outLen);
|
||||||
|
outLen = _fillBuffer(buf, outLen);
|
||||||
|
request->client()->write((const char*)buf, outLen);
|
||||||
|
_sentLength += outLen;
|
||||||
|
os_free(buf);
|
||||||
|
if(_sentLength == _contentLength){
|
||||||
|
_state = RESPONSE_WAIT_ACK;
|
||||||
|
}
|
||||||
|
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){
|
||||||
|
if(_ackedLength >= (_headLength+_contentLength)){
|
||||||
|
_state = RESPONSE_END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* File Response
|
* File Response
|
||||||
* */
|
* */
|
||||||
|
@ -223,67 +294,9 @@ AsyncFileResponse::AsyncFileResponse(FS &fs, String path, String contentType, bo
|
||||||
_contentLength = _content.size();
|
_contentLength = _content.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncFileResponse::_respond(AsyncWebServerRequest *request){
|
size_t AsyncFileResponse::_fillBuffer(uint8_t *data, size_t len){
|
||||||
if(!_content){
|
_content.read(data, len);
|
||||||
_state = RESPONSE_FAILED;
|
return len;
|
||||||
request->send(500);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_head = _assembleHead();
|
|
||||||
_state = RESPONSE_HEADERS;
|
|
||||||
size_t outLen = _head.length();
|
|
||||||
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 AsyncFileResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){
|
|
||||||
if(!_content){
|
|
||||||
_state = RESPONSE_FAILED;
|
|
||||||
request->client()->close();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
_ackedLength += len;
|
|
||||||
size_t space = request->client()->space();
|
|
||||||
if(_state == RESPONSE_CONTENT){
|
|
||||||
size_t remaining = _contentLength - _sentLength;
|
|
||||||
size_t outLen = (remaining > space)?space:remaining;
|
|
||||||
uint8_t *buf = (uint8_t *)os_malloc(outLen);
|
|
||||||
_content.read(buf, outLen);
|
|
||||||
request->client()->write((const char*)buf, outLen);
|
|
||||||
_sentLength += outLen;
|
|
||||||
os_free(buf);
|
|
||||||
if(_sentLength == _contentLength){
|
|
||||||
_state = RESPONSE_WAIT_ACK;
|
|
||||||
}
|
|
||||||
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){
|
|
||||||
if(_ackedLength >= (_headLength+_contentLength)){
|
|
||||||
_state = RESPONSE_END;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -297,71 +310,13 @@ AsyncStreamResponse::AsyncStreamResponse(Stream &stream, String contentType, siz
|
||||||
_contentType = contentType;
|
_contentType = contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncStreamResponse::_respond(AsyncWebServerRequest *request){
|
size_t AsyncStreamResponse::_fillBuffer(uint8_t *data, size_t len){
|
||||||
if(!_content){
|
size_t available = _content->available();
|
||||||
_state = RESPONSE_FAILED;
|
size_t outLen = (available > len)?len:available;
|
||||||
request->send(500);
|
size_t i;
|
||||||
return;
|
for(i=0;i<outLen;i++)
|
||||||
}
|
data[i] = _content->read();
|
||||||
_head = _assembleHead();
|
return outLen;
|
||||||
_state = RESPONSE_HEADERS;
|
|
||||||
size_t outLen = _head.length();
|
|
||||||
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 AsyncStreamResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){
|
|
||||||
if(!_content){
|
|
||||||
_state = RESPONSE_FAILED;
|
|
||||||
request->client()->close();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
_ackedLength += len;
|
|
||||||
size_t space = request->client()->space();
|
|
||||||
if(_state == RESPONSE_CONTENT){
|
|
||||||
size_t remaining = _contentLength - _sentLength;
|
|
||||||
size_t available = _content->available();
|
|
||||||
available = (remaining >= available)?available:remaining;
|
|
||||||
size_t outLen = (available > space)?space:available;
|
|
||||||
uint8_t *buf = (uint8_t *)os_malloc(outLen);
|
|
||||||
size_t i;
|
|
||||||
for(i=0;i<outLen;i++)
|
|
||||||
buf[i] = _content->read();
|
|
||||||
request->client()->write((const char*)buf, outLen);
|
|
||||||
_sentLength += outLen;
|
|
||||||
os_free(buf);
|
|
||||||
if(_sentLength == _contentLength){
|
|
||||||
_state = RESPONSE_WAIT_ACK;
|
|
||||||
}
|
|
||||||
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){
|
|
||||||
if(_ackedLength >= (_headLength+_contentLength)){
|
|
||||||
_state = RESPONSE_END;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -375,73 +330,10 @@ AsyncCallbackResponse::AsyncCallbackResponse(String contentType, size_t len, Aws
|
||||||
_contentType = contentType;
|
_contentType = contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncCallbackResponse::_respond(AsyncWebServerRequest *request){
|
size_t AsyncCallbackResponse::_fillBuffer(uint8_t *data, size_t len){
|
||||||
if(!_content){
|
return _content(data, len);
|
||||||
_state = RESPONSE_FAILED;
|
|
||||||
request->send(500);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_head = _assembleHead();
|
|
||||||
_state = RESPONSE_HEADERS;
|
|
||||||
size_t outLen = _head.length();
|
|
||||||
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 AsyncCallbackResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){
|
|
||||||
if(!_content){
|
|
||||||
_state = RESPONSE_FAILED;
|
|
||||||
request->client()->close();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
_ackedLength += len;
|
|
||||||
size_t space = request->client()->space();
|
|
||||||
if(_state == RESPONSE_CONTENT){
|
|
||||||
size_t remaining = _contentLength - _sentLength;
|
|
||||||
size_t outLen = (remaining > space)?space:remaining;
|
|
||||||
uint8_t *buf = (uint8_t *)os_malloc(outLen);
|
|
||||||
outLen = _content(buf, outLen, remaining);
|
|
||||||
request->client()->write((const char*)buf, outLen);
|
|
||||||
_sentLength += outLen;
|
|
||||||
os_free(buf);
|
|
||||||
if(_sentLength == _contentLength){
|
|
||||||
_state = RESPONSE_WAIT_ACK;
|
|
||||||
}
|
|
||||||
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){
|
|
||||||
if(_ackedLength >= (_headLength+_contentLength)){
|
|
||||||
_state = RESPONSE_END;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue