From 3063ad27ae047e67aff292230152587206cc490b Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 10 Jun 2019 12:57:49 +0200 Subject: [PATCH] clang-format --- .clang-format | 63 +++++++ src/WebSockets.cpp | 192 ++++++++++---------- src/WebSockets.h | 202 ++++++++++----------- src/WebSocketsClient.cpp | 258 +++++++++++++-------------- src/WebSocketsClient.h | 132 +++++++------- src/WebSocketsServer.cpp | 377 ++++++++++++++++++--------------------- src/WebSocketsServer.h | 224 +++++++++++------------ 7 files changed, 729 insertions(+), 719 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..e72c54b --- /dev/null +++ b/.clang-format @@ -0,0 +1,63 @@ +--- +BasedOnStyle: Google +AccessModifierOffset: '-2' +AlignAfterOpenBracket: DontAlign +AlignConsecutiveAssignments: 'true' +AlignConsecutiveDeclarations: 'false' +AlignEscapedNewlines: Left +AlignTrailingComments: 'true' +AllowAllParametersOfDeclarationOnNextLine: 'false' +AllowShortBlocksOnASingleLine: 'false' +AllowShortCaseLabelsOnASingleLine: 'false' +AllowShortFunctionsOnASingleLine: InlineOnly +AllowShortIfStatementsOnASingleLine: 'true' +AllowShortLoopsOnASingleLine: 'true' +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: 'true' +AlwaysBreakTemplateDeclarations: 'false' +BinPackParameters: 'true' +BreakAfterJavaFieldAnnotations: 'false' +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: 'false' +BreakBeforeTernaryOperators: 'false' +BreakConstructorInitializers: BeforeColon +BreakStringLiterals: 'false' +ColumnLimit: '0' +CompactNamespaces: 'true' +ConstructorInitializerAllOnOneLineOrOnePerLine: 'true' +ConstructorInitializerIndentWidth: '4' +ContinuationIndentWidth: '4' +Cpp11BracedListStyle: 'false' +DerivePointerAlignment: 'false' +FixNamespaceComments: 'true' +IndentCaseLabels: 'true' +IndentWidth: '4' +IndentWrappedFunctionNames: 'false' +JavaScriptQuotes: Single +JavaScriptWrapImports: 'false' +KeepEmptyLinesAtTheStartOfBlocks: 'false' +MaxEmptyLinesToKeep: '1' +NamespaceIndentation: All +ObjCBlockIndentWidth: '4' +ObjCSpaceAfterProperty: 'false' +ObjCSpaceBeforeProtocolList: 'false' +PointerAlignment: Middle +SortIncludes: 'false' +SortUsingDeclarations: 'true' +SpaceAfterCStyleCast: 'false' +SpaceAfterTemplateKeyword: 'false' +SpaceBeforeAssignmentOperators: 'true' +SpaceBeforeParens: Never +SpaceInEmptyParentheses: 'false' +SpacesBeforeTrailingComments: '4' +SpacesInAngles: 'false' +SpacesInCStyleCastParentheses: 'false' +SpacesInContainerLiterals: 'false' +SpacesInParentheses: 'false' +SpacesInSquareBrackets: 'false' +TabWidth: '4' +UseTab: Never + +... diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 0f57922..608c045 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -48,7 +48,6 @@ extern "C" { #endif - /** * * @param client WSclient_t * ptr to the client struct @@ -60,7 +59,7 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] clientDisconnect code: %u\n", client->num, code); if(client->status == WSC_CONNECTED && code) { if(reason) { - sendFrame(client, WSop_close, (uint8_t *) reason, reasonLen); + sendFrame(client, WSop_close, (uint8_t *)reason, reasonLen); } else { uint8_t buffer[2]; buffer[0] = ((code >> 8) & 0xFF); @@ -82,7 +81,6 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea * @return true if ok */ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin, bool headerToPayload) { - if(client->tcp && !client->tcp->connected()) { DEBUG_WEBSOCKETS("[WS][%d][sendFrame] not Connected!?\n", client->num); return false; @@ -100,14 +98,14 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay DEBUG_WEBSOCKETS("[WS][%d][sendFrame] text: %s\n", client->num, (payload + (headerToPayload ? 14 : 0))); } - uint8_t maskKey[4] = { 0x00, 0x00, 0x00, 0x00 }; + uint8_t maskKey[4] = { 0x00, 0x00, 0x00, 0x00 }; uint8_t buffer[WEBSOCKETS_MAX_HEADER_SIZE] = { 0 }; uint8_t headerSize; uint8_t * headerPtr; uint8_t * payloadPtr = payload; bool useInternBuffer = false; - bool ret = true; + bool ret = true; // calculate header Size if(length < 126) { @@ -127,12 +125,12 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay // try to send data in one TCP package (only if some free Heap is there) if(!headerToPayload && ((length > 0) && (length < 1400)) && (GET_FREE_HEAP > 6000)) { DEBUG_WEBSOCKETS("[WS][%d][sendFrame] pack to one TCP package...\n", client->num); - uint8_t * dataPtr = (uint8_t *) malloc(length + WEBSOCKETS_MAX_HEADER_SIZE); + uint8_t * dataPtr = (uint8_t *)malloc(length + WEBSOCKETS_MAX_HEADER_SIZE); if(dataPtr) { memcpy((dataPtr + WEBSOCKETS_MAX_HEADER_SIZE), payload, length); headerToPayload = true; useInternBuffer = true; - payloadPtr = dataPtr; + payloadPtr = dataPtr; } } #endif @@ -152,7 +150,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay if(fin) { *headerPtr |= bit(7); ///< set Fin } - *headerPtr |= opcode; ///< set opcode + *headerPtr |= opcode; ///< set opcode headerPtr++; // byte 1 @@ -268,10 +266,10 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay * @param client WSclient_t * ptr to the client struct */ void WebSockets::headerDone(WSclient_t * client) { - client->status = WSC_CONNECTED; + client->status = WSC_CONNECTED; client->cWsRXsize = 0; DEBUG_WEBSOCKETS("[WS][%d][headerDone] Header Handling Done.\n", client->num); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; handleWebsocket(client); #endif @@ -318,12 +316,12 @@ bool WebSockets::handleWebsocketWaitFor(WSclient_t * client, size_t size) { // timeout or error server->clientDisconnect(client, 1002); } - }, this, size, std::placeholders::_1, std::placeholders::_2)); + }, + this, size, std::placeholders::_1, std::placeholders::_2)); return false; } void WebSockets::handleWebsocketCb(WSclient_t * client) { - if(!client->tcp || !client->tcp->connected()) { return; } @@ -331,7 +329,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { uint8_t * buffer = client->cWsHeader; WSMessageHeader_t * header = &client->cWsHeaderDecode; - uint8_t * payload = NULL; + uint8_t * payload = NULL; uint8_t headerLen = 2; @@ -340,15 +338,15 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { } // split first 2 bytes in the data - header->fin = ((*buffer >> 7) & 0x01); - header->rsv1 = ((*buffer >> 6) & 0x01); - header->rsv2 = ((*buffer >> 5) & 0x01); - header->rsv3 = ((*buffer >> 4) & 0x01); - header->opCode = (WSopcode_t) (*buffer & 0x0F); + header->fin = ((*buffer >> 7) & 0x01); + header->rsv1 = ((*buffer >> 6) & 0x01); + header->rsv2 = ((*buffer >> 5) & 0x01); + header->rsv3 = ((*buffer >> 4) & 0x01); + header->opCode = (WSopcode_t)(*buffer & 0x0F); buffer++; - header->mask = ((*buffer >> 7) & 0x01); - header->payloadLen = (WSopcode_t) (*buffer & 0x7F); + header->mask = ((*buffer >> 7) & 0x01); + header->payloadLen = (WSopcode_t)(*buffer & 0x7F); buffer++; if(header->payloadLen == 126) { @@ -395,7 +393,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { if(header->payloadLen > 0) { // if text data we need one more - payload = (uint8_t *) malloc(header->payloadLen + 1); + payload = (uint8_t *)malloc(header->payloadLen + 1); if(!payload) { DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] to less memory to handle payload %d!\n", client->num, header->payloadLen); @@ -409,7 +407,6 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { } void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload) { - WSMessageHeader_t * header = &client->cWsHeaderDecode; if(ok) { if(header->payloadLen > 0) { @@ -433,22 +430,22 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t break; case WSop_ping: // send pong back - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] ping received (%s)\n", client->num, payload ? (const char*)payload : ""); + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] ping received (%s)\n", client->num, payload ? (const char *)payload : ""); sendFrame(client, WSop_pong, payload, header->payloadLen); messageReceived(client, header->opCode, payload, header->payloadLen, header->fin); break; case WSop_pong: - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload ? (const char*)payload : ""); + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload ? (const char *)payload : ""); client->pongReceived = true; messageReceived(client, header->opCode, payload, header->payloadLen, header->fin); break; case WSop_close: { - #ifndef NODEBUG_WEBSOCKETS - uint16_t reasonCode = 1000; - if(header->payloadLen >= 2) { - reasonCode = payload[0] << 8 | payload[1]; - } - #endif +#ifndef NODEBUG_WEBSOCKETS + uint16_t reasonCode = 1000; + if(header->payloadLen >= 2) { + reasonCode = payload[0] << 8 | payload[1]; + } +#endif DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get ask for close. Code: %d", client->num, reasonCode); if(header->payloadLen > 2) { DEBUG_WEBSOCKETS(" (%s)\n", (payload + 2)); @@ -456,8 +453,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t DEBUG_WEBSOCKETS("\n"); } clientDisconnect(client, 1000); - } - break; + } break; default: clientDisconnect(client, 1002); break; @@ -469,7 +465,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t // reset input client->cWsRXsize = 0; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) //register callback for next message handleWebsocketWaitFor(client, 2); #endif @@ -492,12 +488,12 @@ String WebSockets::acceptKey(String & clientKey) { sha1(clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", &sha1HashBin[0]); #elif defined(ESP32) String data = clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - esp_sha(SHA1, (unsigned char*)data.c_str(), data.length(), &sha1HashBin[0]); + esp_sha(SHA1, (unsigned char *)data.c_str(), data.length(), &sha1HashBin[0]); #else clientKey += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; SHA1_CTX ctx; SHA1Init(&ctx); - SHA1Update(&ctx, (const unsigned char*)clientKey.c_str(), clientKey.length()); + SHA1Update(&ctx, (const unsigned char *)clientKey.c_str(), clientKey.length()); SHA1Final(&sha1HashBin[0], &ctx); #endif @@ -514,13 +510,13 @@ String WebSockets::acceptKey(String & clientKey) { * @return base64 encoded String */ String WebSockets::base64_encode(uint8_t * data, size_t length) { - size_t size = ((length * 1.6f) + 1); - char * buffer = (char *) malloc(size); + size_t size = ((length * 1.6f) + 1); + char * buffer = (char *)malloc(size); if(buffer) { base64_encodestate _state; base64_init_encodestate(&_state); - int len = base64_encode_block((const char *) &data[0], length, &buffer[0], &_state); - len = base64_encode_blockend((buffer + len), &_state); + int len = base64_encode_block((const char *)&data[0], length, &buffer[0], &_state); + len = base64_encode_blockend((buffer + len), &_state); String base64 = String(buffer); free(buffer); @@ -537,7 +533,7 @@ String WebSockets::base64_encode(uint8_t * data, size_t length) { * @return true if ok */ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWaitCb cb) { -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) if(!client->tcp || !client->tcp->connected()) { return false; } @@ -546,7 +542,8 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait if(cb) { cb(client, ok); } - }, client, std::placeholders::_1, cb)); + }, + client, std::placeholders::_1, cb)); #else unsigned long t = millis(); @@ -578,13 +575,13 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait } if(!client->tcp->available()) { -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif continue; } - len = client->tcp->read((uint8_t*) out, n); + len = client->tcp->read((uint8_t *)out, n); if(len) { t = millis(); out += len; @@ -593,7 +590,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait } else { //DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } @@ -611,50 +608,54 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait * @param n size_t byte count * @return bytes send */ -size_t WebSockets::write(WSclient_t * client, uint8_t *out, size_t n) { - if(out == NULL) return 0; - if(client == NULL) return 0; - unsigned long t = millis(); - size_t len = 0; - size_t total = 0; - DEBUG_WEBSOCKETS("[write] n: %zu t: %lu\n", n, t); - while(n > 0) { - if(client->tcp == NULL) { - DEBUG_WEBSOCKETS("[write] tcp is null!\n"); - break; - } +size_t WebSockets::write(WSclient_t * client, uint8_t * out, size_t n) { + if(out == NULL) + return 0; + if(client == NULL) + return 0; + unsigned long t = millis(); + size_t len = 0; + size_t total = 0; + DEBUG_WEBSOCKETS("[write] n: %zu t: %lu\n", n, t); + while(n > 0) { + if(client->tcp == NULL) { + DEBUG_WEBSOCKETS("[write] tcp is null!\n"); + break; + } - if(!client->tcp->connected()) { - DEBUG_WEBSOCKETS("[write] not connected!\n"); - break; - } + if(!client->tcp->connected()) { + DEBUG_WEBSOCKETS("[write] not connected!\n"); + break; + } - if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) { - DEBUG_WEBSOCKETS("[write] write TIMEOUT! %lu\n", (millis() - t)); - break; - } + if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) { + DEBUG_WEBSOCKETS("[write] write TIMEOUT! %lu\n", (millis() - t)); + break; + } - len = client->tcp->write((const uint8_t*)out, n); - if(len) { - t = millis(); - out += len; - n -= len; - total += len; - //DEBUG_WEBSOCKETS("write %d left %d!\n", len, n); - } else { - //DEBUG_WEBSOCKETS("write %d failed left %d!\n", len, n); - } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - delay(0); + len = client->tcp->write((const uint8_t *)out, n); + if(len) { + t = millis(); + out += len; + n -= len; + total += len; + //DEBUG_WEBSOCKETS("write %d left %d!\n", len, n); + } else { + //DEBUG_WEBSOCKETS("write %d failed left %d!\n", len, n); + } +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + delay(0); #endif - } - return total; + } + return total; } -size_t WebSockets::write(WSclient_t * client, const char *out) { - if(client == NULL) return 0; - if(out == NULL) return 0; - return write(client, (uint8_t*)out, strlen(out)); +size_t WebSockets::write(WSclient_t * client, const char * out) { + if(client == NULL) + return 0; + if(out == NULL) + return 0; + return write(client, (uint8_t *)out, strlen(out)); } /** @@ -664,36 +665,37 @@ size_t WebSockets::write(WSclient_t * client, const char *out) { * @param pongTimeout uint32_t millis after which pong should timout if not received * @param disconnectTimeoutCount uint8_t how many timeouts before disconnect, 0=> do not disconnect */ -void WebSockets::enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount){ - if(client == NULL) return; - client->pingInterval = pingInterval; - client->pongTimeout = pongTimeout; +void WebSockets::enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { + if(client == NULL) + return; + client->pingInterval = pingInterval; + client->pongTimeout = pongTimeout; client->disconnectTimeoutCount = disconnectTimeoutCount; - client->pongReceived = false; + client->pongReceived = false; } /** * handle ping/pong heartbeat timeout process * @param client WSclient_t * - */ -void WebSockets::handleHBTimeout(WSclient_t * client){ - if (client->pingInterval) { // if heartbeat is enabled + */ +void WebSockets::handleHBTimeout(WSclient_t * client) { + if(client->pingInterval) { // if heartbeat is enabled uint32_t pi = millis() - client->lastPing; - if (client->pongReceived) { + if(client->pongReceived) { client->pongTimeoutCount = 0; } else { - if (pi > client->pongTimeout){ // pong not received in time + if(pi > client->pongTimeout) { // pong not received in time client->pongTimeoutCount++; - client->lastPing = millis() - client->pingInterval - 500; // force ping on the next run + client->lastPing = millis() - client->pingInterval - 500; // force ping on the next run DEBUG_WEBSOCKETS("[HBtimeout] pong TIMEOUT! lp=%d millis=%d pi=%d count=%d\n", client->lastPing, millis(), pi, client->pongTimeoutCount); - if (client->disconnectTimeoutCount && client->pongTimeoutCount >= client->disconnectTimeoutCount){ + if(client->disconnectTimeoutCount && client->pongTimeoutCount >= client->disconnectTimeoutCount) { DEBUG_WEBSOCKETS("[HBtimeout] count=%d, DISCONNECTING\n", client->pongTimeoutCount); clientDisconnect(client); } - } + } } } } diff --git a/src/WebSockets.h b/src/WebSockets.h index f9c2a94..6a749fa 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -27,7 +27,7 @@ #ifdef STM32_DEVICE #include -#define bit(b) (1UL << (b)) // Taken directly from Arduino.h +#define bit(b) (1UL << (b)) // Taken directly from Arduino.h #else #include #include @@ -40,16 +40,14 @@ #include #endif - #ifndef NODEBUG_WEBSOCKETS #ifdef DEBUG_ESP_PORT -#define DEBUG_WEBSOCKETS(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ ) +#define DEBUG_WEBSOCKETS(...) DEBUG_ESP_PORT.printf(__VA_ARGS__) #else //#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) #endif #endif - #ifndef DEBUG_WEBSOCKETS #define DEBUG_WEBSOCKETS(...) #define NODEBUG_WEBSOCKETS @@ -57,7 +55,7 @@ #if defined(ESP8266) || defined(ESP32) -#define WEBSOCKETS_MAX_DATA_SIZE (15*1024) +#define WEBSOCKETS_MAX_DATA_SIZE (15 * 1024) #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP ESP.getFreeHeap() // moves all Header strings to Flash (~300 Byte) @@ -65,31 +63,30 @@ #elif defined(STM32_DEVICE) -#define WEBSOCKETS_MAX_DATA_SIZE (15*1024) +#define WEBSOCKETS_MAX_DATA_SIZE (15 * 1024) #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP System.freeMemory() #else //atmega328p has only 2KB ram! -#define WEBSOCKETS_MAX_DATA_SIZE (1024) +#define WEBSOCKETS_MAX_DATA_SIZE (1024) // moves all Header strings to Flash #define WEBSOCKETS_SAVE_RAM #endif +#define WEBSOCKETS_TCP_TIMEOUT (2000) -#define WEBSOCKETS_TCP_TIMEOUT (2000) - -#define NETWORK_ESP8266_ASYNC (0) -#define NETWORK_ESP8266 (1) -#define NETWORK_W5100 (2) -#define NETWORK_ENC28J60 (3) -#define NETWORK_ESP32 (4) -#define NETWORK_ESP32_ETH (5) +#define NETWORK_ESP8266_ASYNC (0) +#define NETWORK_ESP8266 (1) +#define NETWORK_W5100 (2) +#define NETWORK_ENC28J60 (3) +#define NETWORK_ESP32 (4) +#define NETWORK_ESP32_ETH (5) // max size of the WS Message Header -#define WEBSOCKETS_MAX_HEADER_SIZE (14) +#define WEBSOCKETS_MAX_HEADER_SIZE (14) #if !defined(WEBSOCKETS_NETWORK_TYPE) // select Network type based @@ -108,13 +105,12 @@ #endif // Includes and defined based on Network Type -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) // Note: // No SSL/WSS support for client in Async mode // TLS lib need a sync interface! - #if defined(ESP8266) #include #elif defined(ESP32) @@ -131,7 +127,7 @@ #define WEBSOCKETS_NETWORK_CLASS AsyncTCPbuffer #define WEBSOCKETS_NETWORK_SERVER_CLASS AsyncServer -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) #if !defined(ESP8266) && !defined(ESP31B) #error "network type ESP8266 only possible on the ESP mcu!" @@ -146,7 +142,7 @@ #define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) #ifdef STM32_DEVICE #define WEBSOCKETS_NETWORK_CLASS TCPClient @@ -158,13 +154,13 @@ #define WEBSOCKETS_NETWORK_SERVER_CLASS EthernetServer #endif -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ENC28J60) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ENC28J60) #include #define WEBSOCKETS_NETWORK_CLASS UIPClient #define WEBSOCKETS_NETWORK_SERVER_CLASS UIPServer -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) #include #include @@ -172,7 +168,7 @@ #define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32_ETH) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32_ETH) #include #define WEBSOCKETS_NETWORK_CLASS WiFiClient @@ -182,16 +178,15 @@ #error "no network type selected!" #endif - #ifdef WEBSOCKETS_NETWORK_SSL_CLASS #define HAS_SSL #endif // moves all Header strings to Flash (~300 Byte) #ifdef WEBSOCKETS_SAVE_RAM -#define WEBSOCKETS_STRING(var) F(var) +#define WEBSOCKETS_STRING(var) F(var) #else -#define WEBSOCKETS_STRING(var) var +#define WEBSOCKETS_STRING(var) var #endif typedef enum { @@ -206,130 +201,125 @@ typedef enum { WStype_CONNECTED, WStype_TEXT, WStype_BIN, - WStype_FRAGMENT_TEXT_START, - WStype_FRAGMENT_BIN_START, - WStype_FRAGMENT, - WStype_FRAGMENT_FIN, - WStype_PING, - WStype_PONG, + WStype_FRAGMENT_TEXT_START, + WStype_FRAGMENT_BIN_START, + WStype_FRAGMENT, + WStype_FRAGMENT_FIN, + WStype_PING, + WStype_PONG, } WStype_t; typedef enum { - WSop_continuation = 0x00, ///< %x0 denotes a continuation frame - WSop_text = 0x01, ///< %x1 denotes a text frame - WSop_binary = 0x02, ///< %x2 denotes a binary frame - ///< %x3-7 are reserved for further non-control frames - WSop_close = 0x08, ///< %x8 denotes a connection close - WSop_ping = 0x09, ///< %x9 denotes a ping - WSop_pong = 0x0A ///< %xA denotes a pong - ///< %xB-F are reserved for further control frames + WSop_continuation = 0x00, ///< %x0 denotes a continuation frame + WSop_text = 0x01, ///< %x1 denotes a text frame + WSop_binary = 0x02, ///< %x2 denotes a binary frame + ///< %x3-7 are reserved for further non-control frames + WSop_close = 0x08, ///< %x8 denotes a connection close + WSop_ping = 0x09, ///< %x9 denotes a ping + WSop_pong = 0x0A ///< %xA denotes a pong + ///< %xB-F are reserved for further control frames } WSopcode_t; typedef struct { + bool fin; + bool rsv1; + bool rsv2; + bool rsv3; - bool fin; - bool rsv1; - bool rsv2; - bool rsv3; + WSopcode_t opCode; + bool mask; - WSopcode_t opCode; - bool mask; + size_t payloadLen; - size_t payloadLen; - - uint8_t * maskKey; + uint8_t * maskKey; } WSMessageHeader_t; typedef struct { - uint8_t num; ///< connection number + uint8_t num; ///< connection number - WSclientsStatus_t status; + WSclientsStatus_t status; - WEBSOCKETS_NETWORK_CLASS * tcp; + WEBSOCKETS_NETWORK_CLASS * tcp; - bool isSocketIO; ///< client for socket.io server + bool isSocketIO; ///< client for socket.io server #if defined(HAS_SSL) - bool isSSL; ///< run in ssl mode - WEBSOCKETS_NETWORK_SSL_CLASS * ssl; + bool isSSL; ///< run in ssl mode + WEBSOCKETS_NETWORK_SSL_CLASS * ssl; #endif - String cUrl; ///< http url - uint16_t cCode; ///< http code + String cUrl; ///< http url + uint16_t cCode; ///< http code - bool cIsClient = false; ///< will be used for masking - bool cIsUpgrade; ///< Connection == Upgrade - bool cIsWebsocket; ///< Upgrade == websocket + bool cIsClient = false; ///< will be used for masking + bool cIsUpgrade; ///< Connection == Upgrade + bool cIsWebsocket; ///< Upgrade == websocket - String cSessionId; ///< client Set-Cookie (session id) - String cKey; ///< client Sec-WebSocket-Key - String cAccept; ///< client Sec-WebSocket-Accept - String cProtocol; ///< client Sec-WebSocket-Protocol - String cExtensions; ///< client Sec-WebSocket-Extensions - uint16_t cVersion; ///< client Sec-WebSocket-Version + String cSessionId; ///< client Set-Cookie (session id) + String cKey; ///< client Sec-WebSocket-Key + String cAccept; ///< client Sec-WebSocket-Accept + String cProtocol; ///< client Sec-WebSocket-Protocol + String cExtensions; ///< client Sec-WebSocket-Extensions + uint16_t cVersion; ///< client Sec-WebSocket-Version - uint8_t cWsRXsize; ///< State of the RX - uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer - WSMessageHeader_t cWsHeaderDecode; + uint8_t cWsRXsize; ///< State of the RX + uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer + WSMessageHeader_t cWsHeaderDecode; - String base64Authorization; ///< Base64 encoded Auth request - String plainAuthorization; ///< Base64 encoded Auth request + String base64Authorization; ///< Base64 encoded Auth request + String plainAuthorization; ///< Base64 encoded Auth request - String extraHeaders; + String extraHeaders; - bool cHttpHeadersValid; ///< non-websocket http header validity indicator - size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count + bool cHttpHeadersValid; ///< non-websocket http header validity indicator + size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count - bool pongReceived; - uint32_t pingInterval; // how often ping will be sent, 0 means "heartbeat is not active" - uint32_t lastPing; // millis when last pong has been received - uint32_t pongTimeout; // interval in millis after which pong is considered to timeout - uint8_t disconnectTimeoutCount; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect" - uint8_t pongTimeoutCount; // current pong timeout count + bool pongReceived; + uint32_t pingInterval; // how often ping will be sent, 0 means "heartbeat is not active" + uint32_t lastPing; // millis when last pong has been received + uint32_t pongTimeout; // interval in millis after which pong is considered to timeout + uint8_t disconnectTimeoutCount; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect" + uint8_t pongTimeoutCount; // current pong timeout count -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - String cHttpLine; ///< HTTP header lines +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + String cHttpLine; ///< HTTP header lines #endif } WSclient_t; - - class WebSockets { - protected: + protected: #ifdef __AVR__ - typedef void (*WSreadWaitCb)(WSclient_t * client, bool ok); + typedef void (*WSreadWaitCb)(WSclient_t * client, bool ok); #else - typedef std::function WSreadWaitCb; + typedef std::function WSreadWaitCb; #endif - virtual void clientDisconnect(WSclient_t * client) = 0; - virtual bool clientIsConnected(WSclient_t * client) = 0; + virtual void clientDisconnect(WSclient_t * client) = 0; + virtual bool clientIsConnected(WSclient_t * client) = 0; - virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) = 0; + virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) = 0; - void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); - bool sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool fin = true, bool headerToPayload = false); + void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); + bool sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool fin = true, bool headerToPayload = false); - void headerDone(WSclient_t * client); + void headerDone(WSclient_t * client); - void handleWebsocket(WSclient_t * client); + void handleWebsocket(WSclient_t * client); - bool handleWebsocketWaitFor(WSclient_t * client, size_t size); - void handleWebsocketCb(WSclient_t * client); - void handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload); + bool handleWebsocketWaitFor(WSclient_t * client, size_t size); + void handleWebsocketCb(WSclient_t * client); + void handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload); - String acceptKey(String & clientKey); - String base64_encode(uint8_t * data, size_t length); - - bool readCb(WSclient_t * client, uint8_t *out, size_t n, WSreadWaitCb cb); - virtual size_t write(WSclient_t * client, uint8_t *out, size_t n); - size_t write(WSclient_t * client, const char *out); - - void enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); - void handleHBTimeout(WSclient_t * client); + String acceptKey(String & clientKey); + String base64_encode(uint8_t * data, size_t length); + bool readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWaitCb cb); + virtual size_t write(WSclient_t * client, uint8_t * out, size_t n); + size_t write(WSclient_t * client, const char * out); + void enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); + void handleHBTimeout(WSclient_t * client); }; #ifndef UNUSED diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 0002561..8d48ccd 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -26,9 +26,9 @@ #include "WebSocketsClient.h" WebSocketsClient::WebSocketsClient() { - _cbEvent = NULL; - _client.num = 0; - _client.cIsClient = true; + _cbEvent = NULL; + _client.num = 0; + _client.cIsClient = true; _client.extraHeaders = WEBSOCKETS_STRING("Origin: file://"); } @@ -39,37 +39,37 @@ WebSocketsClient::~WebSocketsClient() { /** * calles to init the Websockets server */ -void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, const char * protocol) { +void WebSocketsClient::begin(const char * host, uint16_t port, const char * url, const char * protocol) { _host = host; _port = port; #if defined(HAS_SSL) _fingerprint = ""; - _CA_cert = NULL; + _CA_cert = NULL; #endif - _client.num = 0; + _client.num = 0; _client.status = WSC_NOT_CONNECTED; - _client.tcp = NULL; + _client.tcp = NULL; #if defined(HAS_SSL) _client.isSSL = false; - _client.ssl = NULL; + _client.ssl = NULL; #endif - _client.cUrl = url; - _client.cCode = 0; - _client.cIsUpgrade = false; - _client.cIsWebsocket = true; - _client.cKey = ""; - _client.cAccept = ""; - _client.cProtocol = protocol; - _client.cExtensions = ""; - _client.cVersion = 0; + _client.cUrl = url; + _client.cCode = 0; + _client.cIsUpgrade = false; + _client.cIsWebsocket = true; + _client.cKey = ""; + _client.cAccept = ""; + _client.cProtocol = protocol; + _client.cExtensions = ""; + _client.cVersion = 0; _client.base64Authorization = ""; - _client.plainAuthorization = ""; - _client.isSocketIO = false; + _client.plainAuthorization = ""; + _client.isSocketIO = false; - _client.lastPing = 0; - _client.pongReceived = false; - _client.pongTimeoutCount = 0; + _client.lastPing = 0; + _client.pongReceived = false; + _client.pongTimeoutCount = 0; #ifdef ESP8266 randomSeed(RANDOM_REG32); @@ -77,12 +77,12 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, // todo find better seed randomSeed(millis()); #endif -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) asyncConnect(); #endif _lastConnectionFail = 0; - _reconnectInterval = 500; + _reconnectInterval = 500; } void WebSocketsClient::begin(String host, uint16_t port, String url, String protocol) { @@ -94,26 +94,26 @@ void WebSocketsClient::begin(IPAddress host, uint16_t port, const char * url, co } #if defined(HAS_SSL) -void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * url, const char * fingerprint, const char * protocol) { +void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * url, const char * fingerprint, const char * protocol) { begin(host, port, url, protocol); _client.isSSL = true; - _fingerprint = fingerprint; - _CA_cert = NULL; + _fingerprint = fingerprint; + _CA_cert = NULL; } void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String fingerprint, String protocol) { beginSSL(host.c_str(), port, url.c_str(), fingerprint.c_str(), protocol.c_str()); } -void WebSocketsClient::beginSslWithCA(const char *host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { +void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { begin(host, port, url, protocol); _client.isSSL = true; - _fingerprint = ""; - _CA_cert = CA_cert; + _fingerprint = ""; + _CA_cert = CA_cert; } #endif -void WebSocketsClient::beginSocketIO(const char *host, uint16_t port, const char * url, const char * protocol) { +void WebSocketsClient::beginSocketIO(const char * host, uint16_t port, const char * url, const char * protocol) { begin(host, port, url, protocol); _client.isSocketIO = true; } @@ -123,27 +123,27 @@ void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, Str } #if defined(HAS_SSL) -void WebSocketsClient::beginSocketIOSSL(const char *host, uint16_t port, const char * url, const char * protocol) { +void WebSocketsClient::beginSocketIOSSL(const char * host, uint16_t port, const char * url, const char * protocol) { begin(host, port, url, protocol); _client.isSocketIO = true; - _client.isSSL = true; - _fingerprint = ""; + _client.isSSL = true; + _fingerprint = ""; } void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url, String protocol) { beginSocketIOSSL(host.c_str(), port, url.c_str(), protocol.c_str()); } -void WebSocketsClient::beginSocketIOSSLWithCA(const char *host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { +void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { begin(host, port, url, protocol); _client.isSocketIO = true; - _client.isSSL = true; - _fingerprint = ""; - _CA_cert = CA_cert; + _client.isSSL = true; + _fingerprint = ""; + _CA_cert = CA_cert; } #endif -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * called in arduino loop */ @@ -169,7 +169,7 @@ void WebSocketsClient::loop(void) { #if defined(ESP32) _client.ssl->setCACert(_CA_cert); #elif defined(ESP8266) - _client.ssl->setCACert((const uint8_t *)_CA_cert, strlen(_CA_cert) + 1); + _client.ssl->setCACert((const uint8_t *)_CA_cert, strlen(_CA_cert) + 1); #else #error setCACert not implemented #endif @@ -197,16 +197,14 @@ void WebSocketsClient::loop(void) { } else { connectFailedCb(); _lastConnectionFail = millis(); - } } else { handleClientData(); - if (_client.status == WSC_CONNECTED){ + if(_client.status == WSC_CONNECTED) { handleHBPing(); handleHBTimeout(&_client); } - } } #endif @@ -229,7 +227,7 @@ void WebSocketsClient::onEvent(WebSocketClientEvent cbEvent) { */ bool WebSocketsClient::sendTXT(uint8_t * payload, size_t length, bool headerToPayload) { if(length == 0) { - length = strlen((const char *) payload); + length = strlen((const char *)payload); } if(clientIsConnected(&_client)) { return sendFrame(&_client, WSop_text, payload, length, true, headerToPayload); @@ -238,19 +236,19 @@ bool WebSocketsClient::sendTXT(uint8_t * payload, size_t length, bool headerToPa } bool WebSocketsClient::sendTXT(const uint8_t * payload, size_t length) { - return sendTXT((uint8_t *) payload, length); + return sendTXT((uint8_t *)payload, length); } bool WebSocketsClient::sendTXT(char * payload, size_t length, bool headerToPayload) { - return sendTXT((uint8_t *) payload, length, headerToPayload); + return sendTXT((uint8_t *)payload, length, headerToPayload); } bool WebSocketsClient::sendTXT(const char * payload, size_t length) { - return sendTXT((uint8_t *) payload, length); + return sendTXT((uint8_t *)payload, length); } bool WebSocketsClient::sendTXT(String & payload) { - return sendTXT((uint8_t *) payload.c_str(), payload.length()); + return sendTXT((uint8_t *)payload.c_str(), payload.length()); } /** @@ -269,7 +267,7 @@ bool WebSocketsClient::sendBIN(uint8_t * payload, size_t length, bool headerToPa } bool WebSocketsClient::sendBIN(const uint8_t * payload, size_t length) { - return sendBIN((uint8_t *) payload, length); + return sendBIN((uint8_t *)payload, length); } /** @@ -281,7 +279,7 @@ bool WebSocketsClient::sendBIN(const uint8_t * payload, size_t length) { bool WebSocketsClient::sendPing(uint8_t * payload, size_t length) { if(clientIsConnected(&_client)) { bool sent = sendFrame(&_client, WSop_ping, payload, length); - if (sent) + if(sent) _client.lastPing = millis(); return sent; } @@ -289,7 +287,7 @@ bool WebSocketsClient::sendPing(uint8_t * payload, size_t length) { } bool WebSocketsClient::sendPing(String & payload) { - return sendPing((uint8_t *) payload.c_str(), payload.length()); + return sendPing((uint8_t *)payload.c_str(), payload.length()); } /** @@ -312,7 +310,7 @@ void WebSocketsClient::setAuthorization(const char * user, const char * password String auth = user; auth += ":"; auth += password; - _client.base64Authorization = base64_encode((uint8_t *) auth.c_str(), auth.length()); + _client.base64Authorization = base64_encode((uint8_t *)auth.c_str(), auth.length()); } } @@ -383,7 +381,6 @@ void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, u } runCbEvent(type, payload, length); - } /** @@ -391,10 +388,9 @@ void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, u * @param client WSclient_t * ptr to the client struct */ void WebSocketsClient::clientDisconnect(WSclient_t * client) { - bool event = false; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) if(client->isSSL && client->ssl) { if(client->ssl->connected()) { client->ssl->flush(); @@ -409,13 +405,13 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { if(client->tcp) { if(client->tcp->connected()) { -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) client->tcp->flush(); #endif client->tcp->stop(); } event = true; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->status = WSC_NOT_CONNECTED; #else delete client->tcp; @@ -423,13 +419,13 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { client->tcp = NULL; } - client->cCode = 0; - client->cKey = ""; - client->cAccept = ""; - client->cVersion = 0; - client->cIsUpgrade = false; + client->cCode = 0; + client->cKey = ""; + client->cAccept = ""; + client->cVersion = 0; + client->cIsUpgrade = false; client->cIsWebsocket = false; - client->cSessionId = ""; + client->cSessionId = ""; client->status = WSC_NOT_CONNECTED; @@ -445,7 +441,6 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { * @return true = conneted */ bool WebSocketsClient::clientIsConnected(WSclient_t * client) { - if(!client->tcp) { return false; } @@ -470,7 +465,7 @@ bool WebSocketsClient::clientIsConnected(WSclient_t * client) { return false; } -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * Handel incomming data from Client */ @@ -481,8 +476,7 @@ void WebSocketsClient::handleClientData(void) { case WSC_HEADER: { String headerLine = _client.tcp->readStringUntil('\n'); handleHeader(&_client, &headerLine); - } - break; + } break; case WSC_CONNECTED: WebSockets::handleWebsocket(&_client); break; @@ -491,7 +485,7 @@ void WebSocketsClient::handleClientData(void) { break; } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) delay(0); #endif } @@ -502,7 +496,6 @@ void WebSocketsClient::handleClientData(void) { * @param client WSclient_t * ptr to the client struct */ void WebSocketsClient::sendHeader(WSclient_t * client) { - static const char * NEW_LINE = "\r\n"; DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header...\n"); @@ -521,7 +514,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { String handshake; bool ws_header = true; - String url = client->cUrl; + String url = client->cUrl; if(client->isSocketIO) { if(client->cSessionId.length() == 0) { @@ -534,15 +527,17 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { } handshake = WEBSOCKETS_STRING("GET "); - handshake += url + WEBSOCKETS_STRING(" HTTP/1.1\r\n" - "Host: "); + handshake += url + WEBSOCKETS_STRING( + " HTTP/1.1\r\n" + "Host: "); handshake += _host + ":" + _port + NEW_LINE; if(ws_header) { - handshake += WEBSOCKETS_STRING("Connection: Upgrade\r\n" - "Upgrade: websocket\r\n" - "Sec-WebSocket-Version: 13\r\n" - "Sec-WebSocket-Key: "); + handshake += WEBSOCKETS_STRING( + "Connection: Upgrade\r\n" + "Upgrade: websocket\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Sec-WebSocket-Key: "); handshake += client->cKey + NEW_LINE; if(client->cProtocol.length() > 0) { @@ -577,15 +572,14 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { handshake += NEW_LINE; - DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t* )handshake.c_str()); - write(client, (uint8_t*) handshake.c_str(), handshake.length()); + DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t *)handshake.c_str()); + write(client, (uint8_t *)handshake.c_str(), handshake.length()); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine))); #endif DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%luus).\n", (micros() - start)); - } /** @@ -593,8 +587,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { * @param client WSclient_t * ptr to the client struct */ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { - - headerLine->trim(); // remove \r + headerLine->trim(); // remove \r if(headerLine->length() > 0) { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str()); @@ -603,7 +596,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { // "HTTP/1.1 101 Switching Protocols" client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt(); } else if(headerLine->indexOf(':') >= 0) { - String headerName = headerLine->substring(0, headerLine->indexOf(':')); + String headerName = headerLine->substring(0, headerLine->indexOf(':')); String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); // remove space in the beginning (RFC2616) @@ -621,7 +614,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Accept"))) { client->cAccept = headerValue; - client->cAccept.trim(); // see rfc6455 + client->cAccept.trim(); // see rfc6455 } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { client->cProtocol = headerValue; } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { @@ -640,10 +633,9 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } (*headerLine) = ""; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine))); #endif - } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header read fin.\n"); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Client settings:\n"); @@ -665,16 +657,16 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { if(ok) { switch(client->cCode) { - case 101: ///< Switching Protocols + case 101: ///< Switching Protocols break; case 200: if(client->isSocketIO) { break; } - case 403: ///< Forbidden + case 403: ///< Forbidden // todo handle login - default: ///< Server dont unterstand requrst + default: ///< Server dont unterstand requrst ok = false; DEBUG_WEBSOCKETS("[WS-Client][handleHeader] serverCode is not 101 (%d)\n", client->cCode); clientDisconnect(client); @@ -684,7 +676,6 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } if(ok) { - if(client->cAccept.length() == 0) { ok = false; } else { @@ -698,12 +689,10 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } if(ok) { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Websocket connection init done.\n"); headerDone(client); - runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length()); - + runCbEvent(WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length()); } else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) { sendHeader(client); } else { @@ -718,30 +707,30 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } void WebSocketsClient::connectedCb() { - DEBUG_WEBSOCKETS("[WS-Client] connected to %s:%u.\n", _host.c_str(), _port); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) _client.tcp->onDisconnect(std::bind([](WebSocketsClient * c, AsyncTCPbuffer * obj, WSclient_t * client) -> bool { - DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num); - client->status = WSC_NOT_CONNECTED; - client->tcp = NULL; + DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num); + client->status = WSC_NOT_CONNECTED; + client->tcp = NULL; - // reconnect - c->asyncConnect(); + // reconnect + c->asyncConnect(); - return true; - }, this, std::placeholders::_1, &_client)); + return true; + }, + this, std::placeholders::_1, &_client)); #endif _client.status = WSC_HEADER; -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) // set Timeout for readBytesUntil and readStringUntil _client.tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); #endif -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32 +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) _client.tcp->setNoDelay(true); #endif @@ -761,17 +750,15 @@ void WebSocketsClient::connectedCb() { // send Header to Server sendHeader(&_client); - } void WebSocketsClient::connectFailedCb() { DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Failed\n", _host.c_str(), _port); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) void WebSocketsClient::asyncConnect() { - DEBUG_WEBSOCKETS("[WS-Client] asyncConnect...\n"); AsyncClient * tcpclient = new AsyncClient(); @@ -781,51 +768,52 @@ void WebSocketsClient::asyncConnect() { return; } - tcpclient->onDisconnect([](void *obj, AsyncClient* c) { - c->free(); - delete c; - }); + tcpclient->onDisconnect([](void * obj, AsyncClient * c) { + c->free(); + delete c; + }); - tcpclient->onConnect(std::bind([](WebSocketsClient * ws , AsyncClient * tcp) { - ws->_client.tcp = new AsyncTCPbuffer(tcp); - if(!ws->_client.tcp) { - DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!\n"); - ws->connectFailedCb(); - return; - } - ws->connectedCb(); - }, this, std::placeholders::_2)); + tcpclient->onConnect(std::bind([](WebSocketsClient * ws, AsyncClient * tcp) { + ws->_client.tcp = new AsyncTCPbuffer(tcp); + if(!ws->_client.tcp) { + DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!\n"); + ws->connectFailedCb(); + return; + } + ws->connectedCb(); + }, + this, std::placeholders::_2)); - tcpclient->onError(std::bind([](WebSocketsClient * ws , AsyncClient * tcp) { - ws->connectFailedCb(); + tcpclient->onError(std::bind([](WebSocketsClient * ws, AsyncClient * tcp) { + ws->connectFailedCb(); - // reconnect - ws->asyncConnect(); - }, this, std::placeholders::_2)); + // reconnect + ws->asyncConnect(); + }, + this, std::placeholders::_2)); if(!tcpclient->connect(_host.c_str(), _port)) { connectFailedCb(); delete tcpclient; } - } #endif /** * send heartbeat ping to server in set intervals - */ -void WebSocketsClient::handleHBPing(){ - if (_client.pingInterval == 0) return; + */ +void WebSocketsClient::handleHBPing() { + if(_client.pingInterval == 0) + return; uint32_t pi = millis() - _client.lastPing; - if (pi > _client.pingInterval){ + if(pi > _client.pingInterval) { DEBUG_WEBSOCKETS("[WS-Client] sending HB ping\n"); - if (sendPing()) { - _client.lastPing = millis(); + if(sendPing()) { + _client.lastPing = millis(); _client.pongReceived = false; } } - } /** @@ -834,13 +822,13 @@ void WebSocketsClient::handleHBPing(){ * @param pongTimeout uint32_t millis after which pong should timout if not received * @param disconnectTimeoutCount uint8_t how many timeouts before disconnect, 0=> do not disconnect */ -void WebSocketsClient::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount){ +void WebSocketsClient::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { WebSockets::enableHeartbeat(&_client, pingInterval, pongTimeout, disconnectTimeoutCount); } /** * disable ping/pong heartbeat process */ -void WebSocketsClient::disableHeartbeat(){ +void WebSocketsClient::disableHeartbeat() { _client.pingInterval = 0; } diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 07c82d1..557a6d7 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -27,118 +27,116 @@ #include "WebSockets.h" -class WebSocketsClient: private WebSockets { - public: +class WebSocketsClient : private WebSockets { + public: #ifdef __AVR__ - typedef void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length); + typedef void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length); #else - typedef std::function WebSocketClientEvent; + typedef std::function WebSocketClientEvent; #endif + WebSocketsClient(void); + virtual ~WebSocketsClient(void); - WebSocketsClient(void); - virtual ~WebSocketsClient(void); - - void begin(const char *host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); - void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); - void begin(IPAddress host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); + void begin(const char * host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); + void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); + void begin(IPAddress host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); #if defined(HAS_SSL) - void beginSSL(const char *host, uint16_t port, const char * url = "/", const char * = "", const char * protocol = "arduino"); - void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino"); - void beginSslWithCA(const char *host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino"); + void beginSSL(const char * host, uint16_t port, const char * url = "/", const char * = "", const char * protocol = "arduino"); + void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino"); + void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino"); #endif - void beginSocketIO(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); - void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); + void beginSocketIO(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); + void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); #if defined(HAS_SSL) - void beginSocketIOSSL(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); - void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); - void beginSocketIOSSLWithCA(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino"); + void beginSocketIOSSL(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); + void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); + void beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino"); #endif -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - void loop(void); +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + void loop(void); #else - // Async interface not need a loop call - void loop(void) __attribute__ ((deprecated)) {} + // Async interface not need a loop call + void loop(void) __attribute__((deprecated)) {} #endif - void onEvent(WebSocketClientEvent cbEvent); + void onEvent(WebSocketClientEvent cbEvent); - bool sendTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); - bool sendTXT(const uint8_t * payload, size_t length = 0); - bool sendTXT(char * payload, size_t length = 0, bool headerToPayload = false); - bool sendTXT(const char * payload, size_t length = 0); - bool sendTXT(String & payload); + bool sendTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); + bool sendTXT(const uint8_t * payload, size_t length = 0); + bool sendTXT(char * payload, size_t length = 0, bool headerToPayload = false); + bool sendTXT(const char * payload, size_t length = 0); + bool sendTXT(String & payload); - bool sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false); - bool sendBIN(const uint8_t * payload, size_t length); + bool sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false); + bool sendBIN(const uint8_t * payload, size_t length); - bool sendPing(uint8_t * payload = NULL, size_t length = 0); - bool sendPing(String & payload); + bool sendPing(uint8_t * payload = NULL, size_t length = 0); + bool sendPing(String & payload); - void disconnect(void); + void disconnect(void); - void setAuthorization(const char * user, const char * password); - void setAuthorization(const char * auth); - - void setExtraHeaders(const char * extraHeaders = NULL); + void setAuthorization(const char * user, const char * password); + void setAuthorization(const char * auth); - void setReconnectInterval(unsigned long time); + void setExtraHeaders(const char * extraHeaders = NULL); - void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); - void disableHeartbeat(); + void setReconnectInterval(unsigned long time); - protected: - String _host; - uint16_t _port; + void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); + void disableHeartbeat(); + + protected: + String _host; + uint16_t _port; #if defined(HAS_SSL) - String _fingerprint; - const char *_CA_cert; + String _fingerprint; + const char * _CA_cert; #endif - WSclient_t _client; + WSclient_t _client; - WebSocketClientEvent _cbEvent; + WebSocketClientEvent _cbEvent; - unsigned long _lastConnectionFail; - unsigned long _reconnectInterval; + unsigned long _lastConnectionFail; + unsigned long _reconnectInterval; - void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); + void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); - void clientDisconnect(WSclient_t * client); - bool clientIsConnected(WSclient_t * client); + void clientDisconnect(WSclient_t * client); + bool clientIsConnected(WSclient_t * client); -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - void handleClientData(void); +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + void handleClientData(void); #endif - void sendHeader(WSclient_t * client); - void handleHeader(WSclient_t * client, String * headerLine); + void sendHeader(WSclient_t * client); + void handleHeader(WSclient_t * client, String * headerLine); - void connectedCb(); - void connectFailedCb(); + void connectedCb(); + void connectFailedCb(); - void handleHBPing(); // send ping in specified intervals + void handleHBPing(); // send ping in specified intervals -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - void asyncConnect(); +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + void asyncConnect(); #endif - /** + /** * called for sending a Event to the app * @param type WStype_t * @param payload uint8_t * * @param length size_t */ - virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) { - if(_cbEvent) { - _cbEvent(type, payload, length); - } + virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) { + if(_cbEvent) { + _cbEvent(type, payload, length); } - + } }; #endif /* WEBSOCKETSCLIENT_H_ */ diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index a6492c0..b05dc5e 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -26,34 +26,34 @@ #include "WebSocketsServer.h" WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol) { - _port = port; - _origin = origin; + _port = port; + _origin = origin; _protocol = protocol; _runnning = false; _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - _server->onClient([](void *s, AsyncClient* c){ - ((WebSocketsServer*)s)->newClient(new AsyncTCPbuffer(c)); - }, this); +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + _server->onClient([](void * s, AsyncClient * c) { + ((WebSocketsServer *)s)->newClient(new AsyncTCPbuffer(c)); + }, + this); #endif _cbEvent = NULL; _httpHeaderValidationFunc = NULL; - _mandatoryHttpHeaders = NULL; + _mandatoryHttpHeaders = NULL; _mandatoryHttpHeaderCount = 0; memset(&_clients[0], 0x00, (sizeof(WSclient_t) * WEBSOCKETS_SERVER_CLIENT_MAX)); } - WebSocketsServer::~WebSocketsServer() { // disconnect all clients - close(); + close(); - if (_mandatoryHttpHeaders) + if(_mandatoryHttpHeaders) delete[] _mandatoryHttpHeaders; _mandatoryHttpHeaderCount = 0; @@ -69,26 +69,26 @@ void WebSocketsServer::begin(void) { for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; - client->num = i; + client->num = i; client->status = WSC_NOT_CONNECTED; - client->tcp = NULL; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) + client->tcp = NULL; +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) client->isSSL = false; - client->ssl = NULL; + client->ssl = NULL; #endif - client->cUrl = ""; - client->cCode = 0; - client->cKey = ""; - client->cProtocol = ""; - client->cVersion = 0; - client->cIsUpgrade = false; + client->cUrl = ""; + client->cCode = 0; + client->cKey = ""; + client->cProtocol = ""; + client->cVersion = 0; + client->cIsUpgrade = false; client->cIsWebsocket = false; client->base64Authorization = ""; client->cWsRXsize = 0; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; #endif } @@ -96,7 +96,7 @@ void WebSocketsServer::begin(void) { #ifdef ESP8266 randomSeed(RANDOM_REG32); #elif defined(ESP32) - #define DR_REG_RNG_BASE 0x3ff75144 +#define DR_REG_RNG_BASE 0x3ff75144 randomSeed(READ_PERI_REG(DR_REG_RNG_BASE)); #else // TODO find better seed @@ -110,28 +110,27 @@ void WebSocketsServer::begin(void) { } void WebSocketsServer::close(void) { - _runnning = false; - disconnect(); + _runnning = false; + disconnect(); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) _server->close(); -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) _server->end(); #else // TODO how to close server? #endif - } -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * called in arduino loop */ void WebSocketsServer::loop(void) { - if(_runnning) { - handleNewClients(); - handleClientData(); - } + if(_runnning) { + handleNewClients(); + handleClientData(); + } } #endif @@ -150,21 +149,20 @@ void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) { * @param mandatoryHttpHeaderCount size_t ///< the number of items in the mandatoryHttpHeaders array */ void WebSocketsServer::onValidateHttpHeader( - WebSocketServerHttpHeaderValFunc validationFunc, - const char* mandatoryHttpHeaders[], - size_t mandatoryHttpHeaderCount) -{ - _httpHeaderValidationFunc = validationFunc; + WebSocketServerHttpHeaderValFunc validationFunc, + const char * mandatoryHttpHeaders[], + size_t mandatoryHttpHeaderCount) { + _httpHeaderValidationFunc = validationFunc; - if (_mandatoryHttpHeaders) - delete[] _mandatoryHttpHeaders; + if(_mandatoryHttpHeaders) + delete[] _mandatoryHttpHeaders; - _mandatoryHttpHeaderCount = mandatoryHttpHeaderCount; - _mandatoryHttpHeaders = new String[_mandatoryHttpHeaderCount]; + _mandatoryHttpHeaderCount = mandatoryHttpHeaderCount; + _mandatoryHttpHeaders = new String[_mandatoryHttpHeaderCount]; - for (size_t i = 0; i < _mandatoryHttpHeaderCount; i++) { - _mandatoryHttpHeaders[i] = mandatoryHttpHeaders[i]; - } + for(size_t i = 0; i < _mandatoryHttpHeaderCount; i++) { + _mandatoryHttpHeaders[i] = mandatoryHttpHeaders[i]; + } } /* @@ -180,7 +178,7 @@ bool WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bo return false; } if(length == 0) { - length = strlen((const char *) payload); + length = strlen((const char *)payload); } WSclient_t * client = &_clients[num]; if(clientIsConnected(client)) { @@ -190,19 +188,19 @@ bool WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bo } bool WebSocketsServer::sendTXT(uint8_t num, const uint8_t * payload, size_t length) { - return sendTXT(num, (uint8_t *) payload, length); + return sendTXT(num, (uint8_t *)payload, length); } bool WebSocketsServer::sendTXT(uint8_t num, char * payload, size_t length, bool headerToPayload) { - return sendTXT(num, (uint8_t *) payload, length, headerToPayload); + return sendTXT(num, (uint8_t *)payload, length, headerToPayload); } bool WebSocketsServer::sendTXT(uint8_t num, const char * payload, size_t length) { - return sendTXT(num, (uint8_t *) payload, length); + return sendTXT(num, (uint8_t *)payload, length); } bool WebSocketsServer::sendTXT(uint8_t num, String & payload) { - return sendTXT(num, (uint8_t *) payload.c_str(), payload.length()); + return sendTXT(num, (uint8_t *)payload.c_str(), payload.length()); } /** @@ -216,7 +214,7 @@ bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade WSclient_t * client; bool ret = true; if(length == 0) { - length = strlen((const char *) payload); + length = strlen((const char *)payload); } for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { @@ -226,7 +224,7 @@ bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade ret = false; } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } @@ -234,19 +232,19 @@ bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade } bool WebSocketsServer::broadcastTXT(const uint8_t * payload, size_t length) { - return broadcastTXT((uint8_t *) payload, length); + return broadcastTXT((uint8_t *)payload, length); } bool WebSocketsServer::broadcastTXT(char * payload, size_t length, bool headerToPayload) { - return broadcastTXT((uint8_t *) payload, length, headerToPayload); + return broadcastTXT((uint8_t *)payload, length, headerToPayload); } bool WebSocketsServer::broadcastTXT(const char * payload, size_t length) { - return broadcastTXT((uint8_t *) payload, length); + return broadcastTXT((uint8_t *)payload, length); } bool WebSocketsServer::broadcastTXT(String & payload) { - return broadcastTXT((uint8_t *) payload.c_str(), payload.length()); + return broadcastTXT((uint8_t *)payload.c_str(), payload.length()); } /** @@ -269,7 +267,7 @@ bool WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bo } bool WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t length) { - return sendBIN(num, (uint8_t *) payload, length); + return sendBIN(num, (uint8_t *)payload, length); } /** @@ -289,7 +287,7 @@ bool WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool heade ret = false; } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } @@ -297,10 +295,9 @@ bool WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool heade } bool WebSocketsServer::broadcastBIN(const uint8_t * payload, size_t length) { - return broadcastBIN((uint8_t *) payload, length); + return broadcastBIN((uint8_t *)payload, length); } - /** * sends a WS ping to Client * @param num uint8_t client id @@ -320,7 +317,7 @@ bool WebSocketsServer::sendPing(uint8_t num, uint8_t * payload, size_t length) { } bool WebSocketsServer::sendPing(uint8_t num, String & payload) { - return sendPing(num, (uint8_t *) payload.c_str(), payload.length()); + return sendPing(num, (uint8_t *)payload.c_str(), payload.length()); } /** @@ -339,7 +336,7 @@ bool WebSocketsServer::broadcastPing(uint8_t * payload, size_t length) { ret = false; } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } @@ -347,10 +344,9 @@ bool WebSocketsServer::broadcastPing(uint8_t * payload, size_t length) { } bool WebSocketsServer::broadcastPing(String & payload) { - return broadcastPing((uint8_t *) payload.c_str(), payload.length()); + return broadcastPing((uint8_t *)payload.c_str(), payload.length()); } - /** * disconnect all clients */ @@ -378,7 +374,6 @@ void WebSocketsServer::disconnect(uint8_t num) { } } - /* * set the Authorization for the http request * @param user const char * @@ -410,18 +405,18 @@ void WebSocketsServer::setAuthorization(const char * auth) { int WebSocketsServer::connectedClients(bool ping) { WSclient_t * client; int count = 0; - for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - client = &_clients[i]; - if(client->status == WSC_CONNECTED) { - if(ping != true || sendPing(i)) { - count++; - } - } - } + for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + client = &_clients[i]; + if(client->status == WSC_CONNECTED) { + if(ping != true || sendPing(i)) { + count++; + } + } + } return count; } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) /** * get an IP for a client * @param num uint8_t client id @@ -455,38 +450,36 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { // state is not connected or tcp connection is lost if(!clientIsConnected(client)) { - client->tcp = TCPclient; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) client->isSSL = false; client->tcp->setNoDelay(true); #endif -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) // set Timeout for readBytesUntil and readStringUntil client->tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); #endif client->status = WSC_HEADER; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) IPAddress ip = client->tcp->remoteIP(); DEBUG_WEBSOCKETS("[WS-Server][%d] new client from %d.%d.%d.%d\n", client->num, ip[0], ip[1], ip[2], ip[3]); #else DEBUG_WEBSOCKETS("[WS-Server][%d] new client\n", client->num); #endif - -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->tcp->onDisconnect(std::bind([](WebSocketsServer * server, AsyncTCPbuffer * obj, WSclient_t * client) -> bool { DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num); AsyncTCPbuffer ** sl = &server->_clients[client->num].tcp; if(*sl == obj) { client->status = WSC_NOT_CONNECTED; - *sl = NULL; + *sl = NULL; } return true; - }, this, std::placeholders::_1, client)); - + }, + this, std::placeholders::_1, client)); client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine))); #endif @@ -530,7 +523,6 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u } runCbEvent(client->num, type, payload, length); - } /** @@ -538,9 +530,7 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u * @param client WSclient_t * ptr to the client struct */ void WebSocketsServer::clientDisconnect(WSclient_t * client) { - - -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) if(client->isSSL && client->ssl) { if(client->ssl->connected()) { client->ssl->flush(); @@ -554,12 +544,12 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { if(client->tcp) { if(client->tcp->connected()) { -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) client->tcp->flush(); #endif client->tcp->stop(); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->status = WSC_NOT_CONNECTED; #else delete client->tcp; @@ -567,16 +557,16 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { client->tcp = NULL; } - client->cUrl = ""; - client->cKey = ""; - client->cProtocol = ""; - client->cVersion = 0; - client->cIsUpgrade = false; + client->cUrl = ""; + client->cKey = ""; + client->cProtocol = ""; + client->cVersion = 0; + client->cIsUpgrade = false; client->cIsWebsocket = false; client->cWsRXsize = 0; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; #endif @@ -585,7 +575,6 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { DEBUG_WEBSOCKETS("[WS-Server][%d] client disconnected.\n", client->num); runCbEvent(client->num, WStype_DISCONNECTED, NULL, 0); - } /** @@ -594,7 +583,6 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { * @return true = connected */ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { - if(!client->tcp) { return false; } @@ -620,22 +608,21 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { return false; } -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * Handle incoming Connection Request */ void WebSocketsServer::handleNewClients(void) { - -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) while(_server->hasClient()) { #endif bool ok = false; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) // store new connection WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); #else - WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); + WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); #endif if(!tcpClient) { @@ -647,28 +634,25 @@ void WebSocketsServer::handleNewClients(void) { if(!ok) { // no free space to handle client -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) IPAddress ip = tcpClient->remoteIP(); DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); #else - DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); + DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); #endif tcpClient->stop(); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) delay(0); } #endif - } - /** * Handel incomming data from Client */ void WebSocketsServer::handleClientData(void) { - WSclient_t * client; for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; @@ -677,12 +661,10 @@ void WebSocketsServer::handleClientData(void) { if(len > 0) { //DEBUG_WEBSOCKETS("[WS-Server][%d][handleClientData] len: %d\n", client->num, len); switch(client->status) { - case WSC_HEADER: - { + case WSC_HEADER: { String headerLine = client->tcp->readStringUntil('\n'); handleHeader(client, &headerLine); - } - break; + } break; case WSC_CONNECTED: WebSockets::handleWebsocket(client); break; @@ -692,7 +674,7 @@ void WebSocketsServer::handleClientData(void) { } } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } @@ -704,84 +686,80 @@ void WebSocketsServer::handleClientData(void) { * @param headerName String ///< the name of the header being checked */ bool WebSocketsServer::hasMandatoryHeader(String headerName) { - for (size_t i = 0; i < _mandatoryHttpHeaderCount; i++) { - if (_mandatoryHttpHeaders[i].equalsIgnoreCase(headerName)) - return true; - } - return false; + for(size_t i = 0; i < _mandatoryHttpHeaderCount; i++) { + if(_mandatoryHttpHeaders[i].equalsIgnoreCase(headerName)) + return true; + } + return false; } - /** * handles http header reading for WebSocket upgrade * @param client WSclient_t * ///< pointer to the client struct * @param headerLine String ///< the header being read / processed */ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { + static const char * NEW_LINE = "\r\n"; - static const char * NEW_LINE = "\r\n"; + headerLine->trim(); // remove \r - headerLine->trim(); // remove \r + if(headerLine->length() > 0) { + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine->c_str()); - if(headerLine->length() > 0) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine->c_str()); + // websocket requests always start with GET see rfc6455 + if(headerLine->startsWith("GET ")) { + // cut URL out + client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4)); - // websocket requests always start with GET see rfc6455 - if(headerLine->startsWith("GET ")) { + //reset non-websocket http header validation state for this client + client->cHttpHeadersValid = true; + client->cMandatoryHeadersCount = 0; - // cut URL out - client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4)); + } else if(headerLine->indexOf(':') >= 0) { + String headerName = headerLine->substring(0, headerLine->indexOf(':')); + String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); - //reset non-websocket http header validation state for this client - client->cHttpHeadersValid = true; - client->cMandatoryHeadersCount = 0; + // remove space in the beginning (RFC2616) + if(headerValue[0] == ' ') { + headerValue.remove(0, 1); + } - } else if(headerLine->indexOf(':') >= 0) { - String headerName = headerLine->substring(0, headerLine->indexOf(':')); - String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); + if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { + headerValue.toLowerCase(); + if(headerValue.indexOf(WEBSOCKETS_STRING("upgrade")) >= 0) { + client->cIsUpgrade = true; + } + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) { + if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) { + client->cIsWebsocket = true; + } + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { + client->cVersion = headerValue.toInt(); + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Key"))) { + client->cKey = headerValue; + client->cKey.trim(); // see rfc6455 + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { + client->cProtocol = headerValue; + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { + client->cExtensions = headerValue; + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Authorization"))) { + client->base64Authorization = headerValue; + } else { + client->cHttpHeadersValid &= execHttpHeaderValidation(headerName, headerValue); + if(_mandatoryHttpHeaderCount > 0 && hasMandatoryHeader(headerName)) { + client->cMandatoryHeadersCount++; + } + } - // remove space in the beginning (RFC2616) - if(headerValue[0] == ' ') { - headerValue.remove(0, 1); - } - - if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { - headerValue.toLowerCase(); - if(headerValue.indexOf(WEBSOCKETS_STRING("upgrade")) >= 0) { - client->cIsUpgrade = true; - } - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) { - if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) { - client->cIsWebsocket = true; - } - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { - client->cVersion = headerValue.toInt(); - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Key"))) { - client->cKey = headerValue; - client->cKey.trim(); // see rfc6455 - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { - client->cProtocol = headerValue; - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { - client->cExtensions = headerValue; - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Authorization"))) { - client->base64Authorization = headerValue; - } else { - client->cHttpHeadersValid &= execHttpHeaderValidation(headerName, headerValue); - if(_mandatoryHttpHeaderCount > 0 && hasMandatoryHeader(headerName)) { - client->cMandatoryHeadersCount++; - } - } - - } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); - } + } else { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); + } (*headerLine) = ""; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine))); #endif } else { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cURL: %s\n", client->num, client->cUrl.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cIsUpgrade: %d\n", client->num, client->cIsUpgrade); @@ -796,36 +774,35 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { bool ok = (client->cIsUpgrade && client->cIsWebsocket); - if(ok) { - if(client->cUrl.length() == 0) { - ok = false; - } - if(client->cKey.length() == 0) { + if(ok) { + if(client->cUrl.length() == 0) { + ok = false; + } + if(client->cKey.length() == 0) { ok = false; } if(client->cVersion != 13) { ok = false; } if(!client->cHttpHeadersValid) { - ok = false; + ok = false; } - if (client->cMandatoryHeadersCount != _mandatoryHttpHeaderCount) { - ok = false; + if(client->cMandatoryHeadersCount != _mandatoryHttpHeaderCount) { + ok = false; } } if(_base64Authorization.length() > 0) { - String auth = WEBSOCKETS_STRING("Basic "); - auth += _base64Authorization; - if(auth != client->base64Authorization) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] HTTP Authorization failed!\n", client->num); - handleAuthorizationFailed(client); - return; - } + String auth = WEBSOCKETS_STRING("Basic "); + auth += _base64Authorization; + if(auth != client->base64Authorization) { + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] HTTP Authorization failed!\n", client->num); + handleAuthorizationFailed(client); + return; + } } if(ok) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incoming.\n", client->num); // generate Sec-WebSocket-Accept key @@ -835,43 +812,41 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { client->status = WSC_CONNECTED; - String handshake = WEBSOCKETS_STRING("HTTP/1.1 101 Switching Protocols\r\n" - "Server: arduino-WebSocketsServer\r\n" - "Upgrade: websocket\r\n" - "Connection: Upgrade\r\n" - "Sec-WebSocket-Version: 13\r\n" - "Sec-WebSocket-Accept: "); - handshake += sKey + NEW_LINE; + String handshake = WEBSOCKETS_STRING( + "HTTP/1.1 101 Switching Protocols\r\n" + "Server: arduino-WebSocketsServer\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Sec-WebSocket-Accept: "); + handshake += sKey + NEW_LINE; if(_origin.length() > 0) { handshake += WEBSOCKETS_STRING("Access-Control-Allow-Origin: "); - handshake +=_origin + NEW_LINE; + handshake += _origin + NEW_LINE; } if(client->cProtocol.length() > 0) { - handshake += WEBSOCKETS_STRING("Sec-WebSocket-Protocol: "); - handshake +=_protocol + NEW_LINE; + handshake += WEBSOCKETS_STRING("Sec-WebSocket-Protocol: "); + handshake += _protocol + NEW_LINE; } // header end handshake += NEW_LINE; - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] handshake %s", client->num, (uint8_t*)handshake.c_str()); + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] handshake %s", client->num, (uint8_t *)handshake.c_str()); - write(client, (uint8_t*)handshake.c_str(), handshake.length()); + write(client, (uint8_t *)handshake.c_str(), handshake.length()); headerDone(client); // send ping WebSockets::sendFrame(client, WSop_ping); - runCbEvent(client->num, WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length()); + runCbEvent(client->num, WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length()); } else { handleNonWebsocketConnection(client); } } } - - - diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index e010488..4874a70 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -28,160 +28,157 @@ #include "WebSockets.h" #ifndef WEBSOCKETS_SERVER_CLIENT_MAX -#define WEBSOCKETS_SERVER_CLIENT_MAX (5) +#define WEBSOCKETS_SERVER_CLIENT_MAX (5) #endif - - - -class WebSocketsServer: protected WebSockets { -public: - +class WebSocketsServer : protected WebSockets { + public: #ifdef __AVR__ - typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length); - typedef bool (*WebSocketServerHttpHeaderValFunc)(String headerName, String headerValue); + typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length); + typedef bool (*WebSocketServerHttpHeaderValFunc)(String headerName, String headerValue); #else - typedef std::function WebSocketServerEvent; - typedef std::function WebSocketServerHttpHeaderValFunc; + typedef std::function WebSocketServerEvent; + typedef std::function WebSocketServerHttpHeaderValFunc; #endif - WebSocketsServer(uint16_t port, String origin = "", String protocol = "arduino"); - virtual ~WebSocketsServer(void); + WebSocketsServer(uint16_t port, String origin = "", String protocol = "arduino"); + virtual ~WebSocketsServer(void); - void begin(void); - void close(void); + void begin(void); + void close(void); -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - void loop(void); +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + void loop(void); #else - // Async interface not need a loop call - void loop(void) __attribute__ ((deprecated)) {} + // Async interface not need a loop call + void loop(void) __attribute__((deprecated)) {} #endif - void onEvent(WebSocketServerEvent cbEvent); - void onValidateHttpHeader( - WebSocketServerHttpHeaderValFunc validationFunc, - const char* mandatoryHttpHeaders[], - size_t mandatoryHttpHeaderCount); + void onEvent(WebSocketServerEvent cbEvent); + void onValidateHttpHeader( + WebSocketServerHttpHeaderValFunc validationFunc, + const char * mandatoryHttpHeaders[], + size_t mandatoryHttpHeaderCount); + bool sendTXT(uint8_t num, uint8_t * payload, size_t length = 0, bool headerToPayload = false); + bool sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0); + bool sendTXT(uint8_t num, char * payload, size_t length = 0, bool headerToPayload = false); + bool sendTXT(uint8_t num, const char * payload, size_t length = 0); + bool sendTXT(uint8_t num, String & payload); - bool sendTXT(uint8_t num, uint8_t * payload, size_t length = 0, bool headerToPayload = false); - bool sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0); - bool sendTXT(uint8_t num, char * payload, size_t length = 0, bool headerToPayload = false); - bool sendTXT(uint8_t num, const char * payload, size_t length = 0); - bool sendTXT(uint8_t num, String & payload); + bool broadcastTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); + bool broadcastTXT(const uint8_t * payload, size_t length = 0); + bool broadcastTXT(char * payload, size_t length = 0, bool headerToPayload = false); + bool broadcastTXT(const char * payload, size_t length = 0); + bool broadcastTXT(String & payload); - bool broadcastTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); - bool broadcastTXT(const uint8_t * payload, size_t length = 0); - bool broadcastTXT(char * payload, size_t length = 0, bool headerToPayload = false); - bool broadcastTXT(const char * payload, size_t length = 0); - bool broadcastTXT(String & payload); + bool sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload = false); + bool sendBIN(uint8_t num, const uint8_t * payload, size_t length); - bool sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload = false); - bool sendBIN(uint8_t num, const uint8_t * payload, size_t length); + bool broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload = false); + bool broadcastBIN(const uint8_t * payload, size_t length); - bool broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload = false); - bool broadcastBIN(const uint8_t * payload, size_t length); + bool sendPing(uint8_t num, uint8_t * payload = NULL, size_t length = 0); + bool sendPing(uint8_t num, String & payload); - bool sendPing(uint8_t num, uint8_t * payload = NULL, size_t length = 0); - bool sendPing(uint8_t num, String & payload); + bool broadcastPing(uint8_t * payload = NULL, size_t length = 0); + bool broadcastPing(String & payload); - bool broadcastPing(uint8_t * payload = NULL, size_t length = 0); - bool broadcastPing(String & payload); + void disconnect(void); + void disconnect(uint8_t num); - void disconnect(void); - void disconnect(uint8_t num); + void setAuthorization(const char * user, const char * password); + void setAuthorization(const char * auth); - void setAuthorization(const char * user, const char * password); - void setAuthorization(const char * auth); + int connectedClients(bool ping = false); - int connectedClients(bool ping = false); - -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) - IPAddress remoteIP(uint8_t num); +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) + IPAddress remoteIP(uint8_t num); #endif -protected: - uint16_t _port; - String _origin; - String _protocol; - String _base64Authorization; ///< Base64 encoded Auth request - String * _mandatoryHttpHeaders; - size_t _mandatoryHttpHeaderCount; + protected: + uint16_t _port; + String _origin; + String _protocol; + String _base64Authorization; ///< Base64 encoded Auth request + String * _mandatoryHttpHeaders; + size_t _mandatoryHttpHeaderCount; - WEBSOCKETS_NETWORK_SERVER_CLASS * _server; + WEBSOCKETS_NETWORK_SERVER_CLASS * _server; - WSclient_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX]; + WSclient_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX]; - WebSocketServerEvent _cbEvent; - WebSocketServerHttpHeaderValFunc _httpHeaderValidationFunc; + WebSocketServerEvent _cbEvent; + WebSocketServerHttpHeaderValFunc _httpHeaderValidationFunc; - bool _runnning; + bool _runnning; - bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); + bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); - void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); + void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); - void clientDisconnect(WSclient_t * client); - bool clientIsConnected(WSclient_t * client); + void clientDisconnect(WSclient_t * client); + bool clientIsConnected(WSclient_t * client); -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - void handleNewClients(void); - void handleClientData(void); +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + void handleNewClients(void); + void handleClientData(void); #endif - void handleHeader(WSclient_t * client, String * headerLine); + void handleHeader(WSclient_t * client, String * headerLine); - /** + /** * called if a non Websocket connection is coming in. * Note: can be override * @param client WSclient_t * ptr to the client struct */ - virtual void handleNonWebsocketConnection(WSclient_t * client) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] no Websocket connection close.\n", client->num); - client->tcp->write("HTTP/1.1 400 Bad Request\r\n" - "Server: arduino-WebSocket-Server\r\n" - "Content-Type: text/plain\r\n" - "Content-Length: 32\r\n" - "Connection: close\r\n" - "Sec-WebSocket-Version: 13\r\n" - "\r\n" - "This is a Websocket server only!"); - clientDisconnect(client); - } + virtual void handleNonWebsocketConnection(WSclient_t * client) { + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] no Websocket connection close.\n", client->num); + client->tcp->write( + "HTTP/1.1 400 Bad Request\r\n" + "Server: arduino-WebSocket-Server\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 32\r\n" + "Connection: close\r\n" + "Sec-WebSocket-Version: 13\r\n" + "\r\n" + "This is a Websocket server only!"); + clientDisconnect(client); + } - /** + /** * called if a non Authorization connection is coming in. * Note: can be override * @param client WSclient_t * ptr to the client struct */ - virtual void handleAuthorizationFailed(WSclient_t *client) { - client->tcp->write("HTTP/1.1 401 Unauthorized\r\n" - "Server: arduino-WebSocket-Server\r\n" - "Content-Type: text/plain\r\n" - "Content-Length: 45\r\n" - "Connection: close\r\n" - "Sec-WebSocket-Version: 13\r\n" - "WWW-Authenticate: Basic realm=\"WebSocket Server\"" - "\r\n" - "This Websocket server requires Authorization!"); - clientDisconnect(client); - } + virtual void handleAuthorizationFailed(WSclient_t * client) { + client->tcp->write( + "HTTP/1.1 401 Unauthorized\r\n" + "Server: arduino-WebSocket-Server\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 45\r\n" + "Connection: close\r\n" + "Sec-WebSocket-Version: 13\r\n" + "WWW-Authenticate: Basic realm=\"WebSocket Server\"" + "\r\n" + "This Websocket server requires Authorization!"); + clientDisconnect(client); + } - /** + /** * called for sending a Event to the app * @param num uint8_t * @param type WStype_t * @param payload uint8_t * * @param length size_t */ - virtual void runCbEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { - if(_cbEvent) { - _cbEvent(num, type, payload, length); - } + virtual void runCbEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { + if(_cbEvent) { + _cbEvent(num, type, payload, length); } + } - /* + /* * Called at client socket connect handshake negotiation time for each http header that is not * a websocket specific http header (not Connection, Upgrade, Sec-WebSocket-*) * If the custom httpHeaderValidationFunc returns false for any headerName / headerValue passed, the @@ -189,24 +186,21 @@ protected: * This mechanism can be used to enable custom authentication schemes e.g. test the value * of a session cookie to determine if a user is logged on / authenticated */ - virtual bool execHttpHeaderValidation(String headerName, String headerValue) { - if(_httpHeaderValidationFunc) { - //return the value of the custom http header validation function - return _httpHeaderValidationFunc(headerName, headerValue); - } - //no custom http header validation so just assume all is good - return true; + virtual bool execHttpHeaderValidation(String headerName, String headerValue) { + if(_httpHeaderValidationFunc) { + //return the value of the custom http header validation function + return _httpHeaderValidationFunc(headerName, headerValue); } + //no custom http header validation so just assume all is good + return true; + } -private: - /* + private: + /* * returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection * @param headerName String ///< the name of the header being checked */ - bool hasMandatoryHeader(String headerName); - + bool hasMandatoryHeader(String headerName); }; - - #endif /* WEBSOCKETSSERVER_H_ */