better up responses

This commit is contained in:
Me No Dev 2015-12-19 20:48:53 +02:00
parent 010c311469
commit 457db5e7f5
3 changed files with 103 additions and 204 deletions

View File

@ -17,37 +17,44 @@ class AsyncBasicResponse: public AsyncWebServerResponse {
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:
File _content;
String _path;
String _head;
void _setContentType(String path);
public:
AsyncFileResponse(FS &fs, String path, String contentType=String(), bool download=false);
~AsyncFileResponse();
void _respond(AsyncWebServerRequest *request);
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
bool _sourceValid(){ return !!(_content); }
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
};
class AsyncStreamResponse: public AsyncWebServerResponse {
class AsyncStreamResponse: public AsyncAbstractResponse {
private:
Stream *_content;
String _head;
public:
AsyncStreamResponse(Stream &stream, String contentType, size_t len);
void _respond(AsyncWebServerRequest *request);
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
bool _sourceValid(){ return !!(_content); }
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
};
class AsyncCallbackResponse: public AsyncWebServerResponse {
class AsyncCallbackResponse: public AsyncAbstractResponse {
private:
AwsResponseFiller _content;
String _head;
public:
AsyncCallbackResponse(String contentType, size_t len, AwsResponseFiller callback);
void _respond(AsyncWebServerRequest *request);
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
bool _sourceValid(){ return !!(_content); }
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
};
#endif /* ASYNCWEBSERVERRESPONSEIMPL_H_ */

View File

@ -72,7 +72,7 @@ class AsyncWebHeader {
* 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 {
private:

View File

@ -180,6 +180,77 @@ size_t AsyncBasicResponse::_ack(AsyncWebServerRequest *request, size_t len, uint
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
* */
@ -223,67 +294,9 @@ AsyncFileResponse::AsyncFileResponse(FS &fs, String path, String contentType, bo
_contentLength = _content.size();
}
void AsyncFileResponse::_respond(AsyncWebServerRequest *request){
if(!_content){
_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 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;
size_t AsyncFileResponse::_fillBuffer(uint8_t *data, size_t len){
_content.read(data, len);
return len;
}
/*
@ -297,71 +310,13 @@ AsyncStreamResponse::AsyncStreamResponse(Stream &stream, String contentType, siz
_contentType = contentType;
}
void AsyncStreamResponse::_respond(AsyncWebServerRequest *request){
if(!_content){
_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 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;
size_t AsyncStreamResponse::_fillBuffer(uint8_t *data, size_t len){
size_t available = _content->available();
size_t outLen = (available > len)?len:available;
size_t i;
for(i=0;i<outLen;i++)
data[i] = _content->read();
return outLen;
}
/*
@ -375,73 +330,10 @@ AsyncCallbackResponse::AsyncCallbackResponse(String contentType, size_t len, Aws
_contentType = contentType;
}
void AsyncCallbackResponse::_respond(AsyncWebServerRequest *request){
if(!_content){
_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;
size_t AsyncCallbackResponse::_fillBuffer(uint8_t *data, size_t len){
return _content(data, len);
}