From ed351a08c702abc95ec12d79386355b29e16ea79 Mon Sep 17 00:00:00 2001 From: john Date: Tue, 6 May 2025 11:04:04 +0200 Subject: [PATCH] Added support for header modification --- src/tiny_websockets/client.hpp | 1 + src/websockets_client.cpp | 575 +++++++++++++++++++++------------ 2 files changed, 366 insertions(+), 210 deletions(-) diff --git a/src/tiny_websockets/client.hpp b/src/tiny_websockets/client.hpp index e7681fd..b8aa241 100644 --- a/src/tiny_websockets/client.hpp +++ b/src/tiny_websockets/client.hpp @@ -35,6 +35,7 @@ namespace websockets { WebsocketsClient& operator=(const WebsocketsClient&& other); void addHeader(const WSInterfaceString key, const WSInterfaceString value); + bool setHeader(const WSInterfaceString key, const WSInterfaceString value, bool AddIfNotExist); bool connect(const WSInterfaceString url); bool connect(const WSInterfaceString host, const int port, const WSInterfaceString path); diff --git a/src/websockets_client.cpp b/src/websockets_client.cpp index f72a14a..6a3e77c 100644 --- a/src/websockets_client.cpp +++ b/src/websockets_client.cpp @@ -4,48 +4,51 @@ #include #include -namespace websockets { - WebsocketsClient::WebsocketsClient() : WebsocketsClient(std::make_shared()) { +namespace websockets +{ + WebsocketsClient::WebsocketsClient() : WebsocketsClient(std::make_shared()) + { // Empty } - WebsocketsClient::WebsocketsClient(std::shared_ptr client) : - _client(client), - _endpoint(client), - _connectionOpen(client->available()), - _messagesCallback([](WebsocketsClient&, WebsocketsMessage){}), - _eventsCallback([](WebsocketsClient&, WebsocketsEvent, WSInterfaceString){}), - _sendMode(SendMode_Normal) { + WebsocketsClient::WebsocketsClient(std::shared_ptr client) : _client(client), + _endpoint(client), + _connectionOpen(client->available()), + _messagesCallback([](WebsocketsClient &, WebsocketsMessage) {}), + _eventsCallback([](WebsocketsClient &, WebsocketsEvent, WSInterfaceString) {}), + _sendMode(SendMode_Normal) + { // Empty } - WebsocketsClient::WebsocketsClient(const WebsocketsClient& other) : - _client(other._client), - _endpoint(other._endpoint), - _connectionOpen(other._client->available()), - _messagesCallback(other._messagesCallback), - _eventsCallback(other._eventsCallback), - _sendMode(other._sendMode) { + WebsocketsClient::WebsocketsClient(const WebsocketsClient &other) : _client(other._client), + _endpoint(other._endpoint), + _connectionOpen(other._client->available()), + _messagesCallback(other._messagesCallback), + _eventsCallback(other._eventsCallback), + _sendMode(other._sendMode) + { // delete other's client - const_cast(other)._client = nullptr; - const_cast(other)._connectionOpen = false; + const_cast(other)._client = nullptr; + const_cast(other)._connectionOpen = false; } - WebsocketsClient::WebsocketsClient(const WebsocketsClient&& other) : - _client(other._client), - _endpoint(other._endpoint), - _connectionOpen(other._client->available()), - _messagesCallback(other._messagesCallback), - _eventsCallback(other._eventsCallback), - _sendMode(other._sendMode) { + WebsocketsClient::WebsocketsClient(const WebsocketsClient &&other) : _client(other._client), + _endpoint(other._endpoint), + _connectionOpen(other._client->available()), + _messagesCallback(other._messagesCallback), + _eventsCallback(other._eventsCallback), + _sendMode(other._sendMode) + { // delete other's client - const_cast(other)._client = nullptr; - const_cast(other)._connectionOpen = false; + const_cast(other)._client = nullptr; + const_cast(other)._connectionOpen = false; } - WebsocketsClient& WebsocketsClient::operator=(const WebsocketsClient& other) { + WebsocketsClient &WebsocketsClient::operator=(const WebsocketsClient &other) + { // call endpoint's copy operator _endpoint = other._endpoint; @@ -57,12 +60,13 @@ namespace websockets { this->_sendMode = other._sendMode; // delete other's client - const_cast(other)._client = nullptr; - const_cast(other)._connectionOpen = false; + const_cast(other)._client = nullptr; + const_cast(other)._connectionOpen = false; return *this; } - WebsocketsClient& WebsocketsClient::operator=(const WebsocketsClient&& other) { + WebsocketsClient &WebsocketsClient::operator=(const WebsocketsClient &&other) + { // call endpoint's copy operator _endpoint = other._endpoint; @@ -74,19 +78,23 @@ namespace websockets { this->_sendMode = other._sendMode; // delete other's client - const_cast(other)._client = nullptr; - const_cast(other)._connectionOpen = false; + const_cast(other)._client = nullptr; + const_cast(other)._connectionOpen = false; return *this; } - struct HandshakeRequestResult { + struct HandshakeRequestResult + { WSString requestStr; WSString expectedAcceptKey; }; - bool shouldAddDefaultHeader(const std::string& keyWord, const std::vector>& customHeaders) { - for (const auto& header : customHeaders) { - if(!keyWord.compare(header.first)) { + bool shouldAddDefaultHeader(const std::string &keyWord, const std::vector> &customHeaders) + { + for (const auto &header : customHeaders) + { + if (!keyWord.compare(header.first)) + { return false; } } @@ -94,8 +102,9 @@ namespace websockets { return true; } - HandshakeRequestResult generateHandshake(const WSString& host, const WSString& uri, - const std::vector>& customHeaders) { + HandshakeRequestResult generateHandshake(const WSString &host, const WSString &uri, + const std::vector> &customHeaders) + { WSString key = crypto::base64Encode(crypto::randomBytes(16)); @@ -103,27 +112,33 @@ namespace websockets { handshake += "Host: " + host + "\r\n"; handshake += "Sec-WebSocket-Key: " + key + "\r\n"; - for (const auto& header: customHeaders) { + for (const auto &header : customHeaders) + { handshake += header.first + ": " + header.second + "\r\n"; } - if (shouldAddDefaultHeader("Upgrade", customHeaders)) { + if (shouldAddDefaultHeader("Upgrade", customHeaders)) + { handshake += "Upgrade: websocket\r\n"; } - if (shouldAddDefaultHeader("Connection", customHeaders)) { + if (shouldAddDefaultHeader("Connection", customHeaders)) + { handshake += "Connection: Upgrade\r\n"; } - if (shouldAddDefaultHeader("Sec-WebSocket-Version", customHeaders)) { + if (shouldAddDefaultHeader("Sec-WebSocket-Version", customHeaders)) + { handshake += "Sec-WebSocket-Version: 13\r\n"; } - if (shouldAddDefaultHeader("User-Agent", customHeaders)) { + if (shouldAddDefaultHeader("User-Agent", customHeaders)) + { handshake += "User-Agent: TinyWebsockets Client\r\n"; } - if (shouldAddDefaultHeader("Origin", customHeaders)) { + if (shouldAddDefaultHeader("Origin", customHeaders)) + { handshake += "Origin: https://github.com/gilmaimon/TinyWebsockets\r\n"; } @@ -137,41 +152,54 @@ namespace websockets { return result; } - bool isWhitespace(char ch) { + bool isWhitespace(char ch) + { return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; } - struct HandshakeResponseResult { + struct HandshakeResponseResult + { bool isSuccess; WSString serverAccept; }; - bool isCaseInsensetiveEqual(const WSString lhs, const WSString rhs) { - if (lhs.size() != rhs.size()) return false; + bool isCaseInsensetiveEqual(const WSString lhs, const WSString rhs) + { + if (lhs.size() != rhs.size()) + return false; - for (size_t i = 0; i < lhs.size(); i++) { - char leftLowerCaseChar = lhs[i] >= 'A' && lhs[i] <= 'Z' ? lhs[i] - 'A' + 'a' : lhs[i]; - char righerLowerCaseChar = rhs[i] >= 'A' && rhs[i] <= 'Z' ? rhs[i] - 'A' + 'a' : rhs[i]; - if (leftLowerCaseChar != righerLowerCaseChar) return false; - } + for (size_t i = 0; i < lhs.size(); i++) + { + char leftLowerCaseChar = lhs[i] >= 'A' && lhs[i] <= 'Z' ? lhs[i] - 'A' + 'a' : lhs[i]; + char righerLowerCaseChar = rhs[i] >= 'A' && rhs[i] <= 'Z' ? rhs[i] - 'A' + 'a' : rhs[i]; + if (leftLowerCaseChar != righerLowerCaseChar) + return false; + } - return true; + return true; } - HandshakeResponseResult parseHandshakeResponse(std::vector responseHeaders) { + HandshakeResponseResult parseHandshakeResponse(std::vector responseHeaders) + { bool didUpgradeToWebsockets = false, isConnectionUpgraded = false; WSString serverAccept = ""; - for(WSString header : responseHeaders) { + for (WSString header : responseHeaders) + { auto colonIndex = header.find_first_of(':'); WSString key = header.substr(0, colonIndex); WSString value = header.substr(colonIndex + 2); // +2 (ignore space and ':') - if(isCaseInsensetiveEqual(key, "upgrade")) { + if (isCaseInsensetiveEqual(key, "upgrade")) + { didUpgradeToWebsockets = isCaseInsensetiveEqual(value, "Websocket"); - } else if(isCaseInsensetiveEqual(key, "connection")) { + } + else if (isCaseInsensetiveEqual(key, "connection")) + { isConnectionUpgraded = isCaseInsensetiveEqual(value, "upgrade"); - } else if(isCaseInsensetiveEqual(key, "Sec-WebSocket-Accept")) { + } + else if (isCaseInsensetiveEqual(key, "Sec-WebSocket-Accept")) + { serverAccept = value; } } @@ -182,98 +210,157 @@ namespace websockets { return result; } - bool doestStartsWith(WSString str, WSString prefix) { - if(str.size() < prefix.size()) return false; - for(size_t i = 0; i < prefix.size(); i++) { - if(str[i] != prefix[i]) return false; + bool doestStartsWith(WSString str, WSString prefix) + { + if (str.size() < prefix.size()) + return false; + for (size_t i = 0; i < prefix.size(); i++) + { + if (str[i] != prefix[i]) + return false; } return true; } - void WebsocketsClient::upgradeToSecuredConnection() { - #ifndef _WS_CONFIG_NO_SSL + void WebsocketsClient::upgradeToSecuredConnection() + { +#ifndef _WS_CONFIG_NO_SSL auto client = new WSDefaultSecuredTcpClient; - #ifdef ESP8266 - if( - this->_optional_ssl_fingerprint - || (this->_optional_ssl_rsa_cert && this->_optional_ssl_rsa_private_key) - || (this->_optional_ssl_ec_cert && this->_optional_ssl_ec_private_key) - || this->_optional_ssl_trust_anchors - || this->_optional_ssl_known_key - ) { - if(this->_optional_ssl_fingerprint) { +#ifdef ESP8266 + if ( + this->_optional_ssl_fingerprint || (this->_optional_ssl_rsa_cert && this->_optional_ssl_rsa_private_key) || (this->_optional_ssl_ec_cert && this->_optional_ssl_ec_private_key) || this->_optional_ssl_trust_anchors || this->_optional_ssl_known_key) + { + if (this->_optional_ssl_fingerprint) + { client->setFingerprint(this->_optional_ssl_fingerprint); } - if(this->_optional_ssl_trust_anchors) { + if (this->_optional_ssl_trust_anchors) + { client->setTrustAnchors(this->_optional_ssl_trust_anchors); } - if(this->_optional_ssl_known_key) { - client->setKnownKey(this->_optional_ssl_known_key); - } - if(this->_optional_ssl_rsa_cert && this->_optional_ssl_rsa_private_key) { + if (this->_optional_ssl_known_key) + { + client->setKnownKey(this->_optional_ssl_known_key); + } + if (this->_optional_ssl_rsa_cert && this->_optional_ssl_rsa_private_key) + { client->setClientRSACert(this->_optional_ssl_rsa_cert, this->_optional_ssl_rsa_private_key); } - if(this->_optional_ssl_ec_cert && this->_optional_ssl_ec_private_key) { + if (this->_optional_ssl_ec_cert && this->_optional_ssl_ec_private_key) + { client->setClientECCert(this->_optional_ssl_ec_cert, this->_optional_ssl_ec_private_key); } - } else { + } + else + { client->setInsecure(); } - #elif defined(ESP32) - if(this->_optional_ssl_ca_cert) { +#elif defined(ESP32) + if (this->_optional_ssl_ca_cert) + { client->setCACert(this->_optional_ssl_ca_cert); } - if(this->_optional_ssl_client_ca) { + if (this->_optional_ssl_client_ca) + { client->setCertificate(this->_optional_ssl_client_ca); } - if(this->_optional_ssl_private_key) { + if (this->_optional_ssl_private_key) + { client->setPrivateKey(this->_optional_ssl_private_key); } - #endif +#endif this->_client = std::shared_ptr(client); this->_endpoint.setInternalSocket(this->_client); - #endif //_WS_CONFIG_NO_SSL +#endif //_WS_CONFIG_NO_SSL } - void WebsocketsClient::addHeader(const WSInterfaceString key, const WSInterfaceString value) { + bool areKeysEqualIgnoringCase(const WSString &key1, const WSString &key2) + { + if (key1.length() != key2.length()) + { + return false; + } + for (size_t i = 0; i < key1.length(); ++i) + { + if (tolower(key1[i]) != tolower(key2[i])) + { + return false; + } + } + return true; + } + + bool WebsocketsClient::setHeader(const WSInterfaceString key, const WSInterfaceString value, bool AddIfNotExist) + { + WSString Key = internals::fromInterfaceString(key); + WSString Value = internals::fromInterfaceString(value); + + for (auto &header : _customHeaders) + { + if (areKeysEqualIgnoringCase(header.first, Key)) // Ignore case of header + { + header.second = Value; + return true; // Header found and updated + } + } + + // Header not found + if (AddIfNotExist) + { + addHeader(key, value); // Add missing header + return true; + } + return false; + } + + void WebsocketsClient::addHeader(const WSInterfaceString key, const WSInterfaceString value) + { _customHeaders.push_back({internals::fromInterfaceString(key), internals::fromInterfaceString(value)}); } - bool WebsocketsClient::connect(WSInterfaceString _url) { + bool WebsocketsClient::connect(WSInterfaceString _url) + { WSString url = internals::fromInterfaceString(_url); WSString protocol = ""; int defaultPort = 0; - if(doestStartsWith(url, "http://")) { + if (doestStartsWith(url, "http://")) + { defaultPort = 80; protocol = "http"; - url = url.substr(7); //strlen("http://") == 7 - } else if(doestStartsWith(url, "ws://")) { + url = url.substr(7); // strlen("http://") == 7 + } + else if (doestStartsWith(url, "ws://")) + { defaultPort = 80; protocol = "ws"; - url = url.substr(5); //strlen("ws://") == 5 + url = url.substr(5); // strlen("ws://") == 5 } - #ifndef _WS_CONFIG_NO_SSL - else if(doestStartsWith(url, "wss://")) { +#ifndef _WS_CONFIG_NO_SSL + else if (doestStartsWith(url, "wss://")) + { defaultPort = 443; protocol = "wss"; - url = url.substr(6); //strlen("wss://") == 6 + url = url.substr(6); // strlen("wss://") == 6 upgradeToSecuredConnection(); - } else if(doestStartsWith(url, "https://")) { + } + else if (doestStartsWith(url, "https://")) + { defaultPort = 443; protocol = "https"; - url = url.substr(8); //strlen("https://") == 8 + url = url.substr(8); // strlen("https://") == 8 upgradeToSecuredConnection(); } - #endif +#endif - else { + else + { return false; // Not supported } @@ -281,18 +368,21 @@ namespace websockets { auto uriBeg = url.find_first_of('/'); std::string host = url, uri = "/"; - if(static_cast(uriBeg) != -1) { + if (static_cast(uriBeg) != -1) + { uri = url.substr(uriBeg); host = url.substr(0, uriBeg); } auto portIdx = host.find_first_of(':'); int port = defaultPort; - if(static_cast(portIdx) != -1) { + if (static_cast(portIdx) != -1) + { auto onlyHost = host.substr(0, portIdx); ++portIdx; port = 0; - while(portIdx < host.size() && host[portIdx] >= '0' && host[portIdx] <= '9') { + while (portIdx < host.size() && host[portIdx] >= '0' && host[portIdx] <= '9') + { port = port * 10 + (host[portIdx] - '0'); ++portIdx; } @@ -303,40 +393,46 @@ namespace websockets { return this->connect( internals::fromInternalString(host), port, - internals::fromInternalString(uri) - ); + internals::fromInternalString(uri)); } - bool WebsocketsClient::connect(WSInterfaceString host, int port, WSInterfaceString path) { + bool WebsocketsClient::connect(WSInterfaceString host, int port, WSInterfaceString path) + { this->_connectionOpen = this->_client->connect(internals::fromInterfaceString(host), port); - if (!this->_connectionOpen) return false; + if (!this->_connectionOpen) + return false; auto handshake = generateHandshake(internals::fromInterfaceString(host), internals::fromInterfaceString(path), _customHeaders); this->_client->send(handshake.requestStr); // This check is needed because of an ESP32 lib bug that wont signal that the connection had // failed in `->connect` (called above), sometimes the disconnect will only be noticed here (after a `send`) - if(!available()) { + if (!available()) + { return false; } auto head = this->_client->readLine(); - if(!doestStartsWith(head, "HTTP/1.1 101")) { + if (!doestStartsWith(head, "HTTP/1.1 101")) + { close(CloseReason_ProtocolError); return false; } std::vector serverResponseHeaders; WSString line = ""; - while (true) { + while (true) + { line = this->_client->readLine(); - if (line.size() < 2) { + if (line.size() < 2) + { close(CloseReason_ProtocolError); return false; } - if (line == "\r\n") break; + if (line == "\r\n") + break; // remove /r/n from line end line = line.substr(0, line.size() - 2); @@ -349,7 +445,8 @@ namespace websockets { #else bool serverAcceptMismatch = parsedResponse.serverAccept != handshake.expectedAcceptKey; #endif - if(parsedResponse.isSuccess == false || serverAcceptMismatch) { + if (parsedResponse.isSuccess == false || serverAcceptMismatch) + { close(CloseReason_ProtocolError); return false; } @@ -358,51 +455,70 @@ namespace websockets { return true; } - bool WebsocketsClient::connectSecure(WSInterfaceString host, int port, WSInterfaceString path) { + bool WebsocketsClient::connectSecure(WSInterfaceString host, int port, WSInterfaceString path) + { upgradeToSecuredConnection(); - + return connect(host, port, path); } - void WebsocketsClient::onMessage(MessageCallback callback) { + void WebsocketsClient::onMessage(MessageCallback callback) + { this->_messagesCallback = callback; } - void WebsocketsClient::onMessage(PartialMessageCallback callback) { - this->_messagesCallback = [callback](WebsocketsClient&, WebsocketsMessage msg) { + void WebsocketsClient::onMessage(PartialMessageCallback callback) + { + this->_messagesCallback = [callback](WebsocketsClient &, WebsocketsMessage msg) + { callback(msg); }; } - void WebsocketsClient::onEvent(EventCallback callback) { + void WebsocketsClient::onEvent(EventCallback callback) + { this->_eventsCallback = callback; } - void WebsocketsClient::onEvent(PartialEventCallback callback) { - this->_eventsCallback = [callback](WebsocketsClient&, WebsocketsEvent event, WSInterfaceString data) { + void WebsocketsClient::onEvent(PartialEventCallback callback) + { + this->_eventsCallback = [callback](WebsocketsClient &, WebsocketsEvent event, WSInterfaceString data) + { callback(event, data); }; } - bool WebsocketsClient::poll() { + bool WebsocketsClient::poll() + { bool messageReceived = false; - while(available() && _endpoint.poll()) { + while (available() && _endpoint.poll()) + { auto msg = _endpoint.recv(); - if(msg.isEmpty()) { + if (msg.isEmpty()) + { continue; } messageReceived = true; - if(msg.isBinary() || msg.isText()) { + if (msg.isBinary() || msg.isText()) + { this->_messagesCallback(*this, std::move(msg)); - } else if(msg.isContinuation()) { + } + else if (msg.isContinuation()) + { // continuation messages will only be returned when policy is appropriate this->_messagesCallback(*this, std::move(msg)); - } else if(msg.isPing()) { + } + else if (msg.isPing()) + { _handlePing(std::move(msg)); - } else if(msg.isPong()) { + } + else if (msg.isPong()) + { _handlePong(std::move(msg)); - } else if(msg.isClose()) { + } + else if (msg.isClose()) + { this->_connectionOpen = false; _handleClose(std::move(msg)); } @@ -411,137 +527,155 @@ namespace websockets { return messageReceived; } - WebsocketsMessage WebsocketsClient::readBlocking() { - while(available()) { + WebsocketsMessage WebsocketsClient::readBlocking() + { + while (available()) + { #ifdef PLATFORM_DOES_NOT_SUPPORT_BLOCKING_READ - while(available() && _endpoint.poll() == false) continue; + while (available() && _endpoint.poll() == false) + continue; #endif auto msg = _endpoint.recv(); - if(!msg.isEmpty()) return msg; + if (!msg.isEmpty()) + return msg; } return {}; } - bool WebsocketsClient::send(const WSInterfaceString& data) { + bool WebsocketsClient::send(const WSInterfaceString &data) + { auto str = internals::fromInterfaceString(data); return this->send(str.c_str(), str.size()); } - bool WebsocketsClient::send(const WSInterfaceString&& data) { + bool WebsocketsClient::send(const WSInterfaceString &&data) + { auto str = internals::fromInterfaceString(data); return this->send(str.c_str(), str.size()); } - bool WebsocketsClient::send(const char* data) { + bool WebsocketsClient::send(const char *data) + { return this->send(data, strlen(data)); } - bool WebsocketsClient::send(const char* data, const size_t len) { - if(available()) { + bool WebsocketsClient::send(const char *data, const size_t len) + { + if (available()) + { // if in normal mode - if(this->_sendMode == SendMode_Normal) { + if (this->_sendMode == SendMode_Normal) + { // send a normal message return _endpoint.send( data, len, internals::ContentType::Text, - true - ); + true); } // if in streaming mode - else if(this->_sendMode == SendMode_Streaming) { + else if (this->_sendMode == SendMode_Streaming) + { // send a continue frame return _endpoint.send( data, len, internals::ContentType::Continuation, - false - ); + false); } } return false; } - bool WebsocketsClient::sendBinary(WSInterfaceString data) { + bool WebsocketsClient::sendBinary(WSInterfaceString data) + { auto str = internals::fromInterfaceString(data); return this->sendBinary(str.c_str(), str.size()); } - bool WebsocketsClient::sendBinary(const char* data, const size_t len) { - if(available()) { + bool WebsocketsClient::sendBinary(const char *data, const size_t len) + { + if (available()) + { // if in normal mode - if(this->_sendMode == SendMode_Normal) { + if (this->_sendMode == SendMode_Normal) + { // send a normal message return _endpoint.send( data, len, internals::ContentType::Binary, - true - ); + true); } // if in streaming mode - else if(this->_sendMode == SendMode_Streaming) { + else if (this->_sendMode == SendMode_Streaming) + { // send a continue frame return _endpoint.send( data, len, internals::ContentType::Continuation, - false - ); + false); } } return false; } - bool WebsocketsClient::stream(const WSInterfaceString data) { - if(available() && this->_sendMode == SendMode_Normal) { + bool WebsocketsClient::stream(const WSInterfaceString data) + { + if (available() && this->_sendMode == SendMode_Normal) + { this->_sendMode = SendMode_Streaming; return _endpoint.send( internals::fromInterfaceString(data), internals::ContentType::Text, - false - ); + false); } return false; } - - bool WebsocketsClient::streamBinary(const WSInterfaceString data) { - if(available() && this->_sendMode == SendMode_Normal) { + bool WebsocketsClient::streamBinary(const WSInterfaceString data) + { + if (available() && this->_sendMode == SendMode_Normal) + { this->_sendMode = SendMode_Streaming; return _endpoint.send( internals::fromInterfaceString(data), internals::ContentType::Binary, - false - ); + false); } return false; } - bool WebsocketsClient::end(const WSInterfaceString data) { - if(available() && this->_sendMode == SendMode_Streaming) { + bool WebsocketsClient::end(const WSInterfaceString data) + { + if (available() && this->_sendMode == SendMode_Streaming) + { this->_sendMode = SendMode_Normal; return _endpoint.send( internals::fromInterfaceString(data), internals::ContentType::Continuation, - true - ); + true); } return false; } - void WebsocketsClient::setFragmentsPolicy(const FragmentsPolicy newPolicy) { + void WebsocketsClient::setFragmentsPolicy(const FragmentsPolicy newPolicy) + { _endpoint.setFragmentsPolicy(newPolicy); } - bool WebsocketsClient::available(const bool activeTest) { - if(activeTest) { + bool WebsocketsClient::available(const bool activeTest) + { + if (activeTest) + { _endpoint.ping(""); } bool updatedConnectionOpen = this->_connectionOpen && this->_client && this->_client->available(); - if(updatedConnectionOpen != this->_connectionOpen) { + if (updatedConnectionOpen != this->_connectionOpen) + { _endpoint.close(CloseReason_AbnormalClosure); this->_eventsCallback(*this, WebsocketsEvent::ConnectionClosed, ""); } @@ -550,100 +684,121 @@ namespace websockets { return this->_connectionOpen; } - bool WebsocketsClient::ping(const WSInterfaceString data) { - if(available()) { + bool WebsocketsClient::ping(const WSInterfaceString data) + { + if (available()) + { return _endpoint.ping(internals::fromInterfaceString(data)); } return false; } - bool WebsocketsClient::pong(const WSInterfaceString data) { - if(available()) { + bool WebsocketsClient::pong(const WSInterfaceString data) + { + if (available()) + { return _endpoint.pong(internals::fromInterfaceString(data)); } return false; } - void WebsocketsClient::close(const CloseReason reason) { - if(available()) { + void WebsocketsClient::close(const CloseReason reason) + { + if (available()) + { this->_connectionOpen = false; _endpoint.close(reason); _handleClose({}); } } - CloseReason WebsocketsClient::getCloseReason() const { + CloseReason WebsocketsClient::getCloseReason() const + { return _endpoint.getCloseReason(); } - void WebsocketsClient::_handlePing(const WebsocketsMessage message) { + void WebsocketsClient::_handlePing(const WebsocketsMessage message) + { this->_eventsCallback(*this, WebsocketsEvent::GotPing, message.data()); } - void WebsocketsClient::_handlePong(const WebsocketsMessage message) { + void WebsocketsClient::_handlePong(const WebsocketsMessage message) + { this->_eventsCallback(*this, WebsocketsEvent::GotPong, message.data()); } - void WebsocketsClient::_handleClose(const WebsocketsMessage message) { + void WebsocketsClient::_handleClose(const WebsocketsMessage message) + { this->_eventsCallback(*this, WebsocketsEvent::ConnectionClosed, message.data()); } - #ifdef ESP8266 - void WebsocketsClient::setFingerprint(const char* fingerprint) { + void WebsocketsClient::setFingerprint(const char *fingerprint) + { this->_optional_ssl_fingerprint = fingerprint; } - void WebsocketsClient::setInsecure() { + void WebsocketsClient::setInsecure() + { this->_optional_ssl_fingerprint = nullptr; - this->_optional_ssl_rsa_cert = nullptr; - this->_optional_ssl_rsa_private_key = nullptr; - this->_optional_ssl_ec_cert = nullptr; - this->_optional_ssl_ec_private_key = nullptr; - this->_optional_ssl_trust_anchors = nullptr; - this->_optional_ssl_known_key = nullptr; + this->_optional_ssl_rsa_cert = nullptr; + this->_optional_ssl_rsa_private_key = nullptr; + this->_optional_ssl_ec_cert = nullptr; + this->_optional_ssl_ec_private_key = nullptr; + this->_optional_ssl_trust_anchors = nullptr; + this->_optional_ssl_known_key = nullptr; } - void WebsocketsClient::setClientRSACert(const X509List *cert, const PrivateKey *sk) { - this->_optional_ssl_rsa_cert = cert; - this->_optional_ssl_rsa_private_key = sk; - } + void WebsocketsClient::setClientRSACert(const X509List *cert, const PrivateKey *sk) + { + this->_optional_ssl_rsa_cert = cert; + this->_optional_ssl_rsa_private_key = sk; + } - void WebsocketsClient::setClientECCert(const X509List *cert, const PrivateKey *sk) { - this->_optional_ssl_ec_cert = cert; - this->_optional_ssl_ec_private_key = sk; - } + void WebsocketsClient::setClientECCert(const X509List *cert, const PrivateKey *sk) + { + this->_optional_ssl_ec_cert = cert; + this->_optional_ssl_ec_private_key = sk; + } - void WebsocketsClient::setTrustAnchors(const X509List *ta){ - this->_optional_ssl_trust_anchors = ta; - } + void WebsocketsClient::setTrustAnchors(const X509List *ta) + { + this->_optional_ssl_trust_anchors = ta; + } - void WebsocketsClient::setKnownKey(const PublicKey *pk) { - this->_optional_ssl_known_key = pk; - } + void WebsocketsClient::setKnownKey(const PublicKey *pk) + { + this->_optional_ssl_known_key = pk; + } #elif defined(ESP32) - void WebsocketsClient::setCACert(const char* ca_cert) { + void WebsocketsClient::setCACert(const char *ca_cert) + { this->_optional_ssl_ca_cert = ca_cert; } - void WebsocketsClient::setCertificate(const char* client_ca) { + void WebsocketsClient::setCertificate(const char *client_ca) + { this->_optional_ssl_client_ca = client_ca; } - void WebsocketsClient::setPrivateKey(const char* private_key) { + void WebsocketsClient::setPrivateKey(const char *private_key) + { this->_optional_ssl_private_key = private_key; } - void WebsocketsClient::setInsecure() { + void WebsocketsClient::setInsecure() + { this->_optional_ssl_ca_cert = nullptr; this->_optional_ssl_client_ca = nullptr; this->_optional_ssl_private_key = nullptr; } #endif - WebsocketsClient::~WebsocketsClient() { - if(available()) { + WebsocketsClient::~WebsocketsClient() + { + if (available()) + { this->close(CloseReason_GoingAway); } }