[Libreoffice-commits] online.git: Branch 'private/Ashod/nonblocking' - net/loolnb.cpp
Michael Meeks
michael.meeks at collabora.com
Thu Feb 16 18:50:10 UTC 2017
net/loolnb.cpp | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 94 insertions(+), 5 deletions(-)
New commits:
commit b9d1721e46950bbfb960e9d975d616705265b293
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Thu Feb 16 18:49:31 2017 +0000
WS - basic handshake / upgrade and start of read framing.
diff --git a/net/loolnb.cpp b/net/loolnb.cpp
index 636a4d9..fe027fa 100644
--- a/net/loolnb.cpp
+++ b/net/loolnb.cpp
@@ -32,22 +32,25 @@ using Poco::StringTokenizer;
constexpr int PortNumber = 9191;
+static std::string computeAccept(const std::string &key);
+
class SimpleResponseClient : public ClientSocket
{
int _wsVersion;
std::string _wsKey;
std::string _wsProtocol;
+ std::vector<char> _wsPayload;
+ enum { HTTP, WEBSOCKET } _wsState;
public:
SimpleResponseClient(const int fd) :
ClientSocket(fd),
- _wsVersion(0)
+ _wsVersion(0),
+ _wsState(HTTP)
{
}
- virtual void handleIncomingMessage() override
+ virtual void handleHTTP()
{
- std::cerr << "message had size " << _inBuffer.size() << "\n";
-
int number = 0;
MemoryInputStream message(&_inBuffer[0], _inBuffer.size());
Poco::Net::HTTPRequest req;
@@ -57,6 +60,7 @@ public:
size_t consumed = std::min(_inBuffer.size(),
std::max((size_t)message.tellg(), size_t(0)));
_inBuffer.erase(_inBuffer.begin(), _inBuffer.begin() + consumed);
+ std::cerr << "_inBuffer has " << _inBuffer.size() << " remaining\n";
StringTokenizer tokens(req.getURI(), "/?");
if (tokens.count() == 4)
@@ -93,14 +97,79 @@ public:
oss << "HTTP/1.1 101 Switching Protocols\r\n"
<< "Upgrade: websocket\r\n"
<< "Connection: Upgrade\r\n"
- << "Sec-Websocket-Accept: " << _wsKey << "\r\n"
+ << "Sec-Websocket-Accept: " << computeAccept(_wsKey) << "\r\n"
<< "\r\n";
std::string str = oss.str();
_outBuffer.insert(_outBuffer.end(), str.begin(), str.end());
+ _wsState = WEBSOCKET;
}
else
std::cerr << " unknown tokens " << tokens.count() << std::endl;
}
+
+ enum WSOpCode {
+ Continuation, // 0x0
+ Text, // 0x1
+ Binary, // 0x2
+ Reserved1, // 0x3
+ Reserved2, // 0x4
+ Reserved3, // 0x5
+ Reserved4, // 0x6
+ Reserved5, // 0x7
+ Close, // 0x8
+ Ping, // 0x9
+ Pong // 0xa
+ // ... reserved
+ };
+
+ virtual void handleIncomingMessage() override
+ {
+ std::cerr << "incoming message with buffer size " << _inBuffer.size() << "\n";
+ if (_wsState == HTTP)
+ {
+ handleHTTP();
+ return;
+ }
+
+ // websocket fun !
+ size_t len = _inBuffer.size();
+ const char *p = &_inBuffer[0];
+ if (len < 2) // partial read
+ return;
+
+ bool fin = *p & 0x80;
+ WSOpCode code = static_cast<WSOpCode>(*p & 0x0f);
+ p++;
+ bool mask = *p & 0x80;
+ size_t payloadLen = *p & 0x7f;
+ p++;
+
+ if (payloadLen == 126) // 2 byte length
+ {
+ if (len < 2 + 2)
+ return;
+ std::cerr << "Implement me 2 byte\n";
+ }
+ else if (payloadLen == 127) // 8 byte length
+ {
+ if (len < 2 + 8)
+ return;
+ std::cerr << "Implement me 8 byte\n";
+ }
+ else
+ {
+ _wsPayload.insert(_wsPayload.end(), p, p + std::min(payloadLen, len));
+ }
+ // FIXME: fin, aggregating payloads into _wsPayload etc.
+ handleWSMessage(fin, code, mask, _wsPayload);
+ _wsPayload.clear();
+ }
+
+ virtual void handleWSMessage( bool fin, WSOpCode code, bool mask, std::vector<char> &data)
+ {
+ std::cerr << "Message: fin? " << fin << " code " << code << " mask? " << mask << " data size " << data.size() << "\n";
+ }
+
};
// FIXME: use Poco Thread instead (?)
@@ -260,4 +329,24 @@ int main(int, const char**)
return 0;
}
+// Saves writing this ourselves:
+
+#include <Poco/Net/WebSocket.h>
+
+namespace {
+#include <Poco/Net/WebSocket.h>
+ struct Puncture : private Poco::Net::WebSocket {
+ static std::string doComputeAccept(const std::string &key)
+ {
+ return computeAccept(key);
+ }
+ };
+}
+
+static std::string computeAccept(const std::string &key)
+{
+ return Puncture::doComputeAccept(key);
+}
+
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list