summaryrefslogtreecommitdiff
path: root/includes/BWebSocket.h
diff options
context:
space:
mode:
Diffstat (limited to 'includes/BWebSocket.h')
-rw-r--r--includes/BWebSocket.h62
1 files changed, 62 insertions, 0 deletions
diff --git a/includes/BWebSocket.h b/includes/BWebSocket.h
new file mode 100644
index 0000000..41e5a7d
--- /dev/null
+++ b/includes/BWebSocket.h
@@ -0,0 +1,62 @@
+#pragma once
+
+#include <Task.h>
+#include <StacklessTask.h>
+#include <BStream.h>
+#include <HttpServer.h>
+
+namespace Balau {
+
+class WebSocketActionBase;
+
+class WebSocketWorker : public StacklessTask {
+ public:
+ virtual bool parse(Http::Request & req) { return true; }
+ protected:
+ WebSocketWorker(IO<Handle> socket, const String & url) : m_socket(new BStream(socket)) { m_name = String("WebSocket:") + url + "/" + m_socket->getName(); }
+ ~WebSocketWorker() { free(m_payload); }
+ private:
+ void processMessage();
+ const char * getName() const { return m_name.to_charp(); }
+ void Do();
+ String m_name;
+ IO<BStream> m_socket;
+ enum {
+ READ_H,
+ READ_PLB,
+ READ_PLL,
+ READ_MK,
+ READ_PL,
+ } m_status = READ_H;
+ enum { MAX_WEBSOCKET_LIMIT = 4 * 1024 * 1024 };
+ uint8_t * m_payload = NULL;
+ uint64_t m_payloadLen;
+ uint64_t m_totalLen;
+ uint64_t m_remainingBytes;
+ uint32_t m_mask;
+ uint8_t m_opcode;
+ bool m_hasMask;
+ bool m_fin;
+ bool m_firstFragment = true;
+ bool m_enforceServer = false;
+ bool m_enforceClient = false;
+ friend class WebSocketActionBase;
+};
+
+class WebSocketServerBase : public HttpServer::Action {
+ protected:
+ WebSocketServerBase(const Regex & regex) : Action(regex) { }
+ virtual WebSocketWorker * spawnWorker(IO<Handle> socket, const String & url) = 0;
+ private:
+ void sendError(IO<Handle> out, const char * serverName);
+ bool Do(HttpServer * server, Http::Request & req, HttpServer::Action::ActionMatch & match, IO<Handle> out) throw (GeneralException);
+};
+
+template<class T>
+class WebSocketServer : public WebSocketServerBase {
+ protected:
+ WebSocketServer(const Regex & regex) : WebSocketServerBase(regex) { }
+ virtual WebSocketWorker * spawnWorker(IO<Handle> socket, const String & url) { return new T(socket, url); }
+};
+
+};