insensitive string compare when validating server connection header

This commit is contained in:
Benjamin Sergeant 2019-01-25 16:17:47 -08:00
parent 1d359f0fc4
commit a2e6fa0b16
2 changed files with 24 additions and 4 deletions

View File

@ -125,6 +125,16 @@ namespace ix
return out;
}
bool WebSocketHandshake::insensitiveStringCompare(const std::string& a, const std::string& b)
{
return std::equal(a.begin(), a.end(),
b.begin(), b.end(),
[](char a, char b)
{
return tolower(a) == tolower(b);
});
}
std::tuple<std::string, std::string, std::string> WebSocketHandshake::parseRequestLine(const std::string& line)
{
// Request-Line = Method SP Request-URI SP HTTP-Version CRLF
@ -354,14 +364,23 @@ namespace ix
return WebSocketInitResult(false, status, "Error parsing HTTP headers");
}
// Check the presence of the Upgrade field
if (headers.find("connection") == headers.end() ||
headers["connection"] != "Upgrade")
// Check the presence of the connection field
if (headers.find("connection") == headers.end())
{
std::string errorMsg("Invalid or missing connection value");
std::string errorMsg("Missing connection value");
return WebSocketInitResult(false, status, errorMsg);
}
// Check the value of the connection field
// Some websocket servers (Go/Gorilla?) send lowercase values for the
// connection header, so do a case insensitive comparison
if (!insensitiveStringCompare(headers["connection"], "Upgrade"))
{
std::stringstream ss;
ss << "Invalid connection value: " << headers["connection"];
return WebSocketInitResult(false, status, ss.str());
}
char output[29] = {};
WebSocketHandshakeKeyGen::generate(secWebSocketKey.c_str(), output);
if (std::string(output) != headers["sec-websocket-accept"])

View File

@ -76,6 +76,7 @@ namespace ix
std::tuple<std::string, std::string, std::string> parseRequestLine(const std::string& line);
std::string trim(const std::string& str);
bool insensitiveStringCompare(const std::string& a, const std::string& b);
std::atomic<bool>& _requestInitCancellation;
std::shared_ptr<Socket> _socket;