Drop in firmware when connecting to a non-existing server.
RVelichko opened this issue · comments
Thank you for your library, it was very useful to me in the ESP32 project, but there is a problem:
when I connect to a non-existing server, the firmware crashes. In your code, there is no verification after calling WiFiClient :: connect (...) and reading is performed in a loop until the "\ 0" appears, but this is a guaranteed way out of the available address space. I fixed it myself and everything works fine. Correct this for all who will continue to use your library.
Thanks for reporting this!
Would you like to your fix through a pull request?
I do not have permissions to work with your repository, even to add my branches.
bool WebSocketClient::connect(String host, String path, int port) {
// success criteria
bool hasCorrectStatus = false;
bool isUpgrade = false;
bool isWebsocket = false;
bool hasAcceptedKey = false;
bool isConnected = this->client->connect(host.c_str(), port);
if (isConnected) {
// send handshake
String handshake = "GET " + path + " HTTP/1.1\r\n"
"Host: " + host + "\r\n"
"Connection: Upgrade\r\n"
"Upgrade: websocket\r\n"
"Sec-WebSocket-Version: 13\r\n"
"Sec-WebSocket-Key: " + generateKey() + "=\r\n";
if (authorizationHeader != "")
handshake += "Authorization: " + authorizationHeader + "\r\n";
handshake += "\r\n";
DEBUG_WS("[WS] sending handshake");
DEBUG_WS(handshake);
client->write(handshake.c_str());
bool endOfResponse = false;
// handle response headers
String s;
while (!endOfResponse && (s = client->readStringUntil('\n')).length() > 0) {
DEBUG_WS("[WS][RX] " + s);
// HTTP Status
if (s.indexOf("HTTP/") != -1) {
auto status = s.substring(9, 12);
if (status == "101")
hasCorrectStatus = true;
else {
DEBUG_WS("[WS] wrong status: " + status);
return false;
}
}
// Headers
else if (s.indexOf(":") != -1) {
auto col = s.indexOf(":");
auto key = s.substring(0, col);
auto value = s.substring(col + 2, s.length() - 1);
if (key == "Connection" && (value == "Upgrade" || value == "upgrade"))
isUpgrade = true;
else if (key == "Sec-WebSocket-Accept")
hasAcceptedKey = true;
else if (key == "Upgrade" && value == "websocket")
isWebsocket = true;
}
else if (s == "\r")
endOfResponse = true;
}
}
bool success = hasCorrectStatus && isUpgrade && isWebsocket && hasAcceptedKey;
if (success)
DEBUG_WS("[WS] sucessfully connected");
else {
DEBUG_WS("[WS] could not connect");
}
return success;
}
Method with fix.
I want to note that your library is the only one that is freely available on the network — it correctly sends messages to a remote server via websocket. The rest do not fulfill the conditions rfc6455 - do not disguise messages, which leads to the server’s refusal to service the ESP client.
It's finally merged thanks @Estradiaz @RVelichko.