Refactor using new uSockets API

This commit is contained in:
Alex Hultman
2019-01-25 14:15:40 +01:00
parent e14461e253
commit d331ec3e45
10 changed files with 107 additions and 198 deletions
+2 -2
View File
@@ -28,7 +28,7 @@ int main(int argc, char **argv) {
}; };
int port = 3000; 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) { while ((option = optparse_long(&options, longopts, nullptr)) != -1) {
switch (option) { switch (option) {
@@ -63,7 +63,7 @@ int main(int argc, char **argv) {
AsyncFileStreamer asyncFileStreamer(root); AsyncFileStreamer asyncFileStreamer(root);
/* Either serve over HTTP or HTTPS */ /* 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))) { if (memcmp(&ssl_options, &empty_ssl_options, sizeof(empty_ssl_options))) {
/* HTTPS */ /* HTTPS */
uWS::SSLApp(ssl_options).get("/*", [&asyncFileStreamer](auto *res, auto *req) { uWS::SSLApp(ssl_options).get("/*", [&asyncFileStreamer](auto *res, auto *req) {
-1
View File
@@ -21,7 +21,6 @@ HEADERS += \
../src/HttpContextData.h \ ../src/HttpContextData.h \
../src/HttpResponseData.h \ ../src/HttpResponseData.h \
../src/HttpResponse.h \ ../src/HttpResponse.h \
../src/StaticDispatch.h \
../src/LoopData.h \ ../src/LoopData.h \
../src/AsyncSocket.h \ ../src/AsyncSocket.h \
../src/AsyncSocketData.h \ ../src/AsyncSocketData.h \
+8 -10
View File
@@ -42,14 +42,12 @@ enum CompressOptions {
}; };
template <bool SSL> template <bool SSL>
struct TemplatedApp : StaticDispatch<SSL> { struct TemplatedApp {
private: private:
/* The app always owns at least one http context, but creates websocket contexts on demand */ /* The app always owns at least one http context, but creates websocket contexts on demand */
HttpContext<SSL> *httpContext; HttpContext<SSL> *httpContext;
std::vector<WebSocketContext<SSL, true> *> webSocketContexts; std::vector<WebSocketContext<SSL, true> *> webSocketContexts;
using SOCKET_TYPE = typename StaticDispatch<SSL>::SOCKET_TYPE;
using StaticDispatch<SSL>::static_dispatch;
public: public:
/* Attaches a "filter" function to track socket connections/disconnections */ /* Attaches a "filter" function to track socket connections/disconnections */
@@ -84,8 +82,8 @@ public:
webSocketContexts = std::move(other.webSocketContexts); webSocketContexts = std::move(other.webSocketContexts);
} }
TemplatedApp(us_ssl_socket_context_options sslOptions = {}) { TemplatedApp(us_new_socket_context_options_t options = {}) {
httpContext = uWS::HttpContext<SSL>::create(uWS::Loop::defaultLoop(), &sslOptions); httpContext = uWS::HttpContext<SSL>::create(uWS::Loop::defaultLoop(), options);
} }
struct WebSocketBehavior { struct WebSocketBehavior {
@@ -103,7 +101,7 @@ public:
template <class UserData> template <class UserData>
TemplatedApp &&ws(std::string pattern, WebSocketBehavior &&behavior) { TemplatedApp &&ws(std::string pattern, WebSocketBehavior &&behavior) {
/* Every route has its own websocket context with its own behavior and user data type */ /* Every route has its own websocket context with its own behavior and user data type */
auto *webSocketContext = WebSocketContext<SSL, true>::create(Loop::defaultLoop(), (typename StaticDispatch<SSL>::SOCKET_CONTEXT_TYPE *) httpContext); auto *webSocketContext = WebSocketContext<SSL, true>::create(Loop::defaultLoop(), (us_new_socket_context_t *) httpContext);
/* We need to clear this later on */ /* We need to clear this later on */
webSocketContexts.push_back(webSocketContext); webSocketContexts.push_back(webSocketContext);
@@ -115,7 +113,7 @@ public:
/* If we are the first one to use compression, initialize it */ /* If we are the first one to use compression, initialize it */
if (behavior.compression) { 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 */ /* Initialize loop's deflate inflate streams */
if (!loopData->zlibContext) { if (!loopData->zlibContext) {
@@ -191,8 +189,8 @@ public:
res->getHttpResponseData()->~HttpResponseData(); res->getHttpResponseData()->~HttpResponseData();
/* Adopting a socket invalidates it, do not rely on it directly to carry any data */ /* Adopting a socket invalidates it, do not rely on it directly to carry any data */
WebSocket<SSL, true> *webSocket = (WebSocket<SSL, true> *) StaticDispatch<SSL>::static_dispatch(us_ssl_socket_context_adopt_socket, us_socket_context_adopt_socket)( WebSocket<SSL, true> *webSocket = (WebSocket<SSL, true> *) us_new_socket_context_adopt_socket(SSL,
(typename StaticDispatch<SSL>::SOCKET_CONTEXT_TYPE *) webSocketContext, (typename StaticDispatch<SSL>::SOCKET_TYPE *) res, sizeof(WebSocketData) + sizeof(UserData)); (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). */ /* Update corked socket in case we got a new one (assuming we always are corked in handlers). */
webSocket->cork(); webSocket->cork();
@@ -204,7 +202,7 @@ public:
/* Emit open event and start the timeout */ /* Emit open event and start the timeout */
if (behavior.open) { 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); behavior.open(webSocket, req);
} }
+12 -14
View File
@@ -20,46 +20,44 @@
/* This class implements async socket memory management strategies */ /* This class implements async socket memory management strategies */
#include "StaticDispatch.h"
#include "LoopData.h" #include "LoopData.h"
#include "AsyncSocketData.h" #include "AsyncSocketData.h"
namespace uWS { namespace uWS {
template <bool SSL> template <bool SSL>
struct AsyncSocket : StaticDispatch<SSL> { struct AsyncSocket {
template <bool> friend struct HttpContext; template <bool> friend struct HttpContext;
template <bool, bool> friend struct WebSocketContext; template <bool, bool> friend struct WebSocketContext;
protected: protected:
using SOCKET_TYPE = typename StaticDispatch<SSL>::SOCKET_TYPE;
using StaticDispatch<SSL>::static_dispatch;
/* Get loop data for socket */ /* Get loop data for socket */
LoopData *getLoopData() { LoopData *getLoopData() {
return (LoopData *) us_loop_ext( return (LoopData *) us_loop_ext(
static_dispatch(us_ssl_socket_context_loop, us_socket_context_loop)( us_new_socket_context_loop(SSL,
static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *) this)) us_new_socket_context(SSL, (us_new_socket_t *) this))
); );
} }
/* Get socket extension */ /* Get socket extension */
void *getExt() { 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 */ /* Socket timeout */
void timeout(unsigned int seconds) { 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 */ /* Shutdown socket without any automatic drainage */
void shutdown() { 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 */ /* Immediately close socket */
SOCKET_TYPE *close() { us_new_socket_t *close() {
return static_dispatch(us_ssl_socket_close, us_socket_close)((SOCKET_TYPE *) this); 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 */ /* 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). */ * writable (or we are in a state that implies polling for writable). */
std::pair<int, bool> write(const char *src, int length, bool optionally = false, int nextLength = 0) { std::pair<int, bool> 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 */ /* 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; std::cout << "Faking successful send due to closed socket!" << std::endl;
return {length, false}; return {length, false};
} }
@@ -114,7 +112,7 @@ protected:
/* We are limited if we have a per-socket buffer */ /* We are limited if we have a per-socket buffer */
if (asyncSocketData->buffer.length()) { if (asyncSocketData->buffer.length()) {
/* Write off as much as we can */ /* 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 */ /* On failure return, otherwise continue down the function */
if (written < asyncSocketData->buffer.length()) { if (written < asyncSocketData->buffer.length()) {
@@ -165,7 +163,7 @@ protected:
} }
} else { } else {
/* We are not corked */ /* 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? */ /* Did we fail? */
if (written < length) { if (written < length) {
+35 -43
View File
@@ -25,7 +25,6 @@
#include "HttpResponseData.h" #include "HttpResponseData.h"
#include "AsyncSocket.h" #include "AsyncSocket.h"
#include "StaticDispatch.h"
#include <string_view> #include <string_view>
#include <functional> #include <functional>
@@ -36,41 +35,38 @@ namespace uWS {
template<bool> struct HttpResponse; template<bool> struct HttpResponse;
template <bool SSL> template <bool SSL>
struct HttpContext : StaticDispatch<SSL> { struct HttpContext {
private: private:
using SOCKET_CONTEXT_TYPE = typename StaticDispatch<SSL>::SOCKET_CONTEXT_TYPE;
using SOCKET_TYPE = typename StaticDispatch<SSL>::SOCKET_TYPE;
using StaticDispatch<SSL>::static_dispatch;
HttpContext() = delete; HttpContext() = delete;
/* Maximum delay allowed until an HTTP connection is terminated due to outstanding request or rejected data (slow loris protection) */ /* 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; static const int HTTP_IDLE_TIMEOUT_S = 10;
SOCKET_CONTEXT_TYPE *getSocketContext() { us_new_socket_context_t *getSocketContext() {
return (SOCKET_CONTEXT_TYPE *) this; return (us_new_socket_context_t *) this;
} }
static SOCKET_CONTEXT_TYPE *getSocketContext(SOCKET_TYPE *s) { static us_new_socket_context_t *getSocketContext(us_new_socket_t *s) {
return (SOCKET_CONTEXT_TYPE *) static_dispatch(us_ssl_socket_get_context, us_socket_get_context)(s); return (us_new_socket_context_t *) us_new_socket_context(SSL, s);
} }
HttpContextData<SSL> *getSocketContextData() { HttpContextData<SSL> *getSocketContextData() {
return (HttpContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(getSocketContext()); return (HttpContextData<SSL> *) us_new_socket_context_ext(SSL, getSocketContext());
} }
static HttpContextData<SSL> *getSocketContextDataS(SOCKET_TYPE *s) { static HttpContextData<SSL> *getSocketContextDataS(us_new_socket_t *s) {
return (HttpContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(getSocketContext(s)); return (HttpContextData<SSL> *) us_new_socket_context_ext(SSL, getSocketContext(s));
} }
/* Init the HttpContext by registering libusockets event handlers */ /* Init the HttpContext by registering libusockets event handlers */
HttpContext<SSL> *init() { HttpContext<SSL> *init() {
/* Handle socket connections */ /* 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 */ /* 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 */ /* Init socket ext */
new (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s)) HttpResponseData<SSL>; new (us_new_socket_ext(SSL, s)) HttpResponseData<SSL>;
/* Call filter */ /* Call filter */
HttpContextData<SSL> *httpContextData = getSocketContextDataS(s); HttpContextData<SSL> *httpContextData = getSocketContextDataS(s);
@@ -82,9 +78,9 @@ private:
}); });
/* Handle socket disconnections */ /* 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 */ /* Get socket ext */
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) static_dispatch(us_ssl_socket_ext, us_socket_ext)(s); HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) us_new_socket_ext(SSL, s);
/* Call filter */ /* Call filter */
HttpContextData<SSL> *httpContextData = getSocketContextDataS(s); HttpContextData<SSL> *httpContextData = getSocketContextDataS(s);
@@ -104,7 +100,7 @@ private:
}); });
/* Handle HTTP data streams */ /* 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 // total overhead is about 210k down to 180k
// ~210k req/sec is the original perf with write in data // ~210k req/sec is the original perf with write in data
@@ -115,11 +111,11 @@ private:
HttpContextData<SSL> *httpContextData = getSocketContextDataS(s); HttpContextData<SSL> *httpContextData = getSocketContextDataS(s);
/* Do not accept any data while in shutdown state */ /* 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; return s;
} }
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) static_dispatch(us_ssl_socket_ext, us_socket_ext)(s); HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) us_new_socket_ext(SSL, s);
/* Cork this socket */ /* Cork this socket */
((AsyncSocket<SSL> *) s)->cork(); ((AsyncSocket<SSL> *) s)->cork();
@@ -129,16 +125,16 @@ private:
void *returnedSocket = httpResponseData->consumePostPadded(data, length, s, [httpContextData](void *s, uWS::HttpRequest *httpRequest) -> void * { 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 */ /* 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! */ /* 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 */ /* Reset httpResponse */
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) s); HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) us_new_socket_ext(SSL, (us_new_socket_t *) s);
httpResponseData->offset = 0; httpResponseData->offset = 0;
httpResponseData->state = 0; httpResponseData->state = 0;
/* Are we not ready for another request yet? Terminate the connection. */ /* Are we not ready for another request yet? Terminate the connection. */
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_RESPONSE_PENDING) { if (httpResponseData->state & HttpResponseData<SSL>::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; return nullptr;
} }
@@ -151,7 +147,7 @@ private:
/* If first pass failed, we try and match by "any" method */ /* If first pass failed, we try and match by "any" method */
if (!httpContextData->router.route("*", httpRequest->getUrl(), routerData)) { 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 */ /* 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; return nullptr;
} }
} }
@@ -165,12 +161,12 @@ private:
} }
/* Was the socket closed? */ /* 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; return nullptr;
} }
/* We absolutely have to terminate parsing if shutdown */ /* 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; return nullptr;
} }
@@ -189,19 +185,19 @@ private:
httpResponseData->inStream(data, fin); httpResponseData->inStream(data, fin);
/* Was the socket closed? */ /* 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; return nullptr;
} }
/* We absolutely have to terminate parsing if shutdown */ /* 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 nullptr;
} }
} }
return user; return user;
}, [](void *user) { }, [](void *user) {
/* Close any socket on HTTP errors */ /* 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; return nullptr;
}); });
@@ -214,7 +210,7 @@ private:
((AsyncSocket<SSL> *) s)->timeout(HTTP_IDLE_TIMEOUT_S); ((AsyncSocket<SSL> *) 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 */ /* 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) */ /* 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 */ /* 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<SSL> *asyncSocket = (AsyncSocket<SSL> *) s; AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s;
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) asyncSocket->getExt(); HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) asyncSocket->getExt();
@@ -253,7 +249,7 @@ private:
}); });
/* Handle FIN, HTTP does not support half-closed sockets, so simply close */ /* 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 */ /* We do not care for half closed sockets */
AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s; AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s;
@@ -262,7 +258,7 @@ private:
}); });
/* Handle socket timeouts, simply close them so to not confuse client with FIN */ /* 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 */ /* Force close rather than gracefully shutdown and risk confusing the client with a complete download */
AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s; AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s;
@@ -275,21 +271,17 @@ private:
public: public:
/* Construct a new HttpContext using specified loop */ /* 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; HttpContext *httpContext;
if constexpr(SSL) { httpContext = (HttpContext *) us_new_create_socket_context(SSL, (us_loop *) loop, sizeof(HttpContextData<SSL>), options);
httpContext = (HttpContext *) us_create_ssl_socket_context((us_loop *) loop, sizeof(HttpContextData<SSL>), *ssl_options);
} else {
httpContext = (HttpContext *) us_create_socket_context((us_loop *) loop, sizeof(HttpContextData<SSL>));
}
if (!httpContext) { if (!httpContext) {
return nullptr; return nullptr;
} }
/* Init socket context data */ /* Init socket context data */
new ((HttpContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)((SOCKET_CONTEXT_TYPE *) httpContext)) HttpContextData<SSL>(); new ((HttpContextData<SSL> *) us_new_socket_context_ext(SSL, (us_new_socket_context_t *) httpContext)) HttpContextData<SSL>();
return httpContext->init(); return httpContext->init();
} }
@@ -300,7 +292,7 @@ public:
httpContextData->~HttpContextData<SSL>(); httpContextData->~HttpContextData<SSL>();
/* Free the socket context in whole */ /* 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<void(HttpResponse<SSL> *, int)> &&filterHandler) { void filter(fu2::unique_function<void(HttpResponse<SSL> *, int)> &&filterHandler) {
@@ -333,7 +325,7 @@ public:
/* Listen to port using this HttpContext */ /* Listen to port using this HttpContext */
us_listen_socket *listen(const char *host, int port, int options) { 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<SSL>)); return us_new_socket_context_listen(SSL, getSocketContext(), host, port, options, sizeof(HttpResponseData<SSL>));
} }
}; };
+1 -1
View File
@@ -22,7 +22,7 @@
#include "LoopData.h" #include "LoopData.h"
#include <libusockets.h> #include <libusockets_new.h>
-71
View File
@@ -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 <type_traits>
#include <libusockets.h>
/* 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 <bool SSL>
struct StaticDispatch {
template <class A, class B>
static constexpr typename std::conditional<SSL, A, B>::type *static_dispatch(A *a, B *b) {
if constexpr(SSL) {
return a;
} else {
return b;
}
}
typedef typename std::conditional<SSL, us_ssl_socket, us_socket>::type SOCKET_TYPE;
typedef typename std::conditional<SSL, us_ssl_socket_context, us_socket_context>::type SOCKET_CONTEXT_TYPE;
};
}
#endif // STATICDISPATCH_H
+5 -8
View File
@@ -31,19 +31,16 @@ struct WebSocket : AsyncSocket<SSL> {
template <bool> friend struct TemplatedApp; template <bool> friend struct TemplatedApp;
private: private:
typedef AsyncSocket<SSL> Super; typedef AsyncSocket<SSL> Super;
using SOCKET_TYPE = typename StaticDispatch<SSL>::SOCKET_TYPE;
using SOCKET_CONTEXT_TYPE = typename StaticDispatch<SSL>::SOCKET_CONTEXT_TYPE;
using StaticDispatch<SSL>::static_dispatch;
void *init(bool perMessageDeflate, bool slidingCompression, std::string &&backpressure) { 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; return this;
} }
public: public:
/* Returns pointer to the per socket user data */ /* Returns pointer to the per socket user data */
void *getUserData() { 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 */ /* We just have it overallocated by sizeof type */
return (webSocketData + 1); return (webSocketData + 1);
} }
@@ -92,7 +89,7 @@ public:
/* Send websocket close frame, emit close event, send FIN if successful */ /* Send websocket close frame, emit close event, send FIN if successful */
void close(int code, std::string_view message = {}) { void close(int code, std::string_view message = {}) {
/* Check if we already called this one */ /* 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) { if (webSocketData->isShuttingDown) {
return; return;
} }
@@ -118,8 +115,8 @@ public:
} }
/* Emit close event */ /* Emit close event */
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)( WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_new_socket_context_ext(SSL,
(SOCKET_CONTEXT_TYPE *) static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *) this) (us_new_socket_context_t *) us_new_socket_context(SSL, (us_new_socket_t *) this)
); );
if (webSocketContextData->closeHandler) { if (webSocketContextData->closeHandler) {
webSocketContextData->closeHandler(this, code, message); webSocketContextData->closeHandler(this, code, message);
+43 -47
View File
@@ -18,7 +18,6 @@
#ifndef WEBSOCKETCONTEXT_H #ifndef WEBSOCKETCONTEXT_H
#define WEBSOCKETCONTEXT_H #define WEBSOCKETCONTEXT_H
#include "StaticDispatch.h"
#include "WebSocketContextData.h" #include "WebSocketContextData.h"
#include "WebSocketProtocol.h" #include "WebSocketProtocol.h"
#include "WebSocketData.h" #include "WebSocketData.h"
@@ -27,26 +26,23 @@
namespace uWS { namespace uWS {
template <bool SSL, bool isServer> template <bool SSL, bool isServer>
struct WebSocketContext : StaticDispatch<SSL> { struct WebSocketContext {
template <bool> friend struct TemplatedApp; template <bool> friend struct TemplatedApp;
template <bool, class> friend class WebSocketProtocol; template <bool, class> friend class WebSocketProtocol;
private: private:
using SOCKET_CONTEXT_TYPE = typename StaticDispatch<SSL>::SOCKET_CONTEXT_TYPE;
using SOCKET_TYPE = typename StaticDispatch<SSL>::SOCKET_TYPE;
using StaticDispatch<SSL>::static_dispatch;
WebSocketContext() = delete; WebSocketContext() = delete;
SOCKET_CONTEXT_TYPE *getSocketContext() { us_new_socket_context_t *getSocketContext() {
return (SOCKET_CONTEXT_TYPE *) this; return (us_new_socket_context_t *) this;
} }
WebSocketContextData<SSL> *getExt() { WebSocketContextData<SSL> *getExt() {
return (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)((SOCKET_CONTEXT_TYPE *) this); return (WebSocketContextData<SSL> *) us_new_socket_context_ext(SSL, (us_new_socket_context_t *) this);
} }
/* If we have negotiated compression, set this frame compressed */ /* If we have negotiated compression, set this frame compressed */
static bool setCompressed(uWS::WebSocketState<isServer> *wState, void *s) { static bool setCompressed(uWS::WebSocketState<isServer> *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) { if (webSocketData->compressionStatus == WebSocketData::CompressionStatus::ENABLED) {
webSocketData->compressionStatus = WebSocketData::CompressionStatus::COMPRESSED_FRAME; webSocketData->compressionStatus = WebSocketData::CompressionStatus::COMPRESSED_FRAME;
@@ -57,16 +53,16 @@ private:
} }
static void forceClose(uWS::WebSocketState<isServer> *wState, void *s) { static void forceClose(uWS::WebSocketState<isServer> *wState, void *s) {
us_socket_close((us_socket *) s); us_new_socket_close(SSL, (us_new_socket_t *) s);
} }
/* Returns true on breakage */ /* Returns true on breakage */
static bool handleFragment(char *data, size_t length, unsigned int remainingBytes, int opCode, bool fin, uWS::WebSocketState<isServer> *webSocketState, void *s) { static bool handleFragment(char *data, size_t length, unsigned int remainingBytes, int opCode, bool fin, uWS::WebSocketState<isServer> *webSocketState, void *s) {
/* WebSocketData and WebSocketContextData */ /* WebSocketData and WebSocketContextData */
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)( WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_new_socket_context_ext(SSL,
static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *) s) 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? */ /* Is this a non-control frame? */
if (opCode < 3) { if (opCode < 3) {
@@ -78,8 +74,8 @@ private:
webSocketData->compressionStatus = WebSocketData::CompressionStatus::ENABLED; webSocketData->compressionStatus = WebSocketData::CompressionStatus::ENABLED;
LoopData *loopData = (LoopData *)us_loop_ext( LoopData *loopData = (LoopData *)us_loop_ext(
static_dispatch(us_ssl_socket_context_loop, us_socket_context_loop)( us_new_socket_context_loop(SSL,
static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *)s) 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 */ /* Emit message event & break if we are closed or shut down when returning */
if (webSocketContextData->messageHandler) { if (webSocketContextData->messageHandler) {
webSocketContextData->messageHandler((WebSocket<SSL, isServer> *) s, std::string_view(data, length), (uWS::OpCode) opCode); webSocketContextData->messageHandler((WebSocket<SSL, isServer> *) 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; return true;
} }
} }
@@ -125,8 +121,8 @@ private:
webSocketData->fragmentBuffer.append("...."); webSocketData->fragmentBuffer.append("....");
LoopData *loopData = (LoopData *) us_loop_ext( LoopData *loopData = (LoopData *) us_loop_ext(
static_dispatch(us_ssl_socket_context_loop, us_socket_context_loop)( us_new_socket_context_loop(SSL,
static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *) s) us_new_socket_context(SSL, (us_new_socket_t *) s)
) )
); );
@@ -155,7 +151,7 @@ private:
/* Emit message and check for shutdown or close */ /* Emit message and check for shutdown or close */
if (webSocketContextData->messageHandler) { if (webSocketContextData->messageHandler) {
webSocketContextData->messageHandler((WebSocket<SSL, isServer> *) s, std::string_view(data, length), (uWS::OpCode) opCode); webSocketContextData->messageHandler((WebSocket<SSL, isServer> *) 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; return true;
} }
} }
@@ -223,8 +219,8 @@ private:
} }
static bool refusePayloadLength(uint64_t length, uWS::WebSocketState<isServer> *wState, void *s) { static bool refusePayloadLength(uint64_t length, uWS::WebSocketState<isServer> *wState, void *s) {
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)( WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_new_socket_context_ext(SSL,
static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *)s) us_new_socket_context(SSL, (us_new_socket_t *)s)
); );
/* Return true for refuse, false for accept */ /* Return true for refuse, false for accept */
@@ -237,14 +233,14 @@ private:
* any backpressure from HTTP state kept. */ * any backpressure from HTTP state kept. */
/* Handle socket disconnections */ /* 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 */ /* 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) { if (!webSocketData->isShuttingDown) {
/* Emit close event */ /* Emit close event */
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)( WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_new_socket_context_ext(SSL,
static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *)s) us_new_socket_context(SSL, (us_new_socket_t *)s)
); );
if (webSocketContextData->closeHandler) { if (webSocketContextData->closeHandler) {
@@ -259,18 +255,18 @@ private:
}); });
/* Handle WebSocket data streams */ /* 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 */ /* 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 */ /* 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! // å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<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)( WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_new_socket_context_ext(SSL,
static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *) s) 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 */ /* We always cork on data */
@@ -278,7 +274,7 @@ private:
webSocket->cork(); webSocket->cork();
/* We need the websocket data */ /* 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 */ /* This parser has virtually no overhead */
uWS::WebSocketProtocol<isServer, WebSocketContext<SSL, isServer>>::consume(data, length, (WebSocketState<isServer> *) webSocketData, s); uWS::WebSocketProtocol<isServer, WebSocketContext<SSL, isServer>>::consume(data, length, (WebSocketState<isServer> *) webSocketData, s);
@@ -289,7 +285,7 @@ private:
webSocket->uncork(); webSocket->uncork();
// cannot do anything else if closed // 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; 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) */ /* 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 */ /* 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; return s;
} }
AsyncSocket<SSL> *webSocket = (AsyncSocket<SSL> *) s; AsyncSocket<SSL> *webSocket = (AsyncSocket<SSL> *) 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 */ /* We store old backpressure since it is unclear whether write drained anything */
int backpressure = webSocket->getBufferedAmount(); int backpressure = webSocket->getBufferedAmount();
@@ -322,8 +318,8 @@ private:
/* Behavior: if we actively drain backpressure, always reset timeout (even if we are in shutdown) */ /* Behavior: if we actively drain backpressure, always reset timeout (even if we are in shutdown) */
if (backpressure < webSocket->getBufferedAmount()) { if (backpressure < webSocket->getBufferedAmount()) {
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)( WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_new_socket_context_ext(SSL,
static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *)s) us_new_socket_context(SSL, (us_new_socket_t *)s)
); );
webSocket->timeout(webSocketContextData->idleTimeout); webSocket->timeout(webSocketContextData->idleTimeout);
} }
@@ -337,8 +333,8 @@ private:
} }
} else if (backpressure > webSocket->getBufferedAmount()) { } else if (backpressure > webSocket->getBufferedAmount()) {
/* Only call drain if we actually drained backpressure */ /* Only call drain if we actually drained backpressure */
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)( WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_new_socket_context_ext(SSL,
static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *)s) us_new_socket_context(SSL, (us_new_socket_t *)s)
); );
if (webSocketContextData->drainHandler) { if (webSocketContextData->drainHandler) {
webSocketContextData->drainHandler((WebSocket<SSL, isServer> *) s); webSocketContextData->drainHandler((WebSocket<SSL, isServer> *) s);
@@ -350,19 +346,19 @@ private:
}); });
/* Handle FIN, HTTP does not support half-closed sockets, so simply close */ /* 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 */ /* 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; return s;
}); });
/* Handle socket timeouts, simply close them so to not confuse client with FIN */ /* 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 */ /* 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; return s;
}); });
@@ -371,22 +367,22 @@ private:
} }
void free() { void free() {
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)((SOCKET_CONTEXT_TYPE *) this); WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_new_socket_context_ext(SSL, (us_new_socket_context_t *) this);
webSocketContextData->~WebSocketContextData(); 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: public:
/* WebSocket contexts are always child contexts to a HTTP context so no SSL options are needed as they are inherited */ /* 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) { static WebSocketContext *create(Loop *loop, us_new_socket_context_t *parentSocketContext) {
WebSocketContext *webSocketContext = (WebSocketContext *)static_dispatch(us_create_child_ssl_socket_context, us_create_child_socket_context)(parentSocketContext, sizeof(WebSocketContextData<SSL>)); WebSocketContext *webSocketContext = (WebSocketContext *) us_new_create_child_socket_context(SSL, parentSocketContext, sizeof(WebSocketContextData<SSL>));
if (!webSocketContext) { if (!webSocketContext) {
return nullptr; return nullptr;
} }
/* Init socket context data */ /* Init socket context data */
new ((WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)((SOCKET_CONTEXT_TYPE *)webSocketContext)) WebSocketContextData<SSL>; new ((WebSocketContextData<SSL> *) us_new_socket_context_ext(SSL, (us_new_socket_context_t *)webSocketContext)) WebSocketContextData<SSL>;
return webSocketContext->init(); return webSocketContext->init();
} }
}; };