diff options
author | 2022-06-17 18:48:14 -0700 | |
---|---|---|
committer | 2022-06-22 06:56:47 -0700 | |
commit | 89f08aae2736182bc681446cab631014f51978a7 (patch) | |
tree | 2e78e88c41c1803df71369c2966ea5a75d55db3f | |
parent | 38cc869104584987d0a7f3b21be4da196bb3f390 (diff) | |
download | bun-89f08aae2736182bc681446cab631014f51978a7.tar.gz bun-89f08aae2736182bc681446cab631014f51978a7.tar.zst bun-89f08aae2736182bc681446cab631014f51978a7.zip |
more code
4 files changed, 209 insertions, 58 deletions
diff --git a/src/javascript/jsc/bindings/ScriptExecutionContext.cpp b/src/javascript/jsc/bindings/ScriptExecutionContext.cpp index 67dd30f6f..4a3b07132 100644 --- a/src/javascript/jsc/bindings/ScriptExecutionContext.cpp +++ b/src/javascript/jsc/bindings/ScriptExecutionContext.cpp @@ -12,7 +12,7 @@ us_socket_context_t* webSocketContext() { if constexpr (isSSL) { if (!m_ssl_client_websockets_ctx) { - us_loop_t* loop = (us_loop_t*)uWs::Loop::get(); + us_loop_t* loop = (us_loop_t*)uWS::Loop::get(); us_socket_context_options_t opts; memset(&opts, 0, sizeof(us_socket_context_t)); this->m_ssl_client_websockets_ctx = us_create_socket_context(1, loop, sizeof(*ScriptExecutionContext), opts); @@ -23,7 +23,7 @@ us_socket_context_t* webSocketContext() return m_ssl_client_websockets_ctx; } else { if (!m_client_websockets_ctx) { - us_loop_t* loop = (us_loop_t*)uWs::Loop::get(); + us_loop_t* loop = (us_loop_t*)uWS::Loop::get(); us_socket_context_options_t opts; memset(&opts, 0, sizeof(us_socket_context_t)); this->m_client_websockets_ctx = us_create_socket_context(0, loop, sizeof(*ScriptExecutionContext), opts); diff --git a/src/javascript/jsc/bindings/webcore/WebSocket.cpp b/src/javascript/jsc/bindings/webcore/WebSocket.cpp index 6d03a52b7..3e82af805 100644 --- a/src/javascript/jsc/bindings/webcore/WebSocket.cpp +++ b/src/javascript/jsc/bindings/webcore/WebSocket.cpp @@ -78,8 +78,6 @@ using ThreadableWebSocketChannel = WebSocketStream; using WebSocketChannelClient = WebSocketStream; WTF_MAKE_ISO_ALLOCATED_IMPL(WebSocket); -Lock WebSocket::s_allActiveWebSocketsLock; - const size_t maxReasonSizeInBytes = 123; static inline bool isValidProtocolCharacter(UChar character) @@ -150,19 +148,41 @@ WebSocket::WebSocket(ScriptExecutionContext& context) , m_handshake(url, ) { - Locker locker { allActiveWebSocketsLock() }; - allActiveWebSockets().add(this); } WebSocket::~WebSocket() { - { - Locker locker { allActiveWebSocketsLock() }; - allActiveWebSockets().remove(this); + + if (m_upgradeClient != nullptr) { + void* upgradeClient = m_upgradeClient; + if (m_isSecure) { + Bun_SecureWebSocketUpgradeClient__cancel(upgradeClient); + } else { + Bun_WebSocketUpgradeClient__cancel(upgradeClient); + } } - if (m_channel) - m_channel->disconnect(); + switch (m_connectedWebSocketKind) { + case ConnectedWebSocketKind::Client: { + this->m_connectedWebSocket.client->end(code); + break; + } + case ConnectedWebSocketKind::ClientSSL: { + this->m_connectedWebSocket.clientSSL->end(code); + break; + } + case ConnectedWebSocketKind::Server: { + this->m_connectedWebSocket.server->end(code); + break; + } + case ConnectedWebSocketKind::ServerSSL: { + this->m_connectedWebSocket.serverSSL->end(code); + break; + } + default: { + break; + } + } } ExceptionOr<Ref<WebSocket>> WebSocket::create(ScriptExecutionContext& context, const String& url) @@ -192,17 +212,6 @@ ExceptionOr<Ref<WebSocket>> WebSocket::create(ScriptExecutionContext& context, c return create(context, url, Vector<String> { 1, protocol }); } -HashSet<WebSocket*>& WebSocket::allActiveWebSockets() -{ - static NeverDestroyed<HashSet<WebSocket*>> activeWebSockets; - return activeWebSockets; -} - -Lock& WebSocket::allActiveWebSocketsLock() -{ - return s_allActiveWebSocketsLock; -} - ExceptionOr<void> WebSocket::connect(const String& url) { return connect(url, Vector<String> {}); @@ -257,7 +266,7 @@ ExceptionOr<void> WebSocket::connect(const String& url, const Vector<String>& pr if (!m_url.isValid()) { // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, ); m_state = CLOSED; - return Exception { SyntaxError, "Invalid url for WebSocket " + m_url.stringCenterEllipsizedToLength() }; + return Exception { SyntaxError, makeString("Invalid url for WebSocket "_s, m_url.stringCenterEllipsizedToLength()) }; } bool is_secure = m_url.protocolIs("wss"); @@ -265,12 +274,12 @@ ExceptionOr<void> WebSocket::connect(const String& url, const Vector<String>& pr if (!m_url.protocolIs("ws") && !is_secure) { // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, ); m_state = CLOSED; - return Exception { SyntaxError, "Wrong url scheme for WebSocket " + m_url.stringCenterEllipsizedToLength() }; + return Exception { SyntaxError, makeString("Wrong url scheme for WebSocket "_s, m_url.stringCenterEllipsizedToLength()) }; } if (m_url.hasFragmentIdentifier()) { // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, ); m_state = CLOSED; - return Exception { SyntaxError, "URL has fragment component " + m_url.stringCenterEllipsizedToLength() }; + return Exception { SyntaxError, makeString("URL has fragment component "_s, m_url.stringCenterEllipsizedToLength()) }; } // ASSERT(context.contentSecurityPolicy()); @@ -308,7 +317,7 @@ ExceptionOr<void> WebSocket::connect(const String& url, const Vector<String>& pr if (!isValidProtocolString(protocol)) { // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, ); m_state = CLOSED; - return Exception { SyntaxError, "Wrong protocol for WebSocket '" + encodeProtocolString(protocol) + "'" }; + return Exception { SyntaxError, makeString("Wrong protocol for WebSocket '"_s, encodeProtocolString(protocol), "'"_s) }; } } HashSet<String> visited; @@ -316,7 +325,7 @@ ExceptionOr<void> WebSocket::connect(const String& url, const Vector<String>& pr if (!visited.add(protocol).isNewEntry) { // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, ); m_state = CLOSED; - return Exception { SyntaxError, "WebSocket protocols contain duplicates: '" + encodeProtocolString(protocol) + "'" }; + return Exception { SyntaxError, makeString("WebSocket protocols contain duplicates:"_s, encodeProtocolString(protocol), "'"_s) }; } } @@ -343,7 +352,7 @@ ExceptionOr<void> WebSocket::connect(const String& url, const Vector<String>& pr ZigString path = Zig::toZigString(resource); ZigString clientProtocolString = Zig::toZigString(protocolString); uint16_t port = m_url.port(); - + m_isSecure = is_secure; if (is_secure) { us_socket_context_t* ctx = scriptExecutionContext->webSocketContext<true>(); RELEASE_ASSERT(ctx); @@ -357,7 +366,7 @@ ExceptionOr<void> WebSocket::connect(const String& url, const Vector<String>& pr if (this->m_upgradeClient == nullptr) { // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, ); m_state = CLOSED; - return Exception { SyntaxError, "WebSocket connection failed" }; + return Exception { SyntaxError, "WebSocket connection failed"_s }; } m_state = CONNECTING; @@ -391,10 +400,10 @@ ExceptionOr<void> WebSocket::send(const String& message) m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFramingOverhead(payloadSize)); return {}; } - // FIXME: WebSocketChannel also has a m_bufferedAmount. Remove that one. This one is the correct one accessed by JS. - m_bufferedAmount = saturateAdd(m_bufferedAmount, utf8.length()); - ASSERT(m_channel); - m_channel->send(WTFMove(utf8)); + + if (utf8.length() > 0) + this->sendWebSocketData<false>(utf8.data(), utf8.length()); + return {}; } @@ -409,9 +418,10 @@ ExceptionOr<void> WebSocket::send(ArrayBuffer& binaryData) m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFramingOverhead(payloadSize)); return {}; } - m_bufferedAmount = saturateAdd(m_bufferedAmount, binaryData.byteLength()); - ASSERT(m_channel); - m_channel->send(binaryData, 0, binaryData.byteLength()); + char* data = static_cast<char*>(binaryData.data()); + size_t length = binaryData.byteLength(); + if (length > 0) + this->sendWebSocketData<true>(data, length); return {}; } @@ -427,9 +437,14 @@ ExceptionOr<void> WebSocket::send(ArrayBufferView& arrayBufferView) m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFramingOverhead(payloadSize)); return {}; } - m_bufferedAmount = saturateAdd(m_bufferedAmount, arrayBufferView.byteLength()); ASSERT(m_channel); - m_channel->send(*arrayBufferView.unsharedBuffer(), arrayBufferView.byteOffset(), arrayBufferView.byteLength()); + + auto buffer = arrayBufferView.unsharedBuffer(); + char* baseAddress = reinterpret_cast<char*>(buffer.baseAddress()) + arrayBufferView.byteOffset(); + size_t length = arrayBufferView.byteLength(); + if (length > 0) + this->sendWebSocketData<true>(baseAddress, length); + return {}; } @@ -450,8 +465,45 @@ ExceptionOr<void> WebSocket::send(ArrayBufferView& arrayBufferView) // return {}; // } +template<bool isBinary> +void WebSocket::sendWebSocketData(const char* baseAddress, size_t length) +{ + uWS::OpCode opCode = uWS::OpCode::Text; + + if constexpr (isBinary) + opCode = uWS::OpCode::Binary; + + switch (m_connectedWebSocketKind) { + case ConnectedWebSocketKind::Client: { + this->m_connectedWebSocket.client->send({ baseAddress, length }, opCode, false); + this->m_bufferedAmount = this->m_connectedWebSocket.client->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::ClientSSL: { + this->m_connectedWebSocket.clientSSL->send({ baseAddress, length }, opCode, false); + this->m_bufferedAmount = this->m_connectedWebSocket.clientSSL->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::Server: { + this->m_connectedWebSocket.server->send({ baseAddress, length }, opCode, false); + this->m_bufferedAmount = this->m_connectedWebSocket.server->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::ServerSSL: { + this->m_connectedWebSocket.serverSSL->send({ baseAddress, length }, opCode, false); + this->m_bufferedAmount = this->m_connectedWebSocket.serverSSL->getBufferedAmount(); + break; + } + default: { + RELEASE_ASSERT_NOT_REACHED(); + } + } +} + ExceptionOr<void> WebSocket::close(std::optional<unsigned short> optionalCode, const String& reason) { + + CString utf8 = reason.utf8(StrictConversionReplacingUnpairedSurrogatesWithFFFD); int code = optionalCode ? optionalCode.value() : static_cast<int>(WebSocketChannel::CloseEventCodeNotSpecified); if (code == WebSocketChannel::CloseEventCodeNotSpecified) LOG(Network, "WebSocket %p close() without code and reason", this); @@ -459,7 +511,6 @@ ExceptionOr<void> WebSocket::close(std::optional<unsigned short> optionalCode, c LOG(Network, "WebSocket %p close() code=%d reason='%s'", this, code, reason.utf8().data()); // if (!(code == WebSocketChannel::CloseEventCodeNormalClosure || (WebSocketChannel::CloseEventCodeMinimumUserDefined <= code && code <= WebSocketChannel::CloseEventCodeMaximumUserDefined))) // return Exception { InvalidAccessError }; - CString utf8 = reason.utf8(StrictConversionReplacingUnpairedSurrogatesWithFFFD); if (utf8.length() > maxReasonSizeInBytes) { // scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, "WebSocket close message is too long."_s); return Exception { SyntaxError, "WebSocket close message is too long."_s }; @@ -470,12 +521,45 @@ ExceptionOr<void> WebSocket::close(std::optional<unsigned short> optionalCode, c return {}; if (m_state == CONNECTING) { m_state = CLOSING; - m_channel->fail("WebSocket is closed before the connection is established."_s); + if (m_upgradeClient != nullptr) { + void* upgradeClient = m_upgradeClient; + m_upgradeClient = nullptr; + if (m_isSecure) { + Bun_SecureWebSocketUpgradeClient__cancel(upgradeClient); + } else { + Bun_WebSocketUpgradeClient__cancel(upgradeClient); + } + } return {}; } m_state = CLOSING; - if (m_channel) - m_channel->close(code, reason); + switch (m_connectedWebSocketKind) { + case ConnectedWebSocketKind::Client: { + this->m_connectedWebSocket.client->end(code, { utf8.data(), utf8.length() }); + this->m_bufferedAmount = this->m_connectedWebSocket.client->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::ClientSSL: { + this->m_connectedWebSocket.clientSSL->end(code, { utf8.data(), utf8.length() }); + this->m_bufferedAmount = this->m_connectedWebSocket.clientSSL->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::Server: { + this->m_connectedWebSocket.server->end(code, { utf8.data(), utf8.length() }); + this->m_bufferedAmount = this->m_connectedWebSocket.server->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::ServerSSL: { + this->m_connectedWebSocket.serverSSL->end(code, { utf8.data(), utf8.length() }); + this->m_bufferedAmount = this->m_connectedWebSocket.serverSSL->getBufferedAmount(); + break; + } + default: { + break; + } + } + this->m_connectedWebSocketKind = ConnectedWebSocketKind::None; + return {}; } @@ -532,7 +616,7 @@ ExceptionOr<void> WebSocket::setBinaryType(const String& binaryType) return {}; } // scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, "'" + binaryType + "' is not a valid value for binaryType; binaryType remains unchanged."); - return Exception { SyntaxError, "'" + binaryType + "' is not a valid value for binaryType; binaryType remains unchanged." }; + return Exception { SyntaxError, makeString("'"_s, binaryType, "' is not a valid value for binaryType; binaryType remains unchanged."_s) }; } EventTargetInterface WebSocket::eventTargetInterface() const @@ -707,10 +791,13 @@ void WebSocket::didStartClosingHandshake() void WebSocket::didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason) { LOG(Network, "WebSocket %p didClose()", this); - // queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this, unhandledBufferedAmount, closingHandshakeCompletion, code, reason] { - if (!m_channel) + if (this->m_connectedWebSocketKind == ConnectedWebSocketKind::None) return; + // queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this, unhandledBufferedAmount, closingHandshakeCompletion, code, reason] { + // if (!m_channel) + // return; + // if (UNLIKELY(InspectorInstrumentation::hasFrontends())) { // if (auto* inspector = m_channel->channelInspector()) { // WebSocketFrame closingFrame(WebSocketFrame::OpCodeClose, true, false, false); @@ -726,10 +813,8 @@ void WebSocket::didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompl dispatchEvent(CloseEvent::create(wasClean, code, reason)); - if (m_channel) { - m_channel->disconnect(); - m_channel = nullptr; - } + this->m_connectedWebSocketKind = ConnectedWebSocketKind::None; + this->m_upgradeClient = nullptr; // m_pendingActivity = nullptr; // }); } @@ -767,10 +852,37 @@ void WebSocket::didConnect(us_socket_t* socket, char* bufferedData, size_t buffe { m_state = CONNECTED; this->m_upgradeClient = nullptr; + if (m_isSecure) { + /* Adopting a socket invalidates it, do not rely on it directly to carry any data */ + uWS::WebSocket<true, false, WebSocket*>* webSocket = (uWS::WebSocket<true, false, WebSocket*>*)us_socket_context_adopt_socket(1, + (us_socket_context_t*)this->scriptExecutionContext()->connnectedWebSocketContext<true>(), socket, sizeof(uWS::WebSocketData) + sizeof(WebSocket*)); + + webSocket->init(0, uWS::CompressOptions::disabled, uWS::Backpressure()); + *webSocket->getExt() = this; + this->m_connectedWebSocket.clientSSL = webSocket; + this->m_connectedWebSocketKind = ConnectedWebSocketKind::ClientSSL; + } else { + /* Adopting a socket invalidates it, do not rely on it directly to carry any data */ + uWS::WebSocket<false, false, WebSocket*>* webSocket = (uWS::WebSocket<false, false, WebSocket*>*)us_socket_context_adopt_socket(1, + (us_socket_context_t*)this->scriptExecutionContext()->connnectedWebSocketContext<false>(), socket, sizeof(uWS::WebSocketData) + sizeof(WebSocket*)); + + webSocket->init(0, uWS::CompressOptions::disabled, uWS::Backpressure()); + *webSocket->getExt() = this; + this->m_connectedWebSocket.client = webSocket; + this->m_connectedWebSocketKind = ConnectedWebSocketKind::Client; + } + + this->didConnect(); } void WebSocket::didFailToConnect(int32_t code) { m_state = CLOSED; + + // this means we already handled it + if (this->m_upgradeClient == nullptr) { + return; + } + this->m_upgradeClient = nullptr; switch (code) { @@ -884,11 +996,11 @@ void WebSocket::didFailToConnect(int32_t code) } } // namespace WebCore -extern "C" WebSocket__didConnect(WebSocket* webSocket, us_socket_t* socket, char* bufferedData, size_t len) +extern "C" WebSocket__didConnect(WebCore::WebSocket* webSocket, us_socket_t* socket, char* bufferedData, size_t len) { webSocket->didConnect(socket, bufferedData, len); } -extern "C" WebSocket__didFailToConnect(WebSocket* webSocket, int32_t errorCode) +extern "C" WebSocket__didFailToConnect(WebCore::WebSocket* webSocket, int32_t errorCode) { webSocket->didFailToConnect(socket, errorCode); }
\ No newline at end of file diff --git a/src/javascript/jsc/bindings/webcore/WebSocket.h b/src/javascript/jsc/bindings/webcore/WebSocket.h index ed108705c..73a6d8ca0 100644 --- a/src/javascript/jsc/bindings/webcore/WebSocket.h +++ b/src/javascript/jsc/bindings/webcore/WebSocket.h @@ -49,6 +49,14 @@ namespace WebCore { // class Blob; class WebSocket final : public RefCounted<WebSocket>, public EventTargetWithInlineData, public ContextDestructionObserver { WTF_MAKE_ISO_ALLOCATED(WebSocket); + friend struct uWS::WebSocket<false, false, WebSocket*>; + friend struct uWS::WebSocket<false, true, WebSocket*>; + friend struct uWS::WebSocket<true, false, WebSocket*>; + friend struct uWS::WebSocket<true, true, WebSocket*>; + friend WebCore::WebSocketStream; + friend WebCore::SecureWebSocketStream; + friend WebCore::ServerWebSocketStream; + friend WebCore::ServerSecureWebSocketStream; public: static ASCIILiteral subprotocolSeparator(); @@ -58,9 +66,6 @@ public: static ExceptionOr<Ref<WebSocket>> create(ScriptExecutionContext&, const String& url, const Vector<String>& protocols); ~WebSocket(); - static HashSet<WebSocket*>& allActiveWebSockets() WTF_REQUIRES_LOCK(s_allActiveWebSocketsLock); - static Lock& allActiveWebSocketsLock() WTF_RETURNS_LOCK(s_allActiveWebSocketsLock); - enum State { CONNECTING = 0, OPEN = 1, @@ -97,6 +102,20 @@ public: using RefCounted::ref; private: + typedef union AnyWebSocket { + uWS::WebSocket<false, false, WebSocket*>* client; + uWS::WebSocket<false, true, WebSocket*>* clientSSL; + uWS::WebSocket<true, false, WebSocket*>* server; + uWS::WebSocket<true, true, WebSocket*>* serverSSL; + } AnyWebSocket; + enum ConnectedWebSocketKind { + None, + Client, + ClientSSL, + Server, + ServerSSL + }; + explicit WebSocket(ScriptExecutionContext&); void dispatchErrorEventIfNeeded(); @@ -114,6 +133,7 @@ private: void didConnect(); void didReceiveMessage(String&& message); + void didReceiveData(const char* data, size_t length); void didReceiveBinaryData(Vector<uint8_t>&&); void didReceiveMessageError(String&& reason); void didUpdateBufferedAmount(unsigned bufferedAmount); @@ -121,13 +141,13 @@ private: void didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus, unsigned short code, const String& reason); void didConnect(us_socket_t* socket, char* bufferedData, size_t bufferedDataSize); void didFailToConnect(int32_t code); + void sendWebSocketData(const char* data, size_t length); void failAsynchronously(); enum class BinaryType { Blob, ArrayBuffer }; - static Lock s_allActiveWebSocketsLock; WebSocketStream* m_channel { nullptr }; State m_state { CONNECTING }; @@ -138,6 +158,9 @@ private: String m_subprotocol; String m_extensions; void* m_upgradeClient { nullptr }; + bool m_isSecure { false }; + AnyWebSocket m_connectedWebSocket { nullptr }; + ConnectedWebSocketKind m_connectedWebSocketKind { ConnectedWebSocketKind::None }; bool m_dispatchedErrorEvent { false }; // RefPtr<PendingActivity<WebSocket>> m_pendingActivity; diff --git a/src/javascript/jsc/bindings/webcore/WebSocketStream.cpp b/src/javascript/jsc/bindings/webcore/WebSocketStream.cpp index 434860854..8e059edae 100644 --- a/src/javascript/jsc/bindings/webcore/WebSocketStream.cpp +++ b/src/javascript/jsc/bindings/webcore/WebSocketStream.cpp @@ -46,7 +46,7 @@ uWS::WebSocketContext* WebSocketStreamBase<SSL, isServer>::registerClientContext /* 2 minutes timeout is good */ static unsigned short idleTimeout = 120; /* 64kb backpressure is probably good */ - static unsigned int maxBackpressure = 64 * 1024; + static unsigned int maxBackpressure = 128 * 1024 * 1024; static bool closeOnBackpressureLimit = false; /* This one depends on kernel timeouts and is a bad default */ static bool resetIdleTimeoutOnSend = false; @@ -71,13 +71,29 @@ uWS::WebSocketContext* WebSocketStreamBase<SSL, isServer>::registerClientContext opts->messageHandler = [](uWS::WebSocket<SSL, isServer, WebCore::WebSocket>* ws, std::string_view input, uWS::OpCode opCode) { auto* webSocket = ws->getUserData(); - webSocket->didReceiveData<uWS::WebSocket<SSL, isServer, WebCore::WebSocket>*>(ws, input.data(), input.length()); + if (opCode == uWS::OpCode::BINARY) { + webSocket->didReceiveBinaryData({ input.data(), input.length() }); + } else { + webSocket->didReceiveMessage(WTF::String::fromUTF8(input.data(), input.length())); + } }; + // pts->drainHandler = [](uWS::WebSocket<SSL, isServer, WebCore::WebSocket>* ws, std::string_view input, uWS::OpCode opCode) { + // auto* webSocket = ws->getUserData(); + // webSocket->didReceiveData(input.data(), input.length()); + // }; + opts->closeHandler = [](uWS::WebSocket<SSL, isServer, WebCore::WebSocket>* ws, int code, std::string_view message) { auto* webSocket = ws->getUserData(); - webSocket->didClose<uWS::WebSocket<SSL, isServer, WebCore::WebSocket>*>(ws, code, message.data(), message.length()); + webSocket->didClose( + ws->getBufferedAmount(), + code, + WTF::String::fromUTF8( + message.data(), + message.length())); }; + + return ctx; } }
\ No newline at end of file |