(ixwebsocket client) handle HTTP redirects
This commit is contained in:
parent
7ad5ead0f6
commit
ed2ed0f7ae
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
All changes to this project will be documented in this file.
|
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
|
## [10.2.0] - 2020-08-13
|
||||||
|
|
||||||
(ws) upgrade to latest version of nlohmann json (3.9.1 from 3.2.0)
|
(ws) upgrade to latest version of nlohmann json (3.9.1 from 3.2.0)
|
||||||
|
@ -170,20 +170,11 @@ namespace ix
|
|||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Expecting HTTP/1.1, got " << httpVersion << ". "
|
ss << "Expecting HTTP/1.1, got " << httpVersion << ". "
|
||||||
<< "Rejecting connection to " << host << ":" << port << ", status: " << status
|
<< "Rejecting connection to " << url << ", status: " << status
|
||||||
<< ", HTTP Status line: " << line;
|
<< ", HTTP Status line: " << line;
|
||||||
return WebSocketInitResult(false, status, ss.str());
|
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 result = parseHttpHeaders(_socket, isCancellationRequested);
|
||||||
auto headersValid = result.first;
|
auto headersValid = result.first;
|
||||||
auto headers = result.second;
|
auto headers = result.second;
|
||||||
@ -193,6 +184,17 @@ namespace ix
|
|||||||
return WebSocketInitResult(false, status, "Error parsing HTTP headers");
|
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
|
// Check the presence of the connection field
|
||||||
if (headers.find("connection") == headers.end())
|
if (headers.find("connection") == headers.end())
|
||||||
{
|
{
|
||||||
|
@ -107,36 +107,62 @@ namespace ix
|
|||||||
|
|
||||||
std::string protocol, host, path, query;
|
std::string protocol, host, path, query;
|
||||||
int port;
|
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)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
if (!UrlParser::parse(remoteUrl, protocol, host, path, query, port))
|
||||||
ss << "Could not parse url: '" << url << "'";
|
{
|
||||||
return WebSocketInitResult(false, 0, ss.str());
|
std::stringstream ss;
|
||||||
|
ss << "Could not parse url: '" << url << "'";
|
||||||
|
return WebSocketInitResult(false, 0, ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string errorMsg;
|
||||||
|
bool tls = protocol == "wss";
|
||||||
|
_socket = createSocket(tls, -1, errorMsg, _socketTLSOptions);
|
||||||
|
_perMessageDeflate = std::make_unique<WebSocketPerMessageDeflate>();
|
||||||
|
|
||||||
|
if (!_socket)
|
||||||
|
{
|
||||||
|
return WebSocketInitResult(false, 0, errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebSocketHandshake webSocketHandshake(_requestInitCancellation,
|
||||||
|
_socket,
|
||||||
|
_perMessageDeflate,
|
||||||
|
_perMessageDeflateOptions,
|
||||||
|
_enablePerMessageDeflate);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string errorMsg;
|
|
||||||
bool tls = protocol == "wss";
|
|
||||||
_socket = createSocket(tls, -1, errorMsg, _socketTLSOptions);
|
|
||||||
_perMessageDeflate = std::make_unique<WebSocketPerMessageDeflate>();
|
|
||||||
|
|
||||||
if (!_socket)
|
|
||||||
{
|
|
||||||
return WebSocketInitResult(false, 0, errorMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
WebSocketHandshake webSocketHandshake(_requestInitCancellation,
|
|
||||||
_socket,
|
|
||||||
_perMessageDeflate,
|
|
||||||
_perMessageDeflateOptions,
|
|
||||||
_enablePerMessageDeflate);
|
|
||||||
|
|
||||||
auto result =
|
|
||||||
webSocketHandshake.clientHandshake(url, headers, host, path, port, timeoutSecs);
|
|
||||||
if (result.success)
|
|
||||||
{
|
|
||||||
setReadyState(ReadyState::OPEN);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,4 +6,4 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define IX_WEBSOCKET_VERSION "10.2.0"
|
#define IX_WEBSOCKET_VERSION "10.2.1"
|
||||||
|
Loading…
Reference in New Issue
Block a user