Make getUserData type safe
This commit is contained in:
+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();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user