improve some websocket error messages + add a utility function with unittest to parse status line and stop using scanf which triggers warnings on Windows
This commit is contained in:
parent
6c0890594b
commit
64d3c99f99
@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.
|
||||
## [6.2.0] - 2019-09-09
|
||||
|
||||
- websocket and http server: server does not close the bound client socket in many cases
|
||||
- improve some websocket error messages
|
||||
- add a utility function with unittest to parse status line and stop using scanf which triggers warnings on Windows
|
||||
|
||||
## [6.1.0] - 2019-09-08
|
||||
|
||||
|
@ -27,6 +27,36 @@ namespace ix
|
||||
return out;
|
||||
}
|
||||
|
||||
std::pair<std::string, int> Http::parseStatusLine(const std::string& line)
|
||||
{
|
||||
// Request-Line = Method SP Request-URI SP HTTP-Version CRLF
|
||||
std::string token;
|
||||
std::stringstream tokenStream(line);
|
||||
std::vector<std::string> tokens;
|
||||
|
||||
// Split by ' '
|
||||
while (std::getline(tokenStream, token, ' '))
|
||||
{
|
||||
tokens.push_back(token);
|
||||
}
|
||||
|
||||
std::string httpVersion;
|
||||
if (tokens.size() >= 1)
|
||||
{
|
||||
httpVersion = trim(tokens[0]);
|
||||
}
|
||||
|
||||
int statusCode = -1;
|
||||
if (tokens.size() >= 2)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << trim(tokens[1]);
|
||||
ss >> statusCode;
|
||||
}
|
||||
|
||||
return std::make_pair(httpVersion, statusCode);
|
||||
}
|
||||
|
||||
std::tuple<std::string, std::string, std::string> Http::parseRequestLine(const std::string& line)
|
||||
{
|
||||
// Request-Line = Method SP Request-URI SP HTTP-Version CRLF
|
||||
|
@ -115,6 +115,8 @@ namespace ix
|
||||
std::shared_ptr<Socket> socket);
|
||||
static bool sendResponse(HttpResponsePtr response, std::shared_ptr<Socket> socket);
|
||||
|
||||
static std::pair<std::string, int> parseStatusLine(
|
||||
const std::string& line);
|
||||
static std::tuple<std::string, std::string, std::string> parseRequestLine(
|
||||
const std::string& line);
|
||||
static std::string trim(const std::string& str);
|
||||
|
@ -164,20 +164,23 @@ namespace ix
|
||||
}
|
||||
|
||||
// Validate status
|
||||
int status;
|
||||
auto statusLine = Http::parseStatusLine(line);
|
||||
std::string httpVersion = statusLine.first;
|
||||
int status = statusLine.second;
|
||||
|
||||
// HTTP/1.0 is too old.
|
||||
if (sscanf(line.c_str(), "HTTP/1.0 %d", &status) == 1)
|
||||
if (httpVersion != "HTTP/1.1")
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Server version is HTTP/1.0. Rejecting connection to " << host
|
||||
ss << "Expecting HTTP/1.1, got " << httpVersion << ". "
|
||||
<< "Rejecting connection to " << host
|
||||
<< ", status: " << status
|
||||
<< ", HTTP Status line: " << line;
|
||||
return WebSocketInitResult(false, status, ss.str());
|
||||
}
|
||||
|
||||
// We want an 101 HTTP status
|
||||
if (sscanf(line.c_str(), "HTTP/1.1 %d", &status) != 1 || status != 101)
|
||||
if (status != 101)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Got bad status connecting to " << host
|
||||
@ -295,9 +298,15 @@ namespace ix
|
||||
return sendErrorResponse(400, "Missing Sec-WebSocket-Key value");
|
||||
}
|
||||
|
||||
if (headers.find("upgrade") == headers.end())
|
||||
{
|
||||
return sendErrorResponse(400, "Missing Upgrade header");
|
||||
}
|
||||
|
||||
if (!insensitiveStringCompare(headers["upgrade"], "WebSocket"))
|
||||
{
|
||||
return sendErrorResponse(400, "Invalid or missing Upgrade header");
|
||||
return sendErrorResponse(400, "Invalid Upgrade header, "
|
||||
"need WebSocket, got " + headers["upgrade"]);
|
||||
}
|
||||
|
||||
if (headers.find("sec-websocket-version") == headers.end())
|
||||
@ -314,7 +323,7 @@ namespace ix
|
||||
if (version != 13)
|
||||
{
|
||||
return sendErrorResponse(400, "Invalid Sec-WebSocket-Version, "
|
||||
"need 13, got" + ss.str());
|
||||
"need 13, got " + ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -681,8 +681,12 @@ namespace ix
|
||||
reason = WebSocketCloseConstants::kInvalidFramePayloadDataMessage;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate close codes. Autobahn 7.9.*
|
||||
// 1014, 1015 are debattable. The firefox MSDN has a description for them
|
||||
// 1014, 1015 are debattable. The firefox MSDN has a description for them.
|
||||
// Full list of status code and status range is defined in the dedicated
|
||||
// RFC section at https://tools.ietf.org/html/rfc6455#page-45
|
||||
//
|
||||
if (code < 1000 || code == 1004 || code == 1006 ||
|
||||
(code > 1013 && code < 3000))
|
||||
{
|
||||
|
@ -62,6 +62,7 @@ set (SOURCES
|
||||
IXHttpClientTest.cpp
|
||||
IXHttpServerTest.cpp
|
||||
IXUnityBuildsTest.cpp
|
||||
IXHttpTest.cpp
|
||||
)
|
||||
|
||||
# Some unittest don't work on windows yet
|
||||
|
Loading…
Reference in New Issue
Block a user