From a25e2ab3975f15f3e08704e2f4759f9c9f7f9773 Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Thu, 22 Nov 2018 01:29:28 +0100 Subject: [PATCH] A bit of clean-ups and license fixes --- misc/main.cpp | 65 ++++++++++++++++++++------------------ src/App.h | 50 ++++++++++------------------- src/HttpResponse.h | 3 ++ src/WebSocket.h | 19 ++++++++++- src/WebSocketContext.h | 16 ++++++++++ src/WebSocketContextData.h | 16 ++++++++++ src/WebSocketData.h | 16 ++++++++++ 7 files changed, 120 insertions(+), 65 deletions(-) diff --git a/misc/main.cpp b/misc/main.cpp index 76d7990..ba428e8 100644 --- a/misc/main.cpp +++ b/misc/main.cpp @@ -5,10 +5,13 @@ int main(int argc, char **argv) { - // here we have it + struct PerSocketData { + + }; + uWS::App().get("/hello", [](auto *res, auto *req) { res->end("Hello HTTP!"); - }).ws("/*", { + }).ws("/*", { /*.open = */[](auto *ws, auto *req) { }, @@ -33,47 +36,47 @@ int main(int argc, char **argv) { } }).run(); - return 0; +// return 0; - AsyncFileStreamer *asyncFileStreamer = new AsyncFileStreamer("/home/alexhultman/v0.15/public"); +// AsyncFileStreamer *asyncFileStreamer = new AsyncFileStreamer("/home/alexhultman/v0.15/public"); - uWS::/*SSL*/App(/*{ - .key_file_name = "/home/alexhultman/uWebSockets/misc/ssl/key.pem", - .cert_file_name = "/home/alexhultman/uWebSockets/misc/ssl/cert.pem", - .dh_params_file_name = "/home/alexhultman/dhparams.pem", - .passphrase = "1234" - }*/)/*.get("/*", [](auto *res, auto *req) { +// uWS::/*SSL*/App(/*{ +// .key_file_name = "/home/alexhultman/uWebSockets/misc/ssl/key.pem", +// .cert_file_name = "/home/alexhultman/uWebSockets/misc/ssl/cert.pem", +// .dh_params_file_name = "/home/alexhultman/dhparams.pem", +// .passphrase = "1234" +// }*/)/*.get("/*", [](auto *res, auto *req) { - res->end("GET /WILDCARD"); +// res->end("GET /WILDCARD"); - })*/.get("/:param1/:param2", [](auto *res, auto *req) { +// })*/.get("/:param1/:param2", [](auto *res, auto *req) { - res->write("GET /:param1/:param2 = "); - res->write(req->getParameter(0)); - res->write(" and "); - res->end(req->getParameter(1)); +// res->write("GET /:param1/:param2 = "); +// res->write(req->getParameter(0)); +// res->write(" and "); +// res->end(req->getParameter(1)); - }).post("/hello", [asyncFileStreamer](auto *res, auto *req) { +// }).post("/hello", [asyncFileStreamer](auto *res, auto *req) { - // depending on the file type we want to also add mime! - //asyncFileStreamer->streamFile(res, req->getUrl()); +// // depending on the file type we want to also add mime! +// //asyncFileStreamer->streamFile(res, req->getUrl()); - res->end("POST /hello"); +// res->end("POST /hello"); - }).get("/hello", [](auto *res, auto *req) { +// }).get("/hello", [](auto *res, auto *req) { - res->end("GET /hello"); +// res->end("GET /hello"); - }).unhandled([](auto *res, auto *req) { +// }).unhandled([](auto *res, auto *req) { - res->writeStatus("404 Not Found"); - res->writeHeader("Content-Type", "text/html; charset=utf-8"); - res->end("

404 Not Found

µWebSockets v0.15"); +// res->writeStatus("404 Not Found"); +// res->writeHeader("Content-Type", "text/html; charset=utf-8"); +// res->end("

404 Not Found

µWebSockets v0.15"); - }).listen(3000, [](auto *token) { - if (token) { - std::cout << "Listening on port " << 3000 << std::endl; - } - }).run(); +// }).listen(3000, [](auto *token) { +// if (token) { +// std::cout << "Listening on port " << 3000 << std::endl; +// } +// }).run(); } diff --git a/src/App.h b/src/App.h index 1dc9614..6b1ee90 100644 --- a/src/App.h +++ b/src/App.h @@ -32,10 +32,8 @@ namespace uWS { template struct TemplatedApp { private: + /* The app always owns at least one http context, but creates websocket contexts on demand */ HttpContext *httpContext; - - // the app does not own a websocket context, it is created on .ws(...) calls on demand! - public: ~TemplatedApp() { @@ -48,27 +46,28 @@ public: TemplatedApp(us_ssl_socket_context_options sslOptions = {}) { httpContext = uWS::HttpContext::create(uWS::Loop::defaultLoop(), &sslOptions); - - // construct the websocket cintext? no! on demand! } struct WebSocketBehavior { - std::function open = nullptr; - std::function *, std::string_view, uWS::OpCode)> message = nullptr; + std::function *, HttpRequest *)> open = nullptr; + std::function *, std::string_view, uWS::OpCode)> message = nullptr; }; + template TemplatedApp &ws(std::string pattern, WebSocketBehavior &&behavior) { + /* Every route has its own websocket context with its own behavior and user data type */ + auto *webSocketContext = WebSocketContext::create(Loop::defaultLoop(), (typename StaticDispatch::SOCKET_CONTEXT_TYPE *) httpContext); - // init the websocket context here! - uWS::WebSocketContext *webSocketContext = uWS::WebSocketContext::create(uWS::Loop::defaultLoop(), (typename StaticDispatch::SOCKET_CONTEXT_TYPE *) httpContext); - + /* Copy all handlers */ webSocketContext->getExt()->messageHandler = behavior.message; return get(pattern, [webSocketContext, this, behavior](auto *res, auto *req) { - + /* If we have this header set, it's a websocket */ std::string_view secWebSocketKey = req->getHeader("sec-websocket-key"); if (secWebSocketKey.length()) { + // todo: negotiate extensions such as compression here and pass autobahn fully + // note: OpenSSL can be used here to speed this up somewhat char secWebSocketAccept[29] = {}; WebSocketHandshake::generate(secWebSocketKey.data(), secWebSocketAccept); @@ -79,37 +78,22 @@ public: ->writeHeader("Sec-WebSocket-Accept", secWebSocketAccept) ->end(); - //std::cout << "Adopting" << std::endl; - - // adopting will immediately delete the socket! we cannot rely on reading anything on it - // rely on http context data - - // todo: sizeof websocket + /* Adopting a socket invalidates it, do not rely on it directly to carry any data */ WebSocket *webSocket = (WebSocket *) StaticDispatch::static_dispatch(us_ssl_socket_context_adopt_socket, us_socket_context_adopt_socket)( - (typename StaticDispatch::SOCKET_CONTEXT_TYPE *) webSocketContext, (typename StaticDispatch::SOCKET_TYPE *) res, 150); - - webSocket->init(); - - //std::cout << "adopted" << std::endl; + (typename StaticDispatch::SOCKET_CONTEXT_TYPE *) webSocketContext, (typename StaticDispatch::SOCKET_TYPE *) res, /*sizeof(WebSocketData)*/ 150); httpContext->upgradeToWebSocket( - webSocket + webSocket->init() ); - // we should hand the new socket to the handler - behavior.open(webSocket, req); + if (behavior.open) { + behavior.open(webSocket, req); + } } else { - - std::cout << "This is not a websocket so fuck off!" << std::endl; - - // maybe pass this one to a HTTP handler on the websocket - - // note: this calls the http close handler inline + /* For now we do not support having HTTP and websocket routes on the same URL */ res->close(); } - - }); return *this; diff --git a/src/HttpResponse.h b/src/HttpResponse.h index 6477777..3c2fca2 100644 --- a/src/HttpResponse.h +++ b/src/HttpResponse.h @@ -153,6 +153,9 @@ public: httpContextData->upgradedWebSocket = newSocket; + // I jhave no idea what this does + return true; + /*SOCKET_CONTEXT_TYPE *getSocketContext() { return (SOCKET_CONTEXT_TYPE *) this; diff --git a/src/WebSocket.h b/src/WebSocket.h index b09ab49..36afea0 100644 --- a/src/WebSocket.h +++ b/src/WebSocket.h @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Alex Hultman and contributors. + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + + * http://www.apache.org/licenses/LICENSE-2.0 + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef WEBSOCKET_H #define WEBSOCKET_H @@ -15,8 +31,9 @@ struct WebSocket : AsyncSocket { private: typedef AsyncSocket Super; - void init() { + void *init() { new (us_socket_ext((us_socket *) this)) WebSocketData; + return this; } public: diff --git a/src/WebSocketContext.h b/src/WebSocketContext.h index ed8ad87..2a22f7f 100644 --- a/src/WebSocketContext.h +++ b/src/WebSocketContext.h @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Alex Hultman and contributors. + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + + * http://www.apache.org/licenses/LICENSE-2.0 + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef WEBSOCKETCONTEXT_H #define WEBSOCKETCONTEXT_H diff --git a/src/WebSocketContextData.h b/src/WebSocketContextData.h index 0c3634b..da2ec78 100644 --- a/src/WebSocketContextData.h +++ b/src/WebSocketContextData.h @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Alex Hultman and contributors. + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + + * http://www.apache.org/licenses/LICENSE-2.0 + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef WEBSOCKETCONTEXTDATA_H #define WEBSOCKETCONTEXTDATA_H diff --git a/src/WebSocketData.h b/src/WebSocketData.h index 75f4f7a..2231463 100644 --- a/src/WebSocketData.h +++ b/src/WebSocketData.h @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Alex Hultman and contributors. + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + + * http://www.apache.org/licenses/LICENSE-2.0 + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef WEBSOCKETDATA_H #define WEBSOCKETDATA_H