+add utf-8 validation code, not hooked up properly yet

+ws autobahn / Add code to test websocket client compliance with the autobahn test-suite
+Ping received with a payload too large (> 125 bytes) trigger a connection closure
+cobra / add tracking about published messages
+cobra / publish returns a message id, that can be used when
+cobra / new message type in the message received handler when publish/ok is received (can be used to implement an ack system).
This commit is contained in:
Benjamin Sergeant
2019-08-31 16:46:44 -07:00
parent 6b2cdb6b54
commit 10dbe2d44d
16 changed files with 375 additions and 21 deletions

View File

@ -12,6 +12,63 @@
#include <cmath>
#include <cassert>
namespace
{
//
// Stolen from here http://www.zedwood.com/article/cpp-is-valid-utf8-string-function
// There doesn't seem to be anything in the C++ library so far to do that.
// The closest thing is code for converting from utf-8 to utf-16 or utf-32 but
// that isn't working well for some broken input strings.
//
bool isValidUtf8(const std::string& str)
{
size_t i = 0;
size_t ix = str.length();
int c, n, j;
for (; i < ix; i++)
{
c = (unsigned char) str[i];
//if (c==0x09 || c==0x0a || c==0x0d || (0x20 <= c && c <= 0x7e) ) n = 0; // is_printable_ascii
if (0x00 <= c && c <= 0x7f)
{
n = 0; // 0bbbbbbb
}
else if ((c & 0xE0) == 0xC0)
{
n = 1; // 110bbbbb
}
else if ( c==0xed && i<(ix-1) && ((unsigned char)str[i+1] & 0xa0)==0xa0)
{
return false; //U+d800 to U+dfff
}
else if ((c & 0xF0) == 0xE0)
{
n = 2; // 1110bbbb
}
else if ((c & 0xF8) == 0xF0)
{
n = 3; // 11110bbb
}
//else if (($c & 0xFC) == 0xF8) n=4; // 111110bb //byte 5, unnecessary in 4 byte UTF-8
//else if (($c & 0xFE) == 0xFC) n=5; // 1111110b //byte 6, unnecessary in 4 byte UTF-8
else
{
return false;
}
for (j=0; j<n && i<ix; j++)
{ // n bytes matching 10bbbbbb follow ?
if ((++i == ix) || (( (unsigned char)str[i] & 0xC0) != 0x80))
{
return false;
}
}
}
return true;
}
}
namespace ix
{
OnTrafficTrackerCallback WebSocket::_onTrafficTrackerCallback = nullptr;
@ -404,6 +461,11 @@ namespace ix
WebSocketSendInfo WebSocket::sendText(const std::string& text,
const OnProgressCallback& onProgressCallback)
{
if (!isValidUtf8(text))
{
stop();
return false;
}
return sendMessage(text, SendMessageKind::Text, onProgressCallback);
}

View File

@ -590,6 +590,17 @@ namespace ix
std::string pingData(_rxbuf.begin()+ws.header_size,
_rxbuf.begin()+ws.header_size + (size_t) ws.N);
// too large
if (pingData.size() > 125)
{
std::string reason("reason control frame with payload length > 125 octets");
// Unexpected frame type
close(1002,
reason,
reason.size());
return;
}
if (_enablePong)
{
// Reply back right away

View File

@ -6,4 +6,4 @@
#pragma once
#define IX_WEBSOCKET_VERSION "5.0.9"
#define IX_WEBSOCKET_VERSION "5.1.0"