check websocket response before switching protocols
This commit is contained in:
@ -133,6 +133,9 @@ void SslWebsocketClient::send_request()
|
|||||||
|
|
||||||
m_state = State::Request;
|
m_state = State::Request;
|
||||||
|
|
||||||
|
connectionUpgrade = false;
|
||||||
|
upgradeWebsocket = false;
|
||||||
|
|
||||||
asio::async_write(m_socket,
|
asio::async_write(m_socket,
|
||||||
asio::buffer(m_sending->data(), m_sending->size()),
|
asio::buffer(m_sending->data(), m_sending->size()),
|
||||||
[this](const std::error_code &error, std::size_t length) {
|
[this](const std::error_code &error, std::size_t length) {
|
||||||
@ -260,7 +263,7 @@ bool SslWebsocketClient::parseResponseLine(std::string_view line)
|
|||||||
|
|
||||||
if (const auto index2 = line.find(' ', index + 1); index2 == std::string::npos)
|
if (const auto index2 = line.find(' ', index + 1); index2 == std::string::npos)
|
||||||
{
|
{
|
||||||
ESP_LOGW(TAG, "invalid request line (2): \"%.*s\"", line.size(), line.data());
|
ESP_LOGW(TAG, "invalid response line (2): \"%.*s\"", line.size(), line.data());
|
||||||
if (!m_error)
|
if (!m_error)
|
||||||
m_error = Error { .mesage = fmt::format("invalid response line (2): \"{}\"", line) };
|
m_error = Error { .mesage = fmt::format("invalid response line (2): \"{}\"", line) };
|
||||||
std::error_code shutdown_error;
|
std::error_code shutdown_error;
|
||||||
@ -272,6 +275,16 @@ bool SslWebsocketClient::parseResponseLine(std::string_view line)
|
|||||||
const std::string_view status { line.data() + index + 1, line.data() + index2 };
|
const std::string_view status { line.data() + index + 1, line.data() + index2 };
|
||||||
// ESP_LOGV(TAG, "response status: %zd \"%.*s\"", status.size(), status.size(), status.data());
|
// ESP_LOGV(TAG, "response status: %zd \"%.*s\"", status.size(), status.size(), status.data());
|
||||||
|
|
||||||
|
if (status != "101")
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "invalid response status: \"%.*s\"", status.size(), status.data());
|
||||||
|
if (!m_error)
|
||||||
|
m_error = Error { .mesage = fmt::format("invalid response status: \"{}\"", status) };
|
||||||
|
std::error_code shutdown_error;
|
||||||
|
m_socket.shutdown(shutdown_error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string_view message { line.cbegin() + index2 + 1, line.cend() };
|
const std::string_view message { line.cbegin() + index2 + 1, line.cend() };
|
||||||
// ESP_LOGV(TAG, "response message: %zd \"%.*s\"", message.size(), message.size(), message.data());
|
// ESP_LOGV(TAG, "response message: %zd \"%.*s\"", message.size(), message.size(), message.data());
|
||||||
|
|
||||||
@ -313,7 +326,7 @@ bool SslWebsocketClient::parseResponseHeader(std::string_view line)
|
|||||||
ESP_LOGW(TAG, "invalid Content-Length %.*s %.*s", value.size(), value.data(),
|
ESP_LOGW(TAG, "invalid Content-Length %.*s %.*s", value.size(), value.data(),
|
||||||
parsed.error().size(), parsed.error().data());
|
parsed.error().size(), parsed.error().data());
|
||||||
if (!m_error)
|
if (!m_error)
|
||||||
m_error = Error { .mesage = fmt::format("iinvalid Content-Length: \"{}\": {}", value, parsed.error()) };
|
m_error = Error { .mesage = fmt::format("invalid Content-Length: \"{}\": {}", value, parsed.error()) };
|
||||||
std::error_code shutdown_error;
|
std::error_code shutdown_error;
|
||||||
m_socket.shutdown(shutdown_error);
|
m_socket.shutdown(shutdown_error);
|
||||||
return false;
|
return false;
|
||||||
@ -321,6 +334,16 @@ bool SslWebsocketClient::parseResponseHeader(std::string_view line)
|
|||||||
else
|
else
|
||||||
m_responseBodySize = *parsed;
|
m_responseBodySize = *parsed;
|
||||||
}
|
}
|
||||||
|
else if (cpputils::stringEqualsIgnoreCase(key, "Connection"))
|
||||||
|
{
|
||||||
|
if (cpputils::stringEqualsIgnoreCase(value, "Upgrade"))
|
||||||
|
connectionUpgrade = true;
|
||||||
|
}
|
||||||
|
else if (cpputils::stringEqualsIgnoreCase(key, "Upgrade"))
|
||||||
|
{
|
||||||
|
if (value.contains("websocket") || value.contains("Websocket"))
|
||||||
|
upgradeWebsocket = true;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -359,6 +382,25 @@ bool SslWebsocketClient::parseResponseHeader(std::string_view line)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
requestFinished:
|
requestFinished:
|
||||||
|
if (!connectionUpgrade)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "header Connection: Upgrade missing");
|
||||||
|
if (!m_error)
|
||||||
|
m_error = Error { .mesage = "header Connection: Upgrade missing" };
|
||||||
|
std::error_code shutdown_error;
|
||||||
|
m_socket.shutdown(shutdown_error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!upgradeWebsocket)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "header Upgrade: websocket missing");
|
||||||
|
if (!m_error)
|
||||||
|
m_error = Error { .mesage = "header Upgrade: websocket missing" };
|
||||||
|
std::error_code shutdown_error;
|
||||||
|
m_socket.shutdown(shutdown_error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// ESP_LOGV(TAG, "finished");
|
// ESP_LOGV(TAG, "finished");
|
||||||
|
|
||||||
handleConnected();
|
handleConnected();
|
||||||
|
@ -67,6 +67,9 @@ private:
|
|||||||
enum class State { Request, ResponseLine, ResponseHeaders, ResponseBody, WebSocket };
|
enum class State { Request, ResponseLine, ResponseHeaders, ResponseBody, WebSocket };
|
||||||
State m_state { State::Request };
|
State m_state { State::Request };
|
||||||
|
|
||||||
|
bool connectionUpgrade;
|
||||||
|
bool upgradeWebsocket;
|
||||||
|
|
||||||
std::string m_parsingBuffer;
|
std::string m_parsingBuffer;
|
||||||
|
|
||||||
std::size_t m_responseBodySize{};
|
std::size_t m_responseBodySize{};
|
||||||
|
Reference in New Issue
Block a user