Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87a45a2eba |
@@ -1,12 +0,0 @@
|
|||||||
repos:
|
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
||||||
rev: v2.3.0
|
|
||||||
hooks:
|
|
||||||
- id: check-yaml
|
|
||||||
- id: end-of-file-fixer
|
|
||||||
- id: trailing-whitespace
|
|
||||||
|
|
||||||
- repo: https://github.com/pocc/pre-commit-hooks
|
|
||||||
rev: ''
|
|
||||||
hooks:
|
|
||||||
- id: clang-format
|
|
||||||
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,21 +1,6 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## [5.0.7] - 2019-08-23
|
|
||||||
- WebSocket: add new option to pass in extra HTTP headers when connecting.
|
|
||||||
- `ws connect` add new option (-H, works like [curl](https://stackoverflow.com/questions/356705/how-to-send-a-header-using-a-http-request-through-a-curl-call)) to pass in extra HTTP headers when connecting
|
|
||||||
|
|
||||||
If you run against `ws echo_server` you will see the headers being received printed in the terminal.
|
|
||||||
```
|
|
||||||
ws connect -H "foo: bar" -H "baz: buz" ws://127.0.0.1:8008
|
|
||||||
```
|
|
||||||
|
|
||||||
- CobraConnection: sets a unique id field for all messages sent to [cobra](https://github.com/machinezone/cobra).
|
|
||||||
- CobraConnection: sets a counter as a field for each event published.
|
|
||||||
|
|
||||||
## [5.0.6] - 2019-08-22
|
|
||||||
- Windows: silly compile error (poll should be in the global namespace)
|
|
||||||
|
|
||||||
## [5.0.5] - 2019-08-22
|
## [5.0.5] - 2019-08-22
|
||||||
- Windows: use select instead of WSAPoll, through a poll wrapper
|
- Windows: use select instead of WSAPoll, through a poll wrapper
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
5.0.7
|
5.0.4
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -510,13 +510,3 @@ idle connection.
|
|||||||
```
|
```
|
||||||
webSocket.setHeartBeatPeriod(45);
|
webSocket.setHeartBeatPeriod(45);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Supply extra HTTP headers.
|
|
||||||
|
|
||||||
You can set extra HTTP headers to be sent during the WebSocket handshake.
|
|
||||||
|
|
||||||
```
|
|
||||||
WebSocketHttpHeaders headers;
|
|
||||||
headers["foo"] = "bar";
|
|
||||||
webSocket.setExtraHeaders(headers);
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -70,11 +70,6 @@ namespace ix
|
|||||||
std::lock_guard<std::mutex> lock(_configMutex);
|
std::lock_guard<std::mutex> lock(_configMutex);
|
||||||
_url = url;
|
_url = url;
|
||||||
}
|
}
|
||||||
void WebSocket::setExtraHeaders(const WebSocketHttpHeaders& headers)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(_configMutex);
|
|
||||||
_extraHeaders = headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& WebSocket::getUrl() const
|
const std::string& WebSocket::getUrl() const
|
||||||
{
|
{
|
||||||
@@ -181,7 +176,7 @@ namespace ix
|
|||||||
_pingTimeoutSecs);
|
_pingTimeoutSecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocketInitResult status = _ws.connectToUrl(_url, _extraHeaders, timeoutSecs);
|
WebSocketInitResult status = _ws.connectToUrl(_url, timeoutSecs);
|
||||||
if (!status.success)
|
if (!status.success)
|
||||||
{
|
{
|
||||||
return status;
|
return status;
|
||||||
|
|||||||
@@ -44,9 +44,6 @@ namespace ix
|
|||||||
~WebSocket();
|
~WebSocket();
|
||||||
|
|
||||||
void setUrl(const std::string& url);
|
void setUrl(const std::string& url);
|
||||||
|
|
||||||
// send extra headers in client handshake request
|
|
||||||
void setExtraHeaders(const WebSocketHttpHeaders& headers);
|
|
||||||
void setPerMessageDeflateOptions(
|
void setPerMessageDeflateOptions(
|
||||||
const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions);
|
const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions);
|
||||||
void setHeartBeatPeriod(int heartBeatPeriodSecs);
|
void setHeartBeatPeriod(int heartBeatPeriodSecs);
|
||||||
@@ -114,8 +111,6 @@ namespace ix
|
|||||||
WebSocketTransport _ws;
|
WebSocketTransport _ws;
|
||||||
|
|
||||||
std::string _url;
|
std::string _url;
|
||||||
WebSocketHttpHeaders _extraHeaders;
|
|
||||||
|
|
||||||
WebSocketPerMessageDeflateOptions _perMessageDeflateOptions;
|
WebSocketPerMessageDeflateOptions _perMessageDeflateOptions;
|
||||||
mutable std::mutex _configMutex; // protect all config variables access
|
mutable std::mutex _configMutex; // protect all config variables access
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,6 @@ namespace ix
|
|||||||
}
|
}
|
||||||
|
|
||||||
WebSocketInitResult WebSocketHandshake::clientHandshake(const std::string& url,
|
WebSocketInitResult WebSocketHandshake::clientHandshake(const std::string& url,
|
||||||
const WebSocketHttpHeaders& extraHeaders,
|
|
||||||
const std::string& host,
|
const std::string& host,
|
||||||
const std::string& path,
|
const std::string& path,
|
||||||
int port,
|
int port,
|
||||||
@@ -128,9 +127,6 @@ 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();
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace ix
|
namespace ix
|
||||||
{
|
{
|
||||||
@@ -51,13 +50,11 @@ namespace ix
|
|||||||
WebSocketPerMessageDeflateOptions& perMessageDeflateOptions,
|
WebSocketPerMessageDeflateOptions& perMessageDeflateOptions,
|
||||||
std::atomic<bool>& enablePerMessageDeflate);
|
std::atomic<bool>& enablePerMessageDeflate);
|
||||||
|
|
||||||
WebSocketInitResult clientHandshake(
|
WebSocketInitResult clientHandshake(const std::string& url,
|
||||||
const std::string& url,
|
const std::string& host,
|
||||||
const WebSocketHttpHeaders& extraHeaders,
|
const std::string& path,
|
||||||
const std::string& host,
|
int port,
|
||||||
const std::string& path,
|
int timeoutSecs);
|
||||||
int port,
|
|
||||||
int timeoutSecs);
|
|
||||||
|
|
||||||
WebSocketInitResult serverHandshake(int fd, int timeoutSecs);
|
WebSocketInitResult serverHandshake(int fd, int timeoutSecs);
|
||||||
|
|
||||||
|
|||||||
@@ -127,10 +127,8 @@ namespace ix
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Client
|
// Client
|
||||||
WebSocketInitResult WebSocketTransport::connectToUrl(
|
WebSocketInitResult WebSocketTransport::connectToUrl(const std::string& url,
|
||||||
const std::string& url,
|
int timeoutSecs)
|
||||||
const WebSocketHttpHeaders& headers,
|
|
||||||
int timeoutSecs)
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_socketMutex);
|
std::lock_guard<std::mutex> lock(_socketMutex);
|
||||||
|
|
||||||
@@ -158,8 +156,8 @@ namespace ix
|
|||||||
_perMessageDeflateOptions,
|
_perMessageDeflateOptions,
|
||||||
_enablePerMessageDeflate);
|
_enablePerMessageDeflate);
|
||||||
|
|
||||||
auto result = webSocketHandshake.clientHandshake(url, headers, host, path,
|
auto result = webSocketHandshake.clientHandshake(url, host, path, port,
|
||||||
port, timeoutSecs);
|
timeoutSecs);
|
||||||
if (result.success)
|
if (result.success)
|
||||||
{
|
{
|
||||||
setReadyState(ReadyState::OPEN);
|
setReadyState(ReadyState::OPEN);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace ix
|
namespace ix
|
||||||
@@ -76,10 +75,8 @@ namespace ix
|
|||||||
int pingIntervalSecs,
|
int pingIntervalSecs,
|
||||||
int pingTimeoutSecs);
|
int pingTimeoutSecs);
|
||||||
|
|
||||||
WebSocketInitResult connectToUrl( // Client
|
WebSocketInitResult connectToUrl(const std::string& url, // Client
|
||||||
const std::string& url,
|
int timeoutSecs);
|
||||||
const WebSocketHttpHeaders& headers,
|
|
||||||
int timeoutSecs);
|
|
||||||
WebSocketInitResult connectToSocket(int fd, // Server
|
WebSocketInitResult connectToSocket(int fd, // Server
|
||||||
int timeoutSecs);
|
int timeoutSecs);
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ namespace ix
|
|||||||
_webSocket(new WebSocket()),
|
_webSocket(new WebSocket()),
|
||||||
_publishMode(CobraConnection_PublishMode_Immediate),
|
_publishMode(CobraConnection_PublishMode_Immediate),
|
||||||
_authenticated(false),
|
_authenticated(false),
|
||||||
_eventCallback(nullptr),
|
_eventCallback(nullptr)
|
||||||
_id(0)
|
|
||||||
{
|
{
|
||||||
_pdu["action"] = "rtm/publish";
|
_pdu["action"] = "rtm/publish";
|
||||||
|
|
||||||
@@ -245,7 +244,6 @@ namespace ix
|
|||||||
Json::Value pdu;
|
Json::Value pdu;
|
||||||
pdu["action"] = "auth/handshake";
|
pdu["action"] = "auth/handshake";
|
||||||
pdu["body"] = body;
|
pdu["body"] = body;
|
||||||
pdu["id"] = _id++;
|
|
||||||
|
|
||||||
std::string serializedJson = serializeJson(pdu);
|
std::string serializedJson = serializeJson(pdu);
|
||||||
CobraConnection::invokeTrafficTrackerCallback(serializedJson.size(), false);
|
CobraConnection::invokeTrafficTrackerCallback(serializedJson.size(), false);
|
||||||
@@ -308,7 +306,6 @@ namespace ix
|
|||||||
Json::Value pdu;
|
Json::Value pdu;
|
||||||
pdu["action"] = "auth/authenticate";
|
pdu["action"] = "auth/authenticate";
|
||||||
pdu["body"] = body;
|
pdu["body"] = body;
|
||||||
pdu["id"] = _id++;
|
|
||||||
|
|
||||||
std::string serializedJson = serializeJson(pdu);
|
std::string serializedJson = serializeJson(pdu);
|
||||||
CobraConnection::invokeTrafficTrackerCallback(serializedJson.size(), false);
|
CobraConnection::invokeTrafficTrackerCallback(serializedJson.size(), false);
|
||||||
@@ -405,7 +402,6 @@ namespace ix
|
|||||||
_body["channels"] = channels;
|
_body["channels"] = channels;
|
||||||
_body["message"] = msg;
|
_body["message"] = msg;
|
||||||
_pdu["body"] = _body;
|
_pdu["body"] = _body;
|
||||||
_pdu["id"] = _id++;
|
|
||||||
|
|
||||||
std::string serializedJson = serializeJson(_pdu);
|
std::string serializedJson = serializeJson(_pdu);
|
||||||
|
|
||||||
@@ -448,7 +444,6 @@ namespace ix
|
|||||||
Json::Value pdu;
|
Json::Value pdu;
|
||||||
pdu["action"] = "rtm/subscribe";
|
pdu["action"] = "rtm/subscribe";
|
||||||
pdu["body"] = body;
|
pdu["body"] = body;
|
||||||
pdu["id"] = _id++;
|
|
||||||
|
|
||||||
_webSocket->send(pdu.toStyledString());
|
_webSocket->send(pdu.toStyledString());
|
||||||
|
|
||||||
@@ -474,7 +469,6 @@ namespace ix
|
|||||||
Json::Value pdu;
|
Json::Value pdu;
|
||||||
pdu["action"] = "rtm/unsubscribe";
|
pdu["action"] = "rtm/unsubscribe";
|
||||||
pdu["body"] = body;
|
pdu["body"] = body;
|
||||||
pdu["id"] = _id++;
|
|
||||||
|
|
||||||
_webSocket->send(pdu.toStyledString());
|
_webSocket->send(pdu.toStyledString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,9 +168,6 @@ namespace ix
|
|||||||
|
|
||||||
// Cap the queue size (100 elems so far -> ~100k)
|
// Cap the queue size (100 elems so far -> ~100k)
|
||||||
static constexpr size_t kQueueMaxSize = 256;
|
static constexpr size_t kQueueMaxSize = 256;
|
||||||
|
|
||||||
// Each pdu sent should have an incremental unique id
|
|
||||||
std::atomic<uint64_t> _id;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ix
|
} // namespace ix
|
||||||
|
|||||||
@@ -191,19 +191,6 @@ namespace ix
|
|||||||
msg["device"] = _device;
|
msg["device"] = _device;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Bump a counter for each id
|
|
||||||
// This is used to make sure that we are not
|
|
||||||
// dropping messages, by checking that all the ids is the list of
|
|
||||||
// all natural numbers until the last value sent (0, 1, 2, ..., N)
|
|
||||||
//
|
|
||||||
std::lock_guard<std::mutex> lock(_device_mutex);
|
|
||||||
auto it = _counters.emplace(id, 0);
|
|
||||||
msg["per_id_counter"] = it.first->second;
|
|
||||||
it.first->second += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now actually enqueue the task
|
// Now actually enqueue the task
|
||||||
_cobra_metrics_theaded_publisher.push(msg);
|
_cobra_metrics_theaded_publisher.push(msg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,10 +151,6 @@ namespace ix
|
|||||||
_last_update;
|
_last_update;
|
||||||
mutable std::mutex _last_update_mutex; // protect access to _last_update
|
mutable std::mutex _last_update_mutex; // protect access to _last_update
|
||||||
|
|
||||||
/// Bump a counter for each metric type
|
|
||||||
std::unordered_map<std::string, int> _counters;
|
|
||||||
mutable std::mutex _counters_mutex; // protect access to _counters
|
|
||||||
|
|
||||||
// const strings for internal ids
|
// const strings for internal ids
|
||||||
static const std::string kSetRateControlId;
|
static const std::string kSetRateControlId;
|
||||||
static const std::string kSetBlacklistId;
|
static const std::string kSetBlacklistId;
|
||||||
|
|||||||
@@ -109,7 +109,6 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
CLI::App* connectApp = app.add_subcommand("connect", "Connect to a remote server");
|
CLI::App* connectApp = app.add_subcommand("connect", "Connect to a remote server");
|
||||||
connectApp->add_option("url", url, "Connection url")->required();
|
connectApp->add_option("url", url, "Connection url")->required();
|
||||||
connectApp->add_option("-H", headers, "Header")->join();
|
|
||||||
connectApp->add_flag("-d", disableAutomaticReconnection, "Disable Automatic Reconnection");
|
connectApp->add_flag("-d", disableAutomaticReconnection, "Disable Automatic Reconnection");
|
||||||
connectApp->add_flag("-x", disablePerMessageDeflate, "Disable per message deflate");
|
connectApp->add_flag("-x", disablePerMessageDeflate, "Disable per message deflate");
|
||||||
connectApp->add_flag("-b", binaryMode, "Send in binary mode");
|
connectApp->add_flag("-b", binaryMode, "Send in binary mode");
|
||||||
@@ -253,7 +252,7 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
else if (app.got_subcommand("connect"))
|
else if (app.got_subcommand("connect"))
|
||||||
{
|
{
|
||||||
ret = ix::ws_connect_main(url, headers, disableAutomaticReconnection,
|
ret = ix::ws_connect_main(url, disableAutomaticReconnection,
|
||||||
disablePerMessageDeflate, binaryMode);
|
disablePerMessageDeflate, binaryMode);
|
||||||
}
|
}
|
||||||
else if (app.got_subcommand("chat"))
|
else if (app.got_subcommand("chat"))
|
||||||
|
|||||||
1
ws/ws.h
1
ws/ws.h
@@ -31,7 +31,6 @@ namespace ix
|
|||||||
int ws_chat_main(const std::string& url, const std::string& user);
|
int ws_chat_main(const std::string& url, const std::string& user);
|
||||||
|
|
||||||
int ws_connect_main(const std::string& url,
|
int ws_connect_main(const std::string& url,
|
||||||
const std::string& headers,
|
|
||||||
bool disableAutomaticReconnection,
|
bool disableAutomaticReconnection,
|
||||||
bool disablePerMessageDeflate,
|
bool disablePerMessageDeflate,
|
||||||
bool binaryMode);
|
bool binaryMode);
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ namespace ix
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WebSocketConnect(const std::string& _url,
|
WebSocketConnect(const std::string& _url,
|
||||||
const std::string& headers,
|
|
||||||
bool disableAutomaticReconnection,
|
bool disableAutomaticReconnection,
|
||||||
bool disablePerMessageDeflate,
|
bool disablePerMessageDeflate,
|
||||||
bool binaryMode);
|
bool binaryMode);
|
||||||
@@ -31,17 +30,14 @@ namespace ix
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string _url;
|
std::string _url;
|
||||||
WebSocketHttpHeaders _headers;
|
|
||||||
ix::WebSocket _webSocket;
|
ix::WebSocket _webSocket;
|
||||||
bool _disablePerMessageDeflate;
|
bool _disablePerMessageDeflate;
|
||||||
bool _binaryMode;
|
bool _binaryMode;
|
||||||
|
|
||||||
void log(const std::string& msg);
|
void log(const std::string& msg);
|
||||||
WebSocketHttpHeaders parseHeaders(const std::string& data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
WebSocketConnect::WebSocketConnect(const std::string& url,
|
WebSocketConnect::WebSocketConnect(const std::string& url,
|
||||||
const std::string& headers,
|
|
||||||
bool disableAutomaticReconnection,
|
bool disableAutomaticReconnection,
|
||||||
bool disablePerMessageDeflate,
|
bool disablePerMessageDeflate,
|
||||||
bool binaryMode) :
|
bool binaryMode) :
|
||||||
@@ -53,8 +49,6 @@ namespace ix
|
|||||||
{
|
{
|
||||||
_webSocket.disableAutomaticReconnection();
|
_webSocket.disableAutomaticReconnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
_headers = parseHeaders(headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSocketConnect::log(const std::string& msg)
|
void WebSocketConnect::log(const std::string& msg)
|
||||||
@@ -62,31 +56,6 @@ namespace ix
|
|||||||
std::cout << msg << std::endl;
|
std::cout << msg << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocketHttpHeaders WebSocketConnect::parseHeaders(const std::string& data)
|
|
||||||
{
|
|
||||||
WebSocketHttpHeaders headers;
|
|
||||||
|
|
||||||
// Split by \n
|
|
||||||
std::string token;
|
|
||||||
std::stringstream tokenStream(data);
|
|
||||||
|
|
||||||
while (std::getline(tokenStream, token))
|
|
||||||
{
|
|
||||||
std::size_t pos = token.rfind(':');
|
|
||||||
|
|
||||||
// Bail out if last '.' is found
|
|
||||||
if (pos == std::string::npos) continue;
|
|
||||||
|
|
||||||
auto key = token.substr(0, pos);
|
|
||||||
auto val = token.substr(pos+1);
|
|
||||||
|
|
||||||
std::cerr << key << ": " << val << std::endl;
|
|
||||||
headers[key] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
return headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebSocketConnect::stop()
|
void WebSocketConnect::stop()
|
||||||
{
|
{
|
||||||
_webSocket.stop();
|
_webSocket.stop();
|
||||||
@@ -95,7 +64,6 @@ namespace ix
|
|||||||
void WebSocketConnect::start()
|
void WebSocketConnect::start()
|
||||||
{
|
{
|
||||||
_webSocket.setUrl(_url);
|
_webSocket.setUrl(_url);
|
||||||
_webSocket.setExtraHeaders(_headers);
|
|
||||||
|
|
||||||
if (_disablePerMessageDeflate)
|
if (_disablePerMessageDeflate)
|
||||||
{
|
{
|
||||||
@@ -183,14 +151,12 @@ namespace ix
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ws_connect_main(const std::string& url,
|
int ws_connect_main(const std::string& url,
|
||||||
const std::string& headers,
|
|
||||||
bool disableAutomaticReconnection,
|
bool disableAutomaticReconnection,
|
||||||
bool disablePerMessageDeflate,
|
bool disablePerMessageDeflate,
|
||||||
bool binaryMode)
|
bool binaryMode)
|
||||||
{
|
{
|
||||||
std::cout << "Type Ctrl-D to exit prompt..." << std::endl;
|
std::cout << "Type Ctrl-D to exit prompt..." << std::endl;
|
||||||
WebSocketConnect webSocketChat(url,
|
WebSocketConnect webSocketChat(url,
|
||||||
headers,
|
|
||||||
disableAutomaticReconnection,
|
disableAutomaticReconnection,
|
||||||
disablePerMessageDeflate,
|
disablePerMessageDeflate,
|
||||||
binaryMode);
|
binaryMode);
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace ix
|
|||||||
if (pos == std::string::npos) continue;
|
if (pos == std::string::npos) continue;
|
||||||
|
|
||||||
auto key = token.substr(0, pos);
|
auto key = token.substr(0, pos);
|
||||||
auto val = token.substr(pos+1);
|
auto val = token.substr(pos+2);
|
||||||
|
|
||||||
std::cerr << key << ": " << val << std::endl;
|
std::cerr << key << ": " << val << std::endl;
|
||||||
headers[key] = val;
|
headers[key] = val;
|
||||||
|
|||||||
Reference in New Issue
Block a user