Add client handshake extra headers (#105)

Even though 6455 defines all the necessary headers needed for
client/server handshake, in practice most of the cases websocket servers
expect few more headers. Therefore adding this functionality.
This commit is contained in:
ozychhi 2019-08-26 11:37:40 -05:00 committed by Benjamin Sergeant
parent 193da820b2
commit f18f04c0ee
6 changed files with 34 additions and 12 deletions

View File

@ -70,6 +70,11 @@ namespace ix
std::lock_guard<std::mutex> lock(_configMutex); std::lock_guard<std::mutex> lock(_configMutex);
_url = url; _url = url;
} }
void WebSocket::setExtraHeaders(const std::unordered_map<std::string, std::string>& headers)
{
std::lock_guard<std::mutex> lock(_configMutex);
_extraHeaders = headers;
}
const std::string& WebSocket::getUrl() const const std::string& WebSocket::getUrl() const
{ {
@ -176,7 +181,7 @@ namespace ix
_pingTimeoutSecs); _pingTimeoutSecs);
} }
WebSocketInitResult status = _ws.connectToUrl(_url, timeoutSecs); WebSocketInitResult status = _ws.connectToUrl(_url, _extraHeaders, timeoutSecs);
if (!status.success) if (!status.success)
{ {
return status; return status;

View File

@ -21,6 +21,7 @@
#include <mutex> #include <mutex>
#include <string> #include <string>
#include <thread> #include <thread>
#include <unordered_map>
namespace ix namespace ix
{ {
@ -44,6 +45,8 @@ namespace ix
~WebSocket(); ~WebSocket();
void setUrl(const std::string& url); void setUrl(const std::string& url);
void setExtraHeaders(const std::unordered_map<std::string, std::string>&
headers); // send extra headers in client handshake request
void setPerMessageDeflateOptions( void setPerMessageDeflateOptions(
const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions); const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions);
void setHeartBeatPeriod(int heartBeatPeriodSecs); void setHeartBeatPeriod(int heartBeatPeriodSecs);
@ -111,6 +114,8 @@ namespace ix
WebSocketTransport _ws; WebSocketTransport _ws;
std::string _url; std::string _url;
std::unordered_map<std::string, std::string> _extraHeaders;
WebSocketPerMessageDeflateOptions _perMessageDeflateOptions; WebSocketPerMessageDeflateOptions _perMessageDeflateOptions;
mutable std::mutex _configMutex; // protect all config variables access mutable std::mutex _configMutex; // protect all config variables access

View File

@ -88,6 +88,7 @@ namespace ix
} }
WebSocketInitResult WebSocketHandshake::clientHandshake(const std::string& url, WebSocketInitResult WebSocketHandshake::clientHandshake(const std::string& url,
const std::unordered_map<std::string, std::string>& extraHeaders,
const std::string& host, const std::string& host,
const std::string& path, const std::string& path,
int port, int port,
@ -127,6 +128,9 @@ namespace ix
ss << "Sec-WebSocket-Version: 13\r\n"; ss << "Sec-WebSocket-Version: 13\r\n";
ss << "Sec-WebSocket-Key: " << secWebSocketKey << "\r\n"; ss << "Sec-WebSocket-Key: " << secWebSocketKey << "\r\n";
for (auto& it : extraHeaders) {
ss << it.first << ":" << it.second << "\r\n";
}
if (_enablePerMessageDeflate) if (_enablePerMessageDeflate)
{ {
ss << _perMessageDeflateOptions.generateHeader(); ss << _perMessageDeflateOptions.generateHeader();

View File

@ -16,6 +16,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <unordered_map>
namespace ix namespace ix
{ {
@ -50,7 +51,9 @@ namespace ix
WebSocketPerMessageDeflateOptions& perMessageDeflateOptions, WebSocketPerMessageDeflateOptions& perMessageDeflateOptions,
std::atomic<bool>& enablePerMessageDeflate); std::atomic<bool>& enablePerMessageDeflate);
WebSocketInitResult clientHandshake(const std::string& url, WebSocketInitResult clientHandshake(
const std::string& url,
const std::unordered_map<std::string, std::string>& extraHeaders,
const std::string& host, const std::string& host,
const std::string& path, const std::string& path,
int port, int port,

View File

@ -127,7 +127,9 @@ namespace ix
} }
// Client // Client
WebSocketInitResult WebSocketTransport::connectToUrl(const std::string& url, WebSocketInitResult WebSocketTransport::connectToUrl(
const std::string& url,
const std::unordered_map<std::string, std::string>& headers,
int timeoutSecs) int timeoutSecs)
{ {
std::lock_guard<std::mutex> lock(_socketMutex); std::lock_guard<std::mutex> lock(_socketMutex);
@ -156,8 +158,8 @@ namespace ix
_perMessageDeflateOptions, _perMessageDeflateOptions,
_enablePerMessageDeflate); _enablePerMessageDeflate);
auto result = webSocketHandshake.clientHandshake(url, host, path, port, auto result = webSocketHandshake.clientHandshake(url, headers, host, path,
timeoutSecs); port, timeoutSecs);
if (result.success) if (result.success)
{ {
setReadyState(ReadyState::OPEN); setReadyState(ReadyState::OPEN);

View File

@ -24,6 +24,7 @@
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
namespace ix namespace ix
@ -75,7 +76,9 @@ namespace ix
int pingIntervalSecs, int pingIntervalSecs,
int pingTimeoutSecs); int pingTimeoutSecs);
WebSocketInitResult connectToUrl(const std::string& url, // Client WebSocketInitResult connectToUrl( // Client
const std::string& url,
const std::unordered_map<std::string, std::string>& headers,
int timeoutSecs); int timeoutSecs);
WebSocketInitResult connectToSocket(int fd, // Server WebSocketInitResult connectToSocket(int fd, // Server
int timeoutSecs); int timeoutSecs);