(ixwebsocket client) handle HTTP redirects

This commit is contained in:
Benjamin Sergeant 2020-08-14 18:13:34 -07:00
parent 7ad5ead0f6
commit ed2ed0f7ae
4 changed files with 69 additions and 37 deletions

View File

@ -2,6 +2,10 @@
All changes to this project will be documented in this file.
## [10.2.0] - 2020-08-14
(ixwebsocket client) handle HTTP redirects
## [10.2.0] - 2020-08-13
(ws) upgrade to latest version of nlohmann json (3.9.1 from 3.2.0)

View File

@ -170,20 +170,11 @@ namespace ix
{
std::stringstream ss;
ss << "Expecting HTTP/1.1, got " << httpVersion << ". "
<< "Rejecting connection to " << host << ":" << port << ", status: " << status
<< "Rejecting connection to " << url << ", status: " << status
<< ", HTTP Status line: " << line;
return WebSocketInitResult(false, status, ss.str());
}
// We want an 101 HTTP status
if (status != 101)
{
std::stringstream ss;
ss << "Expecting status 101 (Switching Protocol), got " << status
<< " status connecting to " << host << ":" << port << ", HTTP Status line: " << line;
return WebSocketInitResult(false, status, ss.str());
}
auto result = parseHttpHeaders(_socket, isCancellationRequested);
auto headersValid = result.first;
auto headers = result.second;
@ -193,6 +184,17 @@ namespace ix
return WebSocketInitResult(false, status, "Error parsing HTTP headers");
}
// We want an 101 HTTP status for websocket, otherwise it could be
// a redirection (like 301)
if (status != 101)
{
std::stringstream ss;
ss << "Expecting status 101 (Switching Protocol), got " << status
<< " status connecting to " << url << ", HTTP Status line: " << line;
return WebSocketInitResult(false, status, ss.str(), headers, path);
}
// Check the presence of the connection field
if (headers.find("connection") == headers.end())
{

View File

@ -107,8 +107,14 @@ namespace ix
std::string protocol, host, path, query;
int port;
std::string remoteUrl(url);
if (!UrlParser::parse(url, protocol, host, path, query, port))
WebSocketInitResult result;
const int maxRedirections = 10;
for (int i = 0; i < maxRedirections; ++i)
{
if (!UrlParser::parse(remoteUrl, protocol, host, path, query, port))
{
std::stringstream ss;
ss << "Could not parse url: '" << url << "'";
@ -131,8 +137,25 @@ namespace ix
_perMessageDeflateOptions,
_enablePerMessageDeflate);
auto result =
webSocketHandshake.clientHandshake(url, headers, host, path, port, timeoutSecs);
result = webSocketHandshake.clientHandshake(
remoteUrl, headers, host, path, port, timeoutSecs);
if (result.http_status >= 300 && result.http_status < 400)
{
auto it = result.headers.find("Location");
if (it == result.headers.end())
{
std::stringstream ss;
ss << "Missing Location Header for HTTP Redirect response. "
<< "Rejecting connection to " << url << ", status: " << result.http_status;
result.errorStr = ss.str();
break;
}
remoteUrl = it->second;
continue;
}
if (result.success)
{
setReadyState(ReadyState::OPEN);
@ -140,6 +163,9 @@ namespace ix
return result;
}
return result;
}
// Server
WebSocketInitResult WebSocketTransport::connectToSocket(std::unique_ptr<Socket> socket,
int timeoutSecs)

View File

@ -6,4 +6,4 @@
#pragma once
#define IX_WEBSOCKET_VERSION "10.2.0"
#define IX_WEBSOCKET_VERSION "10.2.1"