Make getUserData type safe
This commit is contained in:
@@ -53,7 +53,7 @@ struct TemplatedApp {
|
||||
private:
|
||||
/* The app always owns at least one http context, but creates websocket contexts on demand */
|
||||
HttpContext<SSL> *httpContext;
|
||||
std::vector<WebSocketContext<SSL, true> *> webSocketContexts;
|
||||
std::vector<WebSocketContext<SSL, true, int> *> webSocketContexts;
|
||||
|
||||
public:
|
||||
|
||||
@@ -134,6 +134,7 @@ public:
|
||||
return !httpContext;
|
||||
}
|
||||
|
||||
template <typename UserData>
|
||||
struct WebSocketBehavior {
|
||||
/* Disabled compression by default - probably a bad default */
|
||||
CompressOptions compression = DISABLED;
|
||||
@@ -151,16 +152,16 @@ public:
|
||||
/* Maximum socket lifetime in seconds before forced closure (defaults to disabled) */
|
||||
unsigned short maxLifetime = 0;
|
||||
MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *, struct us_socket_context_t *)> upgrade = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true> *)> open = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true> *, std::string_view, OpCode)> message = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true> *)> drain = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true> *)> ping = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true> *)> pong = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true> *, int, std::string_view)> close = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true, UserData> *)> open = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true, UserData> *, std::string_view, OpCode)> message = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true, UserData> *)> drain = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true, UserData> *)> ping = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true, UserData> *)> pong = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true, UserData> *, int, std::string_view)> close = nullptr;
|
||||
};
|
||||
|
||||
template <typename UserData>
|
||||
TemplatedApp &&ws(std::string pattern, WebSocketBehavior &&behavior) {
|
||||
TemplatedApp &&ws(std::string pattern, WebSocketBehavior<UserData> &&behavior) {
|
||||
/* Don't compile if alignment rules cannot be satisfied */
|
||||
static_assert(alignof(UserData) <= LIBUS_EXT_ALIGNMENT,
|
||||
"µWebSockets cannot satisfy UserData alignment requirements. You need to recompile µSockets with LIBUS_EXT_ALIGNMENT adjusted accordingly.");
|
||||
@@ -180,10 +181,10 @@ public:
|
||||
}
|
||||
|
||||
/* Every route has its own websocket context with its own behavior and user data type */
|
||||
auto *webSocketContext = WebSocketContext<SSL, true>::create(Loop::get(), (us_socket_context_t *) httpContext);
|
||||
auto *webSocketContext = WebSocketContext<SSL, true, UserData>::create(Loop::get(), (us_socket_context_t *) httpContext);
|
||||
|
||||
/* We need to clear this later on */
|
||||
webSocketContexts.push_back(webSocketContext);
|
||||
webSocketContexts.push_back((WebSocketContext<SSL, true, int> *) webSocketContext);
|
||||
|
||||
/* Quick fix to disable any compression if set */
|
||||
#ifdef UWS_NO_ZLIB
|
||||
@@ -206,7 +207,7 @@ public:
|
||||
webSocketContext->getExt()->openHandler = std::move(behavior.open);
|
||||
webSocketContext->getExt()->messageHandler = std::move(behavior.message);
|
||||
webSocketContext->getExt()->drainHandler = std::move(behavior.drain);
|
||||
webSocketContext->getExt()->closeHandler = std::move([closeHandler = std::move(behavior.close)](WebSocket<SSL, true> *ws, int code, std::string_view message) mutable {
|
||||
webSocketContext->getExt()->closeHandler = std::move([closeHandler = std::move(behavior.close)](WebSocket<SSL, true, UserData> *ws, int code, std::string_view message) mutable {
|
||||
if (closeHandler) {
|
||||
closeHandler(ws, code, message);
|
||||
}
|
||||
|
||||
+3
-3
@@ -29,13 +29,13 @@
|
||||
|
||||
namespace uWS {
|
||||
|
||||
template <bool, bool> struct WebSocketContext;
|
||||
template <bool, bool, typename> struct WebSocketContext;
|
||||
|
||||
template <bool SSL>
|
||||
struct AsyncSocket {
|
||||
template <bool> friend struct HttpContext;
|
||||
template <bool, bool> friend struct WebSocketContext;
|
||||
template <bool> friend struct WebSocketContextData;
|
||||
template <bool, bool, typename> friend struct WebSocketContext;
|
||||
template <bool, typename> friend struct WebSocketContextData;
|
||||
friend struct TopicTree;
|
||||
|
||||
protected:
|
||||
|
||||
+2
-2
@@ -214,7 +214,7 @@ public:
|
||||
struct us_socket_context_t *webSocketContext) {
|
||||
|
||||
/* Extract needed parameters from WebSocketContextData */
|
||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL, webSocketContext);
|
||||
WebSocketContextData<SSL, UserData> *webSocketContextData = (WebSocketContextData<SSL, UserData> *) us_socket_context_ext(SSL, webSocketContext);
|
||||
|
||||
/* Note: OpenSSL can be used here to speed this up somewhat */
|
||||
char secWebSocketAccept[29] = {};
|
||||
@@ -281,7 +281,7 @@ public:
|
||||
bool wasCorked = Super::isCorked();
|
||||
|
||||
/* Adopting a socket invalidates it, do not rely on it directly to carry any data */
|
||||
WebSocket<SSL, true> *webSocket = (WebSocket<SSL, true> *) us_socket_context_adopt_socket(SSL,
|
||||
WebSocket<SSL, true, UserData> *webSocket = (WebSocket<SSL, true, UserData> *) us_socket_context_adopt_socket(SSL,
|
||||
(us_socket_context_t *) webSocketContext, (us_socket_t *) this, sizeof(WebSocketData) + sizeof(UserData));
|
||||
|
||||
/* For whatever reason we were corked, update cork to the new socket */
|
||||
|
||||
+12
-13
@@ -27,7 +27,7 @@
|
||||
|
||||
namespace uWS {
|
||||
|
||||
template <bool SSL, bool isServer>
|
||||
template <bool SSL, bool isServer, typename USERDATA>
|
||||
struct WebSocket : AsyncSocket<SSL> {
|
||||
template <bool> friend struct TemplatedApp;
|
||||
template <bool> friend struct HttpResponse;
|
||||
@@ -41,10 +41,10 @@ private:
|
||||
public:
|
||||
|
||||
/* Returns pointer to the per socket user data */
|
||||
void *getUserData() {
|
||||
USERDATA *getUserData() {
|
||||
WebSocketData *webSocketData = (WebSocketData *) us_socket_ext(SSL, (us_socket_t *) this);
|
||||
/* We just have it overallocated by sizeof type */
|
||||
return (webSocketData + 1);
|
||||
return (USERDATA *) (webSocketData + 1);
|
||||
}
|
||||
|
||||
/* See AsyncSocket */
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
/* Send or buffer a WebSocket frame, compressed or not. Returns BACKPRESSURE on increased user space backpressure,
|
||||
* DROPPED on dropped message (due to backpressure) or SUCCCESS if you are free to send even more now. */
|
||||
SendStatus send(std::string_view message, OpCode opCode = OpCode::BINARY, bool compress = false) {
|
||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL,
|
||||
WebSocketContextData<SSL, USERDATA> *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL,
|
||||
(us_socket_context_t *) us_socket_context(SSL, (us_socket_t *) this)
|
||||
);
|
||||
|
||||
@@ -159,17 +159,16 @@ public:
|
||||
bool ok = send(std::string_view(closePayload, closePayloadLength), OpCode::CLOSE);
|
||||
|
||||
/* FIN if we are ok and not corked */
|
||||
WebSocket<SSL, true> *webSocket = (WebSocket<SSL, true> *) this;
|
||||
if (!webSocket->isCorked()) {
|
||||
if (!this->isCorked()) {
|
||||
if (ok) {
|
||||
/* If we are not corked, and we just sent off everything, we need to FIN right here.
|
||||
* In all other cases, we need to fin either if uncork was successful, or when drainage is complete. */
|
||||
webSocket->shutdown();
|
||||
this->shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit close event */
|
||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL,
|
||||
WebSocketContextData<SSL, USERDATA> *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL,
|
||||
(us_socket_context_t *) us_socket_context(SSL, (us_socket_t *) this)
|
||||
);
|
||||
if (webSocketContextData->closeHandler) {
|
||||
@@ -199,7 +198,7 @@ public:
|
||||
|
||||
/* Subscribe to a topic according to MQTT rules and syntax. Returns [numSubscribers, success]. */
|
||||
std::pair<unsigned int, bool> subscribe(std::string_view topic, bool nonStrict = false) {
|
||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL,
|
||||
WebSocketContextData<SSL, USERDATA> *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL,
|
||||
(us_socket_context_t *) us_socket_context(SSL, (us_socket_t *) this)
|
||||
);
|
||||
|
||||
@@ -214,7 +213,7 @@ public:
|
||||
|
||||
/* Unsubscribe from a topic, returns true if we were subscribed. Returns [numSubscribers, success]. */
|
||||
std::pair<unsigned int, bool> unsubscribe(std::string_view topic, bool nonStrict = false) {
|
||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL,
|
||||
WebSocketContextData<SSL, USERDATA> *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL,
|
||||
(us_socket_context_t *) us_socket_context(SSL, (us_socket_t *) this)
|
||||
);
|
||||
|
||||
@@ -225,7 +224,7 @@ public:
|
||||
|
||||
/* Returns whether this socket is subscribed to the specified topic */
|
||||
bool isSubscribed(std::string_view topic) {
|
||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL,
|
||||
WebSocketContextData<SSL, USERDATA> *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL,
|
||||
(us_socket_context_t *) us_socket_context(SSL, (us_socket_t *) this)
|
||||
);
|
||||
|
||||
@@ -239,7 +238,7 @@ public:
|
||||
|
||||
/* Returns number of subscribers for this topic, or 0 for failure */
|
||||
unsigned int numSubscribers(std::string_view topic) {
|
||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL,
|
||||
WebSocketContextData<SSL, USERDATA> *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL,
|
||||
(us_socket_context_t *) us_socket_context(SSL, (us_socket_t *) this)
|
||||
);
|
||||
|
||||
@@ -274,7 +273,7 @@ public:
|
||||
* We, the WebSocket, must be subscribed to the topic itself and if so - no message will be sent to ourselves.
|
||||
* Use App::publish for an unconditional publish that simply publishes to whomever might be subscribed. */
|
||||
bool publish(std::string_view topic, std::string_view message, OpCode opCode = OpCode::TEXT, bool compress = false) {
|
||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL,
|
||||
WebSocketContextData<SSL, USERDATA> *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL,
|
||||
(us_socket_context_t *) us_socket_context(SSL, (us_socket_t *) this)
|
||||
);
|
||||
|
||||
|
||||
+20
-20
@@ -25,7 +25,7 @@
|
||||
|
||||
namespace uWS {
|
||||
|
||||
template <bool SSL, bool isServer>
|
||||
template <bool SSL, bool isServer, typename USERDATA>
|
||||
struct WebSocketContext {
|
||||
template <bool> friend struct TemplatedApp;
|
||||
template <bool, typename> friend struct WebSocketProtocol;
|
||||
@@ -36,8 +36,8 @@ private:
|
||||
return (us_socket_context_t *) this;
|
||||
}
|
||||
|
||||
WebSocketContextData<SSL> *getExt() {
|
||||
return (WebSocketContextData<SSL> *) us_socket_context_ext(SSL, (us_socket_context_t *) this);
|
||||
WebSocketContextData<SSL, USERDATA> *getExt() {
|
||||
return (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL, (us_socket_context_t *) this);
|
||||
}
|
||||
|
||||
/* If we have negotiated compression, set this frame compressed */
|
||||
@@ -59,7 +59,7 @@ private:
|
||||
/* Returns true on breakage */
|
||||
static bool handleFragment(char *data, size_t length, unsigned int remainingBytes, int opCode, bool fin, WebSocketState<isServer> *webSocketState, void *s) {
|
||||
/* WebSocketData and WebSocketContextData */
|
||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
WebSocketContextData<SSL, USERDATA> *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
WebSocketData *webSocketData = (WebSocketData *) us_socket_ext(SSL, (us_socket_t *) s);
|
||||
|
||||
/* Is this a non-control frame? */
|
||||
@@ -90,7 +90,7 @@ private:
|
||||
|
||||
/* Emit message event & break if we are closed or shut down when returning */
|
||||
if (webSocketContextData->messageHandler) {
|
||||
webSocketContextData->messageHandler((WebSocket<SSL, isServer> *) s, std::string_view(data, length), (OpCode) opCode);
|
||||
webSocketContextData->messageHandler((WebSocket<SSL, isServer, USERDATA> *) s, std::string_view(data, length), (OpCode) opCode);
|
||||
if (us_socket_is_closed(SSL, (us_socket_t *) s) || webSocketData->isShuttingDown) {
|
||||
return true;
|
||||
}
|
||||
@@ -148,7 +148,7 @@ private:
|
||||
|
||||
/* Emit message and check for shutdown or close */
|
||||
if (webSocketContextData->messageHandler) {
|
||||
webSocketContextData->messageHandler((WebSocket<SSL, isServer> *) s, std::string_view(data, length), (OpCode) opCode);
|
||||
webSocketContextData->messageHandler((WebSocket<SSL, isServer, USERDATA> *) s, std::string_view(data, length), (OpCode) opCode);
|
||||
if (us_socket_is_closed(SSL, (us_socket_t *) s) || webSocketData->isShuttingDown) {
|
||||
return true;
|
||||
}
|
||||
@@ -160,7 +160,7 @@ private:
|
||||
}
|
||||
} else {
|
||||
/* Control frames need the websocket to send pings, pongs and close */
|
||||
WebSocket<SSL, isServer> *webSocket = (WebSocket<SSL, isServer> *) s;
|
||||
WebSocket<SSL, isServer, USERDATA> *webSocket = (WebSocket<SSL, isServer, USERDATA> *) s;
|
||||
|
||||
if (!remainingBytes && fin && !webSocketData->controlTipLength) {
|
||||
if (opCode == CLOSE) {
|
||||
@@ -225,13 +225,13 @@ private:
|
||||
}
|
||||
|
||||
static bool refusePayloadLength(uint64_t length, WebSocketState<isServer> */*wState*/, void *s) {
|
||||
auto *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
auto *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
|
||||
/* Return true for refuse, false for accept */
|
||||
return webSocketContextData->maxPayloadLength < length;
|
||||
}
|
||||
|
||||
WebSocketContext<SSL, isServer> *init() {
|
||||
WebSocketContext<SSL, isServer, USERDATA> *init() {
|
||||
/* Adopting a socket does not trigger open event.
|
||||
* We arreive as WebSocket with timeout set and
|
||||
* any backpressure from HTTP state kept. */
|
||||
@@ -242,10 +242,10 @@ private:
|
||||
WebSocketData *webSocketData = (WebSocketData *) (us_socket_ext(SSL, s));
|
||||
if (!webSocketData->isShuttingDown) {
|
||||
/* Emit close event */
|
||||
auto *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
auto *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
|
||||
if (webSocketContextData->closeHandler) {
|
||||
webSocketContextData->closeHandler((WebSocket<SSL, true> *) s, 1006, {(char *) reason, (size_t) code});
|
||||
webSocketContextData->closeHandler((WebSocket<SSL, isServer, USERDATA> *) s, 1006, {(char *) reason, (size_t) code});
|
||||
}
|
||||
|
||||
/* Make sure to unsubscribe from any pub/sub node at exit */
|
||||
@@ -272,7 +272,7 @@ private:
|
||||
return s;
|
||||
}
|
||||
|
||||
auto *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
auto *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
auto *asyncSocket = (AsyncSocket<SSL> *) s;
|
||||
|
||||
/* Every time we get data and not in shutdown state we simply reset the timeout */
|
||||
@@ -283,7 +283,7 @@ private:
|
||||
asyncSocket->cork();
|
||||
|
||||
/* This parser has virtually no overhead */
|
||||
WebSocketProtocol<isServer, WebSocketContext<SSL, isServer>>::consume(data, (unsigned int) length, (WebSocketState<isServer> *) webSocketData, s);
|
||||
WebSocketProtocol<isServer, WebSocketContext<SSL, isServer, USERDATA>>::consume(data, (unsigned int) length, (WebSocketState<isServer> *) webSocketData, s);
|
||||
|
||||
/* Uncorking a closed socekt is fine, in fact it is needed */
|
||||
asyncSocket->uncork();
|
||||
@@ -325,7 +325,7 @@ private:
|
||||
/* Behavior: if we actively drain backpressure, always reset timeout (even if we are in shutdown) */
|
||||
/* Also reset timeout if we came here with 0 backpressure */
|
||||
if (!backpressure || backpressure > asyncSocket->getBufferedAmount()) {
|
||||
auto *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
auto *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
asyncSocket->timeout(webSocketContextData->idleTimeoutComponents.first);
|
||||
webSocketData->hasTimedOut = false;
|
||||
}
|
||||
@@ -339,9 +339,9 @@ private:
|
||||
}
|
||||
} else if (!backpressure || backpressure > asyncSocket->getBufferedAmount()) {
|
||||
/* Only call drain if we actually drained backpressure or if we came here with 0 backpressure */
|
||||
auto *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
auto *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
if (webSocketContextData->drainHandler) {
|
||||
webSocketContextData->drainHandler((WebSocket<SSL, isServer> *) s);
|
||||
webSocketContextData->drainHandler((WebSocket<SSL, isServer, USERDATA> *) s);
|
||||
}
|
||||
/* No need to check for closed here as we leave the handler immediately*/
|
||||
}
|
||||
@@ -362,7 +362,7 @@ private:
|
||||
us_socket_context_on_timeout(SSL, getSocketContext(), [](auto *s) {
|
||||
|
||||
auto *webSocketData = (WebSocketData *)(us_socket_ext(SSL, s));
|
||||
auto *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
auto *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL, us_socket_context(SSL, (us_socket_t *) s));
|
||||
|
||||
if (webSocketContextData->sendPingsAutomatically && !webSocketData->hasTimedOut) {
|
||||
webSocketData->hasTimedOut = true;
|
||||
@@ -383,7 +383,7 @@ private:
|
||||
}
|
||||
|
||||
void free() {
|
||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) us_socket_context_ext(SSL, (us_socket_context_t *) this);
|
||||
WebSocketContextData<SSL, USERDATA> *webSocketContextData = (WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL, (us_socket_context_t *) this);
|
||||
webSocketContextData->~WebSocketContextData();
|
||||
|
||||
us_socket_context_free(SSL, (us_socket_context_t *) this);
|
||||
@@ -392,13 +392,13 @@ private:
|
||||
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*/, us_socket_context_t *parentSocketContext) {
|
||||
WebSocketContext *webSocketContext = (WebSocketContext *) us_create_child_socket_context(SSL, parentSocketContext, sizeof(WebSocketContextData<SSL>));
|
||||
WebSocketContext *webSocketContext = (WebSocketContext *) us_create_child_socket_context(SSL, parentSocketContext, sizeof(WebSocketContextData<SSL, USERDATA>));
|
||||
if (!webSocketContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Init socket context data */
|
||||
new ((WebSocketContextData<SSL> *) us_socket_context_ext(SSL, (us_socket_context_t *)webSocketContext)) WebSocketContextData<SSL>;
|
||||
new ((WebSocketContextData<SSL, USERDATA> *) us_socket_context_ext(SSL, (us_socket_context_t *)webSocketContext)) WebSocketContextData<SSL, USERDATA>;
|
||||
return webSocketContext->init();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
|
||||
namespace uWS {
|
||||
|
||||
template <bool, bool> struct WebSocket;
|
||||
template <bool, bool, typename> struct WebSocket;
|
||||
|
||||
/* todo: this looks identical to WebSocketBehavior, why not just std::move that entire thing in? */
|
||||
|
||||
template <bool SSL>
|
||||
template <bool SSL, typename USERDATA>
|
||||
struct WebSocketContextData {
|
||||
private:
|
||||
/* Used for prepending unframed messages when using dedicated compressors */
|
||||
@@ -47,13 +47,13 @@ private:
|
||||
|
||||
public:
|
||||
/* The callbacks for this context */
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true> *)> openHandler = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true> *, std::string_view, OpCode)> messageHandler = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true> *)> drainHandler = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true> *, int, std::string_view)> closeHandler = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true, USERDATA> *)> openHandler = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true, USERDATA> *, std::string_view, OpCode)> messageHandler = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true, USERDATA> *)> drainHandler = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true, USERDATA> *, int, std::string_view)> closeHandler = nullptr;
|
||||
/* Todo: these should take message also; breaking change for v0.18 */
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true> *)> pingHandler = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true> *)> pongHandler = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true, USERDATA> *)> pingHandler = nullptr;
|
||||
MoveOnlyFunction<void(WebSocket<SSL, true, USERDATA> *)> pongHandler = nullptr;
|
||||
|
||||
/* Settings for this context */
|
||||
size_t maxPayloadLength = 0;
|
||||
@@ -135,7 +135,7 @@ public:
|
||||
/* However, dedicated compression has its own path */
|
||||
if (compression != SHARED_COMPRESSOR) {
|
||||
|
||||
WebSocket<SSL, true> *ws = (WebSocket<SSL, true> *) asyncSocket;
|
||||
WebSocket<SSL, true, int> *ws = (WebSocket<SSL, true, int> *) asyncSocket;
|
||||
|
||||
/* For performance reasons we always cork when in dedicated mode.
|
||||
* Is this really the best? We already kind of cork things in Zlib?
|
||||
|
||||
+3
-3
@@ -29,9 +29,9 @@ namespace uWS {
|
||||
|
||||
struct WebSocketData : AsyncSocketData<false>, WebSocketState<true> {
|
||||
/* This guy has a lot of friends - why? */
|
||||
template <bool, bool> friend struct WebSocketContext;
|
||||
template <bool> friend struct WebSocketContextData;
|
||||
template <bool, bool> friend struct WebSocket;
|
||||
template <bool, bool, typename> friend struct WebSocketContext;
|
||||
template <bool, typename> friend struct WebSocketContextData;
|
||||
template <bool, bool, typename> friend struct WebSocket;
|
||||
template <bool> friend struct HttpContext;
|
||||
private:
|
||||
std::string fragmentBuffer;
|
||||
|
||||
Reference in New Issue
Block a user