[DEV] correct key of websocket
This commit is contained in:
parent
4f82e11375
commit
19d49bb462
@ -368,25 +368,21 @@ void enet::Http::getHeader() {
|
||||
continue;
|
||||
}
|
||||
header += type;
|
||||
if ( header.size() > 6
|
||||
if ( header.size() > 4
|
||||
&& header[header.size()-1] == '\n'
|
||||
&& header[header.size()-2] == '\r'
|
||||
&& header[header.size()-3] == '\n'
|
||||
&& header[header.size()-4] == '\r'
|
||||
&& header[header.size()-5] == '\n'
|
||||
&& header[header.size()-6] == '\r') {
|
||||
&& header[header.size()-4] == '\r') {
|
||||
// Normal end case ...
|
||||
break;
|
||||
} else if ( header.size() > 3
|
||||
} else if ( header.size() > 2
|
||||
&& header[header.size()-1] == '\n'
|
||||
&& header[header.size()-2] == '\n'
|
||||
&& header[header.size()-3] == '\n') {
|
||||
&& header[header.size()-2] == '\n') {
|
||||
// linux end case
|
||||
break;
|
||||
} else if ( header.size() > 3
|
||||
} else if ( header.size() > 2
|
||||
&& header[header.size()-1] == '\r'
|
||||
&& header[header.size()-2] == '\r'
|
||||
&& header[header.size()-3] == '\r') {
|
||||
&& header[header.size()-2] == '\r') {
|
||||
// Mac end case
|
||||
break;
|
||||
}
|
||||
@ -600,13 +596,6 @@ void enet::HttpHeader::rmKey(const std::string& _key) {
|
||||
}
|
||||
|
||||
std::string enet::HttpHeader::getKey(const std::string& _key) const {
|
||||
ENET_WARNING("search key: " << _key << " in:");
|
||||
for (auto &it : m_map) {
|
||||
ENET_WARNING(" '" << it.first << "' : '" << it.second << "'");
|
||||
if (it.first == _key) {
|
||||
ENET_WARNING(" ==> Find");
|
||||
}
|
||||
}
|
||||
auto it = m_map.find(_key);
|
||||
if (it != m_map.end()) {
|
||||
return it->second;
|
||||
@ -672,7 +661,7 @@ std::string enet::HttpAnswer::generate() const {
|
||||
}
|
||||
out += "\r\n";
|
||||
out += generateKeys();
|
||||
out += "\r\n\r\n";
|
||||
out += "\r\n";
|
||||
return out;
|
||||
}
|
||||
enet::HttpServer::HttpServer(enet::Tcp _connection) :
|
||||
@ -715,7 +704,7 @@ std::string enet::HttpRequest::generate() const {
|
||||
out += etk::to_string(m_protocol);
|
||||
out += "\r\n";
|
||||
out += generateKeys();
|
||||
out += "\r\n\r\n";
|
||||
out += "\r\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include <etk/stdTools.h>
|
||||
#include <string.h>
|
||||
#include <random>
|
||||
#include <algue/base64.h>
|
||||
#include <algue/sha1.h>
|
||||
|
||||
|
||||
namespace enet {
|
||||
@ -47,6 +49,23 @@ enet::WebSocket::~WebSocket() {
|
||||
stop(true);
|
||||
}
|
||||
|
||||
static std::string generateKey() {
|
||||
// create dynamic key:
|
||||
std::random_device rd;
|
||||
std::mt19937 e2(rd());
|
||||
std::uniform_real_distribution<> dist(0, 0xFF);
|
||||
uint8_t dataKey[16];
|
||||
for (size_t iii=0; iii<16; ++iii) {
|
||||
dataKey[iii] = uint8_t(dist(e2));
|
||||
}
|
||||
return algue::base64::encode(dataKey, 16);
|
||||
}
|
||||
|
||||
static std::string generateCheckKey(const std::string& _key) {
|
||||
std::string out = _key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||
std::vector<uint8_t> keyData = algue::sha1::encode(out);
|
||||
return algue::base64::encode(keyData);
|
||||
}
|
||||
|
||||
void enet::WebSocket::start(const std::string& _uri) {
|
||||
if (m_interface == nullptr) {
|
||||
@ -59,8 +78,12 @@ void enet::WebSocket::start(const std::string& _uri) {
|
||||
req.setUri(_uri);
|
||||
req.setKey("Upgrade", "websocket");
|
||||
req.setKey("Connection", "Upgrade");
|
||||
req.setKey("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ=="); // this is an example key ...
|
||||
m_checkKey = generateKey();
|
||||
req.setKey("Sec-WebSocket-Key", m_checkKey); // this is an example key ...
|
||||
m_checkKey = generateCheckKey(m_checkKey);
|
||||
req.setKey("Sec-WebSocket-Version", "13");
|
||||
req.setKey("Pragma", "no-cache");
|
||||
req.setKey("Cache-Control", "no-cache");
|
||||
ememory::SharedPtr<enet::HttpClient> interface = std::dynamic_pointer_cast<enet::HttpClient>(m_interface);
|
||||
if (interface!=nullptr) {
|
||||
interface->setHeader(req);
|
||||
@ -83,7 +106,9 @@ void enet::WebSocket::onReceiveData(enet::Tcp& _connection) {
|
||||
int32_t len = _connection.read(&opcode, sizeof(uint8_t));
|
||||
if (len <= 0) {
|
||||
if (len < 0) {
|
||||
ENET_ERROR("Protocol error occured ...");
|
||||
if (_connection.getConnectionStatus() == enet::Tcp::status::link) {
|
||||
ENET_ERROR("Protocol error occured ...");
|
||||
}
|
||||
ENET_VERBOSE("ReadRaw 1 [STOP]");
|
||||
m_interface->stop(true);
|
||||
return;
|
||||
@ -103,7 +128,9 @@ void enet::WebSocket::onReceiveData(enet::Tcp& _connection) {
|
||||
ENET_VERBOSE("Read payload : " << uint32_t(size1));
|
||||
if (len <= 0) {
|
||||
if (len < 0) {
|
||||
ENET_ERROR("Protocol error occured ...");
|
||||
if (_connection.getConnectionStatus() == enet::Tcp::status::link) {
|
||||
ENET_ERROR("Protocol error occured ...");
|
||||
}
|
||||
ENET_VERBOSE("ReadRaw 1 [STOP]");
|
||||
m_interface->stop(true);
|
||||
return;
|
||||
@ -118,7 +145,9 @@ void enet::WebSocket::onReceiveData(enet::Tcp& _connection) {
|
||||
len = _connection.read(&tmpSize, sizeof(uint16_t));
|
||||
if (len <= 1) {
|
||||
if (len < 0) {
|
||||
ENET_ERROR("Protocol error occured ...");
|
||||
if (_connection.getConnectionStatus() == enet::Tcp::status::link) {
|
||||
ENET_ERROR("Protocol error occured ...");
|
||||
}
|
||||
ENET_VERBOSE("ReadRaw 1 [STOP]");
|
||||
m_interface->stop(true);
|
||||
return;
|
||||
@ -132,7 +161,9 @@ void enet::WebSocket::onReceiveData(enet::Tcp& _connection) {
|
||||
len = _connection.read(&totalSize, sizeof(uint64_t));
|
||||
if (len <= 7) {
|
||||
if (len < 0) {
|
||||
ENET_ERROR("Protocol error occured ...");
|
||||
if (_connection.getConnectionStatus() == enet::Tcp::status::link) {
|
||||
ENET_ERROR("Protocol error occured ...");
|
||||
}
|
||||
ENET_VERBOSE("ReadRaw 1 [STOP]");
|
||||
m_interface->stop(true);
|
||||
return;
|
||||
@ -148,7 +179,9 @@ void enet::WebSocket::onReceiveData(enet::Tcp& _connection) {
|
||||
len = _connection.read(&dataMask, sizeof(uint32_t));
|
||||
if (len <= 3) {
|
||||
if (len < 0) {
|
||||
ENET_ERROR("Protocol error occured ...");
|
||||
if (_connection.getConnectionStatus() == enet::Tcp::status::link) {
|
||||
ENET_ERROR("Protocol error occured ...");
|
||||
}
|
||||
ENET_VERBOSE("ReadRaw 1 [STOP]");
|
||||
m_interface->stop(true);
|
||||
return;
|
||||
@ -265,8 +298,8 @@ void enet::WebSocket::onReceiveRequest(const enet::HttpRequest& _data) {
|
||||
enet::HttpAnswer answer(enet::HTTPAnswerCode::c101_switchingProtocols);
|
||||
answer.setKey("Upgrade", "websocket");
|
||||
answer.setKey("Connection", "Upgrade");
|
||||
// TODO: Do it better:
|
||||
answer.setKey("Sec-WebSocket-Accept", "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="); //base64::encode());
|
||||
std::string answerKey = generateCheckKey(_data.getKey("Sec-WebSocket-Key"));
|
||||
answer.setKey("Sec-WebSocket-Accept", answerKey);
|
||||
interface->setHeader(answer);
|
||||
}
|
||||
|
||||
@ -292,7 +325,7 @@ void enet::WebSocket::onReceiveAnswer(const enet::HttpAnswer& _data) {
|
||||
return;
|
||||
}
|
||||
// NOTE : This is a temporary magic check ...
|
||||
if (_data.getKey("Sec-WebSocket-Accept") != "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=") {
|
||||
if (_data.getKey("Sec-WebSocket-Accept") != m_checkKey) {
|
||||
ENET_ERROR("Wrong key : 'Sec-WebSocket-Accept : xxx' get '" << _data.getKey("Sec-WebSocket-Accept") << "'");
|
||||
m_interface->stop(true);
|
||||
return;
|
||||
|
@ -15,6 +15,7 @@ namespace enet {
|
||||
protected:
|
||||
ememory::SharedPtr<enet::Http> m_interface;
|
||||
std::vector<uint8_t> m_buffer;
|
||||
std::string m_checkKey;
|
||||
public:
|
||||
WebSocket(enet::Tcp _connection, bool _isServer=false);
|
||||
virtual ~WebSocket();
|
||||
|
@ -26,7 +26,7 @@ def get_version():
|
||||
|
||||
def create(target, module_name):
|
||||
my_module = module.Module(__file__, module_name, get_type())
|
||||
my_module.add_module_depend(['etk', 'ememory'])
|
||||
my_module.add_module_depend(['etk', 'ememory', 'algue'])
|
||||
my_module.add_src_file([
|
||||
'enet/debug.cpp'
|
||||
])
|
||||
|
@ -53,7 +53,7 @@ int main(int _argc, const char *_argv[]) {
|
||||
connection.connect(appl::onReceiveData);
|
||||
|
||||
// start http connection (the actual state is just TCP start ...)
|
||||
connection.start("plop.txt");
|
||||
connection.start("/plop.txt");
|
||||
|
||||
// send some data to play ...
|
||||
connection.write("coucou comment ca vas ???");
|
||||
|
40
test/main-client-websocket.html
Normal file
40
test/main-client-websocket.html
Normal file
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
function WebSocketTest() {
|
||||
if ("WebSocket" in window) {
|
||||
} else {
|
||||
// The browser doesn't support WebSocket
|
||||
alert("WebSocket NOT supported by your Browser!");
|
||||
return;
|
||||
}
|
||||
alert("WebSocket is supported by your Browser!");
|
||||
// Let us open a web socket
|
||||
//var ws = new WebSocket("ws://localhost:1983");
|
||||
var ws = new WebSocket("ws://localhost:12345/plop.txt");
|
||||
ws.onopen = function() {
|
||||
// Web Socket is connected, send data using send()
|
||||
ws.send("Message to send");
|
||||
alert("Message is sent...");
|
||||
};
|
||||
ws.onmessage = function (evt) {
|
||||
var received_msg = evt.data;
|
||||
alert("Message is received...");
|
||||
};
|
||||
ws.onclose = function() {
|
||||
// websocket is closed.
|
||||
alert("Connection is closed...");
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="sse">
|
||||
<a href="javascript:WebSocketTest()">Run WebSocket</a>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -27,7 +27,7 @@ namespace appl {
|
||||
}
|
||||
bool onReceiveUri(enet::WebSocket* _interface, const std::string& _uri) {
|
||||
TEST_INFO("Receive Header uri: " << _uri);
|
||||
if (_uri == "plop.txt") {
|
||||
if (_uri == "/plop.txt") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user