Make getUserData type safe

This commit is contained in:
Alex Hultman
2021-02-21 01:31:38 +01:00
parent c7805e2e48
commit 380b3a7134
7 changed files with 61 additions and 61 deletions
+20 -20
View File
@@ -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();
}
};