Template container instead of direct pointer manipulation. (#95)
* using Container instead ofdirect pointers list manipulation * fixed different type of virtual methods. * Fixed typo in conditional * Renamed ListArray to LinkedList * Const reference to String as method parameters to prevent additional copy and memory allocation when String passed by value * fix 'min' redefinition * removed #include <iterator> begin/end methods it's enough for 'for( : )' loop count() renamed to length() spacing fixing * Const reference to String as method parameters to prevent additional copy and memory allocation when String passed by value * Fixed unused params warnings
This commit is contained in:
parent
3e6e890808
commit
a7c4dfb04f
|
@ -189,7 +189,7 @@ void setup(){
|
|||
|
||||
request->send(404);
|
||||
});
|
||||
server.onFileUpload([](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
|
||||
server.onFileUpload([](AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final){
|
||||
if(!index)
|
||||
Serial.printf("UploadStart: %s\n", filename.c_str());
|
||||
Serial.printf("%s", (const char*)data);
|
||||
|
|
|
@ -110,7 +110,6 @@ AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest *request, A
|
|||
_client = request->client();
|
||||
_server = server;
|
||||
_lastId = 0;
|
||||
next = NULL;
|
||||
if(request->hasHeader("Last-Event-ID"))
|
||||
_lastId = atoi(request->getHeader("Last-Event-ID")->value().c_str());
|
||||
|
||||
|
@ -119,7 +118,7 @@ AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest *request, A
|
|||
_client->onAck(NULL, NULL);
|
||||
_client->onPoll(NULL, NULL);
|
||||
_client->onData(NULL, NULL);
|
||||
_client->onTimeout([](void *r, AsyncClient* c, uint32_t time){ ((AsyncEventSourceClient*)(r))->_onTimeout(time); }, this);
|
||||
_client->onTimeout([](void *r, AsyncClient* c __attribute__((unused)), uint32_t time){ ((AsyncEventSourceClient*)(r))->_onTimeout(time); }, this);
|
||||
_client->onDisconnect([](void *r, AsyncClient* c){ ((AsyncEventSourceClient*)(r))->_onDisconnect(); delete c; }, this);
|
||||
_server->_addClient(this);
|
||||
delete request;
|
||||
|
@ -129,7 +128,7 @@ AsyncEventSourceClient::~AsyncEventSourceClient(){
|
|||
close();
|
||||
}
|
||||
|
||||
void AsyncEventSourceClient::_onTimeout(uint32_t time){
|
||||
void AsyncEventSourceClient::_onTimeout(uint32_t time __attribute__((unused))){
|
||||
_client->close(true);
|
||||
}
|
||||
|
||||
|
@ -161,9 +160,9 @@ void AsyncEventSourceClient::send(const char *message, const char *event, uint32
|
|||
|
||||
// Handler
|
||||
|
||||
AsyncEventSource::AsyncEventSource(String url)
|
||||
AsyncEventSource::AsyncEventSource(const String& url)
|
||||
: _url(url)
|
||||
, _clients(NULL)
|
||||
, _clients(LinkedList<AsyncEventSourceClient *>([](AsyncEventSourceClient *c){ delete c; }))
|
||||
, _connectcb(NULL)
|
||||
{}
|
||||
|
||||
|
@ -188,68 +187,38 @@ void AsyncEventSource::_addClient(AsyncEventSourceClient * client){
|
|||
client->write((const char *)temp, 2053);
|
||||
free(temp);
|
||||
}*/
|
||||
if(_clients == NULL){
|
||||
_clients = client;
|
||||
if(_connectcb)
|
||||
_connectcb(client);
|
||||
return;
|
||||
}
|
||||
AsyncEventSourceClient * c = _clients;
|
||||
while(c->next != NULL) c = c->next;
|
||||
c->next = client;
|
||||
|
||||
_clients.add(client);
|
||||
if(_connectcb)
|
||||
_connectcb(client);
|
||||
}
|
||||
|
||||
void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient * client){
|
||||
if(_clients == NULL){
|
||||
return;
|
||||
}
|
||||
if(_clients == client){
|
||||
_clients = client->next;
|
||||
delete client;
|
||||
return;
|
||||
}
|
||||
AsyncEventSourceClient * c = _clients;
|
||||
while(c->next != NULL && c->next != client) c = c->next;
|
||||
if(c->next == NULL){
|
||||
return;
|
||||
}
|
||||
c->next = client->next;
|
||||
delete client;
|
||||
_clients.remove(client);
|
||||
}
|
||||
|
||||
void AsyncEventSource::close(){
|
||||
AsyncEventSourceClient * c = _clients;
|
||||
while(c != NULL){
|
||||
for(const auto &c: _clients){
|
||||
if(c->connected())
|
||||
c->close();
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncEventSource::send(const char *message, const char *event, uint32_t id, uint32_t reconnect){
|
||||
if(_clients == NULL)
|
||||
if(_clients.isEmpty())
|
||||
return;
|
||||
|
||||
String ev = generateEventMessage(message, event, id, reconnect);
|
||||
AsyncEventSourceClient * c = _clients;
|
||||
while(c != NULL){
|
||||
for(const auto &c: _clients){
|
||||
if(c->connected())
|
||||
c->write(ev.c_str(), ev.length());
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
|
||||
size_t AsyncEventSource::count(){
|
||||
size_t i = 0;
|
||||
AsyncEventSourceClient * c = _clients;
|
||||
while(c != NULL){
|
||||
if(c->connected())
|
||||
i++;
|
||||
c = c->next;
|
||||
}
|
||||
return i;
|
||||
size_t AsyncEventSource::count() const {
|
||||
return _clients.count_if([](AsyncEventSourceClient *c){
|
||||
return c->connected();
|
||||
});
|
||||
}
|
||||
|
||||
bool AsyncEventSource::canHandle(AsyncWebServerRequest *request){
|
||||
|
@ -280,7 +249,7 @@ void AsyncEventSourceResponse::_respond(AsyncWebServerRequest *request){
|
|||
_state = RESPONSE_WAIT_ACK;
|
||||
}
|
||||
|
||||
size_t AsyncEventSourceResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){
|
||||
size_t AsyncEventSourceResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time __attribute__((unused))){
|
||||
if(len){
|
||||
new AsyncEventSourceClient(request, _server);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ class AsyncEventSourceClient {
|
|||
uint32_t _lastId;
|
||||
|
||||
public:
|
||||
AsyncEventSourceClient * next;
|
||||
|
||||
AsyncEventSourceClient(AsyncWebServerRequest *request, AsyncEventSource *server);
|
||||
~AsyncEventSourceClient();
|
||||
|
@ -45,8 +44,8 @@ class AsyncEventSourceClient {
|
|||
void close();
|
||||
void write(const char * message, size_t len);
|
||||
void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0);
|
||||
bool connected(){ return (_client != NULL) && _client->connected(); }
|
||||
uint32_t lastId(){ return _lastId; }
|
||||
bool connected() const { return (_client != NULL) && _client->connected(); }
|
||||
uint32_t lastId() const { return _lastId; }
|
||||
|
||||
//system callbacks (do not call)
|
||||
void _onTimeout(uint32_t time);
|
||||
|
@ -56,23 +55,23 @@ class AsyncEventSourceClient {
|
|||
class AsyncEventSource: public AsyncWebHandler {
|
||||
private:
|
||||
String _url;
|
||||
AsyncEventSourceClient * _clients;
|
||||
LinkedList<AsyncEventSourceClient *> _clients;
|
||||
ArEventHandlerFunction _connectcb;
|
||||
public:
|
||||
AsyncEventSource(String url);
|
||||
AsyncEventSource(const String& url);
|
||||
~AsyncEventSource();
|
||||
|
||||
const char * url(){ return _url.c_str(); }
|
||||
const char * url() const { return _url.c_str(); }
|
||||
void close();
|
||||
void onConnect(ArEventHandlerFunction cb);
|
||||
void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0);
|
||||
size_t count(); //number clinets connected
|
||||
size_t count() const; //number clinets connected
|
||||
|
||||
//system callbacks (do not call)
|
||||
void _addClient(AsyncEventSourceClient * client);
|
||||
void _handleDisconnect(AsyncEventSourceClient * client);
|
||||
bool canHandle(AsyncWebServerRequest *request);
|
||||
void handleRequest(AsyncWebServerRequest *request);
|
||||
virtual bool canHandle(AsyncWebServerRequest *request) override final;
|
||||
virtual void handleRequest(AsyncWebServerRequest *request) override final;
|
||||
};
|
||||
|
||||
class AsyncEventSourceResponse: public AsyncWebServerResponse {
|
||||
|
|
|
@ -69,7 +69,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
|
|||
size_t setLength() {
|
||||
_contentLength = _root.measureLength();
|
||||
if (_contentLength) { _isValid = true; }
|
||||
return _contentLength;
|
||||
return _contentLength;
|
||||
}
|
||||
|
||||
size_t _fillBuffer(uint8_t *data, size_t len){
|
||||
|
|
|
@ -133,13 +133,12 @@ class AsyncWebSocketControl {
|
|||
bool _mask;
|
||||
bool _finished;
|
||||
public:
|
||||
AsyncWebSocketControl * next;
|
||||
AsyncWebSocketControl(uint8_t opcode, uint8_t *data=NULL, size_t len=0, bool mask=false)
|
||||
:_opcode(opcode)
|
||||
,_len(len)
|
||||
,_mask(len && mask)
|
||||
,_finished(false)
|
||||
,next(NULL){
|
||||
{
|
||||
if(data == NULL)
|
||||
_len = 0;
|
||||
if(_len){
|
||||
|
@ -151,11 +150,11 @@ class AsyncWebSocketControl {
|
|||
else memcpy(_data, data, len);
|
||||
} else _data = NULL;
|
||||
}
|
||||
~AsyncWebSocketControl(){
|
||||
virtual ~AsyncWebSocketControl(){
|
||||
if(_data != NULL)
|
||||
free(_data);
|
||||
}
|
||||
bool finished(){ return _finished; }
|
||||
virtual bool finished(){ return _finished; }
|
||||
uint8_t opcode(){ return _opcode; }
|
||||
uint8_t len(){ return _len + 2; }
|
||||
size_t send(AsyncClient *client){
|
||||
|
@ -195,18 +194,18 @@ class AsyncWebSocketBasicMessage: public AsyncWebSocketMessage {
|
|||
_data[_len] = 0;
|
||||
}
|
||||
}
|
||||
virtual ~AsyncWebSocketBasicMessage(){
|
||||
virtual ~AsyncWebSocketBasicMessage() override {
|
||||
if(_data != NULL)
|
||||
free(_data);
|
||||
}
|
||||
virtual bool betweenFrames(){ return _acked == _ack; }
|
||||
virtual void ack(size_t len, uint32_t time){
|
||||
virtual bool betweenFrames() const override { return _acked == _ack; }
|
||||
virtual void ack(size_t len, uint32_t time) override {
|
||||
_acked += len;
|
||||
if(_sent == _len && _acked == _ack){
|
||||
_status = WS_MSG_SENT;
|
||||
}
|
||||
}
|
||||
virtual size_t send(AsyncClient *client){
|
||||
virtual size_t send(AsyncClient *client) override {
|
||||
if(_status != WS_MSG_SENDING)
|
||||
return 0;
|
||||
if(_acked < _ack){
|
||||
|
@ -239,17 +238,17 @@ class AsyncWebSocketBasicMessage: public AsyncWebSocketMessage {
|
|||
const char * AWSC_PING_PAYLOAD = "ESPAsyncWebServer-PING";
|
||||
const size_t AWSC_PING_PAYLOAD_LEN = 22;
|
||||
|
||||
AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server){
|
||||
AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server)
|
||||
: _controlQueue(LinkedList<AsyncWebSocketControl *>([](AsyncWebSocketControl *c){ delete c; }))
|
||||
, _messageQueue(LinkedList<AsyncWebSocketMessage *>([](AsyncWebSocketMessage *m){ delete m; }))
|
||||
{
|
||||
_client = request->client();
|
||||
_server = server;
|
||||
_clientId = _server->_getNextId();
|
||||
_status = WS_CONNECTED;
|
||||
_controlQueue = NULL;
|
||||
_messageQueue = NULL;
|
||||
_pstate = 0;
|
||||
_lastMessageTime = millis();
|
||||
_keepAlivePeriod = 0;
|
||||
next = NULL;
|
||||
_client->setRxTimeout(0);
|
||||
_client->onError([](void *r, AsyncClient* c, int8_t error){ ((AsyncWebSocketClient*)(r))->_onError(error); }, this);
|
||||
_client->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ ((AsyncWebSocketClient*)(r))->_onAck(len, time); }, this);
|
||||
|
@ -263,61 +262,49 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async
|
|||
}
|
||||
|
||||
AsyncWebSocketClient::~AsyncWebSocketClient(){
|
||||
while(_messageQueue != NULL){
|
||||
AsyncWebSocketMessage * m = _messageQueue;
|
||||
_messageQueue = _messageQueue->next;
|
||||
delete(m);
|
||||
}
|
||||
while(_controlQueue != NULL){
|
||||
AsyncWebSocketControl * c = _controlQueue;
|
||||
_controlQueue = _controlQueue->next;
|
||||
delete(c);
|
||||
}
|
||||
_messageQueue.free();
|
||||
_controlQueue.free();
|
||||
_server->_handleEvent(this, WS_EVT_DISCONNECT, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){
|
||||
_lastMessageTime = millis();
|
||||
if(_controlQueue != NULL){
|
||||
AsyncWebSocketControl *controlMessage = _controlQueue;
|
||||
if(controlMessage->finished()){
|
||||
_controlQueue = _controlQueue->next;
|
||||
len -= controlMessage->len();
|
||||
if(_status == WS_DISCONNECTING && controlMessage->opcode() == WS_DISCONNECT){
|
||||
delete controlMessage;
|
||||
if(!_controlQueue.isEmpty()){
|
||||
auto head = _controlQueue.front();
|
||||
if(head->finished()){
|
||||
len -= head->len();
|
||||
if(_status == WS_DISCONNECTING && head->opcode() == WS_DISCONNECT){
|
||||
_controlQueue.remove(head);
|
||||
_status = WS_DISCONNECTED;
|
||||
_client->close(true);
|
||||
return;
|
||||
}
|
||||
delete controlMessage;
|
||||
_controlQueue.remove(head);
|
||||
}
|
||||
}
|
||||
if(len && _messageQueue != NULL){
|
||||
_messageQueue->ack(len, time);
|
||||
if(len && !_messageQueue.isEmpty()){
|
||||
_messageQueue.front()->ack(len, time);
|
||||
}
|
||||
_runQueue();
|
||||
}
|
||||
|
||||
void AsyncWebSocketClient::_onPoll(){
|
||||
if(_client->canSend() && (_controlQueue != NULL || _messageQueue != NULL)){
|
||||
if(_client->canSend() && (!_controlQueue.isEmpty() || !_messageQueue.isEmpty())){
|
||||
_runQueue();
|
||||
} else if(_keepAlivePeriod > 0 && _controlQueue == NULL && _messageQueue == NULL && (millis() - _lastMessageTime) >= _keepAlivePeriod){
|
||||
} else if(_keepAlivePeriod > 0 && _controlQueue.isEmpty() && _messageQueue.isEmpty() && (millis() - _lastMessageTime) >= _keepAlivePeriod){
|
||||
ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebSocketClient::_runQueue(){
|
||||
while(_messageQueue != NULL && _messageQueue->finished()){
|
||||
AsyncWebSocketMessage * m = _messageQueue;
|
||||
_messageQueue = _messageQueue->next;
|
||||
delete(m);
|
||||
while(!_messageQueue.isEmpty() && _messageQueue.front()->finished()){
|
||||
_messageQueue.remove(_messageQueue.front());
|
||||
}
|
||||
|
||||
if(_controlQueue != NULL && (_messageQueue == NULL || _messageQueue->betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue->len() - 1)){
|
||||
AsyncWebSocketControl *control = _controlQueue;
|
||||
control->send(_client);
|
||||
} else if(_messageQueue != NULL && _messageQueue->betweenFrames() && webSocketSendFrameWindow(_client)){
|
||||
_messageQueue->send(_client);
|
||||
if(!_controlQueue.isEmpty() && (_messageQueue.isEmpty() || _messageQueue.front()->betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front()->len() - 1)){
|
||||
_controlQueue.front()->send(_client);
|
||||
} else if(!_messageQueue.isEmpty() && _messageQueue.front()->betweenFrames() && webSocketSendFrameWindow(_client)){
|
||||
_messageQueue.front()->send(_client);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,13 +315,7 @@ void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessage *dataMessage){
|
|||
delete dataMessage;
|
||||
return;
|
||||
}
|
||||
if(_messageQueue == NULL){
|
||||
_messageQueue = dataMessage;
|
||||
} else {
|
||||
AsyncWebSocketMessage * m = _messageQueue;
|
||||
while(m->next != NULL) m = m->next;
|
||||
m->next = dataMessage;
|
||||
}
|
||||
_messageQueue.add(dataMessage);
|
||||
if(_client->canSend())
|
||||
_runQueue();
|
||||
}
|
||||
|
@ -342,13 +323,7 @@ void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessage *dataMessage){
|
|||
void AsyncWebSocketClient::_queueControl(AsyncWebSocketControl *controlMessage){
|
||||
if(controlMessage == NULL)
|
||||
return;
|
||||
if(_controlQueue == NULL){
|
||||
_controlQueue = controlMessage;
|
||||
} else {
|
||||
AsyncWebSocketControl * m = _controlQueue;
|
||||
while(m->next != NULL) m = m->next;
|
||||
m->next = controlMessage;
|
||||
}
|
||||
_controlQueue.add(controlMessage);
|
||||
if(_client->canSend())
|
||||
_runQueue();
|
||||
}
|
||||
|
@ -604,9 +579,9 @@ uint16_t AsyncWebSocketClient::remotePort() {
|
|||
* Async Web Socket - Each separate socket location
|
||||
*/
|
||||
|
||||
AsyncWebSocket::AsyncWebSocket(String url)
|
||||
AsyncWebSocket::AsyncWebSocket(const String& url)
|
||||
:_url(url)
|
||||
,_clients(NULL)
|
||||
,_clients(LinkedList<AsyncWebSocketClient *>([](AsyncWebSocketClient *c){ delete c; }))
|
||||
,_cNextId(1)
|
||||
,_enabled(true)
|
||||
{
|
||||
|
@ -622,133 +597,100 @@ void AsyncWebSocket::_handleEvent(AsyncWebSocketClient * client, AwsEventType ty
|
|||
}
|
||||
|
||||
void AsyncWebSocket::_addClient(AsyncWebSocketClient * client){
|
||||
if(_clients == NULL){
|
||||
_clients = client;
|
||||
return;
|
||||
}
|
||||
AsyncWebSocketClient * c = _clients;
|
||||
while(c->next != NULL) c = c->next;
|
||||
c->next = client;
|
||||
_clients.add(client);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::_handleDisconnect(AsyncWebSocketClient * client){
|
||||
if(_clients == NULL){
|
||||
return;
|
||||
}
|
||||
if(_clients->id() == client->id()){
|
||||
_clients = client->next;
|
||||
delete client;
|
||||
return;
|
||||
}
|
||||
AsyncWebSocketClient * c = _clients;
|
||||
while(c->next != NULL && c->next->id() != client->id()) c = c->next;
|
||||
if(c->next == NULL){
|
||||
return;
|
||||
}
|
||||
c->next = client->next;
|
||||
delete client;
|
||||
|
||||
_clients.remove_first([=](AsyncWebSocketClient * c){
|
||||
return c->id() == client->id();
|
||||
});
|
||||
}
|
||||
|
||||
size_t AsyncWebSocket::count(){
|
||||
size_t i = 0;
|
||||
AsyncWebSocketClient * c = _clients;
|
||||
while(c != NULL){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
i++;
|
||||
c = c->next;
|
||||
}
|
||||
return i;
|
||||
size_t AsyncWebSocket::count() const {
|
||||
return _clients.count_if([](AsyncWebSocketClient * c){
|
||||
return c->status() == WS_CONNECTED;
|
||||
});
|
||||
}
|
||||
|
||||
AsyncWebSocketClient * AsyncWebSocket::client(uint32_t id){
|
||||
AsyncWebSocketClient * c = _clients;
|
||||
while(c != NULL && c->id() != id)
|
||||
c = c->next;
|
||||
if(c != NULL && c->status() == WS_CONNECTED)
|
||||
return c;
|
||||
return NULL;
|
||||
for(const auto &c: _clients){
|
||||
if(c->id() == id && c->status() == WS_CONNECTED){
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void AsyncWebSocket::close(uint32_t id, uint16_t code, const char * message){
|
||||
AsyncWebSocketClient * c = client(id);
|
||||
if(c != NULL)
|
||||
if(c)
|
||||
c->close(code, message);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::closeAll(uint16_t code, const char * message){
|
||||
AsyncWebSocketClient * c = _clients;
|
||||
while(c != NULL){
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c->close(code, message);
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len){
|
||||
AsyncWebSocketClient * c = client(id);
|
||||
if(c != NULL)
|
||||
if(c)
|
||||
c->ping(data, len);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::pingAll(uint8_t *data, size_t len){
|
||||
AsyncWebSocketClient * c = _clients;
|
||||
while(c != NULL){
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c->ping(data, len);
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AsyncWebSocket::text(uint32_t id, const char * message, size_t len){
|
||||
AsyncWebSocketClient * c = client(id);
|
||||
if(c != NULL)
|
||||
if(c)
|
||||
c->text(message, len);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::textAll(const char * message, size_t len){
|
||||
AsyncWebSocketClient * c = _clients;
|
||||
while(c != NULL){
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c->text(message, len);
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len){
|
||||
AsyncWebSocketClient * c = client(id);
|
||||
if(c != NULL)
|
||||
if(c)
|
||||
c->binary(message, len);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::binaryAll(const char * message, size_t len){
|
||||
AsyncWebSocketClient * c = _clients;
|
||||
while(c != NULL){
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c->binary(message, len);
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebSocket::message(uint32_t id, AsyncWebSocketMessage *message){
|
||||
AsyncWebSocketClient * c = client(id);
|
||||
if(c != NULL)
|
||||
if(c)
|
||||
c->message(message);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::messageAll(AsyncWebSocketMessage *message){
|
||||
AsyncWebSocketClient * c = _clients;
|
||||
while(c != NULL){
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c->message(message);
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
|
||||
size_t AsyncWebSocket::printf(uint32_t id, const char *format, ...){
|
||||
AsyncWebSocketClient * c = client(id);
|
||||
if(c != NULL){
|
||||
if(c){
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
size_t len = c->printf(format, arg);
|
||||
|
@ -854,11 +796,9 @@ void AsyncWebSocket::textAll(const String &message){
|
|||
textAll(message.c_str(), message.length());
|
||||
}
|
||||
void AsyncWebSocket::textAll(const __FlashStringHelper *message){
|
||||
AsyncWebSocketClient * c = _clients;
|
||||
while(c != NULL){
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c->text(message);
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
void AsyncWebSocket::binary(uint32_t id, const char * message){
|
||||
|
@ -891,11 +831,9 @@ void AsyncWebSocket::binaryAll(const String &message){
|
|||
binaryAll(message.c_str(), message.length());
|
||||
}
|
||||
void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len){
|
||||
AsyncWebSocketClient * c = _clients;
|
||||
while(c != NULL){
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c-> binary(message, len);
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -952,7 +890,7 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request){
|
|||
* Authentication code from https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSockets.cpp#L480
|
||||
*/
|
||||
|
||||
AsyncWebSocketResponse::AsyncWebSocketResponse(String key, AsyncWebSocket *server){
|
||||
AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket *server){
|
||||
_server = server;
|
||||
_code = 101;
|
||||
uint8_t * hash = (uint8_t*)malloc(20);
|
||||
|
|
|
@ -52,13 +52,12 @@ class AsyncWebSocketMessage {
|
|||
bool _mask;
|
||||
AwsMessageStatus _status;
|
||||
public:
|
||||
AsyncWebSocketMessage * next;
|
||||
AsyncWebSocketMessage():_opcode(WS_TEXT),_mask(false),_status(WS_MSG_ERROR),next(NULL){}
|
||||
AsyncWebSocketMessage():_opcode(WS_TEXT),_mask(false),_status(WS_MSG_ERROR){}
|
||||
virtual ~AsyncWebSocketMessage(){}
|
||||
virtual void ack(size_t len, uint32_t time){}
|
||||
virtual size_t send(AsyncClient *client){ return 0; }
|
||||
virtual void ack(size_t len __attribute__((unused)), uint32_t time __attribute__((unused))){}
|
||||
virtual size_t send(AsyncClient *client __attribute__((unused))){ return 0; }
|
||||
virtual bool finished(){ return _status != WS_MSG_SENDING; }
|
||||
virtual bool betweenFrames(){ return false; }
|
||||
virtual bool betweenFrames() const { return false; }
|
||||
};
|
||||
|
||||
class AsyncWebSocketClient {
|
||||
|
@ -68,8 +67,8 @@ class AsyncWebSocketClient {
|
|||
uint32_t _clientId;
|
||||
AwsClientStatus _status;
|
||||
|
||||
AsyncWebSocketControl * _controlQueue;
|
||||
AsyncWebSocketMessage * _messageQueue;
|
||||
LinkedList<AsyncWebSocketControl *> _controlQueue;
|
||||
LinkedList<AsyncWebSocketMessage *> _messageQueue;
|
||||
|
||||
uint8_t _pstate;
|
||||
AwsFrameInfo _pinfo;
|
||||
|
@ -82,8 +81,6 @@ class AsyncWebSocketClient {
|
|||
void _runQueue();
|
||||
|
||||
public:
|
||||
AsyncWebSocketClient * next;
|
||||
|
||||
AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server);
|
||||
~AsyncWebSocketClient();
|
||||
|
||||
|
@ -142,18 +139,18 @@ typedef std::function<void(AsyncWebSocket * server, AsyncWebSocketClient * clien
|
|||
class AsyncWebSocket: public AsyncWebHandler {
|
||||
private:
|
||||
String _url;
|
||||
AsyncWebSocketClient * _clients;
|
||||
LinkedList<AsyncWebSocketClient *> _clients;
|
||||
uint32_t _cNextId;
|
||||
AwsEventHandler _eventHandler;
|
||||
bool _enabled;
|
||||
public:
|
||||
AsyncWebSocket(String url);
|
||||
AsyncWebSocket(const String& url);
|
||||
~AsyncWebSocket();
|
||||
const char * url(){ return _url.c_str(); }
|
||||
const char * url() const { return _url.c_str(); }
|
||||
void enable(bool e){ _enabled = e; }
|
||||
bool enabled() { return _enabled; }
|
||||
bool enabled() const { return _enabled; }
|
||||
|
||||
size_t count();
|
||||
size_t count() const;
|
||||
AsyncWebSocketClient * client(uint32_t id);
|
||||
bool hasClient(uint32_t id){ return client(id) != NULL; }
|
||||
|
||||
|
@ -209,8 +206,8 @@ class AsyncWebSocket: public AsyncWebHandler {
|
|||
void _addClient(AsyncWebSocketClient * client);
|
||||
void _handleDisconnect(AsyncWebSocketClient * client);
|
||||
void _handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len);
|
||||
bool canHandle(AsyncWebServerRequest *request);
|
||||
void handleRequest(AsyncWebServerRequest *request);
|
||||
virtual bool canHandle(AsyncWebServerRequest *request) override final;
|
||||
virtual void handleRequest(AsyncWebServerRequest *request) override final;
|
||||
};
|
||||
|
||||
//WebServer response to authenticate the socket and detach the tcp client from the web server request
|
||||
|
@ -219,7 +216,7 @@ class AsyncWebSocketResponse: public AsyncWebServerResponse {
|
|||
String _content;
|
||||
AsyncWebSocket *_server;
|
||||
public:
|
||||
AsyncWebSocketResponse(String key, AsyncWebSocket *server);
|
||||
AsyncWebSocketResponse(const String& key, AsyncWebSocket *server);
|
||||
void _respond(AsyncWebServerRequest *request);
|
||||
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
||||
bool _sourceValid(){ return true; }
|
||||
|
|
|
@ -76,14 +76,13 @@ class AsyncWebParameter {
|
|||
bool _isFile;
|
||||
|
||||
public:
|
||||
AsyncWebParameter *next;
|
||||
|
||||
AsyncWebParameter(String name, String value, bool form=false, bool file=false, size_t size=0): _name(name), _value(value), _size(size), _isForm(form), _isFile(file), next(NULL){}
|
||||
String name(){ return _name; }
|
||||
String value(){ return _value; }
|
||||
size_t size(){ return _size; }
|
||||
bool isPost(){ return _isForm; }
|
||||
bool isFile(){ return _isFile; }
|
||||
AsyncWebParameter(const String& name, const String& value, bool form=false, bool file=false, size_t size=0): _name(name), _value(value), _size(size), _isForm(form), _isFile(file){}
|
||||
const String& name() const { return _name; }
|
||||
const String& value() const { return _value; }
|
||||
size_t size() const { return _size; }
|
||||
bool isPost() const { return _isForm; }
|
||||
bool isFile() const { return _isFile; }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -96,10 +95,8 @@ class AsyncWebHeader {
|
|||
String _value;
|
||||
|
||||
public:
|
||||
AsyncWebHeader *next;
|
||||
|
||||
AsyncWebHeader(String name, String value): _name(name), _value(value), next(NULL){}
|
||||
AsyncWebHeader(String data): _name(), _value(), next(NULL){
|
||||
AsyncWebHeader(const String& name, const String& value): _name(name), _value(value){}
|
||||
AsyncWebHeader(const String& data): _name(), _value(){
|
||||
if(!data) return;
|
||||
int index = data.indexOf(':');
|
||||
if (index < 0) return;
|
||||
|
@ -107,9 +104,9 @@ class AsyncWebHeader {
|
|||
_value = data.substring(index + 2);
|
||||
}
|
||||
~AsyncWebHeader(){}
|
||||
String name(){ return _name; }
|
||||
String value(){ return _value; }
|
||||
String toString(){ return String(_name+": "+_value+"\r\n"); }
|
||||
const String& name() const { return _name; }
|
||||
const String& value() const { return _value; }
|
||||
String toString() const { return String(_name+": "+_value+"\r\n"); }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -125,7 +122,7 @@ class AsyncWebServerRequest {
|
|||
AsyncWebServer* _server;
|
||||
AsyncWebHandler* _handler;
|
||||
AsyncWebServerResponse* _response;
|
||||
StringArray* _interestingHeaders;
|
||||
StringArray _interestingHeaders;
|
||||
|
||||
String _temp;
|
||||
uint8_t _parseState;
|
||||
|
@ -144,8 +141,8 @@ class AsyncWebServerRequest {
|
|||
size_t _contentLength;
|
||||
size_t _parsedLength;
|
||||
|
||||
AsyncWebHeader *_headers;
|
||||
AsyncWebParameter *_params;
|
||||
LinkedList<AsyncWebHeader *> _headers;
|
||||
LinkedList<AsyncWebParameter *> _params;
|
||||
|
||||
uint8_t _multiParseState;
|
||||
uint8_t _boundaryPosition;
|
||||
|
@ -173,7 +170,7 @@ class AsyncWebServerRequest {
|
|||
void _parseLine();
|
||||
void _parsePlainPostChar(uint8_t data);
|
||||
void _parseMultipartPostByte(uint8_t data, bool last);
|
||||
void _addGetParams(String params);
|
||||
void _addGetParams(const String& params);
|
||||
|
||||
void _handleUploadStart();
|
||||
void _handleUploadByte(uint8_t data, bool last);
|
||||
|
@ -182,20 +179,19 @@ class AsyncWebServerRequest {
|
|||
public:
|
||||
File _tempFile;
|
||||
void *_tempObject;
|
||||
AsyncWebServerRequest *next;
|
||||
|
||||
AsyncWebServerRequest(AsyncWebServer*, AsyncClient*);
|
||||
~AsyncWebServerRequest();
|
||||
|
||||
AsyncClient* client(){ return _client; }
|
||||
uint8_t version(){ return _version; }
|
||||
WebRequestMethodComposite method(){ return _method; }
|
||||
String url(){ return _url; }
|
||||
String host(){ return _host; }
|
||||
String contentType(){ return _contentType; }
|
||||
size_t contentLength(){ return _contentLength; }
|
||||
bool multipart(){ return _isMultipart; }
|
||||
const char * methodToString();
|
||||
uint8_t version() const { return _version; }
|
||||
WebRequestMethodComposite method() const { return _method; }
|
||||
const String& url() const { return _url; }
|
||||
const String& host() const { return _host; }
|
||||
const String& contentType() const { return _contentType; }
|
||||
size_t contentLength() const { return _contentLength; }
|
||||
bool multipart() const { return _isMultipart; }
|
||||
const char * methodToString() const;
|
||||
|
||||
|
||||
//hash is the string representation of:
|
||||
|
@ -206,52 +202,50 @@ class AsyncWebServerRequest {
|
|||
void requestAuthentication(const char * realm = NULL, bool isDigest = true);
|
||||
|
||||
void setHandler(AsyncWebHandler *handler){ _handler = handler; }
|
||||
void addInterestingHeader(String name);
|
||||
void addInterestingHeader(const String& name);
|
||||
|
||||
void redirect(String url);
|
||||
void redirect(const String& url);
|
||||
|
||||
void send(AsyncWebServerResponse *response);
|
||||
void send(int code, String contentType=String(), String content=String());
|
||||
void send(FS &fs, String path, String contentType=String(), bool download=false);
|
||||
void send(File content, String path, String contentType=String(), bool download=false);
|
||||
void send(Stream &stream, String contentType, size_t len);
|
||||
void send(String contentType, size_t len, AwsResponseFiller callback);
|
||||
void sendChunked(String contentType, AwsResponseFiller callback);
|
||||
void send_P(int code, String contentType, const uint8_t * content, size_t len);
|
||||
void send_P(int code, String contentType, PGM_P content);
|
||||
void send(int code, const String& contentType=String(), const String& content=String());
|
||||
void send(FS &fs, const String& path, const String& contentType=String(), bool download=false);
|
||||
void send(File content, const String& path, const String& contentType=String(), bool download=false);
|
||||
void send(Stream &stream, const String& contentType, size_t len);
|
||||
void send(const String& contentType, size_t len, AwsResponseFiller callback);
|
||||
void sendChunked(const String& contentType, AwsResponseFiller callback);
|
||||
void send_P(int code, const String& contentType, const uint8_t * content, size_t len);
|
||||
void send_P(int code, const String& contentType, PGM_P content);
|
||||
|
||||
AsyncWebServerResponse *beginResponse(int code, String contentType=String(), String content=String());
|
||||
AsyncWebServerResponse *beginResponse(FS &fs, String path, String contentType=String(), bool download=false);
|
||||
AsyncWebServerResponse *beginResponse(File content, String path, String contentType=String(), bool download=false);
|
||||
AsyncWebServerResponse *beginResponse(Stream &stream, String contentType, size_t len);
|
||||
AsyncWebServerResponse *beginResponse(String contentType, size_t len, AwsResponseFiller callback);
|
||||
AsyncWebServerResponse *beginChunkedResponse(String contentType, AwsResponseFiller callback);
|
||||
AsyncResponseStream *beginResponseStream(String contentType, size_t bufferSize=1460);
|
||||
AsyncWebServerResponse *beginResponse_P(int code, String contentType, const uint8_t * content, size_t len);
|
||||
AsyncWebServerResponse *beginResponse_P(int code, String contentType, PGM_P content);
|
||||
AsyncWebServerResponse *beginResponse(int code, const String& contentType=String(), const String& content=String());
|
||||
AsyncWebServerResponse *beginResponse(FS &fs, const String& path, const String& contentType=String(), bool download=false);
|
||||
AsyncWebServerResponse *beginResponse(File content, const String& path, const String& contentType=String(), bool download=false);
|
||||
AsyncWebServerResponse *beginResponse(Stream &stream, const String& contentType, size_t len);
|
||||
AsyncWebServerResponse *beginResponse(const String& contentType, size_t len, AwsResponseFiller callback);
|
||||
AsyncWebServerResponse *beginChunkedResponse(const String& contentType, AwsResponseFiller callback);
|
||||
AsyncResponseStream *beginResponseStream(const String& contentType, size_t bufferSize=1460);
|
||||
AsyncWebServerResponse *beginResponse_P(int code, const String& contentType, const uint8_t * content, size_t len);
|
||||
AsyncWebServerResponse *beginResponse_P(int code, const String& contentType, PGM_P content);
|
||||
|
||||
int headers(); // get header count
|
||||
bool hasHeader(String name);
|
||||
AsyncWebHeader* getHeader(String name);
|
||||
AsyncWebHeader* getHeader(int num);
|
||||
size_t headers() const; // get header count
|
||||
bool hasHeader(const String& name) const; // check if header exists
|
||||
AsyncWebHeader* getHeader(const String& name) const;
|
||||
AsyncWebHeader* getHeader(size_t num) const;
|
||||
|
||||
int params(); // get arguments count
|
||||
bool hasParam(String name, bool post=false, bool file=false);
|
||||
AsyncWebParameter* getParam(String name, bool post=false, bool file=false);
|
||||
AsyncWebParameter* getParam(int num);
|
||||
size_t params() const; // get arguments count
|
||||
bool hasParam(const String& name, bool post=false, bool file=false) const;
|
||||
AsyncWebParameter* getParam(const String& name, bool post=false, bool file=false) const;
|
||||
AsyncWebParameter* getParam(size_t num) const;
|
||||
|
||||
int args(){ return params(); } // get arguments count
|
||||
String arg(const char* name); // get request argument value by name
|
||||
String arg(int i); // get request argument value by number
|
||||
String argName(int i); // get request argument name by number
|
||||
bool hasArg(const char* name); // check if argument exists
|
||||
size_t args() const { return params(); } // get arguments count
|
||||
const String& arg(const String& name) const; // get request argument value by name
|
||||
const String& arg(size_t i) const; // get request argument value by number
|
||||
const String& argName(size_t i) const; // get request argument name by number
|
||||
bool hasArg(const char* name) const; // check if argument exists
|
||||
|
||||
String header(const char* name); // get request header value by name
|
||||
String header(int i); // get request header value by number
|
||||
String headerName(int i); // get request header name by number
|
||||
bool hasHeader(const char* name); // check if header exists
|
||||
|
||||
String urlDecode(const String& text);
|
||||
const String& header(const char* name) const;// get request header value by name
|
||||
const String& header(size_t i) const; // get request header value by number
|
||||
const String& headerName(size_t i) const; // get request header name by number
|
||||
String urlDecode(const String& text) const;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -260,13 +254,9 @@ class AsyncWebServerRequest {
|
|||
|
||||
typedef std::function<bool(AsyncWebServerRequest *request)> ArRequestFilterFunction;
|
||||
|
||||
static bool ON_STA_FILTER(AsyncWebServerRequest *request) {
|
||||
return WiFi.localIP() == request->client()->localIP();
|
||||
}
|
||||
bool ON_STA_FILTER(AsyncWebServerRequest *request);
|
||||
|
||||
static bool ON_AP_FILTER(AsyncWebServerRequest *request) {
|
||||
return WiFi.localIP() != request->client()->localIP();
|
||||
}
|
||||
bool ON_AP_FILTER(AsyncWebServerRequest *request);
|
||||
|
||||
/*
|
||||
* REWRITE :: One instance can be handle any Request (done by the Server)
|
||||
|
@ -279,8 +269,7 @@ class AsyncWebRewrite {
|
|||
String _params;
|
||||
ArRequestFilterFunction _filter;
|
||||
public:
|
||||
AsyncWebRewrite* next;
|
||||
AsyncWebRewrite(const char* from, const char* to): _from(from), _toUrl(to), _params(String()), _filter(NULL), next(NULL){
|
||||
AsyncWebRewrite(const char* from, const char* to): _from(from), _toUrl(to), _params(String()), _filter(NULL){
|
||||
int index = _toUrl.indexOf('?');
|
||||
if (index > 0) {
|
||||
_params = _toUrl.substring(index +1);
|
||||
|
@ -288,10 +277,10 @@ class AsyncWebRewrite {
|
|||
}
|
||||
}
|
||||
AsyncWebRewrite& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; }
|
||||
bool filter(AsyncWebServerRequest *request){ return _filter == NULL || _filter(request); }
|
||||
String from(void) { return _from; }
|
||||
String toUrl(void) { return _toUrl; }
|
||||
String params(void) { return _params; }
|
||||
bool filter(AsyncWebServerRequest *request) const { return _filter == NULL || _filter(request); }
|
||||
const String& from(void) const { return _from; }
|
||||
const String& toUrl(void) const { return _toUrl; }
|
||||
const String& params(void) const { return _params; }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -302,15 +291,16 @@ class AsyncWebHandler {
|
|||
protected:
|
||||
ArRequestFilterFunction _filter;
|
||||
public:
|
||||
AsyncWebHandler* next;
|
||||
AsyncWebHandler(): next(NULL){}
|
||||
AsyncWebHandler(){}
|
||||
AsyncWebHandler& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; }
|
||||
bool filter(AsyncWebServerRequest *request){ return _filter == NULL || _filter(request); }
|
||||
virtual ~AsyncWebHandler(){}
|
||||
virtual bool canHandle(AsyncWebServerRequest *request){ return false; }
|
||||
virtual void handleRequest(AsyncWebServerRequest *request){}
|
||||
virtual void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){}
|
||||
virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){}
|
||||
virtual bool canHandle(AsyncWebServerRequest *request __attribute__((unused))){
|
||||
return false;
|
||||
}
|
||||
virtual void handleRequest(AsyncWebServerRequest *request __attribute__((unused))){}
|
||||
virtual void handleUpload(AsyncWebServerRequest *request __attribute__((unused)), const String& filename __attribute__((unused)), size_t index __attribute__((unused)), uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), bool final __attribute__((unused))){}
|
||||
virtual void handleBody(AsyncWebServerRequest *request __attribute__((unused)), uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), size_t index __attribute__((unused)), size_t total __attribute__((unused))){}
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -324,7 +314,7 @@ typedef enum {
|
|||
class AsyncWebServerResponse {
|
||||
protected:
|
||||
int _code;
|
||||
AsyncWebHeader *_headers;
|
||||
LinkedList<AsyncWebHeader *> _headers;
|
||||
String _contentType;
|
||||
size_t _contentLength;
|
||||
bool _sendContentLength;
|
||||
|
@ -341,13 +331,13 @@ class AsyncWebServerResponse {
|
|||
virtual ~AsyncWebServerResponse();
|
||||
virtual void setCode(int code);
|
||||
virtual void setContentLength(size_t len);
|
||||
virtual void setContentType(String type);
|
||||
virtual void addHeader(String name, String value);
|
||||
virtual void setContentType(const String& type);
|
||||
virtual void addHeader(const String& name, const String& value);
|
||||
virtual String _assembleHead(uint8_t version);
|
||||
virtual bool _started();
|
||||
virtual bool _finished();
|
||||
virtual bool _failed();
|
||||
virtual bool _sourceValid();
|
||||
virtual bool _started() const;
|
||||
virtual bool _finished() const;
|
||||
virtual bool _failed() const;
|
||||
virtual bool _sourceValid() const;
|
||||
virtual void _respond(AsyncWebServerRequest *request);
|
||||
virtual size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
||||
};
|
||||
|
@ -357,14 +347,14 @@ class AsyncWebServerResponse {
|
|||
* */
|
||||
|
||||
typedef std::function<void(AsyncWebServerRequest *request)> ArRequestHandlerFunction;
|
||||
typedef std::function<void(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final)> ArUploadHandlerFunction;
|
||||
typedef std::function<void(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final)> ArUploadHandlerFunction;
|
||||
typedef std::function<void(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)> ArBodyHandlerFunction;
|
||||
|
||||
class AsyncWebServer {
|
||||
protected:
|
||||
AsyncServer _server;
|
||||
AsyncWebRewrite* _rewrites;
|
||||
AsyncWebHandler* _handlers;
|
||||
LinkedList<AsyncWebRewrite*> _rewrites;
|
||||
LinkedList<AsyncWebHandler*> _handlers;
|
||||
AsyncWebHandler* _catchAllHandler;
|
||||
|
||||
public:
|
||||
|
@ -380,7 +370,6 @@ class AsyncWebServer {
|
|||
|
||||
AsyncWebRewrite& addRewrite(AsyncWebRewrite* rewrite);
|
||||
bool removeRewrite(AsyncWebRewrite* rewrite);
|
||||
|
||||
AsyncWebRewrite& rewrite(const char* from, const char* to);
|
||||
|
||||
AsyncWebHandler& addHandler(AsyncWebHandler* handler);
|
||||
|
|
|
@ -317,7 +317,7 @@ const uint8_t edit_htm_gz[] PROGMEM = {
|
|||
|
||||
// WEB HANDLER IMPLEMENTATION
|
||||
|
||||
SPIFFSEditor::SPIFFSEditor(String username, String password)
|
||||
SPIFFSEditor::SPIFFSEditor(const String& username, const String& password)
|
||||
:_username(username)
|
||||
,_password(password)
|
||||
,_authenticated(false)
|
||||
|
@ -418,7 +418,7 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){
|
|||
}
|
||||
}
|
||||
|
||||
void SPIFFSEditor::handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
|
||||
void SPIFFSEditor::handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final){
|
||||
if(!index){
|
||||
if(!_username.length() || request->authenticate(_username.c_str(),_password.c_str())){
|
||||
_authenticated = true;
|
||||
|
|
|
@ -9,10 +9,10 @@ class SPIFFSEditor: public AsyncWebHandler {
|
|||
bool _authenticated;
|
||||
uint32_t _startTime;
|
||||
public:
|
||||
SPIFFSEditor(String username=String(), String password=String());
|
||||
bool canHandle(AsyncWebServerRequest *request);
|
||||
void handleRequest(AsyncWebServerRequest *request);
|
||||
void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
|
||||
SPIFFSEditor(const String& username=String(), const String& password=String());
|
||||
virtual bool canHandle(AsyncWebServerRequest *request) override final;
|
||||
virtual void handleRequest(AsyncWebServerRequest *request) override final;
|
||||
virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,88 +24,110 @@
|
|||
#include "stddef.h"
|
||||
#include "WString.h"
|
||||
|
||||
class StringArrayItem;
|
||||
class StringArrayItem {
|
||||
private:
|
||||
String _string;
|
||||
template <typename T>
|
||||
class LinkedListNode {
|
||||
T _value;
|
||||
public:
|
||||
StringArrayItem *next;
|
||||
StringArrayItem(String str):_string(str), next(NULL){}
|
||||
~StringArrayItem(){}
|
||||
String string(){ return _string; }
|
||||
LinkedListNode<T>* next;
|
||||
LinkedListNode(const T val): _value(val), next(nullptr) {}
|
||||
~LinkedListNode(){}
|
||||
const T& value() const { return _value; };
|
||||
T& value(){ return _value; }
|
||||
};
|
||||
|
||||
class StringArray {
|
||||
private:
|
||||
StringArrayItem *_items;
|
||||
template <typename T, template<typename> class Item = LinkedListNode>
|
||||
class LinkedList {
|
||||
public:
|
||||
StringArray():_items(NULL){}
|
||||
StringArray(StringArrayItem *items):_items(items){}
|
||||
~StringArray(){}
|
||||
StringArrayItem *items(){
|
||||
return _items;
|
||||
}
|
||||
void add(String str){
|
||||
StringArrayItem *it = new StringArrayItem(str);
|
||||
if(_items == NULL){
|
||||
_items = it;
|
||||
typedef Item<T> ItemType;
|
||||
typedef std::function<void(const T&)> OnRemove;
|
||||
typedef std::function<bool(const T&)> Predicate;
|
||||
private:
|
||||
ItemType* _root;
|
||||
OnRemove _onRemove;
|
||||
|
||||
class Iterator {
|
||||
ItemType* _node;
|
||||
public:
|
||||
Iterator(ItemType* current = nullptr) : _node(current) {}
|
||||
Iterator(const Iterator& i) : _node(i._node) {}
|
||||
Iterator& operator ++() { _node = _node->next; return *this; }
|
||||
bool operator != (const Iterator& i) const { return _node != i._node; }
|
||||
const T& operator * () const { return _node->value(); }
|
||||
const T* operator -> () const { return &_node->value(); }
|
||||
};
|
||||
|
||||
public:
|
||||
typedef const Iterator ConstIterator;
|
||||
ConstIterator begin() const { return ConstIterator(_root); }
|
||||
ConstIterator end() const { return ConstIterator(nullptr); }
|
||||
|
||||
LinkedList(OnRemove onRemove) : _root(nullptr), _onRemove(onRemove) {}
|
||||
~LinkedList(){}
|
||||
void add(const T& t){
|
||||
auto it = new ItemType(t);
|
||||
if(!_root){
|
||||
_root = it;
|
||||
} else {
|
||||
StringArrayItem *i = _items;
|
||||
while(i->next != NULL) i = i->next;
|
||||
auto i = _root;
|
||||
while(i->next) i = i->next;
|
||||
i->next = it;
|
||||
}
|
||||
}
|
||||
size_t length(){
|
||||
T& front() const {
|
||||
return _root->value();
|
||||
}
|
||||
|
||||
bool isEmpty() const {
|
||||
return _root == nullptr;
|
||||
}
|
||||
size_t length() const {
|
||||
size_t i = 0;
|
||||
StringArrayItem *it = _items;
|
||||
while(it != NULL){
|
||||
auto it = _root;
|
||||
while(it){
|
||||
i++;
|
||||
it = it->next;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
bool contains(String str){
|
||||
StringArrayItem *it = _items;
|
||||
while(it != NULL){
|
||||
if(it->string() == str)
|
||||
return true;
|
||||
it = it->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool containsIgnoreCase(String str){
|
||||
StringArrayItem *it = _items;
|
||||
while(it != NULL){
|
||||
if(it->string().equalsIgnoreCase(str))
|
||||
return true;
|
||||
it = it->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
String get(size_t index){
|
||||
size_t count_if(Predicate predicate) const {
|
||||
size_t i = 0;
|
||||
StringArrayItem *it = _items;
|
||||
while(it != NULL){
|
||||
if(i++ == index)
|
||||
return it->string();
|
||||
auto it = _root;
|
||||
while(it){
|
||||
if (!predicate){
|
||||
i++;
|
||||
}
|
||||
else if (predicate(it->value())) {
|
||||
i++;
|
||||
}
|
||||
it = it->next;
|
||||
}
|
||||
return String();
|
||||
return i;
|
||||
}
|
||||
bool remove(size_t index){
|
||||
StringArrayItem *it = _items;
|
||||
if(!index){
|
||||
if(_items == NULL)
|
||||
return false;
|
||||
_items = _items->next;
|
||||
delete it;
|
||||
return true;
|
||||
}
|
||||
const T* nth(size_t N) const {
|
||||
size_t i = 0;
|
||||
StringArrayItem *pit = _items;
|
||||
while(it != NULL){
|
||||
if(i++ == index){
|
||||
pit->next = it->next;
|
||||
auto it = _root;
|
||||
while(it){
|
||||
if(i++ == N)
|
||||
return &(it->value());
|
||||
it = it->next;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
bool remove(const T& t){
|
||||
auto it = _root;
|
||||
auto pit = _root;
|
||||
while(it){
|
||||
if(it->value() == t){
|
||||
if(it == _root){
|
||||
_root = _root->next;
|
||||
} else {
|
||||
pit->next = it->next;
|
||||
}
|
||||
|
||||
if (_onRemove) {
|
||||
_onRemove(it->value());
|
||||
}
|
||||
|
||||
delete it;
|
||||
return true;
|
||||
}
|
||||
|
@ -114,16 +136,19 @@ class StringArray {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
bool remove(String str){
|
||||
StringArrayItem *it = _items;
|
||||
StringArrayItem *pit = _items;
|
||||
while(it != NULL){
|
||||
if(it->string() == str){
|
||||
if(it == _items){
|
||||
_items = _items->next;
|
||||
bool remove_first(Predicate predicate){
|
||||
auto it = _root;
|
||||
auto pit = _root;
|
||||
while(it){
|
||||
if(predicate(it->value())){
|
||||
if(it == _root){
|
||||
_root = _root->next;
|
||||
} else {
|
||||
pit->next = it->next;
|
||||
}
|
||||
if (_onRemove) {
|
||||
_onRemove(it->value());
|
||||
}
|
||||
delete it;
|
||||
return true;
|
||||
}
|
||||
|
@ -132,16 +157,37 @@ class StringArray {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void free(){
|
||||
StringArrayItem *it;
|
||||
while(_items != NULL){
|
||||
it = _items;
|
||||
_items = _items->next;
|
||||
while(_root != nullptr){
|
||||
auto it = _root;
|
||||
_root = _root->next;
|
||||
if (_onRemove) {
|
||||
_onRemove(it->value());
|
||||
}
|
||||
delete it;
|
||||
}
|
||||
_root = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class StringArray : public LinkedList<String> {
|
||||
public:
|
||||
|
||||
StringArray() : LinkedList(nullptr) {}
|
||||
|
||||
bool containsIgnoreCase(const String& str){
|
||||
for (const auto& s : *this) {
|
||||
if (str.equalsIgnoreCase(s)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* STRINGARRAY_H_ */
|
||||
|
|
|
@ -84,7 +84,7 @@ static String genRandomMD5(){
|
|||
return res;
|
||||
}
|
||||
|
||||
static String stringMD5(String in){
|
||||
static String stringMD5(const String& in){
|
||||
char * out = (char*)malloc(33);
|
||||
if(out == NULL || !getMD5((uint8_t*)(in.c_str()), in.length(), out))
|
||||
return "";
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
class AsyncStaticWebHandler: public AsyncWebHandler {
|
||||
private:
|
||||
bool _getFile(AsyncWebServerRequest *request);
|
||||
bool _fileExists(AsyncWebServerRequest *request, const String path);
|
||||
uint8_t _countBits(const uint8_t value);
|
||||
bool _fileExists(AsyncWebServerRequest *request, const String& path);
|
||||
uint8_t _countBits(const uint8_t value) const;
|
||||
protected:
|
||||
FS _fs;
|
||||
String _uri;
|
||||
|
@ -42,8 +42,8 @@ class AsyncStaticWebHandler: public AsyncWebHandler {
|
|||
uint8_t _gzipStats;
|
||||
public:
|
||||
AsyncStaticWebHandler(const char* uri, FS& fs, const char* path, const char* cache_control);
|
||||
bool canHandle(AsyncWebServerRequest *request);
|
||||
void handleRequest(AsyncWebServerRequest *request);
|
||||
virtual bool canHandle(AsyncWebServerRequest *request) override final;
|
||||
virtual void handleRequest(AsyncWebServerRequest *request) override final;
|
||||
AsyncStaticWebHandler& setIsDir(bool isDir);
|
||||
AsyncStaticWebHandler& setDefaultFile(const char* filename);
|
||||
AsyncStaticWebHandler& setCacheControl(const char* cache_control);
|
||||
|
@ -65,13 +65,14 @@ class AsyncCallbackWebHandler: public AsyncWebHandler {
|
|||
ArBodyHandlerFunction _onBody;
|
||||
public:
|
||||
AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL){}
|
||||
void setUri(String uri){ _uri = uri; }
|
||||
void setUri(const String& uri){ _uri = uri; }
|
||||
void setMethod(WebRequestMethodComposite method){ _method = method; }
|
||||
void onRequest(ArRequestHandlerFunction fn){ _onRequest = fn; }
|
||||
void onUpload(ArUploadHandlerFunction fn){ _onUpload = fn; }
|
||||
void onBody(ArBodyHandlerFunction fn){ _onBody = fn; }
|
||||
|
||||
bool canHandle(AsyncWebServerRequest *request){
|
||||
virtual bool canHandle(AsyncWebServerRequest *request) override final{
|
||||
|
||||
if(!_onRequest)
|
||||
return false;
|
||||
|
||||
|
@ -84,17 +85,18 @@ class AsyncCallbackWebHandler: public AsyncWebHandler {
|
|||
request->addInterestingHeader("ANY");
|
||||
return true;
|
||||
}
|
||||
void handleRequest(AsyncWebServerRequest *request){
|
||||
|
||||
virtual void handleRequest(AsyncWebServerRequest *request) override final {
|
||||
if(_onRequest)
|
||||
_onRequest(request);
|
||||
else
|
||||
request->send(500);
|
||||
}
|
||||
void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
|
||||
virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final {
|
||||
if(_onUpload)
|
||||
_onUpload(request, filename, index, data, len, final);
|
||||
}
|
||||
void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){
|
||||
virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final {
|
||||
if(_onBody)
|
||||
_onBody(request, data, len, index, total);
|
||||
}
|
||||
|
|
|
@ -79,8 +79,7 @@ AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(){
|
|||
return setLastModified(last_modified);
|
||||
}
|
||||
#endif
|
||||
bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest *request)
|
||||
{
|
||||
bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest *request){
|
||||
if (request->method() == HTTP_GET &&
|
||||
request->url().startsWith(_uri) &&
|
||||
_getFile(request)) {
|
||||
|
@ -125,7 +124,7 @@ bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest *request)
|
|||
return _fileExists(request, path);
|
||||
}
|
||||
|
||||
bool AsyncStaticWebHandler::_fileExists(AsyncWebServerRequest *request, const String path)
|
||||
bool AsyncStaticWebHandler::_fileExists(AsyncWebServerRequest *request, const String& path)
|
||||
{
|
||||
bool fileFound = false;
|
||||
bool gzipFound = false;
|
||||
|
@ -167,7 +166,7 @@ bool AsyncStaticWebHandler::_fileExists(AsyncWebServerRequest *request, const St
|
|||
return found;
|
||||
}
|
||||
|
||||
uint8_t AsyncStaticWebHandler::_countBits(const uint8_t value)
|
||||
uint8_t AsyncStaticWebHandler::_countBits(const uint8_t value) const
|
||||
{
|
||||
uint8_t w = value;
|
||||
uint8_t n;
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#define os_strlen strlen
|
||||
#endif
|
||||
|
||||
static const String SharedEmptyString = String();
|
||||
|
||||
#define __is_param_char(c) ((c) && ((c) != '{') && ((c) != '[') && ((c) != '&') && ((c) != '='))
|
||||
|
||||
enum { PARSE_REQ_START, PARSE_REQ_HEADERS, PARSE_REQ_BODY, PARSE_REQ_END, PARSE_REQ_FAIL };
|
||||
|
@ -35,7 +37,6 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c)
|
|||
, _server(s)
|
||||
, _handler(NULL)
|
||||
, _response(NULL)
|
||||
, _interestingHeaders(new StringArray())
|
||||
, _temp()
|
||||
, _parseState(0)
|
||||
, _version(0)
|
||||
|
@ -51,8 +52,8 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c)
|
|||
, _expectingContinue(false)
|
||||
, _contentLength(0)
|
||||
, _parsedLength(0)
|
||||
, _headers(NULL)
|
||||
, _params(NULL)
|
||||
, _headers(LinkedList<AsyncWebHeader *>([](AsyncWebHeader *h){ delete h; }))
|
||||
, _params(LinkedList<AsyncWebParameter *>([](AsyncWebParameter *p){ delete p; }))
|
||||
, _multiParseState(0)
|
||||
, _boundaryPosition(0)
|
||||
, _itemStartIndex(0)
|
||||
|
@ -65,7 +66,6 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c)
|
|||
, _itemBufferIndex(0)
|
||||
, _itemIsFile(false)
|
||||
, _tempObject(NULL)
|
||||
, next(NULL)
|
||||
{
|
||||
c->onError([](void *r, AsyncClient* c, int8_t error){ AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onError(error); }, this);
|
||||
c->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onAck(len, time); }, this);
|
||||
|
@ -76,20 +76,11 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c)
|
|||
}
|
||||
|
||||
AsyncWebServerRequest::~AsyncWebServerRequest(){
|
||||
while(_headers != NULL){
|
||||
AsyncWebHeader *h = _headers;
|
||||
_headers = h->next;
|
||||
delete h;
|
||||
}
|
||||
_headers.free();
|
||||
|
||||
while(_params != NULL){
|
||||
AsyncWebParameter *p = _params;
|
||||
_params = p->next;
|
||||
delete p;
|
||||
}
|
||||
_params.free();
|
||||
|
||||
_interestingHeaders->free();
|
||||
delete _interestingHeaders;
|
||||
_interestingHeaders.free();
|
||||
|
||||
if(_response != NULL){
|
||||
delete _response;
|
||||
|
@ -199,18 +190,10 @@ void AsyncWebServerRequest::_onDisconnect(){
|
|||
}
|
||||
|
||||
void AsyncWebServerRequest::_addParam(AsyncWebParameter *p){
|
||||
if(p == NULL)
|
||||
return;
|
||||
if(_params == NULL)
|
||||
_params = p;
|
||||
else {
|
||||
AsyncWebParameter *ps = _params;
|
||||
while(ps->next != NULL) ps = ps->next;
|
||||
ps->next = p;
|
||||
}
|
||||
_params.add(p);
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::_addGetParams(String params){
|
||||
void AsyncWebServerRequest::_addGetParams(const String& params){
|
||||
size_t start = 0;
|
||||
while (start < params.length()){
|
||||
int end = params.indexOf('&', start);
|
||||
|
@ -294,15 +277,8 @@ bool AsyncWebServerRequest::_parseReqHeader(){
|
|||
_authorization = value.substring(7);
|
||||
}
|
||||
} else {
|
||||
if(_interestingHeaders->containsIgnoreCase(name) || _interestingHeaders->containsIgnoreCase("ANY")){
|
||||
AsyncWebHeader *h = new AsyncWebHeader(name, value);
|
||||
if(_headers == NULL)
|
||||
_headers = h;
|
||||
else {
|
||||
AsyncWebHeader *hs = _headers;
|
||||
while(hs->next != NULL) hs = hs->next;
|
||||
hs->next = h;
|
||||
}
|
||||
if(_interestingHeaders.containsIgnoreCase(name) || _interestingHeaders.containsIgnoreCase("ANY")){
|
||||
_headers.add(new AsyncWebHeader(name, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -541,89 +517,63 @@ void AsyncWebServerRequest::_parseLine(){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int AsyncWebServerRequest::headers(){
|
||||
int i = 0;
|
||||
AsyncWebHeader* h = _headers;
|
||||
while(h != NULL){
|
||||
i++; h = h->next;
|
||||
}
|
||||
return i;
|
||||
size_t AsyncWebServerRequest::headers() const{
|
||||
return _headers.length();
|
||||
}
|
||||
|
||||
bool AsyncWebServerRequest::hasHeader(String name){
|
||||
AsyncWebHeader* h = _headers;
|
||||
while(h != NULL){
|
||||
if(h->name().equalsIgnoreCase(name))
|
||||
bool AsyncWebServerRequest::hasHeader(const String& name) const {
|
||||
for(const auto& h: _headers){
|
||||
if(h->name().equalsIgnoreCase(name)){
|
||||
return true;
|
||||
h = h->next;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
AsyncWebHeader* AsyncWebServerRequest::getHeader(String name){
|
||||
AsyncWebHeader* h = _headers;
|
||||
while(h != NULL){
|
||||
if(h->name().equalsIgnoreCase(name))
|
||||
AsyncWebHeader* AsyncWebServerRequest::getHeader(const String& name) const {
|
||||
for(const auto& h: _headers){
|
||||
if(h->name().equalsIgnoreCase(name)){
|
||||
return h;
|
||||
h = h->next;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AsyncWebHeader* AsyncWebServerRequest::getHeader(int num){
|
||||
int i = 0;
|
||||
AsyncWebHeader* h = _headers;
|
||||
while(h != NULL){
|
||||
if(num == i++)
|
||||
return h;
|
||||
h = h->next;
|
||||
}
|
||||
return NULL;
|
||||
AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) const {
|
||||
auto header = _headers.nth(num);
|
||||
return header ? *header : nullptr;
|
||||
}
|
||||
|
||||
int AsyncWebServerRequest::params(){
|
||||
int i = 0;
|
||||
AsyncWebParameter* h = _params;
|
||||
while(h != NULL){
|
||||
i++; h = h->next;
|
||||
}
|
||||
return i;
|
||||
size_t AsyncWebServerRequest::params() const {
|
||||
return _params.length();
|
||||
}
|
||||
|
||||
bool AsyncWebServerRequest::hasParam(String name, bool post, bool file){
|
||||
AsyncWebParameter* h = _params;
|
||||
while(h != NULL){
|
||||
if(h->name() == name && h->isPost() == post && h->isFile() == file)
|
||||
bool AsyncWebServerRequest::hasParam(const String& name, bool post, bool file) const {
|
||||
for(const auto& p: _params){
|
||||
if(p->name() == name && p->isPost() == post && p->isFile() == file){
|
||||
return true;
|
||||
h = h->next;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
AsyncWebParameter* AsyncWebServerRequest::getParam(String name, bool post, bool file){
|
||||
AsyncWebParameter* h = _params;
|
||||
while(h != NULL){
|
||||
if(h->name() == name && h->isPost() == post && h->isFile() == file)
|
||||
return h;
|
||||
h = h->next;
|
||||
AsyncWebParameter* AsyncWebServerRequest::getParam(const String& name, bool post, bool file) const {
|
||||
for(const auto& p: _params){
|
||||
if(p->name() == name && p->isPost() == post && p->isFile() == file){
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AsyncWebParameter* AsyncWebServerRequest::getParam(int num){
|
||||
int i = 0;
|
||||
AsyncWebParameter* h = _params;
|
||||
while(h != NULL){
|
||||
if(num == i++)
|
||||
return h;
|
||||
h = h->next;
|
||||
}
|
||||
return NULL;
|
||||
AsyncWebParameter* AsyncWebServerRequest::getParam(size_t num) const {
|
||||
auto param = _params.nth(num);
|
||||
return param ? *param : nullptr;
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::addInterestingHeader(String name){
|
||||
if(!_interestingHeaders->containsIgnoreCase(name)) _interestingHeaders->add(name);
|
||||
void AsyncWebServerRequest::addInterestingHeader(const String& name){
|
||||
if(!_interestingHeaders.containsIgnoreCase(name))
|
||||
_interestingHeaders.add(name);
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::send(AsyncWebServerResponse *response){
|
||||
|
@ -642,85 +592,85 @@ void AsyncWebServerRequest::send(AsyncWebServerResponse *response){
|
|||
_response->_respond(this);
|
||||
}
|
||||
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(int code, String contentType, String content){
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(int code, const String& contentType, const String& content){
|
||||
return new AsyncBasicResponse(code, contentType, content);
|
||||
}
|
||||
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(FS &fs, String path, String contentType, bool download){
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(FS &fs, const String& path, const String& contentType, bool download){
|
||||
if(fs.exists(path) || (!download && fs.exists(path+".gz")))
|
||||
return new AsyncFileResponse(fs, path, contentType, download);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(File content, String path, String contentType, bool download){
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(File content, const String& path, const String& contentType, bool download){
|
||||
if(content == true)
|
||||
return new AsyncFileResponse(content, path, contentType, download);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(Stream &stream, String contentType, size_t len){
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(Stream &stream, const String& contentType, size_t len){
|
||||
return new AsyncStreamResponse(stream, contentType, len);
|
||||
}
|
||||
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(String contentType, size_t len, AwsResponseFiller callback){
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(const String& contentType, size_t len, AwsResponseFiller callback){
|
||||
return new AsyncCallbackResponse(contentType, len, callback);
|
||||
}
|
||||
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginChunkedResponse(String contentType, AwsResponseFiller callback){
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginChunkedResponse(const String& contentType, AwsResponseFiller callback){
|
||||
if(_version)
|
||||
return new AsyncChunkedResponse(contentType, callback);
|
||||
return new AsyncCallbackResponse(contentType, 0, callback);
|
||||
}
|
||||
|
||||
AsyncResponseStream * AsyncWebServerRequest::beginResponseStream(String contentType, size_t bufferSize){
|
||||
AsyncResponseStream * AsyncWebServerRequest::beginResponseStream(const String& contentType, size_t bufferSize){
|
||||
return new AsyncResponseStream(contentType, bufferSize);
|
||||
}
|
||||
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse_P(int code, String contentType, const uint8_t * content, size_t len){
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse_P(int code, const String& contentType, const uint8_t * content, size_t len){
|
||||
return new AsyncProgmemResponse(code, contentType, content, len);
|
||||
}
|
||||
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse_P(int code, String contentType, PGM_P content){
|
||||
AsyncWebServerResponse * AsyncWebServerRequest::beginResponse_P(int code, const String& contentType, PGM_P content){
|
||||
return beginResponse_P(code, contentType, (const uint8_t *)content, strlen_P(content));
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::send(int code, String contentType, String content){
|
||||
void AsyncWebServerRequest::send(int code, const String& contentType, const String& content){
|
||||
send(beginResponse(code, contentType, content));
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::send(FS &fs, String path, String contentType, bool download){
|
||||
void AsyncWebServerRequest::send(FS &fs, const String& path, const String& contentType, bool download){
|
||||
if(fs.exists(path) || (!download && fs.exists(path+".gz"))){
|
||||
send(beginResponse(fs, path, contentType, download));
|
||||
} else send(404);
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::send(File content, String path, String contentType, bool download){
|
||||
void AsyncWebServerRequest::send(File content, const String& path, const String& contentType, bool download){
|
||||
if(content == true){
|
||||
send(beginResponse(content, path, contentType, download));
|
||||
} else send(404);
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::send(Stream &stream, String contentType, size_t len){
|
||||
void AsyncWebServerRequest::send(Stream &stream, const String& contentType, size_t len){
|
||||
send(beginResponse(stream, contentType, len));
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::send(String contentType, size_t len, AwsResponseFiller callback){
|
||||
void AsyncWebServerRequest::send(const String& contentType, size_t len, AwsResponseFiller callback){
|
||||
send(beginResponse(contentType, len, callback));
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::sendChunked(String contentType, AwsResponseFiller callback){
|
||||
void AsyncWebServerRequest::sendChunked(const String& contentType, AwsResponseFiller callback){
|
||||
send(beginChunkedResponse(contentType, callback));
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::send_P(int code, String contentType, const uint8_t * content, size_t len){
|
||||
void AsyncWebServerRequest::send_P(int code, const String& contentType, const uint8_t * content, size_t len){
|
||||
send(beginResponse_P(code, contentType, content, len));
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::send_P(int code, String contentType, PGM_P content){
|
||||
void AsyncWebServerRequest::send_P(int code, const String& contentType, PGM_P content){
|
||||
send(beginResponse_P(code, contentType, content));
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::redirect(String url){
|
||||
void AsyncWebServerRequest::redirect(const String& url){
|
||||
AsyncWebServerResponse * response = beginResponse(302);
|
||||
response->addHeader("Location",url);
|
||||
send(response);
|
||||
|
@ -777,61 +727,48 @@ void AsyncWebServerRequest::requestAuthentication(const char * realm, bool isDig
|
|||
send(r);
|
||||
}
|
||||
|
||||
bool AsyncWebServerRequest::hasArg(const char* name){
|
||||
AsyncWebParameter* h = _params;
|
||||
while(h != NULL){
|
||||
if(h->name() == String(name))
|
||||
bool AsyncWebServerRequest::hasArg(const char* name) const {
|
||||
for(const auto& arg: _params){
|
||||
if(arg->name() == name){
|
||||
return true;
|
||||
h = h->next;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
String AsyncWebServerRequest::arg(const char* name){
|
||||
AsyncWebParameter* h = _params;
|
||||
while(h != NULL){
|
||||
if(h->name() == String(name))
|
||||
return h->value();
|
||||
h = h->next;
|
||||
const String& AsyncWebServerRequest::arg(const String& name) const {
|
||||
for(const auto& arg: _params){
|
||||
if(arg->name() == name){
|
||||
return arg->value();
|
||||
}
|
||||
}
|
||||
return String();
|
||||
return SharedEmptyString;
|
||||
}
|
||||
|
||||
String AsyncWebServerRequest::arg(int i){
|
||||
const String& AsyncWebServerRequest::arg(size_t i) const {
|
||||
return getParam(i)->value();
|
||||
}
|
||||
|
||||
String AsyncWebServerRequest::argName(int i){
|
||||
const String& AsyncWebServerRequest::argName(size_t i) const {
|
||||
return getParam(i)->name();
|
||||
}
|
||||
|
||||
String AsyncWebServerRequest::header(const char* name){
|
||||
const String& AsyncWebServerRequest::header(const char* name) const {
|
||||
AsyncWebHeader* h = getHeader(String(name));
|
||||
if(h)
|
||||
return h->value();
|
||||
return String();
|
||||
return h ? h->value() : SharedEmptyString;
|
||||
}
|
||||
|
||||
String AsyncWebServerRequest::header(int i){
|
||||
const String& AsyncWebServerRequest::header(size_t i) const {
|
||||
AsyncWebHeader* h = getHeader(i);
|
||||
if(h)
|
||||
return h->value();
|
||||
return String();
|
||||
return h ? h->value() : SharedEmptyString;
|
||||
}
|
||||
|
||||
String AsyncWebServerRequest::headerName(int i){
|
||||
const String& AsyncWebServerRequest::headerName(size_t i) const {
|
||||
AsyncWebHeader* h = getHeader(i);
|
||||
if(h)
|
||||
return h->name();
|
||||
return String();
|
||||
return h ? h->name() : SharedEmptyString;
|
||||
}
|
||||
|
||||
bool AsyncWebServerRequest::hasHeader(const char* name){
|
||||
return hasHeader(String(name));
|
||||
}
|
||||
|
||||
|
||||
String AsyncWebServerRequest::urlDecode(const String& text){
|
||||
String AsyncWebServerRequest::urlDecode(const String& text) const {
|
||||
char temp[] = "0x00";
|
||||
unsigned int len = text.length();
|
||||
unsigned int i = 0;
|
||||
|
@ -855,7 +792,7 @@ String AsyncWebServerRequest::urlDecode(const String& text){
|
|||
}
|
||||
|
||||
|
||||
const char * AsyncWebServerRequest::methodToString(){
|
||||
const char * AsyncWebServerRequest::methodToString() const {
|
||||
if(_method == HTTP_ANY) return "ANY";
|
||||
else if(_method & HTTP_GET) return "GET";
|
||||
else if(_method & HTTP_POST) return "POST";
|
||||
|
|
|
@ -25,10 +25,10 @@ class AsyncBasicResponse: public AsyncWebServerResponse {
|
|||
private:
|
||||
String _content;
|
||||
public:
|
||||
AsyncBasicResponse(int code, String contentType=String(), String content=String());
|
||||
AsyncBasicResponse(int code, const String& contentType=String(), const String& content=String());
|
||||
void _respond(AsyncWebServerRequest *request);
|
||||
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
||||
bool _sourceValid(){ return true; }
|
||||
bool _sourceValid() const { return true; }
|
||||
};
|
||||
|
||||
class AsyncAbstractResponse: public AsyncWebServerResponse {
|
||||
|
@ -37,57 +37,57 @@ class AsyncAbstractResponse: public AsyncWebServerResponse {
|
|||
public:
|
||||
void _respond(AsyncWebServerRequest *request);
|
||||
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
||||
bool _sourceValid(){ return false; }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen){ return 0; }
|
||||
bool _sourceValid() const { return false; }
|
||||
virtual size_t _fillBuffer(uint8_t *buf __attribute__((unused)), size_t maxLen __attribute__((unused))) { return 0; }
|
||||
};
|
||||
|
||||
class AsyncFileResponse: public AsyncAbstractResponse {
|
||||
private:
|
||||
File _content;
|
||||
String _path;
|
||||
void _setContentType(String path);
|
||||
void _setContentType(const String& path);
|
||||
public:
|
||||
AsyncFileResponse(FS &fs, String path, String contentType=String(), bool download=false);
|
||||
AsyncFileResponse(File content, String path, String contentType=String(), bool download=false);
|
||||
AsyncFileResponse(FS &fs, const String& path, const String& contentType=String(), bool download=false);
|
||||
AsyncFileResponse(File content, const String& path, const String& contentType=String(), bool download=false);
|
||||
~AsyncFileResponse();
|
||||
bool _sourceValid(){ return !!(_content); }
|
||||
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
|
||||
bool _sourceValid() const { return !!(_content); }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
};
|
||||
|
||||
class AsyncStreamResponse: public AsyncAbstractResponse {
|
||||
private:
|
||||
Stream *_content;
|
||||
public:
|
||||
AsyncStreamResponse(Stream &stream, String contentType, size_t len);
|
||||
bool _sourceValid(){ return !!(_content); }
|
||||
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
|
||||
AsyncStreamResponse(Stream &stream, const String& contentType, size_t len);
|
||||
bool _sourceValid() const { return !!(_content); }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
};
|
||||
|
||||
class AsyncCallbackResponse: public AsyncAbstractResponse {
|
||||
private:
|
||||
AwsResponseFiller _content;
|
||||
public:
|
||||
AsyncCallbackResponse(String contentType, size_t len, AwsResponseFiller callback);
|
||||
bool _sourceValid(){ return !!(_content); }
|
||||
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
|
||||
AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback);
|
||||
bool _sourceValid() const { return !!(_content); }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
};
|
||||
|
||||
class AsyncChunkedResponse: public AsyncAbstractResponse {
|
||||
private:
|
||||
AwsResponseFiller _content;
|
||||
public:
|
||||
AsyncChunkedResponse(String contentType, AwsResponseFiller callback);
|
||||
bool _sourceValid(){ return !!(_content); }
|
||||
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
|
||||
AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback);
|
||||
bool _sourceValid() const { return !!(_content); }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
};
|
||||
|
||||
class AsyncProgmemResponse: public AsyncAbstractResponse {
|
||||
private:
|
||||
const uint8_t * _content;
|
||||
public:
|
||||
AsyncProgmemResponse(int code, String contentType, const uint8_t * content, size_t len);
|
||||
bool _sourceValid(){ return true; }
|
||||
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
|
||||
AsyncProgmemResponse(int code, const String& contentType, const uint8_t * content, size_t len);
|
||||
bool _sourceValid() const { return true; }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
};
|
||||
|
||||
class cbuf;
|
||||
|
@ -96,10 +96,10 @@ class AsyncResponseStream: public AsyncAbstractResponse, public Print {
|
|||
private:
|
||||
cbuf *_content;
|
||||
public:
|
||||
AsyncResponseStream(String contentType, size_t bufferSize);
|
||||
AsyncResponseStream(const String& contentType, size_t bufferSize);
|
||||
~AsyncResponseStream();
|
||||
bool _sourceValid(){ return (_state < RESPONSE_END); }
|
||||
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
|
||||
bool _sourceValid() const { return (_state < RESPONSE_END); }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
size_t write(const uint8_t *data, size_t len);
|
||||
size_t write(uint8_t data);
|
||||
using Print::write;
|
||||
|
|
|
@ -73,7 +73,7 @@ const char* AsyncWebServerResponse::_responseCodeToString(int code) {
|
|||
|
||||
AsyncWebServerResponse::AsyncWebServerResponse()
|
||||
: _code(0)
|
||||
, _headers(NULL)
|
||||
, _headers(LinkedList<AsyncWebHeader *>([](AsyncWebHeader *h){ delete h; }))
|
||||
, _contentType()
|
||||
, _contentLength(0)
|
||||
, _sendContentLength(true)
|
||||
|
@ -86,11 +86,7 @@ AsyncWebServerResponse::AsyncWebServerResponse()
|
|||
{}
|
||||
|
||||
AsyncWebServerResponse::~AsyncWebServerResponse(){
|
||||
while(_headers != NULL){
|
||||
AsyncWebHeader *h = _headers;
|
||||
_headers = h->next;
|
||||
delete h;
|
||||
}
|
||||
_headers.free();
|
||||
}
|
||||
|
||||
void AsyncWebServerResponse::setCode(int code){
|
||||
|
@ -103,20 +99,13 @@ void AsyncWebServerResponse::setContentLength(size_t len){
|
|||
_contentLength = len;
|
||||
}
|
||||
|
||||
void AsyncWebServerResponse::setContentType(String type){
|
||||
void AsyncWebServerResponse::setContentType(const String& type){
|
||||
if(_state == RESPONSE_SETUP)
|
||||
_contentType = type;
|
||||
}
|
||||
|
||||
void AsyncWebServerResponse::addHeader(String name, String value){
|
||||
AsyncWebHeader *header = new AsyncWebHeader(name, value);
|
||||
if(_headers == NULL){
|
||||
_headers = header;
|
||||
} else {
|
||||
AsyncWebHeader *h = _headers;
|
||||
while(h->next != NULL) h = h->next;
|
||||
h->next = header;
|
||||
}
|
||||
void AsyncWebServerResponse::addHeader(const String& name, const String& value){
|
||||
_headers.add(new AsyncWebHeader(name, value));
|
||||
}
|
||||
|
||||
String AsyncWebServerResponse::_assembleHead(uint8_t version){
|
||||
|
@ -141,30 +130,28 @@ String AsyncWebServerResponse::_assembleHead(uint8_t version){
|
|||
out.concat(buf);
|
||||
}
|
||||
|
||||
AsyncWebHeader *h;
|
||||
while(_headers != NULL){
|
||||
h = _headers;
|
||||
_headers = _headers->next;
|
||||
snprintf(buf, bufSize, "%s: %s\r\n", h->name().c_str(), h->value().c_str());
|
||||
for(const auto& header: _headers){
|
||||
snprintf(buf, bufSize, "%s: %s\r\n", header->name().c_str(), header->value().c_str());
|
||||
out.concat(buf);
|
||||
delete h;
|
||||
}
|
||||
_headers.free();
|
||||
|
||||
out.concat("\r\n");
|
||||
_headLength = out.length();
|
||||
return out;
|
||||
}
|
||||
|
||||
bool AsyncWebServerResponse::_started(){ return _state > RESPONSE_SETUP; }
|
||||
bool AsyncWebServerResponse::_finished(){ return _state > RESPONSE_WAIT_ACK; }
|
||||
bool AsyncWebServerResponse::_failed(){ return _state == RESPONSE_FAILED; }
|
||||
bool AsyncWebServerResponse::_sourceValid(){ return false; }
|
||||
bool AsyncWebServerResponse::_started() const { return _state > RESPONSE_SETUP; }
|
||||
bool AsyncWebServerResponse::_finished() const { return _state > RESPONSE_WAIT_ACK; }
|
||||
bool AsyncWebServerResponse::_failed() const { return _state == RESPONSE_FAILED; }
|
||||
bool AsyncWebServerResponse::_sourceValid() const { return false; }
|
||||
void AsyncWebServerResponse::_respond(AsyncWebServerRequest *request){ _state = RESPONSE_END; request->client()->close(); }
|
||||
size_t AsyncWebServerResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ return 0; }
|
||||
|
||||
/*
|
||||
* String/Code Response
|
||||
* */
|
||||
AsyncBasicResponse::AsyncBasicResponse(int code, String contentType, String content){
|
||||
AsyncBasicResponse::AsyncBasicResponse(int code, const String& contentType, const String& content){
|
||||
_code = code;
|
||||
_content = content;
|
||||
_contentType = contentType;
|
||||
|
@ -343,7 +330,7 @@ AsyncFileResponse::~AsyncFileResponse(){
|
|||
_content.close();
|
||||
}
|
||||
|
||||
void AsyncFileResponse::_setContentType(String path){
|
||||
void AsyncFileResponse::_setContentType(const String& path){
|
||||
if (path.endsWith(".html")) _contentType = "text/html";
|
||||
else if (path.endsWith(".htm")) _contentType = "text/html";
|
||||
else if (path.endsWith(".css")) _contentType = "text/css";
|
||||
|
@ -365,7 +352,7 @@ void AsyncFileResponse::_setContentType(String path){
|
|||
else _contentType = "text/plain";
|
||||
}
|
||||
|
||||
AsyncFileResponse::AsyncFileResponse(FS &fs, String path, String contentType, bool download){
|
||||
AsyncFileResponse::AsyncFileResponse(FS &fs, const String& path, const String& contentType, bool download){
|
||||
_code = 200;
|
||||
_path = path;
|
||||
|
||||
|
@ -397,7 +384,7 @@ AsyncFileResponse::AsyncFileResponse(FS &fs, String path, String contentType, bo
|
|||
|
||||
}
|
||||
|
||||
AsyncFileResponse::AsyncFileResponse(File content, String path, String contentType, bool download){
|
||||
AsyncFileResponse::AsyncFileResponse(File content, const String& path, const String& contentType, bool download){
|
||||
_code = 200;
|
||||
_path = path;
|
||||
_content = content;
|
||||
|
@ -432,7 +419,7 @@ size_t AsyncFileResponse::_fillBuffer(uint8_t *data, size_t len){
|
|||
* Stream Response
|
||||
* */
|
||||
|
||||
AsyncStreamResponse::AsyncStreamResponse(Stream &stream, String contentType, size_t len){
|
||||
AsyncStreamResponse::AsyncStreamResponse(Stream &stream, const String& contentType, size_t len){
|
||||
_code = 200;
|
||||
_content = &stream;
|
||||
_contentLength = len;
|
||||
|
@ -452,7 +439,7 @@ size_t AsyncStreamResponse::_fillBuffer(uint8_t *data, size_t len){
|
|||
* Callback Response
|
||||
* */
|
||||
|
||||
AsyncCallbackResponse::AsyncCallbackResponse(String contentType, size_t len, AwsResponseFiller callback){
|
||||
AsyncCallbackResponse::AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback){
|
||||
_code = 200;
|
||||
_content = callback;
|
||||
_contentLength = len;
|
||||
|
@ -469,7 +456,7 @@ size_t AsyncCallbackResponse::_fillBuffer(uint8_t *data, size_t len){
|
|||
* Chunked Response
|
||||
* */
|
||||
|
||||
AsyncChunkedResponse::AsyncChunkedResponse(String contentType, AwsResponseFiller callback){
|
||||
AsyncChunkedResponse::AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback){
|
||||
_code = 200;
|
||||
_content = callback;
|
||||
_contentLength = 0;
|
||||
|
@ -486,7 +473,7 @@ size_t AsyncChunkedResponse::_fillBuffer(uint8_t *data, size_t len){
|
|||
* Progmem Response
|
||||
* */
|
||||
|
||||
AsyncProgmemResponse::AsyncProgmemResponse(int code, String contentType, const uint8_t * content, size_t len){
|
||||
AsyncProgmemResponse::AsyncProgmemResponse(int code, const String& contentType, const uint8_t * content, size_t len){
|
||||
_code = code;
|
||||
_content = content;
|
||||
_contentType = contentType;
|
||||
|
@ -508,7 +495,7 @@ size_t AsyncProgmemResponse::_fillBuffer(uint8_t *data, size_t len){
|
|||
* Response Stream (You can print/write/printf to it, up to the contentLen bytes)
|
||||
* */
|
||||
|
||||
AsyncResponseStream::AsyncResponseStream(String contentType, size_t bufferSize){
|
||||
AsyncResponseStream::AsyncResponseStream(const String& contentType, size_t bufferSize){
|
||||
_code = 200;
|
||||
_contentLength = 0;
|
||||
_contentType = contentType;
|
||||
|
|
|
@ -21,8 +21,20 @@
|
|||
#include "ESPAsyncWebServer.h"
|
||||
#include "WebHandlerImpl.h"
|
||||
|
||||
bool ON_STA_FILTER(AsyncWebServerRequest *request) {
|
||||
return WiFi.localIP() == request->client()->localIP();
|
||||
}
|
||||
|
||||
AsyncWebServer::AsyncWebServer(uint16_t port):_server(port), _rewrites(0), _handlers(0){
|
||||
bool ON_AP_FILTER(AsyncWebServerRequest *request) {
|
||||
return WiFi.localIP() != request->client()->localIP();
|
||||
}
|
||||
|
||||
|
||||
AsyncWebServer::AsyncWebServer(uint16_t port)
|
||||
: _server(port)
|
||||
, _rewrites(LinkedList<AsyncWebRewrite*>([](AsyncWebRewrite* r){ delete r; }))
|
||||
, _handlers(LinkedList<AsyncWebHandler*>([](AsyncWebHandler* h){ delete h; }))
|
||||
{
|
||||
_catchAllHandler = new AsyncCallbackWebHandler();
|
||||
if(_catchAllHandler == NULL)
|
||||
return;
|
||||
|
@ -45,32 +57,12 @@ AsyncWebServer::~AsyncWebServer(){
|
|||
}
|
||||
|
||||
AsyncWebRewrite& AsyncWebServer::addRewrite(AsyncWebRewrite* rewrite){
|
||||
if (_rewrites == NULL){
|
||||
_rewrites = rewrite;
|
||||
} else {
|
||||
AsyncWebRewrite *r = _rewrites;
|
||||
while(r->next != NULL) r = r->next;
|
||||
r->next = rewrite;
|
||||
}
|
||||
_rewrites.add(rewrite);
|
||||
return *rewrite;
|
||||
}
|
||||
|
||||
bool AsyncWebServer::removeRewrite(AsyncWebRewrite *rewrite){
|
||||
if(rewrite == _rewrites){
|
||||
_rewrites = _rewrites->next;
|
||||
return true;
|
||||
}
|
||||
AsyncWebRewrite *r = _rewrites;
|
||||
while(r != NULL){
|
||||
if(rewrite == r->next){
|
||||
AsyncWebRewrite *d = r->next;
|
||||
r->next = d->next;
|
||||
delete d;
|
||||
return true;
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
return false;
|
||||
return _rewrites.remove(rewrite);
|
||||
}
|
||||
|
||||
AsyncWebRewrite& AsyncWebServer::rewrite(const char* from, const char* to){
|
||||
|
@ -78,32 +70,12 @@ AsyncWebRewrite& AsyncWebServer::rewrite(const char* from, const char* to){
|
|||
}
|
||||
|
||||
AsyncWebHandler& AsyncWebServer::addHandler(AsyncWebHandler* handler){
|
||||
if(_handlers == NULL){
|
||||
_handlers = handler;
|
||||
} else {
|
||||
AsyncWebHandler* h = _handlers;
|
||||
while(h->next != NULL) h = h->next;
|
||||
h->next = handler;
|
||||
}
|
||||
_handlers.add(handler);
|
||||
return *handler;
|
||||
}
|
||||
|
||||
bool AsyncWebServer::removeHandler(AsyncWebHandler *handler){
|
||||
if(handler == _handlers){
|
||||
_handlers = _handlers->next;
|
||||
return true;
|
||||
}
|
||||
AsyncWebHandler *h = _handlers;
|
||||
while(h != NULL){
|
||||
if(handler == h->next){
|
||||
AsyncWebHandler *d = h->next;
|
||||
h->next = d->next;
|
||||
delete d;
|
||||
return true;
|
||||
}
|
||||
h = h->next;
|
||||
}
|
||||
return false;
|
||||
return _handlers.remove(handler);
|
||||
}
|
||||
|
||||
void AsyncWebServer::begin(){
|
||||
|
@ -125,27 +97,22 @@ void AsyncWebServer::_handleDisconnect(AsyncWebServerRequest *request){
|
|||
}
|
||||
|
||||
void AsyncWebServer::_rewriteRequest(AsyncWebServerRequest *request){
|
||||
AsyncWebRewrite *r = _rewrites;
|
||||
while(r){
|
||||
for(const auto& r: _rewrites){
|
||||
if (r->from() == request->_url && r->filter(request)){
|
||||
request->_url = r->toUrl();
|
||||
request->_addGetParams(r->params());
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebServer::_attachHandler(AsyncWebServerRequest *request){
|
||||
if(_handlers){
|
||||
AsyncWebHandler* h = _handlers;
|
||||
while(h){
|
||||
if (h->filter(request) && h->canHandle(request)){
|
||||
request->setHandler(h);
|
||||
return;
|
||||
}
|
||||
h = h->next;
|
||||
for(const auto& h: _handlers){
|
||||
if (h->filter(request) && h->canHandle(request)){
|
||||
request->setHandler(h);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
request->addInterestingHeader("ANY");
|
||||
request->setHandler(_catchAllHandler);
|
||||
}
|
||||
|
@ -208,19 +175,8 @@ void AsyncWebServer::onRequestBody(ArBodyHandlerFunction fn){
|
|||
}
|
||||
|
||||
void AsyncWebServer::reset(){
|
||||
while(_rewrites != NULL){
|
||||
AsyncWebRewrite *r = _rewrites;
|
||||
_rewrites = r->next;
|
||||
delete r;
|
||||
}
|
||||
_rewrites = NULL;
|
||||
|
||||
while(_handlers != NULL){
|
||||
AsyncWebHandler *h = _handlers;
|
||||
_handlers = h->next;
|
||||
delete h;
|
||||
}
|
||||
_handlers = NULL;
|
||||
_rewrites.free();
|
||||
_handlers.free();
|
||||
|
||||
if (_catchAllHandler != NULL){
|
||||
((AsyncCallbackWebHandler*)_catchAllHandler)->onRequest(NULL);
|
||||
|
|
Loading…
Reference in New Issue