diff --git a/examples/HttpServer.cpp b/examples/HttpServer.cpp index 0dff880..c956fe4 100644 --- a/examples/HttpServer.cpp +++ b/examples/HttpServer.cpp @@ -28,7 +28,7 @@ int main(int argc, char **argv) { }; int port = 3000; - struct us_ssl_socket_context_options ssl_options = {}; + struct us_new_socket_context_options_t ssl_options = {}; while ((option = optparse_long(&options, longopts, nullptr)) != -1) { switch (option) { @@ -63,7 +63,7 @@ int main(int argc, char **argv) { AsyncFileStreamer asyncFileStreamer(root); /* Either serve over HTTP or HTTPS */ - struct us_ssl_socket_context_options empty_ssl_options = {}; + struct us_new_socket_context_options_t empty_ssl_options = {}; if (memcmp(&ssl_options, &empty_ssl_options, sizeof(empty_ssl_options))) { /* HTTPS */ uWS::SSLApp(ssl_options).get("/*", [&asyncFileStreamer](auto *res, auto *req) { diff --git a/misc/15.pro b/misc/15.pro index 46e4f6f..86073b0 100644 --- a/misc/15.pro +++ b/misc/15.pro @@ -21,7 +21,6 @@ HEADERS += \ ../src/HttpContextData.h \ ../src/HttpResponseData.h \ ../src/HttpResponse.h \ - ../src/StaticDispatch.h \ ../src/LoopData.h \ ../src/AsyncSocket.h \ ../src/AsyncSocketData.h \ diff --git a/src/App.h b/src/App.h index 717c9ae..efb78e5 100644 --- a/src/App.h +++ b/src/App.h @@ -42,14 +42,12 @@ enum CompressOptions { }; template -struct TemplatedApp : StaticDispatch { +struct TemplatedApp { private: /* The app always owns at least one http context, but creates websocket contexts on demand */ HttpContext *httpContext; std::vector *> webSocketContexts; - using SOCKET_TYPE = typename StaticDispatch::SOCKET_TYPE; - using StaticDispatch::static_dispatch; public: /* Attaches a "filter" function to track socket connections/disconnections */ @@ -84,8 +82,8 @@ public: webSocketContexts = std::move(other.webSocketContexts); } - TemplatedApp(us_ssl_socket_context_options sslOptions = {}) { - httpContext = uWS::HttpContext::create(uWS::Loop::defaultLoop(), &sslOptions); + TemplatedApp(us_new_socket_context_options_t options = {}) { + httpContext = uWS::HttpContext::create(uWS::Loop::defaultLoop(), options); } struct WebSocketBehavior { @@ -103,7 +101,7 @@ public: 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); + auto *webSocketContext = WebSocketContext::create(Loop::defaultLoop(), (us_new_socket_context_t *) httpContext); /* We need to clear this later on */ webSocketContexts.push_back(webSocketContext); @@ -115,7 +113,7 @@ public: /* If we are the first one to use compression, initialize it */ if (behavior.compression) { - LoopData *loopData = (LoopData *) us_loop_ext(static_dispatch(us_ssl_socket_context_loop, us_socket_context_loop)(webSocketContext->getSocketContext())); + LoopData *loopData = (LoopData *) us_loop_ext(us_new_socket_context_loop(SSL, webSocketContext->getSocketContext())); /* Initialize loop's deflate inflate streams */ if (!loopData->zlibContext) { @@ -191,8 +189,8 @@ public: res->getHttpResponseData()->~HttpResponseData(); /* 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, sizeof(WebSocketData) + sizeof(UserData)); + WebSocket *webSocket = (WebSocket *) us_new_socket_context_adopt_socket(SSL, + (us_new_socket_context_t *) webSocketContext, (us_new_socket_t *) res, sizeof(WebSocketData) + sizeof(UserData)); /* Update corked socket in case we got a new one (assuming we always are corked in handlers). */ webSocket->cork(); @@ -204,7 +202,7 @@ public: /* Emit open event and start the timeout */ if (behavior.open) { - static_dispatch(us_ssl_socket_timeout, us_socket_timeout)((SOCKET_TYPE *) webSocket, behavior.idleTimeout); + us_new_socket_timeout(SSL, (us_new_socket_t *) webSocket, behavior.idleTimeout); behavior.open(webSocket, req); } diff --git a/src/AsyncSocket.h b/src/AsyncSocket.h index 8178636..0b93f04 100644 --- a/src/AsyncSocket.h +++ b/src/AsyncSocket.h @@ -20,46 +20,44 @@ /* This class implements async socket memory management strategies */ -#include "StaticDispatch.h" + #include "LoopData.h" #include "AsyncSocketData.h" namespace uWS { template -struct AsyncSocket : StaticDispatch { +struct AsyncSocket { template friend struct HttpContext; template friend struct WebSocketContext; protected: - using SOCKET_TYPE = typename StaticDispatch::SOCKET_TYPE; - using StaticDispatch::static_dispatch; /* Get loop data for socket */ LoopData *getLoopData() { return (LoopData *) us_loop_ext( - static_dispatch(us_ssl_socket_context_loop, us_socket_context_loop)( - static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *) this)) + us_new_socket_context_loop(SSL, + us_new_socket_context(SSL, (us_new_socket_t *) this)) ); } /* Get socket extension */ void *getExt() { - return static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this); + return us_new_socket_ext(SSL, (us_new_socket_t *) this); } /* Socket timeout */ void timeout(unsigned int seconds) { - static_dispatch(us_ssl_socket_timeout, us_socket_timeout)((SOCKET_TYPE *) this, seconds); + us_new_socket_timeout(SSL, (us_new_socket_t *) this, seconds); } /* Shutdown socket without any automatic drainage */ void shutdown() { - static_dispatch(us_ssl_socket_shutdown, us_socket_shutdown)((SOCKET_TYPE *) this); + us_new_socket_shutdown(SSL, (us_new_socket_t *) this); } /* Immediately close socket */ - SOCKET_TYPE *close() { - return static_dispatch(us_ssl_socket_close, us_socket_close)((SOCKET_TYPE *) this); + us_new_socket_t *close() { + return us_new_socket_close(SSL, (us_new_socket_t *) this); } /* Cork this socket. Only one socket may ever be corked per-loop at any given time */ @@ -103,7 +101,7 @@ protected: * writable (or we are in a state that implies polling for writable). */ std::pair write(const char *src, int length, bool optionally = false, int nextLength = 0) { /* Fake success if closed, simpel fix to allow uncork of closed socket to succeed */ - if (us_socket_is_closed((us_socket *) this)) { + if (us_new_socket_is_closed(SSL, (us_new_socket_t *) this)) { std::cout << "Faking successful send due to closed socket!" << std::endl; return {length, false}; } @@ -114,7 +112,7 @@ protected: /* We are limited if we have a per-socket buffer */ if (asyncSocketData->buffer.length()) { /* Write off as much as we can */ - int written = static_dispatch(us_ssl_socket_write, us_socket_write)((SOCKET_TYPE *) this, asyncSocketData->buffer.data(), asyncSocketData->buffer.length(), /*nextLength != 0 | */length); + int written = us_new_socket_write(SSL, (us_new_socket_t *) this, asyncSocketData->buffer.data(), asyncSocketData->buffer.length(), /*nextLength != 0 | */length); /* On failure return, otherwise continue down the function */ if (written < asyncSocketData->buffer.length()) { @@ -165,7 +163,7 @@ protected: } } else { /* We are not corked */ - int written = static_dispatch(us_ssl_socket_write, us_socket_write)((SOCKET_TYPE *) this, src, length, nextLength != 0); + int written = us_new_socket_write(SSL, (us_new_socket_t *) this, src, length, nextLength != 0); /* Did we fail? */ if (written < length) { diff --git a/src/HttpContext.h b/src/HttpContext.h index e1c2dbe..e4c73f0 100644 --- a/src/HttpContext.h +++ b/src/HttpContext.h @@ -25,7 +25,6 @@ #include "HttpResponseData.h" #include "AsyncSocket.h" -#include "StaticDispatch.h" #include #include @@ -36,41 +35,38 @@ namespace uWS { template struct HttpResponse; template -struct HttpContext : StaticDispatch { +struct HttpContext { private: - using SOCKET_CONTEXT_TYPE = typename StaticDispatch::SOCKET_CONTEXT_TYPE; - using SOCKET_TYPE = typename StaticDispatch::SOCKET_TYPE; - using StaticDispatch::static_dispatch; HttpContext() = delete; /* Maximum delay allowed until an HTTP connection is terminated due to outstanding request or rejected data (slow loris protection) */ static const int HTTP_IDLE_TIMEOUT_S = 10; - SOCKET_CONTEXT_TYPE *getSocketContext() { - return (SOCKET_CONTEXT_TYPE *) this; + us_new_socket_context_t *getSocketContext() { + return (us_new_socket_context_t *) this; } - static SOCKET_CONTEXT_TYPE *getSocketContext(SOCKET_TYPE *s) { - return (SOCKET_CONTEXT_TYPE *) static_dispatch(us_ssl_socket_get_context, us_socket_get_context)(s); + static us_new_socket_context_t *getSocketContext(us_new_socket_t *s) { + return (us_new_socket_context_t *) us_new_socket_context(SSL, s); } HttpContextData *getSocketContextData() { - return (HttpContextData *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(getSocketContext()); + return (HttpContextData *) us_new_socket_context_ext(SSL, getSocketContext()); } - static HttpContextData *getSocketContextDataS(SOCKET_TYPE *s) { - return (HttpContextData *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(getSocketContext(s)); + static HttpContextData *getSocketContextDataS(us_new_socket_t *s) { + return (HttpContextData *) us_new_socket_context_ext(SSL, getSocketContext(s)); } /* Init the HttpContext by registering libusockets event handlers */ HttpContext *init() { /* Handle socket connections */ - static_dispatch(us_ssl_socket_context_on_open, us_socket_context_on_open)(getSocketContext(), [](auto *s, int is_client) { + us_new_socket_context_on_open(SSL, getSocketContext(), [](auto *s, int is_client) { /* Any connected socket should timeout until it has a request */ - static_dispatch(us_ssl_socket_timeout, us_socket_timeout)(s, HTTP_IDLE_TIMEOUT_S); + us_new_socket_timeout(SSL, s, HTTP_IDLE_TIMEOUT_S); /* Init socket ext */ - new (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s)) HttpResponseData; + new (us_new_socket_ext(SSL, s)) HttpResponseData; /* Call filter */ HttpContextData *httpContextData = getSocketContextDataS(s); @@ -82,9 +78,9 @@ private: }); /* Handle socket disconnections */ - static_dispatch(us_ssl_socket_context_on_close, us_socket_context_on_close)(getSocketContext(), [](auto *s) { + us_new_socket_context_on_close(SSL, getSocketContext(), [](auto *s) { /* Get socket ext */ - HttpResponseData *httpResponseData = (HttpResponseData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)(s); + HttpResponseData *httpResponseData = (HttpResponseData *) us_new_socket_ext(SSL, s); /* Call filter */ HttpContextData *httpContextData = getSocketContextDataS(s); @@ -104,7 +100,7 @@ private: }); /* Handle HTTP data streams */ - static_dispatch(us_ssl_socket_context_on_data, us_socket_context_on_data)(getSocketContext(), [](auto *s, char *data, int length) { + us_new_socket_context_on_data(SSL, getSocketContext(), [](auto *s, char *data, int length) { // total overhead is about 210k down to 180k // ~210k req/sec is the original perf with write in data @@ -115,11 +111,11 @@ private: HttpContextData *httpContextData = getSocketContextDataS(s); /* Do not accept any data while in shutdown state */ - if (static_dispatch(us_ssl_socket_is_shut_down, us_socket_is_shut_down)((SOCKET_TYPE *) s)) { + if (us_new_socket_is_shut_down(SSL, (us_new_socket_t *) s)) { return s; } - HttpResponseData *httpResponseData = (HttpResponseData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)(s); + HttpResponseData *httpResponseData = (HttpResponseData *) us_new_socket_ext(SSL, s); /* Cork this socket */ ((AsyncSocket *) s)->cork(); @@ -129,16 +125,16 @@ private: void *returnedSocket = httpResponseData->consumePostPadded(data, length, s, [httpContextData](void *s, uWS::HttpRequest *httpRequest) -> void * { /* For every request we reset the timeout and hang until user makes action */ /* Warning: if we are in shutdown state, resetting the timer is a security issue! */ - static_dispatch(us_ssl_socket_timeout, us_socket_timeout)((SOCKET_TYPE *) s, 0); + us_new_socket_timeout(SSL, (us_new_socket_t *) s, 0); /* Reset httpResponse */ - HttpResponseData *httpResponseData = (HttpResponseData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) s); + HttpResponseData *httpResponseData = (HttpResponseData *) us_new_socket_ext(SSL, (us_new_socket_t *) s); httpResponseData->offset = 0; httpResponseData->state = 0; /* Are we not ready for another request yet? Terminate the connection. */ if (httpResponseData->state & HttpResponseData::HTTP_RESPONSE_PENDING) { - static_dispatch(us_ssl_socket_close, us_socket_close)((SOCKET_TYPE *) s); + us_new_socket_close(SSL, (us_new_socket_t *) s); return nullptr; } @@ -151,7 +147,7 @@ private: /* If first pass failed, we try and match by "any" method */ if (!httpContextData->router.route("*", httpRequest->getUrl(), routerData)) { /* If second pass fail, we have to force close this socket as we have no handler for it */ - static_dispatch(us_ssl_socket_close, us_socket_close)((SOCKET_TYPE *) s); + us_new_socket_close(SSL, (us_new_socket_t *) s); return nullptr; } } @@ -165,12 +161,12 @@ private: } /* Was the socket closed? */ - if (us_socket_is_closed((struct us_socket *) s)) { + if (us_new_socket_is_closed(SSL, (struct us_new_socket_t *) s)) { return nullptr; } /* We absolutely have to terminate parsing if shutdown */ - if (static_dispatch(us_ssl_socket_is_shut_down, us_socket_is_shut_down)((SOCKET_TYPE *) s)) { + if (us_new_socket_is_shut_down(SSL, (us_new_socket_t *) s)) { return nullptr; } @@ -189,19 +185,19 @@ private: httpResponseData->inStream(data, fin); /* Was the socket closed? */ - if (us_socket_is_closed((struct us_socket *) user)) { + if (us_new_socket_is_closed(SSL, (struct us_new_socket_t *) user)) { return nullptr; } /* We absolutely have to terminate parsing if shutdown */ - if (static_dispatch(us_ssl_socket_is_shut_down, us_socket_is_shut_down)((SOCKET_TYPE *) user)) { + if (us_new_socket_is_shut_down(SSL, (us_new_socket_t *) user)) { return nullptr; } } return user; }, [](void *user) { /* Close any socket on HTTP errors */ - static_dispatch(us_ssl_socket_close, us_socket_close)((SOCKET_TYPE *) user); + us_new_socket_close(SSL, (us_new_socket_t *) user); return nullptr; }); @@ -214,7 +210,7 @@ private: ((AsyncSocket *) s)->timeout(HTTP_IDLE_TIMEOUT_S); } - return (SOCKET_TYPE *) returnedSocket; + return (us_new_socket_t *) returnedSocket; } /* We cannot return nullptr to the underlying stack in any case */ @@ -222,10 +218,10 @@ private: }); /* Handle HTTP write out (note: SSL_read may trigger this spuriously, the app need to handle spurious calls) */ - static_dispatch(us_ssl_socket_context_on_writable, us_socket_context_on_writable)(getSocketContext(), [](auto *s) { + us_new_socket_context_on_writable(SSL, getSocketContext(), [](auto *s) { /* We are now writable, so hang timeout again */ - static_dispatch(us_ssl_socket_timeout, us_socket_timeout)(s, 0); + us_new_socket_timeout(SSL, s, 0); AsyncSocket *asyncSocket = (AsyncSocket *) s; HttpResponseData *httpResponseData = (HttpResponseData *) asyncSocket->getExt(); @@ -253,7 +249,7 @@ private: }); /* Handle FIN, HTTP does not support half-closed sockets, so simply close */ - static_dispatch(us_ssl_socket_context_on_end, us_socket_context_on_end)(getSocketContext(), [](auto *s) { + us_new_socket_context_on_end(SSL, getSocketContext(), [](auto *s) { /* We do not care for half closed sockets */ AsyncSocket *asyncSocket = (AsyncSocket *) s; @@ -262,7 +258,7 @@ private: }); /* Handle socket timeouts, simply close them so to not confuse client with FIN */ - static_dispatch(us_ssl_socket_context_on_timeout, us_socket_context_on_timeout)(getSocketContext(), [](auto *s) { + us_new_socket_context_on_timeout(SSL, getSocketContext(), [](auto *s) { /* Force close rather than gracefully shutdown and risk confusing the client with a complete download */ AsyncSocket *asyncSocket = (AsyncSocket *) s; @@ -275,21 +271,17 @@ private: public: /* Construct a new HttpContext using specified loop */ - static HttpContext *create(Loop *loop, us_ssl_socket_context_options *ssl_options = nullptr) { + static HttpContext *create(Loop *loop, us_new_socket_context_options_t options = {}) { HttpContext *httpContext; - if constexpr(SSL) { - httpContext = (HttpContext *) us_create_ssl_socket_context((us_loop *) loop, sizeof(HttpContextData), *ssl_options); - } else { - httpContext = (HttpContext *) us_create_socket_context((us_loop *) loop, sizeof(HttpContextData)); - } + httpContext = (HttpContext *) us_new_create_socket_context(SSL, (us_loop *) loop, sizeof(HttpContextData), options); if (!httpContext) { return nullptr; } /* Init socket context data */ - new ((HttpContextData *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)((SOCKET_CONTEXT_TYPE *) httpContext)) HttpContextData(); + new ((HttpContextData *) us_new_socket_context_ext(SSL, (us_new_socket_context_t *) httpContext)) HttpContextData(); return httpContext->init(); } @@ -300,7 +292,7 @@ public: httpContextData->~HttpContextData(); /* Free the socket context in whole */ - static_dispatch(us_ssl_socket_context_free, us_socket_context_free)(getSocketContext()); + us_new_socket_context_free(SSL, getSocketContext()); } void filter(fu2::unique_function *, int)> &&filterHandler) { @@ -333,7 +325,7 @@ public: /* Listen to port using this HttpContext */ us_listen_socket *listen(const char *host, int port, int options) { - return static_dispatch(us_ssl_socket_context_listen, us_socket_context_listen)(getSocketContext(), host, port, options, sizeof(HttpResponseData)); + return us_new_socket_context_listen(SSL, getSocketContext(), host, port, options, sizeof(HttpResponseData)); } }; diff --git a/src/Loop.h b/src/Loop.h index 71d55d8..13b951e 100644 --- a/src/Loop.h +++ b/src/Loop.h @@ -22,7 +22,7 @@ #include "LoopData.h" -#include +#include diff --git a/src/StaticDispatch.h b/src/StaticDispatch.h deleted file mode 100644 index 69c197c..0000000 --- a/src/StaticDispatch.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Authored by Alex Hultman, 2018-2019. - * Intellectual property of third-party. - - * 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 STATICDISPATCH_H -#define STATICDISPATCH_H - -/* This headers is basically a statically dispatched libusockets wrapper base */ - -#include -#include - -/* For now we just define all these as nonsense if using a non-SSL version of uSockets */ -#ifdef LIBUS_NO_SSL -#define us_ssl_socket_context_options int -#define us_ssl_socket_context_ext us_socket_context_ext -#define us_ssl_socket_context_on_open us_socket_context_on_open -#define us_ssl_socket_timeout us_socket_timeout -#define us_ssl_socket_ext us_socket_ext -#define us_ssl_socket_context_on_close us_socket_context_on_close -#define us_ssl_socket_context_on_data us_socket_context_on_data -#define us_ssl_socket_context_on_writable us_socket_context_on_writable -#define us_ssl_socket_context_on_end us_socket_context_on_end -#define us_ssl_socket_context_on_timeout us_socket_context_on_timeout -#define us_ssl_socket_is_shut_down us_socket_is_shut_down -#define us_ssl_socket_close us_socket_close -#define us_ssl_socket_write us_socket_write -#define us_ssl_socket_context_loop us_socket_context_loop -#define us_ssl_socket_get_context us_socket_get_context -#define us_ssl_socket_context_listen us_socket_context_listen -#define us_ssl_socket_context_adopt_socket us_socket_context_adopt_socket -#define us_create_child_ssl_socket_context us_create_child_socket_context -#define us_ssl_socket_shutdown us_socket_shutdown -#define us_ssl_socket_context_free us_socket_context_free -/* This is the only differing function - time to fix! */ -#define us_create_ssl_socket_context(l, e, o) us_create_socket_context(l, e) -#endif - -namespace uWS { - -template -struct StaticDispatch { - template - static constexpr typename std::conditional::type *static_dispatch(A *a, B *b) { - if constexpr(SSL) { - return a; - } else { - return b; - } - } - - typedef typename std::conditional::type SOCKET_TYPE; - typedef typename std::conditional::type SOCKET_CONTEXT_TYPE; -}; - -} - -#endif // STATICDISPATCH_H diff --git a/src/WebSocket.h b/src/WebSocket.h index 2378788..e1f1a99 100644 --- a/src/WebSocket.h +++ b/src/WebSocket.h @@ -31,19 +31,16 @@ struct WebSocket : AsyncSocket { template friend struct TemplatedApp; private: typedef AsyncSocket Super; - using SOCKET_TYPE = typename StaticDispatch::SOCKET_TYPE; - using SOCKET_CONTEXT_TYPE = typename StaticDispatch::SOCKET_CONTEXT_TYPE; - using StaticDispatch::static_dispatch; void *init(bool perMessageDeflate, bool slidingCompression, std::string &&backpressure) { - new (static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this)) WebSocketData(perMessageDeflate, slidingCompression, std::move(backpressure)); + new (us_new_socket_ext(SSL, (us_new_socket_t *) this)) WebSocketData(perMessageDeflate, slidingCompression, std::move(backpressure)); return this; } public: /* Returns pointer to the per socket user data */ void *getUserData() { - WebSocketData *webSocketData = (WebSocketData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this); + WebSocketData *webSocketData = (WebSocketData *) us_new_socket_ext(SSL, (us_new_socket_t *) this); /* We just have it overallocated by sizeof type */ return (webSocketData + 1); } @@ -92,7 +89,7 @@ public: /* Send websocket close frame, emit close event, send FIN if successful */ void close(int code, std::string_view message = {}) { /* Check if we already called this one */ - WebSocketData *webSocketData = (WebSocketData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this); + WebSocketData *webSocketData = (WebSocketData *) us_new_socket_ext(SSL, (us_new_socket_t *) this); if (webSocketData->isShuttingDown) { return; } @@ -118,8 +115,8 @@ public: } /* Emit close event */ - WebSocketContextData *webSocketContextData = (WebSocketContextData *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)( - (SOCKET_CONTEXT_TYPE *) static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *) this) + WebSocketContextData *webSocketContextData = (WebSocketContextData *) us_new_socket_context_ext(SSL, + (us_new_socket_context_t *) us_new_socket_context(SSL, (us_new_socket_t *) this) ); if (webSocketContextData->closeHandler) { webSocketContextData->closeHandler(this, code, message); diff --git a/src/WebSocketContext.h b/src/WebSocketContext.h index 7b5b117..151f50f 100644 --- a/src/WebSocketContext.h +++ b/src/WebSocketContext.h @@ -18,7 +18,6 @@ #ifndef WEBSOCKETCONTEXT_H #define WEBSOCKETCONTEXT_H -#include "StaticDispatch.h" #include "WebSocketContextData.h" #include "WebSocketProtocol.h" #include "WebSocketData.h" @@ -27,26 +26,23 @@ namespace uWS { template -struct WebSocketContext : StaticDispatch { +struct WebSocketContext { template friend struct TemplatedApp; template friend class WebSocketProtocol; private: - using SOCKET_CONTEXT_TYPE = typename StaticDispatch::SOCKET_CONTEXT_TYPE; - using SOCKET_TYPE = typename StaticDispatch::SOCKET_TYPE; - using StaticDispatch::static_dispatch; WebSocketContext() = delete; - SOCKET_CONTEXT_TYPE *getSocketContext() { - return (SOCKET_CONTEXT_TYPE *) this; + us_new_socket_context_t *getSocketContext() { + return (us_new_socket_context_t *) this; } WebSocketContextData *getExt() { - return (WebSocketContextData *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)((SOCKET_CONTEXT_TYPE *) this); + return (WebSocketContextData *) us_new_socket_context_ext(SSL, (us_new_socket_context_t *) this); } /* If we have negotiated compression, set this frame compressed */ static bool setCompressed(uWS::WebSocketState *wState, void *s) { - WebSocketData *webSocketData = (WebSocketData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) s); + WebSocketData *webSocketData = (WebSocketData *) us_new_socket_ext(SSL, (us_new_socket_t *) s); if (webSocketData->compressionStatus == WebSocketData::CompressionStatus::ENABLED) { webSocketData->compressionStatus = WebSocketData::CompressionStatus::COMPRESSED_FRAME; @@ -57,16 +53,16 @@ private: } static void forceClose(uWS::WebSocketState *wState, void *s) { - us_socket_close((us_socket *) s); + us_new_socket_close(SSL, (us_new_socket_t *) s); } /* 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 *) 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) + WebSocketContextData *webSocketContextData = (WebSocketContextData *) us_new_socket_context_ext(SSL, + us_new_socket_context(SSL, (us_new_socket_t *) s) ); - WebSocketData *webSocketData = (WebSocketData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) s); + WebSocketData *webSocketData = (WebSocketData *) us_new_socket_ext(SSL, (us_new_socket_t *) s); /* Is this a non-control frame? */ if (opCode < 3) { @@ -78,8 +74,8 @@ private: webSocketData->compressionStatus = WebSocketData::CompressionStatus::ENABLED; LoopData *loopData = (LoopData *)us_loop_ext( - static_dispatch(us_ssl_socket_context_loop, us_socket_context_loop)( - static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *)s) + us_new_socket_context_loop(SSL, + us_new_socket_context(SSL, (us_new_socket_t *)s) ) ); @@ -102,7 +98,7 @@ private: /* Emit message event & break if we are closed or shut down when returning */ if (webSocketContextData->messageHandler) { webSocketContextData->messageHandler((WebSocket *) s, std::string_view(data, length), (uWS::OpCode) opCode); - if (us_socket_is_closed((us_socket *)s) || webSocketData->isShuttingDown) { + if (us_new_socket_is_closed(SSL, (us_new_socket_t *)s) || webSocketData->isShuttingDown) { return true; } } @@ -125,8 +121,8 @@ private: webSocketData->fragmentBuffer.append("...."); LoopData *loopData = (LoopData *) us_loop_ext( - static_dispatch(us_ssl_socket_context_loop, us_socket_context_loop)( - static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *) s) + us_new_socket_context_loop(SSL, + us_new_socket_context(SSL, (us_new_socket_t *) s) ) ); @@ -155,7 +151,7 @@ private: /* Emit message and check for shutdown or close */ if (webSocketContextData->messageHandler) { webSocketContextData->messageHandler((WebSocket *) s, std::string_view(data, length), (uWS::OpCode) opCode); - if (us_socket_is_closed((us_socket *)s) || webSocketData->isShuttingDown) { + if (us_new_socket_is_closed(SSL, (us_new_socket_t *)s) || webSocketData->isShuttingDown) { return true; } } @@ -223,8 +219,8 @@ private: } static bool refusePayloadLength(uint64_t length, uWS::WebSocketState *wState, void *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) + WebSocketContextData *webSocketContextData = (WebSocketContextData *) us_new_socket_context_ext(SSL, + us_new_socket_context(SSL, (us_new_socket_t *)s) ); /* Return true for refuse, false for accept */ @@ -237,14 +233,14 @@ private: * any backpressure from HTTP state kept. */ /* Handle socket disconnections */ - static_dispatch(us_ssl_socket_context_on_close, us_socket_context_on_close)(getSocketContext(), [](auto *s) { + us_new_socket_context_on_close(SSL, getSocketContext(), [](auto *s) { /* For whatever reason, if we already have emitted close event, do not emit it again */ - WebSocketData *webSocketData = (WebSocketData *) (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s)); + WebSocketData *webSocketData = (WebSocketData *) (us_new_socket_ext(SSL, s)); if (!webSocketData->isShuttingDown) { /* Emit close event */ - 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) + WebSocketContextData *webSocketContextData = (WebSocketContextData *) us_new_socket_context_ext(SSL, + us_new_socket_context(SSL, (us_new_socket_t *)s) ); if (webSocketContextData->closeHandler) { @@ -259,18 +255,18 @@ 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) { + us_new_socket_context_on_data(SSL, getSocketContext(), [](auto *s, char *data, int length) { /* Everytime we get data, we reset the timeout to our idleTimeout, that's the only timer we have */ /* If not in websocket shutdown state, for every */ // återställ inte om vi är i shutdown state, dvs, ge den inte massa tid på sig att skicka massa skit-frames mellan och upphålla oss! - 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) + WebSocketContextData *webSocketContextData = (WebSocketContextData *) us_new_socket_context_ext(SSL, + us_new_socket_context(SSL, (us_new_socket_t *) s) ); - static_dispatch(us_ssl_socket_timeout, us_socket_timeout)((SOCKET_TYPE *) s, webSocketContextData->idleTimeout); + us_new_socket_timeout(SSL, (us_new_socket_t *) s, webSocketContextData->idleTimeout); /* We always cork on data */ @@ -278,7 +274,7 @@ private: webSocket->cork(); /* We need the websocket data */ - WebSocketData *webSocketData = (WebSocketData *) (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s)); + WebSocketData *webSocketData = (WebSocketData *) (us_new_socket_ext(SSL, s)); /* This parser has virtually no overhead */ uWS::WebSocketProtocol>::consume(data, length, (WebSocketState *) webSocketData, s); @@ -289,7 +285,7 @@ private: webSocket->uncork(); // cannot do anything else if closed - if (us_socket_is_closed((us_socket *) s)) { + if (us_new_socket_is_closed(SSL, (us_new_socket_t *) s)) { return s; } @@ -304,15 +300,15 @@ private: }); /* Handle HTTP write out (note: SSL_read may trigger this spuriously, the app need to handle spurious calls) */ - static_dispatch(us_ssl_socket_context_on_writable, us_socket_context_on_writable)(getSocketContext(), [](auto *s) { + us_new_socket_context_on_writable(SSL, getSocketContext(), [](auto *s) { /* It makes sense to check for us_is_shut_down here and return if so, to avoid shutting down twice */ - if (static_dispatch(us_ssl_socket_is_shut_down, us_socket_is_shut_down)((SOCKET_TYPE *) s)) { + if (us_new_socket_is_shut_down(SSL, (us_new_socket_t *) s)) { return s; } AsyncSocket *webSocket = (AsyncSocket *) s; - WebSocketData *webSocketData = (WebSocketData *)(static_dispatch(us_ssl_socket_ext, us_socket_ext)(s)); + WebSocketData *webSocketData = (WebSocketData *)(us_new_socket_ext(SSL, s)); /* We store old backpressure since it is unclear whether write drained anything */ int backpressure = webSocket->getBufferedAmount(); @@ -322,8 +318,8 @@ private: /* Behavior: if we actively drain backpressure, always reset timeout (even if we are in shutdown) */ if (backpressure < webSocket->getBufferedAmount()) { - 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) + WebSocketContextData *webSocketContextData = (WebSocketContextData *) us_new_socket_context_ext(SSL, + us_new_socket_context(SSL, (us_new_socket_t *)s) ); webSocket->timeout(webSocketContextData->idleTimeout); } @@ -337,8 +333,8 @@ private: } } else if (backpressure > webSocket->getBufferedAmount()) { /* Only call drain if we actually drained backpressure */ - 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) + WebSocketContextData *webSocketContextData = (WebSocketContextData *) us_new_socket_context_ext(SSL, + us_new_socket_context(SSL, (us_new_socket_t *)s) ); if (webSocketContextData->drainHandler) { webSocketContextData->drainHandler((WebSocket *) s); @@ -350,19 +346,19 @@ private: }); /* Handle FIN, HTTP does not support half-closed sockets, so simply close */ - static_dispatch(us_ssl_socket_context_on_end, us_socket_context_on_end)(getSocketContext(), [](auto *s) { + us_new_socket_context_on_end(SSL, getSocketContext(), [](auto *s) { /* If we get a fin, we just close I guess */ - static_dispatch(us_ssl_socket_close, us_socket_close)((SOCKET_TYPE *) s); + us_new_socket_close(SSL, (us_new_socket_t *) s); return s; }); /* Handle socket timeouts, simply close them so to not confuse client with FIN */ - static_dispatch(us_ssl_socket_context_on_timeout, us_socket_context_on_timeout)(getSocketContext(), [](auto *s) { + us_new_socket_context_on_timeout(SSL, getSocketContext(), [](auto *s) { /* Timeout is very simple; we just close it */ - static_dispatch(us_ssl_socket_close, us_socket_close)((SOCKET_TYPE *) s); + us_new_socket_close(SSL, (us_new_socket_t *) s); return s; }); @@ -371,22 +367,22 @@ private: } void free() { - WebSocketContextData *webSocketContextData = (WebSocketContextData *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)((SOCKET_CONTEXT_TYPE *) this); + WebSocketContextData *webSocketContextData = (WebSocketContextData *) us_new_socket_context_ext(SSL, (us_new_socket_context_t *) this); webSocketContextData->~WebSocketContextData(); - static_dispatch(us_ssl_socket_context_free, us_socket_context_free)((SOCKET_CONTEXT_TYPE *) this); + us_new_socket_context_free(SSL, (us_new_socket_context_t *) this); } public: /* WebSocket contexts are always child contexts to a HTTP context so no SSL options are needed as they are inherited */ - static WebSocketContext *create(Loop *loop, SOCKET_CONTEXT_TYPE *parentSocketContext) { - WebSocketContext *webSocketContext = (WebSocketContext *)static_dispatch(us_create_child_ssl_socket_context, us_create_child_socket_context)(parentSocketContext, sizeof(WebSocketContextData)); + static WebSocketContext *create(Loop *loop, us_new_socket_context_t *parentSocketContext) { + WebSocketContext *webSocketContext = (WebSocketContext *) us_new_create_child_socket_context(SSL, parentSocketContext, sizeof(WebSocketContextData)); if (!webSocketContext) { return nullptr; } /* Init socket context data */ - new ((WebSocketContextData *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)((SOCKET_CONTEXT_TYPE *)webSocketContext)) WebSocketContextData; + new ((WebSocketContextData *) us_new_socket_context_ext(SSL, (us_new_socket_context_t *)webSocketContext)) WebSocketContextData; return webSocketContext->init(); } }; diff --git a/uSockets b/uSockets index 62ae53c..ee6b115 160000 --- a/uSockets +++ b/uSockets @@ -1 +1 @@ -Subproject commit 62ae53c1e91b9511645e3a9139520569e43b81c3 +Subproject commit ee6b1154583b8a18a4b2c6de1ced5acc722a2dae