aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/deps/uws.zig50
-rw-r--r--src/http/websocket_http_client.zig84
-rw-r--r--src/javascript/jsc/bindings/JSFFIFunction.h1
-rw-r--r--src/javascript/jsc/bindings/ScriptExecutionContext.cpp149
-rw-r--r--src/javascript/jsc/bindings/ScriptExecutionContext.h57
-rw-r--r--src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.h10
-rw-r--r--src/javascript/jsc/bindings/ZigGlobalObject.cpp31
-rw-r--r--src/javascript/jsc/bindings/exports.zig7
-rw-r--r--src/javascript/jsc/bindings/headers-cpp.h2
-rw-r--r--src/javascript/jsc/bindings/headers-handwritten.h3
-rw-r--r--src/javascript/jsc/bindings/headers-replacements.zig3
-rw-r--r--src/javascript/jsc/bindings/headers.h22
-rw-r--r--src/javascript/jsc/bindings/headers.zig4
-rw-r--r--src/javascript/jsc/bindings/napi.h1
-rw-r--r--src/javascript/jsc/bindings/sqlite/JSSQLStatement.h1
-rw-r--r--src/javascript/jsc/bindings/webcore/EventFactory.cpp4
-rw-r--r--src/javascript/jsc/bindings/webcore/EventHeaders.h4
-rw-r--r--src/javascript/jsc/bindings/webcore/JSMessageEvent.cpp5
-rw-r--r--src/javascript/jsc/bindings/webcore/WebSocket.cpp34
-rw-r--r--src/javascript/jsc/bindings/webcore/WebSocket.h34
-rw-r--r--src/javascript/jsc/bindings/webcore/WebSocketStream.cpp80
-rw-r--r--src/javascript/jsc/bindings/webcore/WebSocketStream.h14
22 files changed, 334 insertions, 266 deletions
diff --git a/src/deps/uws.zig b/src/deps/uws.zig
index 1fbce62c5..3d3629bcb 100644
--- a/src/deps/uws.zig
+++ b/src/deps/uws.zig
@@ -17,7 +17,7 @@ pub fn NewSocketHandler(comptime ssl: bool) type {
const ThisSocket = @This();
pub fn isEstablished(this: ThisSocket) bool {
- return us_socket_is_established(comptime ssl_int, this.socket);
+ return us_socket_is_established(comptime ssl_int, this.socket) > 0;
}
pub fn timeout(this: ThisSocket, seconds: c_uint) void {
@@ -48,7 +48,7 @@ pub fn NewSocketHandler(comptime ssl: bool) type {
comptime ssl_int,
this.socket,
data.ptr,
- data.len,
+ @intCast(c_int, data.len),
@as(c_int, @boolToInt(msg_more)),
);
}
@@ -77,7 +77,7 @@ pub fn NewSocketHandler(comptime ssl: bool) type {
);
}
pub fn close(this: ThisSocket, code: c_int, reason: ?*anyopaque) void {
- return us_socket_close(
+ _ = us_socket_close(
comptime ssl_int,
this.socket,
code,
@@ -109,7 +109,7 @@ pub fn NewSocketHandler(comptime ssl: bool) type {
) ?*Context {
var stack_fallback = std.heap.stackFallback(1024, bun.default_allocator);
var allocator = stack_fallback.get();
- var host_ = allocator.dupeZ(u8, host) orelse return null;
+ var host_ = allocator.dupeZ(u8, host) catch return null;
defer allocator.free(host_);
var socket = us_socket_context_connect(comptime ssl_int, socket_ctx, host_, port, null, 0, @sizeOf(Context)) orelse return null;
@@ -136,10 +136,10 @@ pub fn NewSocketHandler(comptime ssl: bool) type {
comptime onEnd: anytype,
) void {
const SocketHandler = struct {
- pub fn on_open(socket: *Socket, _: c_int, ip: [*:0]u8, port: c_int) callconv(.C) ?*Socket {
+ pub fn on_open(socket: *Socket, _: c_int, ip: [*c]u8, port: c_int) callconv(.C) ?*Socket {
onOpen(
@ptrCast(*ContextType, @alignCast(std.meta.alignment(ContextType), us_socket_ext(comptime ssl_int, socket).?)),
- socket,
+ ThisSocket{ .socket = socket },
bun.span(ip),
port,
);
@@ -148,7 +148,7 @@ pub fn NewSocketHandler(comptime ssl: bool) type {
pub fn on_close(socket: *Socket, code: c_int, reason: ?*anyopaque) callconv(.C) ?*Socket {
onClose(
@ptrCast(*ContextType, @alignCast(std.meta.alignment(ContextType), us_socket_ext(comptime ssl_int, socket).?)),
- socket,
+ ThisSocket{ .socket = socket },
code,
reason,
);
@@ -157,29 +157,29 @@ pub fn NewSocketHandler(comptime ssl: bool) type {
pub fn on_data(socket: *Socket, buf: ?[*]u8, len: c_int) callconv(.C) ?*Socket {
onData(
@ptrCast(*ContextType, @alignCast(std.meta.alignment(ContextType), us_socket_ext(comptime ssl_int, socket).?)),
- socket,
- buf.?[0..len],
+ ThisSocket{ .socket = socket },
+ buf.?[0..@intCast(usize, len)],
);
return socket;
}
pub fn on_writable(socket: *Socket) callconv(.C) ?*Socket {
onWritable(
@ptrCast(*ContextType, @alignCast(std.meta.alignment(ContextType), us_socket_ext(comptime ssl_int, socket).?)),
- socket,
+ ThisSocket{ .socket = socket },
);
return socket;
}
pub fn on_timeout(socket: *Socket) callconv(.C) ?*Socket {
onTimeout(
@ptrCast(*ContextType, @alignCast(std.meta.alignment(ContextType), us_socket_ext(comptime ssl_int, socket).?)),
- socket,
+ ThisSocket{ .socket = socket },
);
return socket;
}
pub fn on_connect_error(socket: *Socket, code: c_int) callconv(.C) ?*Socket {
onConnectError(
@ptrCast(*ContextType, @alignCast(std.meta.alignment(ContextType), us_socket_ext(comptime ssl_int, socket).?)),
- socket,
+ ThisSocket{ .socket = socket },
code,
);
return socket;
@@ -187,7 +187,7 @@ pub fn NewSocketHandler(comptime ssl: bool) type {
pub fn on_end(socket: *Socket) callconv(.C) ?*Socket {
onEnd(
@ptrCast(*ContextType, @alignCast(std.meta.alignment(ContextType), us_socket_ext(comptime ssl_int, socket).?)),
- socket,
+ ThisSocket{ .socket = socket },
);
return socket;
}
@@ -289,23 +289,23 @@ extern fn us_socket_context_on_server_name(ssl: c_int, context: ?*us_socket_cont
extern fn us_socket_context_get_native_handle(ssl: c_int, context: ?*us_socket_context_t) ?*anyopaque;
extern fn us_create_socket_context(ssl: c_int, loop: ?*Loop, ext_size: c_int, options: us_socket_context_options_t) ?*us_socket_context_t;
extern fn us_socket_context_free(ssl: c_int, context: ?*us_socket_context_t) void;
-extern fn us_socket_context_on_open(ssl: c_int, context: ?*us_socket_context_t, on_open: fn (?*Socket, c_int, [*c]u8, c_int) callconv(.C) ?*Socket) void;
-extern fn us_socket_context_on_close(ssl: c_int, context: ?*us_socket_context_t, on_close: fn (?*Socket, c_int, ?*anyopaque) callconv(.C) ?*Socket) void;
-extern fn us_socket_context_on_data(ssl: c_int, context: ?*us_socket_context_t, on_data: fn (?*Socket, [*c]u8, c_int) callconv(.C) ?*Socket) void;
+extern fn us_socket_context_on_open(ssl: c_int, context: ?*us_socket_context_t, on_open: fn (*Socket, c_int, [*c]u8, c_int) callconv(.C) ?*Socket) void;
+extern fn us_socket_context_on_close(ssl: c_int, context: ?*us_socket_context_t, on_close: fn (*Socket, c_int, ?*anyopaque) callconv(.C) ?*Socket) void;
+extern fn us_socket_context_on_data(ssl: c_int, context: ?*us_socket_context_t, on_data: fn (*Socket, [*c]u8, c_int) callconv(.C) ?*Socket) void;
extern fn us_socket_context_on_writable(ssl: c_int, context: ?*us_socket_context_t, on_writable: fn (*Socket) callconv(.C) ?*Socket) void;
-extern fn us_socket_context_on_timeout(ssl: c_int, context: ?*us_socket_context_t, on_timeout: fn (?*Socket) callconv(.C) ?*Socket) void;
-extern fn us_socket_context_on_connect_error(ssl: c_int, context: ?*us_socket_context_t, on_connect_error: fn (?*Socket, c_int) callconv(.C) ?*Socket) void;
-extern fn us_socket_context_on_end(ssl: c_int, context: ?*us_socket_context_t, on_end: fn (?*Socket) callconv(.C) ?*Socket) void;
+extern fn us_socket_context_on_timeout(ssl: c_int, context: ?*us_socket_context_t, on_timeout: fn (*Socket) callconv(.C) ?*Socket) void;
+extern fn us_socket_context_on_connect_error(ssl: c_int, context: ?*us_socket_context_t, on_connect_error: fn (*Socket, c_int) callconv(.C) ?*Socket) void;
+extern fn us_socket_context_on_end(ssl: c_int, context: ?*us_socket_context_t, on_end: fn (*Socket) callconv(.C) ?*Socket) void;
extern fn us_socket_context_ext(ssl: c_int, context: ?*us_socket_context_t) ?*anyopaque;
extern fn us_socket_context_listen(ssl: c_int, context: ?*us_socket_context_t, host: [*c]const u8, port: c_int, options: c_int, socket_ext_size: c_int) ?*listen_socket_t;
-extern fn us_socket_context_connect(ssl: c_int, context: ?*us_socket_context_t, host: [*c]const u8, port: c_int, source_host: [*c]const u8, options: c_int, socket_ext_size: c_int) ?*Socket;
-extern fn us_socket_is_established(ssl: c_int, s: ?*Socket) c_int;
-extern fn us_socket_close_connecting(ssl: c_int, s: ?*Socket) ?*Socket;
-extern fn us_socket_context_loop(ssl: c_int, context: ?*us_socket_context_t) ?*Loop;
-extern fn us_socket_context_adopt_socket(ssl: c_int, context: ?*us_socket_context_t, s: ?*Socket, ext_size: c_int) ?*Socket;
-extern fn us_create_child_socket_context(ssl: c_int, context: ?*us_socket_context_t, context_ext_size: c_int) ?*us_socket_context_t;
+pub extern fn us_socket_context_connect(ssl: c_int, context: ?*us_socket_context_t, host: [*c]const u8, port: c_int, source_host: [*c]const u8, options: c_int, socket_ext_size: c_int) ?*Socket;
+pub extern fn us_socket_is_established(ssl: c_int, s: ?*Socket) c_int;
+pub extern fn us_socket_close_connecting(ssl: c_int, s: ?*Socket) ?*Socket;
+pub extern fn us_socket_context_loop(ssl: c_int, context: ?*us_socket_context_t) ?*Loop;
+pub extern fn us_socket_context_adopt_socket(ssl: c_int, context: ?*us_socket_context_t, s: ?*Socket, ext_size: c_int) ?*Socket;
+pub extern fn us_create_child_socket_context(ssl: c_int, context: ?*us_socket_context_t, context_ext_size: c_int) ?*us_socket_context_t;
pub const Poll = opaque {
pub fn create(
diff --git a/src/http/websocket_http_client.zig b/src/http/websocket_http_client.zig
index 5e795bb4a..d577fadc6 100644
--- a/src/http/websocket_http_client.zig
+++ b/src/http/websocket_http_client.zig
@@ -25,8 +25,8 @@ const JSC = @import("javascript_core");
const PicoHTTP = @import("picohttp");
const ObjectPool = @import("../pool.zig").ObjectPool;
-fn buildRequestBody(vm: *JSC.VirtualMachine, pathname: *const JSC.ZigString, host: *const JSC.ZigString, client_protocol: *const JSC.ZigString, client_protocol_hash: *u64) ![]u8 {
- const allocator = vm.allocator();
+fn buildRequestBody(vm: *JSC.VirtualMachine, pathname: *const JSC.ZigString, host: *const JSC.ZigString, client_protocol: *const JSC.ZigString, client_protocol_hash: *u64) std.mem.Allocator.Error![]u8 {
+ const allocator = vm.allocator;
var input_rand_buf: [16]u8 = undefined;
std.crypto.random.bytes(&input_rand_buf);
const temp_buf_size = comptime std.base64.standard.Encoder.calcSize(16);
@@ -48,23 +48,26 @@ fn buildRequestBody(vm: *JSC.VirtualMachine, pathname: *const JSC.ZigString, hos
client_protocol_hash.* = std.hash.Wyhash.hash(0, headers[1].value);
var headers_: []PicoHTTP.Header = headers[0 .. 1 + @as(usize, @boolToInt(client_protocol.len > 0))];
-
- return try std.fmt.allocPrint(allocator,
- \\GET {} HTTP/1.1\r
- \\Host: {}\r
- \\Pragma: no-cache\r
- \\Cache-Control: no-cache\r
- \\Connection: Upgrade\r
- \\Upgrade: websocket\r
- \\Sec-WebSocket-Version: 13\r
- \\{s}
- \\\r
- \\
- , .{
- pathname.*,
- host.*,
- PicoHTTP.Headers{ .headers = headers_ },
- });
+ const pathname_ = pathname.slice();
+ const host_ = host.slice();
+ const pico_headers = PicoHTTP.Headers{ .headers = headers_ };
+ return try std.fmt.allocPrint(
+ allocator,
+ "GET {s} HTTP/1.1\r\n" ++
+ "Host: {s}\r\n" ++
+ "Pragma: no-cache\r\n" ++
+ "Cache-Control: no-cache\r\n" ++
+ "Connection: Upgrade\r\n" ++
+ "Upgrade: websocket\r\n" ++
+ "Sec-WebSocket-Version: 13\r\n" ++
+ "{any}\n" ++
+ "\r\n",
+ .{
+ pathname_,
+ host_,
+ pico_headers,
+ },
+ );
}
const ErrorCode = enum(i32) {
@@ -114,13 +117,13 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
body_written: usize = 0,
websocket_protocol: u64 = 0,
- const basename = (if (ssl) "SecureWebSocket" else "WebSocket") ++ "UpgradeClient";
+ pub const name = if (ssl) "WebSocketHTTPSClient" else "WebSocketHTTPClient";
- pub const shim = JSC.Shimmer("Bun", basename, @This());
+ pub const shim = JSC.Shimmer("Bun", name, @This());
const HTTPClient = @This();
- pub fn register(global: *JSC.JSGlobalObject, loop_: *anyopaque, ctx_: *anyopaque) void {
+ pub fn register(global: *JSC.JSGlobalObject, loop_: *anyopaque, ctx_: *anyopaque) callconv(.C) void {
var vm = global.bunVM();
var loop = @ptrCast(*uws.Loop, loop_);
var ctx: *uws.us_socket_context_t = @ptrCast(*uws.us_socket_context_t, ctx_);
@@ -142,8 +145,7 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
port: u16,
pathname: *const JSC.ZigString,
client_protocol: *const JSC.ZigString,
- outgoing_usocket: **anyopaque,
- ) ?*HTTPClient {
+ ) callconv(.C) ?*HTTPClient {
std.debug.assert(global.bunVM().uws_event_loop != null);
var client_protocol_hash: u64 = 0;
@@ -158,7 +160,6 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
defer host_.deinit();
if (Socket.connect(host_.slice(), port, @ptrCast(*uws.us_socket_context_t, socket_ctx), HTTPClient, client, "socket")) |out| {
- outgoing_usocket.* = out.socket.socket;
out.socket.timeout(120);
return out;
}
@@ -179,22 +180,24 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
buf.release();
}
}
- pub fn cancel(this: *HTTPClient) void {
+ pub fn cancel(this: *HTTPClient) callconv(.C) void {
this.clearData();
if (!this.socket.isEstablished()) {
- _ = uws.us_socket_close_connecting(comptime @as(c_int, @boolToInt(ssl)), this.socket);
+ _ = uws.us_socket_close_connecting(comptime @as(c_int, @boolToInt(ssl)), this.socket.socket);
} else {
this.socket.close(0, null);
}
}
pub fn fail(this: *HTTPClient, code: ErrorCode) void {
+ JSC.markBinding();
WebSocket__didFailToConnect(this.outgoing_websocket, code);
this.cancel();
}
pub fn handleClose(this: *HTTPClient, _: Socket, _: c_int, _: ?*anyopaque) void {
+ JSC.markBinding();
this.clearData();
WebSocket__didFailToConnect(this.outgoing_websocket, ErrorCode.closed);
}
@@ -205,7 +208,7 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
this.socket.close(0, null);
}
- pub fn handleOpen(this: *HTTPClient, socket: Socket) void {
+ pub fn handleOpen(this: *HTTPClient, socket: Socket, _: []const u8, _: c_int) void {
std.debug.assert(socket.socket == this.socket.socket);
std.debug.assert(this.input_body_buf.len > 0);
@@ -247,7 +250,7 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
const to_write = remain[0..@minimum(remain.len, data.len)];
if (data.len > 0 and to_write.len > 0) {
- @memcpy(remain.ptr, data, to_write.len);
+ @memcpy(remain.ptr, data.ptr, to_write.len);
this.body_written += to_write.len;
}
@@ -299,7 +302,7 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
"Connection".len => {
if (connection_header.name.len == 0 and strings.eqlCaseInsensitiveASCII(header.name, "Connection", false)) {
connection_header = header;
- if (visited_protocol and upgrade_header.len > 0 and connection_header.len > 0 and websocket_accept_header.len > 0 and visited_version) {
+ if (visited_protocol and upgrade_header.name.len > 0 and connection_header.name.len > 0 and websocket_accept_header.name.len > 0 and visited_version) {
break;
}
}
@@ -307,7 +310,7 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
"Upgrade".len => {
if (upgrade_header.name.len == 0 and strings.eqlCaseInsensitiveASCII(header.name, "Upgrade", false)) {
upgrade_header = header;
- if (visited_protocol and upgrade_header.len > 0 and connection_header.len > 0 and websocket_accept_header.len > 0 and visited_version) {
+ if (visited_protocol and upgrade_header.name.len > 0 and connection_header.name.len > 0 and websocket_accept_header.name.len > 0 and visited_version) {
break;
}
}
@@ -315,7 +318,7 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
"Sec-WebSocket-Version".len => {
if (!visited_version and strings.eqlCaseInsensitiveASCII(header.name, "Sec-WebSocket-Version", false)) {
visited_version = true;
- if (!strings.eqlComptime(header.value, "13", false)) {
+ if (!strings.eqlComptimeIgnoreLen(header.value, "13")) {
this.terminate(ErrorCode.invalid_websocket_version);
return;
}
@@ -324,7 +327,7 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
"Sec-WebSocket-Accept".len => {
if (websocket_accept_header.name.len == 0 and strings.eqlCaseInsensitiveASCII(header.name, "Sec-WebSocket-Accept", false)) {
websocket_accept_header = header;
- if (visited_protocol and upgrade_header.len > 0 and connection_header.len > 0 and websocket_accept_header.len > 0 and visited_version) {
+ if (visited_protocol and upgrade_header.name.len > 0 and connection_header.name.len > 0 and websocket_accept_header.name.len > 0 and visited_version) {
break;
}
}
@@ -337,7 +340,7 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
}
visited_protocol = true;
- if (visited_protocol and upgrade_header.len > 0 and connection_header.len > 0 and websocket_accept_header.len > 0 and visited_version) {
+ if (visited_protocol and upgrade_header.name.len > 0 and connection_header.name.len > 0 and websocket_accept_header.name.len > 0 and visited_version) {
break;
}
}
@@ -395,6 +398,7 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
}
this.clearData();
+ JSC.markBinding();
WebSocket__didConnect(this.outgoing_websocket, this.socket.socket, overflow.ptr, overflow.len);
}
@@ -425,7 +429,7 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
this.terminate(ErrorCode.failed_to_connect);
}
- const Exports = shim.exportFunctions(.{
+ pub const Export = shim.exportFunctions(.{
.connect = connect,
.cancel = cancel,
.register = register,
@@ -434,18 +438,18 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type {
comptime {
if (!JSC.is_bindgen) {
@export(connect, .{
- .name = Exports[0].symbol_name,
+ .name = Export[0].symbol_name,
});
@export(cancel, .{
- .name = Exports[1].symbol_name,
+ .name = Export[1].symbol_name,
});
@export(register, .{
- .name = Exports[2].symbol_name,
+ .name = Export[2].symbol_name,
});
}
}
};
}
-pub const WebSocketUpgradeClient = NewHTTPUpgradeClient(false);
-pub const SecureWebSocketUpgradeClient = NewHTTPUpgradeClient(true);
+pub const WebSocketHTTPClient = NewHTTPUpgradeClient(false);
+pub const WebSocketHTTPSClient = NewHTTPUpgradeClient(true);
diff --git a/src/javascript/jsc/bindings/JSFFIFunction.h b/src/javascript/jsc/bindings/JSFFIFunction.h
index 4d6818db8..e30beb5ea 100644
--- a/src/javascript/jsc/bindings/JSFFIFunction.h
+++ b/src/javascript/jsc/bindings/JSFFIFunction.h
@@ -10,7 +10,6 @@ class GlobalObject;
#include "headers-handwritten.h"
#include "BunClientData.h"
-#include "WebCoreJSBuiltinInternals.h"
#include "JavaScriptCore/CallFrame.h"
namespace JSC {
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
diff --git a/src/javascript/jsc/bindings/ScriptExecutionContext.h b/src/javascript/jsc/bindings/ScriptExecutionContext.h
index f966cf5f6..ea8302356 100644
--- a/src/javascript/jsc/bindings/ScriptExecutionContext.h
+++ b/src/javascript/jsc/bindings/ScriptExecutionContext.h
@@ -14,20 +14,18 @@
namespace uWS {
template<bool isServer, bool isClient, typename UserData>
struct WebSocketContext;
+
}
struct us_socket_t;
struct us_socket_context_t;
+struct us_loop_t;
namespace WebCore {
-class ScriptExecutionContext : public CanMakeWeakPtr<ScriptExecutionContext> {
+class WebSocket;
+class ScriptExecutionContext : public CanMakeWeakPtr<ScriptExecutionContext> {
public:
- ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* globalObject)
- : m_vm(vm)
- , m_globalObject(globalObject)
- {
- }
class Task {
WTF_MAKE_FAST_ALLOCATED;
@@ -62,16 +60,27 @@ public:
bool m_isCleanupTask;
};
+public:
+ ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* globalObject)
+ : m_vm(vm)
+ , m_globalObject(globalObject)
+ {
+ }
+
JSC::JSGlobalObject* jsGlobalObject()
{
return m_globalObject;
}
template<bool isSSL>
- us_socket_context_t* webSocketContext();
-
- template<bool isSSL, bool isServer>
- uWS::WebSocketContext<isSSL, isServer, ScriptExecutionContext*>* connnectedWebSocketContext();
+ us_socket_context_t* webSocketContext()
+ {
+ if constexpr (isSSL) {
+ return this->webSocketContextSSL();
+ } else {
+ return this->webSocketContextNoSSL();
+ }
+ }
const WTF::URL& url() const { return m_url; }
bool activeDOMObjectsAreSuspended() { return false; }
@@ -107,10 +116,34 @@ private:
JSC::JSGlobalObject* m_globalObject = nullptr;
WTF::URL m_url = WTF::URL();
+ us_socket_context_t* webSocketContextSSL();
+ us_socket_context_t* webSocketContextNoSSL();
+ uWS::WebSocketContext<true, false, WebSocket*>* connectedWebSocketKindClientSSL();
+ uWS::WebSocketContext<false, false, WebSocket*>* connectedWebSocketKindClient();
+
us_socket_context_t* m_ssl_client_websockets_ctx = nullptr;
us_socket_context_t* m_client_websockets_ctx = nullptr;
- uWS::WebSocketContext<true, false, ScriptExecutionContext*>* m_connected_ssl_client_websockets_ctx = nullptr;
- uWS::WebSocketContext<true, true, ScriptExecutionContext*>* m_connected_client_websockets_ctx = nullptr;
+ uWS::WebSocketContext<true, false, WebSocket*>* m_connected_ssl_client_websockets_ctx = nullptr;
+ uWS::WebSocketContext<false, false, WebSocket*>* m_connected_client_websockets_ctx = nullptr;
+
+public:
+ template<bool isSSL, bool isServer>
+ uWS::WebSocketContext<isSSL, isServer, WebSocket*>* connnectedWebSocketContext()
+ {
+ if constexpr (isSSL) {
+ if (!m_connected_ssl_client_websockets_ctx) {
+ m_connected_ssl_client_websockets_ctx = connectedWebSocketKindClientSSL();
+ }
+
+ return m_connected_ssl_client_websockets_ctx;
+ } else {
+ if (!m_connected_client_websockets_ctx) {
+ m_connected_client_websockets_ctx = connectedWebSocketKindClient();
+ }
+
+ return m_connected_client_websockets_ctx;
+ }
+ }
};
} \ No newline at end of file
diff --git a/src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.h b/src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.h
index c52f65d85..d533abeec 100644
--- a/src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.h
+++ b/src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.h
@@ -1,5 +1,7 @@
//clang-format off
-namespace Zig { class GlobalObject; }
+namespace Zig {
+class GlobalObject;
+}
/*
* Copyright (c) 2015 Igalia
* Copyright (c) 2015 Igalia S.L.
@@ -8,7 +10,7 @@ namespace Zig { class GlobalObject; }
* Copyright (c) 2015, 2016, 2017 Canon Inc.
* Copyright (c) 2016, 2020 Apple Inc. All rights reserved.
* Copyright (c) 2022 Codeblog Corp. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -17,7 +19,7 @@ namespace Zig { class GlobalObject; }
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
@@ -29,7 +31,7 @@ namespace Zig { class GlobalObject; }
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
- *
+ *
*/
// DO NOT EDIT THIS FILE. It is automatically generated from JavaScript files for
diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp
index 6890c045b..53872f325 100644
--- a/src/javascript/jsc/bindings/ZigGlobalObject.cpp
+++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp
@@ -1,4 +1,5 @@
+#include "root.h"
#include "ZigGlobalObject.h"
#include "helpers.h"
@@ -135,6 +136,8 @@ using JSBuffer = WebCore::JSBuffer;
#include "JavaScriptCore/BuiltinNames.h"
#include "JSTextEncoder.h"
#include "StructuredClone.h"
+#include "JSWebSocket.h"
+#include "JSMessageEvent.h"
#include "ReadableStream.h"
#include "JSSink.h"
@@ -453,6 +456,28 @@ JSC_DEFINE_CUSTOM_GETTER(JSCloseEvent_getter,
WebCore::JSCloseEvent::getConstructor(JSC::getVM(lexicalGlobalObject), thisObject));
}
+JSC_DECLARE_CUSTOM_GETTER(JSMessageEvent_getter);
+
+JSC_DEFINE_CUSTOM_GETTER(JSMessageEvent_getter,
+ (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
+ JSC::PropertyName))
+{
+ Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
+ return JSC::JSValue::encode(
+ WebCore::JSMessageEvent::getConstructor(JSC::getVM(lexicalGlobalObject), thisObject));
+}
+
+JSC_DECLARE_CUSTOM_GETTER(JSWebSocket_getter);
+
+JSC_DEFINE_CUSTOM_GETTER(JSWebSocket_getter,
+ (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
+ JSC::PropertyName))
+{
+ Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
+ return JSC::JSValue::encode(
+ WebCore::JSWebSocket::getConstructor(JSC::getVM(lexicalGlobalObject), thisObject));
+}
+
JSC_DECLARE_CUSTOM_GETTER(JSEvent_getter);
JSC_DEFINE_CUSTOM_GETTER(JSEvent_getter,
@@ -1872,6 +1897,12 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "CloseEvent"_s), JSC::CustomGetterSetter::create(vm, JSCloseEvent_getter, nullptr),
JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
+ putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "MessageEvent"_s), JSC::CustomGetterSetter::create(vm, JSMessageEvent_getter, nullptr),
+ JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
+
+ putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "WebSocket"_s), JSC::CustomGetterSetter::create(vm, JSWebSocket_getter, nullptr),
+ JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
+
putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "Buffer"_s), JSC::CustomGetterSetter::create(vm, JSBuffer_getter, nullptr),
JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "TextEncoder"_s), JSC::CustomGetterSetter::create(vm, JSTextEncoder_getter, nullptr),
diff --git a/src/javascript/jsc/bindings/exports.zig b/src/javascript/jsc/bindings/exports.zig
index 04142d040..0c9c2a677 100644
--- a/src/javascript/jsc/bindings/exports.zig
+++ b/src/javascript/jsc/bindings/exports.zig
@@ -186,6 +186,10 @@ pub const JSReadableStreamFile = JSC.WebCore.FileBlobLoader.Source.JSReadableStr
// Sinks
pub const JSArrayBufferSink = JSC.WebCore.ArrayBufferSink.JSSink;
+// WebSocket
+pub const WebSocketHTTPClient = @import("../../../http/websocket_http_client.zig").WebSocketHTTPClient;
+pub const WebSocketHTTSPClient = @import("../../../http/websocket_http_client.zig").WebSocketHTTPSClient;
+
pub fn Errorable(comptime Type: type) type {
return extern struct {
result: Result,
@@ -2504,6 +2508,9 @@ pub const BunTimer = Bun.Timer;
pub const Formatter = ZigConsoleClient.Formatter;
comptime {
+ WebSocketHTTPClient.shim.ref();
+ WebSocketHTTSPClient.shim.ref();
+
if (!is_bindgen) {
_ = Process.getTitle;
_ = Process.setTitle;
diff --git a/src/javascript/jsc/bindings/headers-cpp.h b/src/javascript/jsc/bindings/headers-cpp.h
index 09731ce13..8d44b538a 100644
--- a/src/javascript/jsc/bindings/headers-cpp.h
+++ b/src/javascript/jsc/bindings/headers-cpp.h
@@ -1,4 +1,4 @@
-//-- AUTOGENERATED FILE -- 1655351052
+//-- AUTOGENERATED FILE -- 1655526456
// clang-format off
#pragma once
diff --git a/src/javascript/jsc/bindings/headers-handwritten.h b/src/javascript/jsc/bindings/headers-handwritten.h
index a2f15cb74..995393b93 100644
--- a/src/javascript/jsc/bindings/headers-handwritten.h
+++ b/src/javascript/jsc/bindings/headers-handwritten.h
@@ -187,6 +187,9 @@ typedef struct StringPointer {
} StringPointer;
#endif
+typedef void WebSocketHTTPClient;
+typedef void WebSocketHTTPSClient;
+
#ifdef __cplusplus
extern "C" ZigErrorCode Zig_ErrorCodeParserError;
diff --git a/src/javascript/jsc/bindings/headers-replacements.zig b/src/javascript/jsc/bindings/headers-replacements.zig
index 4491c79af..80f3dd6dc 100644
--- a/src/javascript/jsc/bindings/headers-replacements.zig
+++ b/src/javascript/jsc/bindings/headers-replacements.zig
@@ -65,3 +65,6 @@ pub const struct_WebCore__FetchHeaders = bindings.FetchHeaders;
pub const StringPointer = @import("../../../api/schema.zig").Api.StringPointer;
pub const struct_VirtualMachine = bindings.VirtualMachine;
pub const ArrayBufferSink = @import("../webcore/streams.zig").ArrayBufferSink;
+
+pub const WebSocketHTTPClient = bindings.WebSocketHTTPClient;
+pub const WebSocketHTTPSClient = bindings.WebSocketHTTPSClient;
diff --git a/src/javascript/jsc/bindings/headers.h b/src/javascript/jsc/bindings/headers.h
index 0257c39ed..0a23cdd2c 100644
--- a/src/javascript/jsc/bindings/headers.h
+++ b/src/javascript/jsc/bindings/headers.h
@@ -1,5 +1,5 @@
// clang-format: off
-//-- AUTOGENERATED FILE -- 1655351052
+//-- AUTOGENERATED FILE -- 1655526456
#pragma once
#include <stddef.h>
@@ -137,6 +137,7 @@ typedef bJSC__Identifier JSC__Identifier; // JSC::Identifier
typedef struct JSC__ArrayPrototype JSC__ArrayPrototype; // JSC::ArrayPrototype
typedef struct Zig__JSMicrotaskCallback Zig__JSMicrotaskCallback; // Zig::JSMicrotaskCallback
typedef bJSC__JSPromise JSC__JSPromise; // JSC::JSPromise
+typedef WebSocketHTTPClient WebSocketHTTPClient;
typedef struct JSC__SetIteratorPrototype JSC__SetIteratorPrototype; // JSC::SetIteratorPrototype
typedef SystemError SystemError;
typedef bJSC__JSCell JSC__JSCell; // JSC::JSCell
@@ -155,6 +156,7 @@ typedef struct JSC__CallFrame JSC__CallFrame; // JSC::CallFrame
typedef bWTF__StringView WTF__StringView; // WTF::StringView
typedef bJSC__ThrowScope JSC__ThrowScope; // JSC::ThrowScope
typedef bWTF__StringImpl WTF__StringImpl; // WTF::StringImpl
+typedef WebSocketHTTPSClient WebSocketHTTPSClient;
typedef bJSC__VM JSC__VM; // JSC::VM
typedef JSClassRef JSClassRef;
typedef Bun__ArrayBuffer Bun__ArrayBuffer;
@@ -235,9 +237,11 @@ class ScriptArguments;
typedef ErrorableResolvedSource ErrorableResolvedSource;
typedef ErrorableZigString ErrorableZigString;
+typedef WebSocketHTTPClient WebSocketHTTPClient;
typedef SystemError SystemError;
typedef Bun__Writable Bun__Writable;
typedef Bun__Readable Bun__Readable;
+typedef WebSocketHTTPSClient WebSocketHTTPSClient;
typedef JSClassRef JSClassRef;
typedef Bun__ArrayBuffer Bun__ArrayBuffer;
typedef ZigException ZigException;
@@ -792,6 +796,22 @@ ZIG_DECL JSC__JSValue ArrayBufferSink__write(JSC__JSGlobalObject* arg0, JSC__Cal
#ifdef __cplusplus
+ZIG_DECL void Bun__WebSocketHTTPClient__cancel(WebSocketHTTPClient* arg0);
+ZIG_DECL WebSocketHTTPClient* Bun__WebSocketHTTPClient__connect(JSC__JSGlobalObject* arg0, void* arg1, void* arg2, const ZigString* arg3, uint16_t arg4, const ZigString* arg5, const ZigString* arg6);
+ZIG_DECL void Bun__WebSocketHTTPClient__register(JSC__JSGlobalObject* arg0, void* arg1, void* arg2);
+
+#endif
+
+#ifdef __cplusplus
+
+ZIG_DECL void Bun__WebSocketHTTPSClient__cancel(WebSocketHTTPSClient* arg0);
+ZIG_DECL WebSocketHTTPSClient* Bun__WebSocketHTTPSClient__connect(JSC__JSGlobalObject* arg0, void* arg1, void* arg2, const ZigString* arg3, uint16_t arg4, const ZigString* arg5, const ZigString* arg6);
+ZIG_DECL void Bun__WebSocketHTTPSClient__register(JSC__JSGlobalObject* arg0, void* arg1, void* arg2);
+
+#endif
+
+#ifdef __cplusplus
+
ZIG_DECL void Bun__Process__exit(JSC__JSGlobalObject* arg0, int32_t arg1);
ZIG_DECL JSC__JSValue Bun__Process__getArgv(JSC__JSGlobalObject* arg0);
ZIG_DECL JSC__JSValue Bun__Process__getCwd(JSC__JSGlobalObject* arg0);
diff --git a/src/javascript/jsc/bindings/headers.zig b/src/javascript/jsc/bindings/headers.zig
index ee59be0a4..4b05ed250 100644
--- a/src/javascript/jsc/bindings/headers.zig
+++ b/src/javascript/jsc/bindings/headers.zig
@@ -65,6 +65,9 @@ pub const struct_WebCore__FetchHeaders = bindings.FetchHeaders;
pub const StringPointer = @import("../../../api/schema.zig").Api.StringPointer;
pub const struct_VirtualMachine = bindings.VirtualMachine;
pub const ArrayBufferSink = @import("../webcore/streams.zig").ArrayBufferSink;
+
+pub const WebSocketHTTPClient = bindings.WebSocketHTTPClient;
+pub const WebSocketHTTPSClient = bindings.WebSocketHTTPSClient;
// GENERATED CODE - DO NOT MODIFY BY HAND
pub const ptrdiff_t = c_long;
@@ -261,7 +264,6 @@ pub extern fn JSC__JSGlobalObject__putCachedObject(arg0: [*c]JSC__JSGlobalObject
pub extern fn JSC__JSGlobalObject__regExpPrototype(arg0: [*c]JSC__JSGlobalObject) ?*JSC__RegExpPrototype;
pub extern fn JSC__JSGlobalObject__setIteratorPrototype(arg0: [*c]JSC__JSGlobalObject) ?*JSC__SetIteratorPrototype;
pub extern fn JSC__JSGlobalObject__startRemoteInspector(arg0: [*c]JSC__JSGlobalObject, arg1: [*c]u8, arg2: u16) bool;
-pub extern fn JSC__JSGlobalObject__stopRemoteInspector(arg0: [*c]JSC__JSGlobalObject) void;
pub extern fn JSC__JSGlobalObject__stringPrototype(arg0: [*c]JSC__JSGlobalObject) ?*JSC__StringPrototype;
pub extern fn JSC__JSGlobalObject__symbolPrototype(arg0: [*c]JSC__JSGlobalObject) [*c]JSC__JSObject;
pub extern fn JSC__JSGlobalObject__vm(arg0: [*c]JSC__JSGlobalObject) [*c]JSC__VM;
diff --git a/src/javascript/jsc/bindings/napi.h b/src/javascript/jsc/bindings/napi.h
index 4a9743d6e..754c34ec4 100644
--- a/src/javascript/jsc/bindings/napi.h
+++ b/src/javascript/jsc/bindings/napi.h
@@ -10,7 +10,6 @@ class GlobalObject;
#include "headers-handwritten.h"
#include "BunClientData.h"
-#include "WebCoreJSBuiltinInternals.h"
#include "JavaScriptCore/CallFrame.h"
#include "js_native_api_types.h"
#include "JavaScriptCore/JSWeakValue.h"
diff --git a/src/javascript/jsc/bindings/sqlite/JSSQLStatement.h b/src/javascript/jsc/bindings/sqlite/JSSQLStatement.h
index 51e8fba99..6bf830ee2 100644
--- a/src/javascript/jsc/bindings/sqlite/JSSQLStatement.h
+++ b/src/javascript/jsc/bindings/sqlite/JSSQLStatement.h
@@ -33,7 +33,6 @@
#include "headers-handwritten.h"
#include "BunClientData.h"
-#include "WebCoreJSBuiltinInternals.h"
#include "JavaScriptCore/CallFrame.h"
#if defined(__APPLE__)
diff --git a/src/javascript/jsc/bindings/webcore/EventFactory.cpp b/src/javascript/jsc/bindings/webcore/EventFactory.cpp
index 0c431eb9f..3677b9dfe 100644
--- a/src/javascript/jsc/bindings/webcore/EventFactory.cpp
+++ b/src/javascript/jsc/bindings/webcore/EventFactory.cpp
@@ -156,8 +156,8 @@ JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObj
// case MerchantValidationEventInterfaceType:
// return createWrapper<MerchantValidationEvent>(globalObject, WTFMove(impl));
// #endif
- // case MessageEventInterfaceType:
- // return createWrapper<MessageEvent>(globalObject, WTFMove(impl));
+ case MessageEventInterfaceType:
+ return createWrapper<MessageEvent>(globalObject, WTFMove(impl));
// case MouseEventInterfaceType:
// return createWrapper<MouseEvent>(globalObject, WTFMove(impl));
// case MutationEventInterfaceType:
diff --git a/src/javascript/jsc/bindings/webcore/EventHeaders.h b/src/javascript/jsc/bindings/webcore/EventHeaders.h
index 3937c5c2b..347d333d0 100644
--- a/src/javascript/jsc/bindings/webcore/EventHeaders.h
+++ b/src/javascript/jsc/bindings/webcore/EventHeaders.h
@@ -146,8 +146,8 @@
// #include "MerchantValidationEvent.h"
// #include "JSMerchantValidationEvent.h"
// #endif
-// #include "MessageEvent.h"
-// #include "JSMessageEvent.h"
+#include "MessageEvent.h"
+#include "JSMessageEvent.h"
// #include "MouseEvent.h"
// #include "JSMouseEvent.h"
// #include "MutationEvent.h"
diff --git a/src/javascript/jsc/bindings/webcore/JSMessageEvent.cpp b/src/javascript/jsc/bindings/webcore/JSMessageEvent.cpp
index 4b951a5a6..ef0a1093d 100644
--- a/src/javascript/jsc/bindings/webcore/JSMessageEvent.cpp
+++ b/src/javascript/jsc/bindings/webcore/JSMessageEvent.cpp
@@ -419,9 +419,10 @@ static inline JSC::EncodedJSValue jsMessageEventPrototypeFunction_initMessageEve
// RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
// EnsureStillAliveScope argument7 = callFrame->argument(7);
// auto messagePorts = JSArray::create(lexicalGlobalObject.vm(), lexicalGlobalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 0);
- auto messagePorts = Converter<IDLSequence<IDLInterface<MessagePort>>>::ReturnType {};
+ // auto messagePorts = Converter<IDLSequence<IDLInterface<MessagePort>>>::ReturnType {};
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
- RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.initMessageEvent(WTFMove(type), WTFMove(bubbles), WTFMove(cancelable), WTFMove(data), WTFMove(originArg), WTFMove(lastEventId), WTFMove(source), WTFMove(messagePorts)); })));
+ // RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.initMessageEvent(WTFMove(type), WTFMove(bubbles), WTFMove(cancelable), WTFMove(data), WTFMove(originArg), WTFMove(lastEventId), WTFMove(source), WTFMove(messagePorts)); })));
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.initMessageEvent(WTFMove(type), WTFMove(bubbles), WTFMove(cancelable), WTFMove(data), WTFMove(originArg), WTFMove(lastEventId), WTFMove(source)); })));
}
JSC_DEFINE_HOST_FUNCTION(jsMessageEventPrototypeFunction_initMessageEvent, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
diff --git a/src/javascript/jsc/bindings/webcore/WebSocket.cpp b/src/javascript/jsc/bindings/webcore/WebSocket.cpp
index dff4500be..691da6aae 100644
--- a/src/javascript/jsc/bindings/webcore/WebSocket.cpp
+++ b/src/javascript/jsc/bindings/webcore/WebSocket.cpp
@@ -31,7 +31,8 @@
#include "config.h"
#include "WebSocket.h"
-
+#include "WebSocketStream.h"
+#include "headers.h"
// #include "Blob.h"
#include "CloseEvent.h"
// #include "ContentSecurityPolicy.h"
@@ -75,9 +76,6 @@
// #include "WebCoreThreadRun.h"
// #endif
namespace WebCore {
-using WebSocketChannel = WebSocketStream;
-using ThreadableWebSocketChannel = WebSocketStream;
-using WebSocketChannelClient = WebSocketStream;
WTF_MAKE_ISO_ALLOCATED_IMPL(WebSocket);
static size_t getFramingOverhead(size_t payloadSize)
@@ -170,9 +168,9 @@ WebSocket::~WebSocket()
if (m_upgradeClient != nullptr) {
void* upgradeClient = m_upgradeClient;
if (m_isSecure) {
- Bun_SecureWebSocketUpgradeClient__cancel(upgradeClient);
+ Bun__WebSocketHTTPSClient__cancel(upgradeClient);
} else {
- Bun_WebSocketUpgradeClient__cancel(upgradeClient);
+ Bun__WebSocketHTTPClient__cancel(upgradeClient);
}
}
@@ -374,11 +372,11 @@ ExceptionOr<void> WebSocket::connect(const String& url, const Vector<String>& pr
if (is_secure) {
us_socket_context_t* ctx = scriptExecutionContext()->webSocketContext<true>();
RELEASE_ASSERT(ctx);
- this->m_upgradeClient = Bun_SecureWebSocketUpgradeClient__connect(scriptExecutionContext()->jsGlobalObject(), ctx, this, &host, port, &path, &clientProtocolString);
+ this->m_upgradeClient = Bun__WebSocketHTTPSClient__connect(scriptExecutionContext()->jsGlobalObject(), ctx, this, &host, port, &path, &clientProtocolString);
} else {
us_socket_context_t* ctx = scriptExecutionContext()->webSocketContext<false>();
RELEASE_ASSERT(ctx);
- this->m_upgradeClient = Bun_WebSocketUpgradeClient__connect(scriptExecutionContext()->jsGlobalObject(), ctx, this, &host, port, &path, &clientProtocolString);
+ this->m_upgradeClient = Bun__WebSocketHTTPClient__connect(scriptExecutionContext()->jsGlobalObject(), ctx, this, &host, port, &path, &clientProtocolString);
}
if (this->m_upgradeClient == nullptr) {
@@ -455,7 +453,6 @@ ExceptionOr<void> WebSocket::send(ArrayBufferView& arrayBufferView)
m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFramingOverhead(payloadSize));
return {};
}
- ASSERT(m_channel);
auto buffer = arrayBufferView.unsharedBuffer().get();
char* baseAddress = reinterpret_cast<char*>(buffer->data()) + arrayBufferView.byteOffset();
@@ -522,8 +519,8 @@ ExceptionOr<void> WebSocket::close(std::optional<unsigned short> optionalCode, c
{
CString utf8 = reason.utf8(StrictConversionReplacingUnpairedSurrogatesWithFFFD);
- int code = optionalCode ? optionalCode.value() : static_cast<int>(WebSocketChannel::CloseEventCodeNotSpecified);
- if (code == WebSocketChannel::CloseEventCodeNotSpecified)
+ int code = optionalCode ? optionalCode.value() : static_cast<int>(0);
+ if (code == 0)
LOG(Network, "WebSocket %p close() without code and reason", this);
else {
LOG(Network, "WebSocket %p close() code=%d reason='%s'", this, code, reason.utf8().data());
@@ -543,9 +540,9 @@ ExceptionOr<void> WebSocket::close(std::optional<unsigned short> optionalCode, c
void* upgradeClient = m_upgradeClient;
m_upgradeClient = nullptr;
if (m_isSecure) {
- Bun_SecureWebSocketUpgradeClient__cancel(upgradeClient);
+ Bun__WebSocketHTTPSClient__cancel(upgradeClient);
} else {
- Bun_WebSocketUpgradeClient__cancel(upgradeClient);
+ Bun__WebSocketHTTPClient__cancel(upgradeClient);
}
}
return {};
@@ -581,11 +578,6 @@ ExceptionOr<void> WebSocket::close(std::optional<unsigned short> optionalCode, c
return {};
}
-WebSocketChannelClient* WebSocket::channel() const
-{
- return m_channel;
-}
-
const URL& WebSocket::url() const
{
return m_url;
@@ -697,7 +689,7 @@ void WebSocket::didConnect()
if (m_state == CLOSED)
return;
if (m_state != CONNECTING) {
- didClose(0, ClosingHandshakeIncomplete, WebSocketChannel::CloseEventCodeAbnormalClosure, emptyString());
+ didClose(0, 0, emptyString());
return;
}
ASSERT(scriptExecutionContext());
@@ -787,7 +779,7 @@ void WebSocket::didStartClosingHandshake()
// });
}
-void WebSocket::didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason)
+void WebSocket::didClose(unsigned unhandledBufferedAmount, unsigned short code, const String& reason)
{
LOG(Network, "WebSocket %p didClose()", this);
if (this->m_connectedWebSocketKind == ConnectedWebSocketKind::None)
@@ -805,7 +797,7 @@ void WebSocket::didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompl
// }
// }
- bool wasClean = m_state == CLOSING && !unhandledBufferedAmount && closingHandshakeCompletion == ClosingHandshakeComplete && code != WebSocketChannel::CloseEventCodeAbnormalClosure;
+ bool wasClean = m_state == CLOSING && !unhandledBufferedAmount && code != 0; // WebSocketChannel::CloseEventCodeAbnormalClosure;
m_state = CLOSED;
m_bufferedAmount = unhandledBufferedAmount;
ASSERT(scriptExecutionContext());
diff --git a/src/javascript/jsc/bindings/webcore/WebSocket.h b/src/javascript/jsc/bindings/webcore/WebSocket.h
index b75bc346c..351e8c6b6 100644
--- a/src/javascript/jsc/bindings/webcore/WebSocket.h
+++ b/src/javascript/jsc/bindings/webcore/WebSocket.h
@@ -37,7 +37,10 @@
#include <wtf/HashSet.h>
#include <wtf/Lock.h>
-#include "WebSocketStream.h"
+namespace uWS {
+template<bool, bool, typename>
+struct WebSocket;
+}
namespace JSC {
class ArrayBuffer;
@@ -49,14 +52,6 @@ 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();
@@ -85,8 +80,6 @@ public:
ExceptionOr<void> close(std::optional<unsigned short> code, const String& reason);
- WebSocketStream* channel() const;
-
const URL& url() const;
State readyState() const;
unsigned bufferedAmount() const;
@@ -102,16 +95,20 @@ public:
using RefCounted::deref;
using RefCounted::ref;
void didConnect();
- void didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus, unsigned short code, const String& reason);
+ void didClose(unsigned unhandledBufferedAmount, unsigned short code, const String& reason);
void didConnect(us_socket_t* socket, char* bufferedData, size_t bufferedDataSize);
void didFailToConnect(int32_t code);
+ void didReceiveMessage(String&& message);
+ void didReceiveData(const char* data, size_t length);
+ void didReceiveBinaryData(Vector<uint8_t>&&);
+
private:
typedef union AnyWebSocket {
- uWS::WebSocket<false, false, WebSocket*>* client;
- uWS::WebSocket<true, false, WebSocket*>* clientSSL;
- uWS::WebSocket<false, true, WebSocket*>* server;
- uWS::WebSocket<true, true, WebSocket*>* serverSSL;
+ uWS::WebSocket<false, false, WebCore::WebSocket*>* client;
+ uWS::WebSocket<true, false, WebCore::WebSocket*>* clientSSL;
+ uWS::WebSocket<false, true, WebCore::WebSocket*>* server;
+ uWS::WebSocket<true, true, WebCore::WebSocket*>* serverSSL;
} AnyWebSocket;
enum ConnectedWebSocketKind {
None,
@@ -137,9 +134,6 @@ private:
void refEventTarget() final { ref(); }
void derefEventTarget() final { deref(); }
- void didReceiveMessage(String&& message);
- void didReceiveData(const char* data, size_t length);
- void didReceiveBinaryData(Vector<uint8_t>&&);
void didReceiveMessageError(WTF::StringImpl::StaticStringImpl* reason);
void didUpdateBufferedAmount(unsigned bufferedAmount);
void didStartClosingHandshake();
@@ -152,8 +146,6 @@ private:
enum class BinaryType { Blob,
ArrayBuffer };
- WebSocketStream* m_channel { nullptr };
-
State m_state { CONNECTING };
URL m_url;
unsigned m_bufferedAmount { 0 };
diff --git a/src/javascript/jsc/bindings/webcore/WebSocketStream.cpp b/src/javascript/jsc/bindings/webcore/WebSocketStream.cpp
index 9aa480bbe..c318130b8 100644
--- a/src/javascript/jsc/bindings/webcore/WebSocketStream.cpp
+++ b/src/javascript/jsc/bindings/webcore/WebSocketStream.cpp
@@ -1,88 +1,10 @@
#include "root.h"
+#include "headers.h"
#include "WebSocketStream.h"
#include "ScriptExecutionContext.h"
#include <uws/src/App.h>
#include <uws/uSockets/src/libusockets.h>
-
namespace WebCore {
-template<bool SSL, bool isServer>
-void registerHTTPContextForWebSocket(ScriptExecutionContext* script, us_socket_context_t* ctx, us_loop_t* loop)
-{
- if constexpr (!isServer) {
- if constexpr (SSL) {
- Bun__SecureWebSocketUpgradeClient__register(script->jsGlobalObject(), loop, ctx);
- } else {
- Bun__WebSocketUpgradeClient__register(script->jsGlobalObject(), loop, ctx);
- }
- } else {
- RELEASE_ASSERT_NOT_REACHED();
- }
-}
-
-template<bool SSL, bool isServer>
-uWS::WebSocketContext<SSL, isServer, ScriptExecutionContext*>* registerWebSocketClientContext(ScriptExecutionContext* script, us_socket_context_t* parent)
-{
- uWS::Loop* loop = uWS::Loop::get();
- uWS::WebSocketContext<SSL, isServer, ScriptExecutionContext*>* ctx = uWS::WebSocketContext<SSL, isServer>::create(loop, parent, nullptr);
- auto* opts = ctx->getExt();
- ScriptExecutionContext** scriptCtx = ctx->getUserData();
- *scriptCtx = script;
-
- /* 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 = false;
-
- opts->openHandler = [](uWS::WebSocket<SSL, isServer, WebCore::WebSocket>* ws) {
- auto* webSocket = ws->getUserData();
- webSocket->didOpen();
- };
-
- opts->messageHandler = [](uWS::WebSocket<SSL, isServer, WebCore::WebSocket>* ws, std::string_view input, uWS::OpCode opCode) {
- auto* webSocket = ws->getUserData();
- 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(
- ws->getBufferedAmount(),
- code,
- WTF::String::fromUTF8(
- message.data(),
- message.length()));
- };
-
- return ctx;
-}
-
} \ No newline at end of file
diff --git a/src/javascript/jsc/bindings/webcore/WebSocketStream.h b/src/javascript/jsc/bindings/webcore/WebSocketStream.h
index b6a2595a3..78c142864 100644
--- a/src/javascript/jsc/bindings/webcore/WebSocketStream.h
+++ b/src/javascript/jsc/bindings/webcore/WebSocketStream.h
@@ -29,6 +29,7 @@
*/
#pragma once
+#include "root.h"
#include "wtf/text/StringImpl.h"
#include "wtf/text/StringView.h"
@@ -36,6 +37,8 @@
#include "wtf/URL.h"
#include "wtf/Vector.h"
#include "wtf/Function.h"
+#include "ScriptExecutionContext.h"
+#include "headers.h"
namespace uWS {
template<bool, bool, typename>
@@ -111,15 +114,4 @@ public:
}
};
-template<bool isSSL, bool isServer>
-void registerHTTPContextForWebSocket(ScriptExecutionContext*, us_socket_context_t*);
-
-template<bool SSL, bool isServer>
-uWS::WebSocketContext<SSL, isServer, ScriptExecutionContext*>* registerWebSocketClientContext(ScriptExecutionContext*, us_socket_context_t* parent);
-
-using WebSocketStream = WebSocketStreamBase<false, false>;
-using SecureWebSocketStream = WebSocketStreamBase<true, false>;
-using ServerWebSocketStream = WebSocketStreamBase<false, true>;
-using ServerSecureWebSocketStream = WebSocketStreamBase<true, true>;
-
} // namespace WebCore