diff options
Diffstat (limited to 'src/javascript/jsc/bindings/ScriptExecutionContext.cpp')
-rw-r--r-- | src/javascript/jsc/bindings/ScriptExecutionContext.cpp | 149 |
1 files changed, 108 insertions, 41 deletions
diff --git a/src/javascript/jsc/bindings/ScriptExecutionContext.cpp b/src/javascript/jsc/bindings/ScriptExecutionContext.cpp index 17bc266dc..b89e0645f 100644 --- a/src/javascript/jsc/bindings/ScriptExecutionContext.cpp +++ b/src/javascript/jsc/bindings/ScriptExecutionContext.cpp @@ -1,62 +1,129 @@ - +#include "root.h" +#include "headers.h" #include "ScriptExecutionContext.h" + +#include "webcore/WebSocket.h" + #include <uws/src/App.h> -#include "WebSocketStream.h" extern "C" void Bun__startLoop(us_loop_t* loop); namespace WebCore { -template<bool isSSL> -us_socket_context_t* ScriptExecutionContext::webSocketContext() +template<bool SSL, bool isServer> +static void registerHTTPContextForWebSocket(ScriptExecutionContext* script, us_socket_context_t* ctx, us_loop_t* loop) { - if constexpr (isSSL) { - if (!m_ssl_client_websockets_ctx) { - us_loop_t* loop = (us_loop_t*)uWS::Loop::get(); - us_socket_context_options_t opts; - memset(&opts, 0, sizeof(us_socket_context_options_t)); - this->m_ssl_client_websockets_ctx = us_create_socket_context(1, loop, sizeof(size_t), opts); - void** ptr = reinterpret_cast<void**>(us_socket_context_ext(1, m_ssl_client_websockets_ctx)); - *ptr = this; - registerHTTPContextForWebSocket<isSSL, false>(this, m_ssl_client_websockets_ctx); + if constexpr (!isServer) { + if constexpr (SSL) { + Bun__WebSocketHTTPSClient__register(script->jsGlobalObject(), loop, ctx); + } else { + Bun__WebSocketHTTPClient__register(script->jsGlobalObject(), loop, ctx); } - - return m_ssl_client_websockets_ctx; } else { - if (!m_client_websockets_ctx) { - us_loop_t* loop = (us_loop_t*)uWS::Loop::get(); - us_socket_context_options_t opts; - memset(&opts, 0, sizeof(us_socket_context_options_t)); - this->m_client_websockets_ctx = us_create_socket_context(0, loop, sizeof(size_t), opts); - void** ptr = reinterpret_cast<void**>(us_socket_context_ext(0, m_client_websockets_ctx)); - *ptr = this; - registerHTTPContextForWebSocket<isSSL, false>(this, m_client_websockets_ctx); - } + RELEASE_ASSERT_NOT_REACHED(); + } +} - return m_client_websockets_ctx; +us_socket_context_t* ScriptExecutionContext::webSocketContextSSL() +{ + if (!m_ssl_client_websockets_ctx) { + us_loop_t* loop = (us_loop_t*)uWS::Loop::get(); + us_socket_context_options_t opts; + memset(&opts, 0, sizeof(us_socket_context_options_t)); + this->m_ssl_client_websockets_ctx = us_create_socket_context(1, loop, sizeof(size_t), opts); + void** ptr = reinterpret_cast<void**>(us_socket_context_ext(1, m_ssl_client_websockets_ctx)); + *ptr = this; + registerHTTPContextForWebSocket<true, false>(this, m_ssl_client_websockets_ctx, loop); } + + return m_ssl_client_websockets_ctx; } -template<bool isSSL, bool isServer> -uWS::WebSocketContext<isSSL, isServer, ScriptExecutionContext*>* ScriptExecutionContext::connnectedWebSocketContext() +us_socket_context_t* ScriptExecutionContext::webSocketContextNoSSL() { - if constexpr (isSSL) { - if (!m_connected_ssl_client_websockets_ctx) { - // should be the parent - RELEASE_ASSERT(m_ssl_client_websockets_ctx); - m_connected_client_websockets_ctx = registerWebSocketClientContext(this, webSocketContext<isSSL>()); - } + if (!m_client_websockets_ctx) { + us_loop_t* loop = (us_loop_t*)uWS::Loop::get(); + us_socket_context_options_t opts; + memset(&opts, 0, sizeof(us_socket_context_options_t)); + this->m_client_websockets_ctx = us_create_socket_context(0, loop, sizeof(size_t), opts); + void** ptr = reinterpret_cast<void**>(us_socket_context_ext(0, m_client_websockets_ctx)); + *ptr = this; + registerHTTPContextForWebSocket<false, false>(this, m_client_websockets_ctx, loop); + } - return m_connected_ssl_client_websockets_ctx; - } else { - if (!m_connected_client_websockets_ctx) { - // should be the parent - RELEASE_ASSERT(m_client_websockets_ctx); - m_connected_client_websockets_ctx = registerWebSocketClientContext(this, webSocketContext<isSSL>()); + return m_client_websockets_ctx; +} + +template<bool SSL> +static uWS::WebSocketContext<SSL, false, WebCore::WebSocket*>* registerWebSocketClientContext(ScriptExecutionContext* script, us_socket_context_t* parent) +{ + uWS::Loop* loop = uWS::Loop::get(); + uWS::WebSocketContext<SSL, false, WebCore::WebSocket*>* ctx = uWS::WebSocketContext<SSL, false, WebCore::WebSocket*>::createClient(loop, parent); + + auto* opts = ctx->getExt(); + + /* Maximum message size we can receive */ + static unsigned int maxPayloadLength = 128 * 1024 * 1024; + /* 2 minutes timeout is good */ + static unsigned short idleTimeout = 120; + /* 64kb backpressure is probably good */ + 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; + /* A good default, esp. for newcomers */ + static bool sendPingsAutomatically = true; + /* Maximum socket lifetime in seconds before forced closure (defaults to disabled) */ + static unsigned short maxLifetime = 0; + + opts->maxPayloadLength = maxPayloadLength; + opts->maxBackpressure = maxBackpressure; + opts->closeOnBackpressureLimit = closeOnBackpressureLimit; + opts->resetIdleTimeoutOnSend = resetIdleTimeoutOnSend; + opts->sendPingsAutomatically = sendPingsAutomatically; + // opts->compression = compression; + // TODO: + opts->compression = uWS::CompressOptions::DISABLED; + + opts->openHandler = [](uWS::WebSocket<SSL, false, WebCore::WebSocket*>* ws) { + WebCore::WebSocket* webSocket = *ws->getUserData(); + webSocket->didConnect(); + }; + + opts->messageHandler = [](uWS::WebSocket<SSL, false, WebCore::WebSocket*>* ws, std::string_view input, uWS::OpCode opCode) { + WebCore::WebSocket* webSocket = *ws->getUserData(); + if (opCode == uWS::OpCode::BINARY) { + webSocket->didReceiveBinaryData({ const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(input.data())), input.length() }); + } else { + webSocket->didReceiveMessage(WTF::String::fromUTF8(input.data(), input.length())); } + }; - return m_connected_client_websockets_ctx; - } + // pts->drainHandler = [](uWS::WebSocket<SSL, false, WebCore::WebSocket>* ws, std::string_view input, uWS::OpCode opCode) { + // WebCore::WebSocket* webSocket = *ws->getUserData(); + // webSocket->didReceiveData(input.data(), input.length()); + // }; + + opts->closeHandler = [](uWS::WebSocket<SSL, false, WebCore::WebSocket*>* ws, int code, std::string_view message) { + WebCore::WebSocket* webSocket = *ws->getUserData(); + webSocket->didClose( + ws->getBufferedAmount(), + code, + WTF::String::fromUTF8( + message.data(), + message.length())); + }; + + return ctx; +} + +uWS::WebSocketContext<false, false, WebSocket*>* ScriptExecutionContext::connectedWebSocketKindClient() +{ + return registerWebSocketClientContext<false>(this, webSocketContextNoSSL()); +} +uWS::WebSocketContext<true, false, WebSocket*>* ScriptExecutionContext::connectedWebSocketKindClientSSL() +{ + return registerWebSocketClientContext<true>(this, webSocketContextSSL()); } }
\ No newline at end of file |