From 3e769fb841d958926f0cc0d59e20c269cdda7ffa Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Thu, 29 Nov 2018 09:59:03 +0100 Subject: [PATCH] Pass a big portion of Autobahn over SSL --- misc/main.cpp | 11 ++++++++++- src/App.h | 10 ++++++++-- src/WebSocket.h | 14 +++++++++++--- src/WebSocketContext.h | 30 +++++++++++++++++++++++++----- uSockets | 2 +- 5 files changed, 55 insertions(+), 12 deletions(-) diff --git a/misc/main.cpp b/misc/main.cpp index 7b50107..b561b7b 100644 --- a/misc/main.cpp +++ b/misc/main.cpp @@ -9,7 +9,16 @@ int main(int argc, char **argv) { }; - uWS::App().get("/hello", [](auto *res, auto *req) { + /*const char *key_file_name; + const char *cert_file_name; + const char *passphrase; + const char *dh_params_file_name;*/ + + uWS::SSLApp({ + "/home/alexhultman/key.pem", + "/home/alexhultman/cert.pem", + "1234" + }).get("/hello", [](auto *res, auto *req) { res->end("Hello HTTP!"); }).ws("/*", { /*.compression = */true, diff --git a/src/App.h b/src/App.h index 648e054..90f982e 100644 --- a/src/App.h +++ b/src/App.h @@ -31,10 +31,13 @@ namespace uWS { template -struct TemplatedApp { +struct TemplatedApp : StaticDispatch { private: /* The app always owns at least one http context, but creates websocket contexts on demand */ HttpContext *httpContext; + + using SOCKET_TYPE = typename StaticDispatch::SOCKET_TYPE; + using StaticDispatch::static_dispatch; public: ~TemplatedApp() { @@ -62,7 +65,8 @@ public: /* If we are the first one to use compression, initialize it */ if (behavior.compression) { - LoopData *loopData = (LoopData *) us_loop_ext(us_socket_context_loop(webSocketContext->getSocketContext())); + + LoopData *loopData = (LoopData *) us_loop_ext(static_dispatch(us_ssl_socket_context_loop, us_socket_context_loop)(webSocketContext->getSocketContext())); if (!loopData->inflationStream) { loopData->inflationStream = new InflationStream; @@ -121,6 +125,8 @@ public: behavior.open(webSocket, req); } + std::cout << "oh hey!" << std::endl; + } else { /* For now we do not support having HTTP and websocket routes on the same URL */ res->close(); diff --git a/src/WebSocket.h b/src/WebSocket.h index 9802115..264dd4e 100644 --- a/src/WebSocket.h +++ b/src/WebSocket.h @@ -30,9 +30,11 @@ struct WebSocket : AsyncSocket { template friend struct TemplatedApp; private: typedef AsyncSocket Super; + using SOCKET_TYPE = typename StaticDispatch::SOCKET_TYPE; + using StaticDispatch::static_dispatch; void *init(bool perMessageDeflate) { - new (us_socket_ext((us_socket *) this)) WebSocketData(perMessageDeflate); + new (static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this)) WebSocketData(perMessageDeflate); return this; } public: @@ -58,14 +60,20 @@ public: void close(int code, std::string_view message = {}) { // closing should trigger close event! - std::cout << "Closing websocket: " << code << " = " << message << std::endl; + /*if (code == 1001) { + std::cout << "Going away" << std::endl; + } + + std::cout << "Closing websocket: " << code << " = " << message << std::endl;*/ static const int MAX_CLOSE_PAYLOAD = 123; int length = std::min(MAX_CLOSE_PAYLOAD, message.length()); // here we start a timeout and handle it accordingly in the timeout handler - WebSocketData *webSocketData = (WebSocketData *) us_socket_ext((us_socket *) this); + //WebSocketData *webSocketData = (WebSocketData *) us_socket_ext((us_socket *) this); + + WebSocketData *webSocketData = (WebSocketData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this); webSocketData->isShuttingDown = true; diff --git a/src/WebSocketContext.h b/src/WebSocketContext.h index dc2c70f..a6212b9 100644 --- a/src/WebSocketContext.h +++ b/src/WebSocketContext.h @@ -43,12 +43,16 @@ private: } WebSocketContextData *getExt() { - return (WebSocketContextData *) us_socket_context_ext((SOCKET_CONTEXT_TYPE *) this); + return (WebSocketContextData *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)((SOCKET_CONTEXT_TYPE *) this); } /* If we have negotiated compression, set this frame compressed */ static bool setCompressed(uWS::WebSocketState *wState, void *s) { - WebSocketData *webSocketData = (WebSocketData *) us_socket_ext((us_socket *) s); + //WebSocketData *webSocketData = (WebSocketData *) us_socket_ext((us_socket *) s); + + std::cout << "set compressed" << std::endl; + + WebSocketData *webSocketData = (WebSocketData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) s); if (webSocketData->compressionStatus == WebSocketData::CompressionStatus::ENABLED) { webSocketData->compressionStatus = WebSocketData::CompressionStatus::COMPRESSED_FRAME; @@ -65,8 +69,18 @@ private: /* Returns true on breakage */ static bool handleFragment(char *data, size_t length, unsigned int remainingBytes, int opCode, bool fin, uWS::WebSocketState *webSocketState, void *s) { /* WebSocketData and WebSocketContextData */ - WebSocketContextData *webSocketContextData = (WebSocketContextData *) us_socket_context_ext(us_socket_get_context((us_socket *) s)); - WebSocketData *webSocketData = (WebSocketData *) us_socket_ext((us_socket *) s); + //WebSocketContextData *webSocketContextData = (WebSocketContextData *) us_socket_context_ext(us_socket_get_context((us_socket *) s)); + //WebSocketData *webSocketData = (WebSocketData *) us_socket_ext((us_socket *) s); + + WebSocketContextData *webSocketContextData = (WebSocketContextData *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)( + + static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *) s) + + ); + + WebSocketData *webSocketData = (WebSocketData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) s); + + //std::cout << "ho" << std::endl; /* Is this a non-control frame? */ if (opCode < 3) { @@ -212,6 +226,9 @@ private: // bug: todo static bool refusePayloadLength(uint64_t length, uWS::WebSocketState *wState) { + + std::cout << "refuse payload length" << std::endl; + /* We check if we want to accept such a frame based on size */ // for now, accept anything return false; @@ -230,12 +247,15 @@ private: /* Handle WebSocket data streams */ static_dispatch(us_ssl_socket_context_on_data, us_socket_context_on_data)(getSocketContext(), [](auto *s, char *data, int length) { + + std::cout << "websocket data" << std::endl; + /* We always cork on data */ AsyncSocket *webSocket = (AsyncSocket *) s; webSocket->cork(); /* We need the websocket data */ - WebSocketData *wsState = (WebSocketData *) us_socket_ext(s); + WebSocketData *wsState = (WebSocketData *) (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s)); // this parser requires almost no time -> 215k req/sec of 215k possible uWS::WebSocketProtocol>::consume(data, length, wsState, s); diff --git a/uSockets b/uSockets index 4a20739..790a95f 160000 --- a/uSockets +++ b/uSockets @@ -1 +1 @@ -Subproject commit 4a20739ca5d4124f0197031348cc91eaa4611fb7 +Subproject commit 790a95fba44bc25645c900569dc119c4f862606d