diff --git a/src/App.h b/src/App.h index 7e1d469..717c9ae 100644 --- a/src/App.h +++ b/src/App.h @@ -184,16 +184,11 @@ public: /* Add mark, we don't want to end anything */ res->writeHeader("WebSocket-Server", "uWebSockets")->end(); - /* bug: memory leak? What about HttpResponseData here? I'm thinking not delete it but destruct it? */ - /* Esp. if the functions hold dynamic memory like something big */ + /* Move any backpressure */ + std::string backpressure(std::move(((AsyncSocketData *) res->getHttpResponseData())->buffer)); - /* Vad om vi inte får plats i cork, och vi har vårt svar i corkbuffern */ - - /* vad om vi är en socket som har endat, men har svaret i sin buffer och strömmas ut? */ - - /* vi antar att vi kan bara kasta asyncsocketdata här */ - - /* res.end ska egentligen inte sätta att man svarat på den före den har drainats */ + /* Destroy HttpResponseData */ + 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)( @@ -202,8 +197,9 @@ public: /* Update corked socket in case we got a new one (assuming we always are corked in handlers). */ webSocket->cork(); + /* Initialize websocket with any moved backpressure intact */ httpContext->upgradeToWebSocket( - webSocket->init(perMessageDeflate, slidingDeflateWindow) + webSocket->init(perMessageDeflate, slidingDeflateWindow, std::move(backpressure)) ); /* Emit open event and start the timeout */ diff --git a/src/AsyncSocketData.h b/src/AsyncSocketData.h index d8b04f0..0e121da 100644 --- a/src/AsyncSocketData.h +++ b/src/AsyncSocketData.h @@ -26,6 +26,14 @@ template struct AsyncSocketData { /* This will do for now */ std::string buffer; + + /* Allow move constructing us */ + AsyncSocketData(std::string &&backpressure) : buffer(std::move(backpressure)) { + + } + + /* Or emppty */ + AsyncSocketData() = default; }; #endif // ASYNCSOCKETDATA_H diff --git a/src/HttpResponse.h b/src/HttpResponse.h index 8596729..b465dbe 100644 --- a/src/HttpResponse.h +++ b/src/HttpResponse.h @@ -39,6 +39,8 @@ static const int HTTP_TIMEOUT_S = 10; template struct HttpResponse : public AsyncSocket { + /* Solely used for getHttpResponseData() */ + template friend struct TemplatedApp; typedef AsyncSocket Super; private: HttpResponseData *getHttpResponseData() { diff --git a/src/WebSocket.h b/src/WebSocket.h index 0d96680..2378788 100644 --- a/src/WebSocket.h +++ b/src/WebSocket.h @@ -35,8 +35,8 @@ private: using SOCKET_CONTEXT_TYPE = typename StaticDispatch::SOCKET_CONTEXT_TYPE; using StaticDispatch::static_dispatch; - void *init(bool perMessageDeflate, bool slidingCompression) { - new (static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this)) WebSocketData(perMessageDeflate, slidingCompression); + 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)); return this; } public: diff --git a/src/WebSocketData.h b/src/WebSocketData.h index ae00bf6..2359e5f 100644 --- a/src/WebSocketData.h +++ b/src/WebSocketData.h @@ -26,7 +26,6 @@ namespace uWS { -// take care with get_ext here ! struct WebSocketData : AsyncSocketData, WebSocketState { template friend struct WebSocketContext; template friend struct WebSocket; @@ -43,7 +42,7 @@ private: /* We might have a dedicated compressor */ DeflationStream *deflationStream = nullptr; public: - WebSocketData(bool perMessageDeflate, bool slidingCompression) : WebSocketState() { + WebSocketData(bool perMessageDeflate, bool slidingCompression, std::string &&backpressure) : AsyncSocketData(std::move(backpressure)), WebSocketState() { compressionStatus = perMessageDeflate ? ENABLED : DISABLED; /* Initialize the dedicated sliding window */