mirror of
https://github.com/me-no-dev/ESPAsyncWebServer.git
synced 2025-09-27 23:00:55 +02:00
Replace homebrewed smart pointer with std::shared_ptr and std::weak_ptr
Based on commit 84833546f04ec6fbaa9c4dcb90d8761475de7a6e of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Buffers to data that is sent to all clients at once are stored as a single copy of the data with multiple references to it. This usage is one for which std::shared_ptr should be used. Each client having an active std::shared_ptr to a master buffer keeps the buffer alive. Once all clients have finished using their reference, the std::weak_ptr ensures that the AsyncWebSocketMessageBuffer goes out of scope and gets invalidated. This invalidation is checked with the lock() method of the std::weak_ptr. Also some code formatting while at it. A future commit will introduce an unification between single-client buffers and multiple-client buffers in such a way that the master buffer list in the AsyncWebSocket class will be redundant and will be removed. Therefore this stage is only temporary.
This commit is contained in:
@@ -140,8 +140,6 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool
|
||||
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer()
|
||||
:_data(nullptr)
|
||||
,_len(0)
|
||||
,_lock(false)
|
||||
,_count(0)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -149,106 +147,36 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer()
|
||||
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(uint8_t * data, size_t size)
|
||||
:_data(nullptr)
|
||||
,_len(size)
|
||||
,_lock(false)
|
||||
,_count(0)
|
||||
{
|
||||
|
||||
if (!data) {
|
||||
if (!data)
|
||||
return;
|
||||
}
|
||||
|
||||
_data = new uint8_t[_len + 1];
|
||||
|
||||
if (_data) {
|
||||
// Serial.println("BUFF alloc");
|
||||
memcpy(_data, data, _len);
|
||||
_data = std::unique_ptr<uint8_t[]>(new uint8_t[_len + 1]); //std::make_unique<uint8_t[]>(_len + 1);
|
||||
memcpy(_data.get(), data, _len);
|
||||
_data[_len] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size)
|
||||
:_data(nullptr)
|
||||
,_len(size)
|
||||
,_lock(false)
|
||||
,_count(0)
|
||||
{
|
||||
_data = new uint8_t[_len + 1];
|
||||
|
||||
if (_data) {
|
||||
// Serial.println("BUFF alloc");
|
||||
_data = std::unique_ptr<uint8_t[]>(new uint8_t[_len + 1]); //std::make_unique<uint8_t[]>(_len + 1);
|
||||
_data[_len] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer & copy)
|
||||
:_data(nullptr)
|
||||
,_len(0)
|
||||
,_lock(false)
|
||||
,_count(0)
|
||||
{
|
||||
_len = copy._len;
|
||||
_lock = copy._lock;
|
||||
_count = 0;
|
||||
|
||||
if (_len) {
|
||||
_data = new uint8_t[_len + 1];
|
||||
_data[_len] = 0;
|
||||
}
|
||||
|
||||
if (_data) {
|
||||
// Serial.println("BUFF alloc");
|
||||
memcpy(_data, copy._data, _len);
|
||||
_data[_len] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer && copy)
|
||||
:_data(nullptr)
|
||||
,_len(0)
|
||||
,_lock(false)
|
||||
,_count(0)
|
||||
{
|
||||
_len = copy._len;
|
||||
_lock = copy._lock;
|
||||
_count = 0;
|
||||
|
||||
if (copy._data) {
|
||||
// Serial.println("BUFF alloc");
|
||||
_data = copy._data;
|
||||
copy._data = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer()
|
||||
{
|
||||
if (_data) {
|
||||
// Serial.println("BUFF free");
|
||||
delete[] _data;
|
||||
}
|
||||
}
|
||||
|
||||
bool AsyncWebSocketMessageBuffer::reserve(size_t size)
|
||||
{
|
||||
_len = size;
|
||||
|
||||
if (_data) {
|
||||
delete[] _data;
|
||||
_data = nullptr;
|
||||
}
|
||||
|
||||
_data = new uint8_t[_len + 1];
|
||||
|
||||
if (_data) {
|
||||
_data = std::unique_ptr<uint8_t[]>(new uint8_t[_len + 1]); //std::make_unique<uint8_t[]>(_len + 1);
|
||||
_data[_len] = 0;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -416,7 +344,7 @@ AsyncWebSocketBasicMessage::~AsyncWebSocketBasicMessage() {
|
||||
*/
|
||||
|
||||
|
||||
AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask)
|
||||
AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode, bool mask)
|
||||
:_len(0)
|
||||
,_sent(0)
|
||||
,_ack(0)
|
||||
@@ -428,8 +356,6 @@ AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuff
|
||||
|
||||
if (buffer) {
|
||||
_WSbuffer = buffer;
|
||||
(*_WSbuffer)++;
|
||||
// Serial.printf("INC WSbuffer == %u\n", _WSbuffer->count());
|
||||
_data = buffer->get();
|
||||
_len = buffer->length();
|
||||
_status = WS_MSG_SENDING;
|
||||
@@ -443,10 +369,6 @@ AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuff
|
||||
|
||||
|
||||
AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() {
|
||||
if (_WSbuffer) {
|
||||
(*_WSbuffer)--; // decreases the counter.
|
||||
// Serial.printf("DEC WSbuffer == %u\n", _WSbuffer->count());
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebSocketMultiMessage::ack(size_t len, uint32_t time) {
|
||||
@@ -680,7 +602,7 @@ void AsyncWebSocketClient::_queueMessage(const char *data, size_t len, uint8_t o
|
||||
_runQueue();
|
||||
}
|
||||
|
||||
void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask)
|
||||
void AsyncWebSocketClient::_queueMessage(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode, bool mask)
|
||||
{
|
||||
if(_status != WS_CONNECTED)
|
||||
return;
|
||||
@@ -922,49 +844,56 @@ void AsyncWebSocketClient::text(const String &message){
|
||||
void AsyncWebSocketClient::text(const __FlashStringHelper *data){
|
||||
text(String(data));
|
||||
}
|
||||
void AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer * buffer)
|
||||
void AsyncWebSocketClient::text(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer)
|
||||
{
|
||||
_queueMessage(buffer);
|
||||
}
|
||||
|
||||
void AsyncWebSocketClient::binary(const char * message, size_t len){
|
||||
void AsyncWebSocketClient::binary(const char * message, size_t len)
|
||||
{
|
||||
_queueMessage(message, len, WS_BINARY);
|
||||
}
|
||||
void AsyncWebSocketClient::binary(const char * message){
|
||||
void AsyncWebSocketClient::binary(const char * message)
|
||||
{
|
||||
binary(message, strlen(message));
|
||||
}
|
||||
void AsyncWebSocketClient::binary(uint8_t * message, size_t len){
|
||||
void AsyncWebSocketClient::binary(uint8_t * message, size_t len)
|
||||
{
|
||||
binary((const char *)message, len);
|
||||
}
|
||||
void AsyncWebSocketClient::binary(char * message){
|
||||
void AsyncWebSocketClient::binary(char * message)
|
||||
{
|
||||
binary(message, strlen(message));
|
||||
}
|
||||
void AsyncWebSocketClient::binary(const String &message){
|
||||
void AsyncWebSocketClient::binary(const String &message)
|
||||
{
|
||||
binary(message.c_str(), message.length());
|
||||
}
|
||||
void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len){
|
||||
void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len)
|
||||
{
|
||||
PGM_P p = reinterpret_cast<PGM_P>(data);
|
||||
char * message = (char*) malloc(len);
|
||||
if(message){
|
||||
if(message) {
|
||||
memcpy_P(message, p, len);
|
||||
binary(message, len);
|
||||
free(message);
|
||||
}
|
||||
|
||||
}
|
||||
void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer)
|
||||
void AsyncWebSocketClient::binary(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer)
|
||||
{
|
||||
_queueMessage(buffer, WS_BINARY);
|
||||
}
|
||||
|
||||
IPAddress AsyncWebSocketClient::remoteIP() const {
|
||||
if(!_client) {
|
||||
IPAddress AsyncWebSocketClient::remoteIP() const
|
||||
{
|
||||
if (!_client) {
|
||||
return IPAddress(0U);
|
||||
}
|
||||
return _client->remoteIP();
|
||||
}
|
||||
|
||||
uint16_t AsyncWebSocketClient::remotePort() const {
|
||||
uint16_t AsyncWebSocketClient::remotePort() const
|
||||
{
|
||||
if(!_client) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1041,8 +970,10 @@ void AsyncWebSocket::close(uint32_t id, uint16_t code, const char * message){
|
||||
c->close(code, message);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::closeAll(uint16_t code, const char * message){
|
||||
for(auto& c: _clients){
|
||||
void AsyncWebSocket::closeAll(uint16_t code, const char * message)
|
||||
{
|
||||
for(auto& c: _clients)
|
||||
{
|
||||
if(c.status() == WS_CONNECTED)
|
||||
c.close(code, message);
|
||||
}
|
||||
@@ -1055,72 +986,68 @@ void AsyncWebSocket::cleanupClients(uint16_t maxClients)
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len){
|
||||
void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len)
|
||||
{
|
||||
AsyncWebSocketClient * c = client(id);
|
||||
if(c)
|
||||
c->ping(data, len);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::pingAll(uint8_t *data, size_t len){
|
||||
void AsyncWebSocket::pingAll(uint8_t *data, size_t len)
|
||||
{
|
||||
for(auto& c: _clients){
|
||||
if(c.status() == WS_CONNECTED)
|
||||
c.ping(data, len);
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebSocket::text(uint32_t id, const char * message, size_t len){
|
||||
void AsyncWebSocket::text(uint32_t id, const char * message, size_t len)
|
||||
{
|
||||
AsyncWebSocketClient *c = client(id);
|
||||
if(c)
|
||||
c->text(message, len);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer)
|
||||
void AsyncWebSocket::textAll(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer)
|
||||
{
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
buffer->lock();
|
||||
|
||||
for(auto &c : _clients)
|
||||
if (c.status() == WS_CONNECTED)
|
||||
c.text(buffer);
|
||||
|
||||
buffer->unlock();
|
||||
|
||||
_cleanBuffers();
|
||||
}
|
||||
|
||||
|
||||
void AsyncWebSocket::textAll(const char * message, size_t len){
|
||||
//if (_buffers.length()) return;
|
||||
AsyncWebSocketMessageBuffer * WSBuffer = makeBuffer((uint8_t *)message, len);
|
||||
void AsyncWebSocket::textAll(const char * message, size_t len)
|
||||
{
|
||||
std::shared_ptr<AsyncWebSocketMessageBuffer> WSBuffer = makeBuffer((uint8_t *)message, len);
|
||||
textAll(WSBuffer);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len){
|
||||
void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len)
|
||||
{
|
||||
AsyncWebSocketClient * c = client(id);
|
||||
if(c)
|
||||
c->binary(message, len);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::binaryAll(const char * message, size_t len){
|
||||
AsyncWebSocketMessageBuffer * buffer = makeBuffer((uint8_t *)message, len);
|
||||
std::shared_ptr<AsyncWebSocketMessageBuffer> buffer = makeBuffer((uint8_t *)message, len);
|
||||
binaryAll(buffer);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer)
|
||||
void AsyncWebSocket::binaryAll(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer)
|
||||
{
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
buffer->lock();
|
||||
|
||||
for (auto &c : _clients)
|
||||
if (c.status() == WS_CONNECTED)
|
||||
c.binary(buffer);
|
||||
|
||||
buffer->unlock();
|
||||
|
||||
_cleanBuffers();
|
||||
}
|
||||
|
||||
@@ -1131,18 +1058,19 @@ void AsyncWebSocket::message(uint32_t id, const char *data, size_t len, uint8_t
|
||||
c->message(data, len, opcode, mask);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::message(uint32_t id, AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask)
|
||||
void AsyncWebSocket::message(uint32_t id, std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode, bool mask)
|
||||
{
|
||||
AsyncWebSocketClient *c = client(id);
|
||||
if (c)
|
||||
c->message(buffer, opcode, mask);
|
||||
}
|
||||
|
||||
void AsyncWebSocket::messageAll(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask){
|
||||
for (auto &c : _clients){
|
||||
void AsyncWebSocket::messageAll(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode, bool mask)
|
||||
{
|
||||
for (auto &c : _clients)
|
||||
if (c.status() == WS_CONNECTED)
|
||||
c.message(buffer, opcode, mask);
|
||||
}
|
||||
|
||||
_cleanBuffers();
|
||||
}
|
||||
|
||||
@@ -1158,7 +1086,8 @@ size_t AsyncWebSocket::printf(uint32_t id, const char *format, ...){
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t AsyncWebSocket::printfAll(const char *format, ...) {
|
||||
size_t AsyncWebSocket::printfAll(const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
char* temp = new char[MAX_PRINTF_LEN];
|
||||
if(!temp){
|
||||
@@ -1169,10 +1098,7 @@ size_t AsyncWebSocket::printfAll(const char *format, ...) {
|
||||
va_end(arg);
|
||||
delete[] temp;
|
||||
|
||||
AsyncWebSocketMessageBuffer * buffer = makeBuffer(len);
|
||||
if (!buffer) {
|
||||
return 0;
|
||||
}
|
||||
std::shared_ptr<AsyncWebSocketMessageBuffer> buffer = makeBuffer(len);
|
||||
|
||||
va_start(arg, format);
|
||||
vsnprintf( (char *)buffer->get(), len + 1, format, arg);
|
||||
@@ -1207,10 +1133,7 @@ size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) {
|
||||
va_end(arg);
|
||||
delete[] temp;
|
||||
|
||||
AsyncWebSocketMessageBuffer * buffer = makeBuffer(len + 1);
|
||||
if (!buffer) {
|
||||
return 0;
|
||||
}
|
||||
std::shared_ptr<AsyncWebSocketMessageBuffer> buffer = makeBuffer(len + 1);
|
||||
|
||||
va_start(arg, formatP);
|
||||
vsnprintf_P((char *)buffer->get(), len + 1, formatP, arg);
|
||||
@@ -1220,76 +1143,95 @@ size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) {
|
||||
return len;
|
||||
}
|
||||
|
||||
void AsyncWebSocket::text(uint32_t id, const char * message){
|
||||
void AsyncWebSocket::text(uint32_t id, const char * message)
|
||||
{
|
||||
text(id, message, strlen(message));
|
||||
}
|
||||
void AsyncWebSocket::text(uint32_t id, uint8_t * message, size_t len){
|
||||
void AsyncWebSocket::text(uint32_t id, uint8_t * message, size_t len)
|
||||
{
|
||||
text(id, (const char *)message, len);
|
||||
}
|
||||
void AsyncWebSocket::text(uint32_t id, char * message){
|
||||
void AsyncWebSocket::text(uint32_t id, char * message)
|
||||
{
|
||||
text(id, message, strlen(message));
|
||||
}
|
||||
void AsyncWebSocket::text(uint32_t id, const String &message){
|
||||
void AsyncWebSocket::text(uint32_t id, const String &message)
|
||||
{
|
||||
text(id, message.c_str(), message.length());
|
||||
}
|
||||
void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *message){
|
||||
void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *message)
|
||||
{
|
||||
AsyncWebSocketClient * c = client(id);
|
||||
if(c != NULL)
|
||||
c->text(message);
|
||||
}
|
||||
void AsyncWebSocket::textAll(const char * message){
|
||||
void AsyncWebSocket::textAll(const char * message)
|
||||
{
|
||||
textAll(message, strlen(message));
|
||||
}
|
||||
void AsyncWebSocket::textAll(uint8_t * message, size_t len){
|
||||
void AsyncWebSocket::textAll(uint8_t * message, size_t len)
|
||||
{
|
||||
textAll((const char *)message, len);
|
||||
}
|
||||
void AsyncWebSocket::textAll(char * message){
|
||||
void AsyncWebSocket::textAll(char * message)
|
||||
{
|
||||
textAll(message, strlen(message));
|
||||
}
|
||||
void AsyncWebSocket::textAll(const String &message){
|
||||
void AsyncWebSocket::textAll(const String &message)
|
||||
{
|
||||
textAll(message.c_str(), message.length());
|
||||
}
|
||||
void AsyncWebSocket::textAll(const __FlashStringHelper *message){
|
||||
for(auto& c: _clients){
|
||||
if(c.status() == WS_CONNECTED)
|
||||
void AsyncWebSocket::textAll(const __FlashStringHelper *message)
|
||||
{
|
||||
for (auto& c : _clients)
|
||||
if (c.status() == WS_CONNECTED)
|
||||
c.text(message);
|
||||
}
|
||||
}
|
||||
void AsyncWebSocket::binary(uint32_t id, const char * message){
|
||||
void AsyncWebSocket::binary(uint32_t id, const char * message)
|
||||
{
|
||||
binary(id, message, strlen(message));
|
||||
}
|
||||
void AsyncWebSocket::binary(uint32_t id, uint8_t * message, size_t len){
|
||||
void AsyncWebSocket::binary(uint32_t id, uint8_t * message, size_t len)
|
||||
{
|
||||
binary(id, (const char *)message, len);
|
||||
}
|
||||
void AsyncWebSocket::binary(uint32_t id, char * message){
|
||||
void AsyncWebSocket::binary(uint32_t id, char * message)
|
||||
{
|
||||
binary(id, message, strlen(message));
|
||||
}
|
||||
void AsyncWebSocket::binary(uint32_t id, const String &message){
|
||||
void AsyncWebSocket::binary(uint32_t id, const String &message)
|
||||
{
|
||||
binary(id, message.c_str(), message.length());
|
||||
}
|
||||
void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *message, size_t len){
|
||||
void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *message, size_t len)
|
||||
{
|
||||
AsyncWebSocketClient * c = client(id);
|
||||
if(c != NULL)
|
||||
if (c != NULL)
|
||||
c-> binary(message, len);
|
||||
}
|
||||
void AsyncWebSocket::binaryAll(const char * message){
|
||||
void AsyncWebSocket::binaryAll(const char * message)
|
||||
{
|
||||
binaryAll(message, strlen(message));
|
||||
}
|
||||
void AsyncWebSocket::binaryAll(uint8_t * message, size_t len){
|
||||
void AsyncWebSocket::binaryAll(uint8_t * message, size_t len)
|
||||
{
|
||||
binaryAll((const char *)message, len);
|
||||
}
|
||||
void AsyncWebSocket::binaryAll(char * message){
|
||||
void AsyncWebSocket::binaryAll(char * message)
|
||||
{
|
||||
binaryAll(message, strlen(message));
|
||||
}
|
||||
void AsyncWebSocket::binaryAll(const String &message){
|
||||
void AsyncWebSocket::binaryAll(const String &message)
|
||||
{
|
||||
binaryAll(message.c_str(), message.length());
|
||||
}
|
||||
void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len){
|
||||
for(auto& c: _clients){
|
||||
if(c.status() == WS_CONNECTED)
|
||||
void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len)
|
||||
{
|
||||
for (auto& c : _clients) {
|
||||
if (c.status() == WS_CONNECTED)
|
||||
c.binary(message, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char __WS_STR_CONNECTION[] PROGMEM = { "Connection" };
|
||||
const char __WS_STR_UPGRADE[] PROGMEM = { "Upgrade" };
|
||||
@@ -1328,24 +1270,23 @@ bool AsyncWebSocket::canHandle(AsyncWebServerRequest *request){
|
||||
return true;
|
||||
}
|
||||
|
||||
void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request){
|
||||
if(!request->hasHeader(WS_STR_VERSION) || !request->hasHeader(WS_STR_KEY)){
|
||||
void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request)
|
||||
{
|
||||
if (!request->hasHeader(WS_STR_VERSION) || !request->hasHeader(WS_STR_KEY)){
|
||||
request->send(400);
|
||||
return;
|
||||
}
|
||||
if((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())){
|
||||
if ((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())){
|
||||
return request->requestAuthentication();
|
||||
}
|
||||
//////////////////////////////////////////
|
||||
if(_handshakeHandler != nullptr){
|
||||
if (_handshakeHandler != nullptr){
|
||||
if(!_handshakeHandler(request)){
|
||||
request->send(401);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////
|
||||
AsyncWebHeader* version = request->getHeader(WS_STR_VERSION);
|
||||
if(version->value().toInt() != 13){
|
||||
if (version->value().toInt() != 13){
|
||||
AsyncWebServerResponse *response = request->beginResponse(400);
|
||||
response->addHeader(WS_STR_VERSION, F("13"));
|
||||
request->send(response);
|
||||
@@ -1353,7 +1294,7 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request){
|
||||
}
|
||||
AsyncWebHeader* key = request->getHeader(WS_STR_KEY);
|
||||
AsyncWebServerResponse *response = new AsyncWebSocketResponse(key->value(), this);
|
||||
if(request->hasHeader(WS_STR_PROTOCOL)){
|
||||
if (request->hasHeader(WS_STR_PROTOCOL)){
|
||||
AsyncWebHeader* protocol = request->getHeader(WS_STR_PROTOCOL);
|
||||
//ToDo: check protocol
|
||||
response->addHeader(WS_STR_PROTOCOL, protocol->value());
|
||||
@@ -1361,27 +1302,25 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request){
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(size_t size)
|
||||
std::shared_ptr<AsyncWebSocketMessageBuffer> AsyncWebSocket::makeBuffer(size_t size)
|
||||
{
|
||||
AsyncWebSocketMessageBuffer * buffer{};
|
||||
std::shared_ptr<AsyncWebSocketMessageBuffer> buffer = std::make_shared<AsyncWebSocketMessageBuffer>(size);
|
||||
|
||||
{
|
||||
AsyncWebLockGuard l(_lock);
|
||||
_buffers.emplace_back(size);
|
||||
buffer = &_buffers.back();
|
||||
_buffers.emplace_back(buffer);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(uint8_t * data, size_t size)
|
||||
std::shared_ptr<AsyncWebSocketMessageBuffer> AsyncWebSocket::makeBuffer(uint8_t * data, size_t size)
|
||||
{
|
||||
AsyncWebSocketMessageBuffer * buffer{};
|
||||
std::shared_ptr<AsyncWebSocketMessageBuffer> buffer = std::make_shared<AsyncWebSocketMessageBuffer>(data, size);
|
||||
|
||||
{
|
||||
AsyncWebLockGuard l(_lock);
|
||||
_buffers.emplace_back(data, size);
|
||||
buffer = &_buffers.back();
|
||||
_buffers.emplace_back(buffer);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
@@ -1390,12 +1329,11 @@ AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(uint8_t * data, size_t s
|
||||
void AsyncWebSocket::_cleanBuffers()
|
||||
{
|
||||
AsyncWebLockGuard l(_lock);
|
||||
|
||||
for (auto iter = std::begin(_buffers); iter != std::end(_buffers);){
|
||||
if(iter->canDelete()){
|
||||
iter = _buffers.erase(iter);
|
||||
} else
|
||||
if(iter->lock())
|
||||
iter++;
|
||||
else
|
||||
iter = _buffers.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,7 @@
|
||||
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
|
||||
#ifdef ESP8266
|
||||
#include <Hash.h>
|
||||
@@ -85,30 +86,17 @@ typedef enum { WS_EVT_CONNECT, WS_EVT_DISCONNECT, WS_EVT_PONG, WS_EVT_ERROR, WS_
|
||||
|
||||
class AsyncWebSocketMessageBuffer {
|
||||
private:
|
||||
uint8_t * _data;
|
||||
size_t _len;
|
||||
bool _lock;
|
||||
uint32_t _count;
|
||||
std::unique_ptr<uint8_t[]> _data;
|
||||
size_t _len{};
|
||||
|
||||
public:
|
||||
AsyncWebSocketMessageBuffer();
|
||||
AsyncWebSocketMessageBuffer(size_t size);
|
||||
AsyncWebSocketMessageBuffer(uint8_t * data, size_t size);
|
||||
AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer &);
|
||||
AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer &&);
|
||||
AsyncWebSocketMessageBuffer(uint8_t *data, size_t size);
|
||||
~AsyncWebSocketMessageBuffer();
|
||||
void operator ++(int i) { (void)i; _count++; }
|
||||
void operator --(int i) { (void)i; if (_count > 0) { _count--; } ; }
|
||||
bool reserve(size_t size);
|
||||
void lock() { _lock = true; }
|
||||
void unlock() { _lock = false; }
|
||||
uint8_t * get() { return _data; }
|
||||
uint8_t *get() { return _data.get(); }
|
||||
size_t length() { return _len; }
|
||||
uint32_t count() { return _count; }
|
||||
bool canDelete() { return (!_count && !_lock); }
|
||||
|
||||
friend AsyncWebSocket;
|
||||
|
||||
};
|
||||
|
||||
class AsyncWebSocketMessage {
|
||||
@@ -148,9 +136,9 @@ class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage {
|
||||
size_t _sent;
|
||||
size_t _ack;
|
||||
size_t _acked;
|
||||
AsyncWebSocketMessageBuffer *_WSbuffer;
|
||||
std::shared_ptr<AsyncWebSocketMessageBuffer> _WSbuffer;
|
||||
public:
|
||||
AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer * buffer, uint8_t opcode=WS_TEXT, bool mask=false);
|
||||
AsyncWebSocketMultiMessage(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode=WS_TEXT, bool mask=false);
|
||||
virtual ~AsyncWebSocketMultiMessage() override;
|
||||
virtual bool betweenFrames() const override { return _acked == _ack; }
|
||||
virtual void ack(size_t len, uint32_t time) override ;
|
||||
@@ -178,7 +166,7 @@ public:
|
||||
new (&basicMessage) AsyncWebSocketBasicMessage{data, len, opcode, mask};
|
||||
}
|
||||
|
||||
PolymorphMessageContainer(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false) :
|
||||
PolymorphMessageContainer(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode=WS_TEXT, bool mask=false) :
|
||||
type{Type::Multi}
|
||||
{
|
||||
new (&multiMessage) AsyncWebSocketMultiMessage{buffer, opcode, mask};
|
||||
@@ -234,7 +222,7 @@ class AsyncWebSocketClient {
|
||||
|
||||
void _queueControl(uint8_t opcode, uint8_t *data=NULL, size_t len=0, bool mask=false);
|
||||
void _queueMessage(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false);
|
||||
void _queueMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false);
|
||||
void _queueMessage(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode=WS_TEXT, bool mask=false);
|
||||
void _runQueue();
|
||||
void _clearQueue();
|
||||
|
||||
@@ -270,7 +258,7 @@ class AsyncWebSocketClient {
|
||||
|
||||
//data packets
|
||||
void message(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(data, len, opcode, mask); }
|
||||
void message(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); }
|
||||
void message(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); }
|
||||
bool queueIsFull() const;
|
||||
size_t queueLen() const;
|
||||
|
||||
@@ -284,7 +272,7 @@ class AsyncWebSocketClient {
|
||||
void text(char * message);
|
||||
void text(const String &message);
|
||||
void text(const __FlashStringHelper *data);
|
||||
void text(AsyncWebSocketMessageBuffer *buffer);
|
||||
void text(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer);
|
||||
|
||||
void binary(const char * message, size_t len);
|
||||
void binary(const char * message);
|
||||
@@ -292,7 +280,7 @@ class AsyncWebSocketClient {
|
||||
void binary(char * message);
|
||||
void binary(const String &message);
|
||||
void binary(const __FlashStringHelper *data, size_t len);
|
||||
void binary(AsyncWebSocketMessageBuffer *buffer);
|
||||
void binary(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer);
|
||||
|
||||
bool canSend() const;
|
||||
|
||||
@@ -352,7 +340,7 @@ class AsyncWebSocket: public AsyncWebHandler {
|
||||
void textAll(char * message);
|
||||
void textAll(const String &message);
|
||||
void textAll(const __FlashStringHelper *message); // need to convert
|
||||
void textAll(AsyncWebSocketMessageBuffer *buffer);
|
||||
void textAll(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer);
|
||||
|
||||
void binary(uint32_t id, const char * message, size_t len);
|
||||
void binary(uint32_t id, const char * message);
|
||||
@@ -367,11 +355,11 @@ class AsyncWebSocket: public AsyncWebHandler {
|
||||
void binaryAll(char * message);
|
||||
void binaryAll(const String &message);
|
||||
void binaryAll(const __FlashStringHelper *message, size_t len);
|
||||
void binaryAll(AsyncWebSocketMessageBuffer *buffer);
|
||||
void binaryAll(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer);
|
||||
|
||||
void message(uint32_t id, const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false);
|
||||
void message(uint32_t id, AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false);
|
||||
void messageAll(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false);
|
||||
void message(uint32_t id, std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode=WS_TEXT, bool mask=false);
|
||||
void messageAll(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode=WS_TEXT, bool mask=false);
|
||||
|
||||
size_t printf(uint32_t id, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
size_t printfAll(const char *format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
@@ -400,9 +388,9 @@ class AsyncWebSocket: public AsyncWebHandler {
|
||||
|
||||
|
||||
// messagebuffer functions/objects.
|
||||
AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0);
|
||||
AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size);
|
||||
std::list<AsyncWebSocketMessageBuffer> _buffers;
|
||||
std::shared_ptr<AsyncWebSocketMessageBuffer> makeBuffer(size_t size = 0);
|
||||
std::shared_ptr<AsyncWebSocketMessageBuffer> makeBuffer(uint8_t * data, size_t size);
|
||||
std::list<std::weak_ptr<AsyncWebSocketMessageBuffer>> _buffers;
|
||||
void _cleanBuffers();
|
||||
|
||||
const std::list<AsyncWebSocketClient> &getClients() const { return _clients; }
|
||||
|
Reference in New Issue
Block a user