diff options
author | 2023-07-03 16:19:50 -0300 | |
---|---|---|
committer | 2023-07-03 12:19:50 -0700 | |
commit | a7a01bd52f20e7908f06d4de9a1814902b838a4b (patch) | |
tree | 7c06354f17b98cb09eeb33c31dde70cb053bfa72 /src/bun.js | |
parent | 48d726bfd0701f8e33442f2c7075dc8191a2ccb4 (diff) | |
download | bun-a7a01bd52f20e7908f06d4de9a1814902b838a4b.tar.gz bun-a7a01bd52f20e7908f06d4de9a1814902b838a4b.tar.zst bun-a7a01bd52f20e7908f06d4de9a1814902b838a4b.zip |
[tls] add socket parameter, setServername and ALPNprotocols support (#3457)
* add socket parameter support
* refactor #socket
* add test and more fixs
* some fixes
* bump uws
* handlers fix
* more fixes
* fix node net and node tls tests
* fix duplicate port
* fix deinit on CallbackJobs
* cleanup
* add setImmediate repro
* add test to setImmediate
* this is necessary?
* fix prependOnce on native listener
* try to findout the error on nodemailer CI
* show error message
* Update bun.lockb
* prettier
* Use exact versions of packages
* add alpnProtocol support
* update
* emit error when connect fails on net.Socket
* format
* fix _write and cleanup
* fixup
* fix connect, add alpn test
* fix socket.io
* add socket parameter to TLSSocket
* add TLSSocket socket first parameter
* fixup and _start
* remove flask tests
* fmt
---------
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/bun.js')
-rw-r--r-- | src/bun.js/api/bun.zig | 2 | ||||
-rw-r--r-- | src/bun.js/api/bun/socket.zig | 544 | ||||
-rw-r--r-- | src/bun.js/api/server.zig | 48 | ||||
-rw-r--r-- | src/bun.js/api/sockets.classes.ts | 16 | ||||
-rw-r--r-- | src/bun.js/bindings/JSSink.cpp | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/JSSink.h | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/JSSinkLookupTable.h | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGeneratedClasses.cpp | 218 | ||||
-rw-r--r-- | src/bun.js/bindings/generated_classes.zig | 26 | ||||
-rw-r--r-- | src/bun.js/bindings/webcore/JSEventEmitter.cpp | 2 |
10 files changed, 795 insertions, 67 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig index 2e6381c74..1e5a5e004 100644 --- a/src/bun.js/api/bun.zig +++ b/src/bun.js/api/bun.zig @@ -3794,6 +3794,8 @@ pub const Timer = struct { result.then(globalThis, this, CallbackJob__onResolve, CallbackJob__onReject); }, } + } else { + this.deinit(); } } }; diff --git a/src/bun.js/api/bun/socket.zig b/src/bun.js/api/bun/socket.zig index 69d6611cb..329cc40e4 100644 --- a/src/bun.js/api/bun/socket.zig +++ b/src/bun.js/api/bun/socket.zig @@ -69,6 +69,11 @@ fn normalizeHost(input: anytype) @TypeOf(input) { const BinaryType = JSC.BinaryType; +const WrappedType = enum { + none, + tls, + tcp, +}; const Handlers = struct { onOpen: JSC.JSValue = .zero, onClose: JSC.JSValue = .zero, @@ -97,8 +102,8 @@ const Handlers = struct { handlers: *Handlers, socket_context: *uws.SocketContext, - pub fn exit(this: *Scope, ssl: bool) void { - this.handlers.markInactive(ssl, this.socket_context); + pub fn exit(this: *Scope, ssl: bool, wrapped: WrappedType) void { + this.handlers.markInactive(ssl, this.socket_context, wrapped); } }; @@ -123,19 +128,24 @@ const Handlers = struct { return true; } - pub fn markInactive(this: *Handlers, ssl: bool, ctx: *uws.SocketContext) void { + pub fn markInactive(this: *Handlers, ssl: bool, ctx: *uws.SocketContext, wrapped: WrappedType) void { Listener.log("markInactive", .{}); this.active_connections -= 1; - if (this.active_connections == 0 and this.is_server) { - var listen_socket: *Listener = @fieldParentPtr(Listener, "handlers", this); - // allow it to be GC'd once the last connection is closed and it's not listening anymore - if (listen_socket.listener == null) { - listen_socket.strong_self.clear(); + if (this.active_connections == 0) { + if (this.is_server) { + var listen_socket: *Listener = @fieldParentPtr(Listener, "handlers", this); + // allow it to be GC'd once the last connection is closed and it's not listening anymore + if (listen_socket.listener == null) { + listen_socket.strong_self.clear(); + } + } else { + this.unprotect(); + // will deinit when is not wrapped or when is the TCP wrapped connection + if (wrapped != .tls) { + ctx.deinit(ssl); + } + bun.default_allocator.destroy(this); } - } else if (this.active_connections == 0 and !this.is_server) { - this.unprotect(); - ctx.deinit(ssl); - bun.default_allocator.destroy(this); } } @@ -364,6 +374,7 @@ pub const Listener = struct { connection: UnixOrHost, socket_context: ?*uws.SocketContext = null, ssl: bool = false, + protos: ?[]const u8 = null, strong_data: JSC.Strong = .{}, strong_self: JSC.Strong = .{}, @@ -395,6 +406,19 @@ pub const Listener = struct { port: u16, }, + pub fn clone(this: UnixOrHost) UnixOrHost { + switch (this) { + .unix => |u| { + return .{ + .unix = (bun.default_allocator.dupe(u8, u) catch unreachable), + }; + }, + .host => |h| { + return .{ .host = .{ .host = (bun.default_allocator.dupe(u8, h.host) catch unreachable), .port = this.host.port } }; + }, + } + } + pub fn deinit(this: UnixOrHost) void { switch (this) { .unix => |u| { @@ -455,10 +479,12 @@ pub const Listener = struct { var socket_config = SocketConfig.fromJS(opts, globalObject, exception) orelse { return .zero; }; + var hostname_or_unix = socket_config.hostname_or_unix; var port = socket_config.port; var ssl = socket_config.ssl; var handlers = socket_config.handlers; + var protos: ?[]const u8 = null; const exclusive = socket_config.exclusive; handlers.is_server = true; @@ -496,6 +522,10 @@ pub const Listener = struct { }; if (ssl_enabled) { + if (ssl.?.protos) |p| { + protos = p[0..ssl.?.protos_len]; + } + uws.NewSocketHandler(true).configure( socket_context, true, @@ -593,6 +623,7 @@ pub const Listener = struct { .ssl = ssl_enabled, .socket_context = socket_context, .listener = listen_socket, + .protos = if (protos) |p| (bun.default_allocator.dupe(u8, p) catch unreachable) else null, }; socket.handlers.protect(); @@ -649,6 +680,8 @@ pub const Listener = struct { .handlers = &listener.handlers, .this_value = .zero, .socket = socket, + .protos = listener.protos, + .owned_protos = false, }; if (listener.strong_data.get()) |default_data| { const globalObject = listener.handlers.globalObject; @@ -715,6 +748,10 @@ pub const Listener = struct { this.handlers.unprotect(); this.connection.deinit(); + if (this.protos) |protos| { + this.protos = null; + bun.default_allocator.destroy(protos); + } bun.default_allocator.destroy(this); } @@ -775,13 +812,16 @@ pub const Listener = struct { const socket_config = SocketConfig.fromJS(opts, globalObject, exception) orelse { return .zero; }; + var hostname_or_unix = socket_config.hostname_or_unix; var port = socket_config.port; var ssl = socket_config.ssl; var handlers = socket_config.handlers; var default_data = socket_config.default_data; + var protos: ?[]const u8 = null; const ssl_enabled = ssl != null; + defer if (ssl != null) ssl.?.deinit(); handlers.protect(); @@ -797,6 +837,9 @@ pub const Listener = struct { }; if (ssl_enabled) { + if (ssl.?.protos) |p| { + protos = p[0..ssl.?.protos_len]; + } uws.NewSocketHandler(true).configure( socket_context, true, @@ -848,6 +891,7 @@ pub const Listener = struct { .this_value = .zero, .socket = undefined, .connection = connection, + .protos = if (protos) |p| (bun.default_allocator.dupe(u8, p) catch unreachable) else null, }; TLSSocket.dataSetCached(tls.getThisValue(globalObject), globalObject, default_data); @@ -871,6 +915,7 @@ pub const Listener = struct { .this_value = .zero, .socket = undefined, .connection = null, + .protos = null, }; TCPSocket.dataSetCached(tcp.getThisValue(globalObject), globalObject, default_data); @@ -898,11 +943,41 @@ fn JSSocketType(comptime ssl: bool) type { } } +fn selectALPNCallback( + _: ?*BoringSSL.SSL, + out: [*c][*c]const u8, + outlen: [*c]u8, + in: [*c]const u8, + inlen: c_uint, + arg: ?*anyopaque, +) callconv(.C) c_int { + const this = bun.cast(*TLSSocket, arg); + if (this.protos) |protos| { + if (protos.len == 0) { + return BoringSSL.SSL_TLSEXT_ERR_NOACK; + } + + const status = BoringSSL.SSL_select_next_proto(bun.cast([*c][*c]u8, out), outlen, protos.ptr, @intCast(c_uint, protos.len), in, inlen); + + // Previous versions of Node.js returned SSL_TLSEXT_ERR_NOACK if no protocol + // match was found. This would neither cause a fatal alert nor would it result + // in a useful ALPN response as part of the Server Hello message. + // We now return SSL_TLSEXT_ERR_ALERT_FATAL in that case as per Section 3.2 + // of RFC 7301, which causes a fatal no_application_protocol alert. + const expected = if (comptime BoringSSL.OPENSSL_NPN_NEGOTIATED == 1) BoringSSL.SSL_TLSEXT_ERR_OK else BoringSSL.SSL_TLSEXT_ERR_ALERT_FATAL; + + return if (status == expected) 1 else 0; + } else { + return BoringSSL.SSL_TLSEXT_ERR_NOACK; + } +} + fn NewSocket(comptime ssl: bool) type { return struct { pub const Socket = uws.NewSocketHandler(ssl); socket: Socket, detached: bool = false, + wrapped: WrappedType = .none, handlers: *Handlers, this_value: JSC.JSValue = .zero, poll_ref: JSC.PollRef = JSC.PollRef.init(), @@ -910,6 +985,8 @@ fn NewSocket(comptime ssl: bool) type { last_4: [4]u8 = .{ 0, 0, 0, 0 }, authorized: bool = false, connection: ?Listener.UnixOrHost = null, + protos: ?[]const u8, + owned_protos: bool = true, // TODO: switch to something that uses `visitAggregate` and have the // `Listener` keep a list of all the sockets JSValue in there @@ -1079,7 +1156,7 @@ fn NewSocket(comptime ssl: bool) type { var vm = this.handlers.vm; this.reffer.unref(vm); - this.handlers.markInactive(ssl, this.socket.context()); + this.handlers.markInactive(ssl, this.socket.context(), this.wrapped); this.poll_ref.unref(vm); this.has_pending_activity.store(false, .Release); } @@ -1091,25 +1168,35 @@ fn NewSocket(comptime ssl: bool) type { // Add SNI support for TLS (mongodb and others requires this) if (comptime ssl) { - if (this.connection) |connection| { - if (connection == .host) { - const host = normalizeHost(connection.host.host); - if (host.len > 0) { - var ssl_ptr: *BoringSSL.SSL = @ptrCast(*BoringSSL.SSL, socket.getNativeHandle()); - if (!ssl_ptr.isInitFinished()) { + var ssl_ptr: *BoringSSL.SSL = @ptrCast(*BoringSSL.SSL, socket.getNativeHandle()); + if (!ssl_ptr.isInitFinished()) { + if (this.connection) |connection| { + if (connection == .host) { + const host = normalizeHost(connection.host.host); + if (host.len > 0) { var host__ = default_allocator.dupeZ(u8, host) catch unreachable; defer default_allocator.free(host__); ssl_ptr.setHostname(host__); } } } + if (this.protos) |protos| { + if (this.handlers.is_server) { + BoringSSL.SSL_CTX_set_alpn_select_cb(BoringSSL.SSL_get_SSL_CTX(ssl_ptr), selectALPNCallback, bun.cast(*anyopaque, this)); + } else { + _ = BoringSSL.SSL_set_alpn_protos(ssl_ptr, protos.ptr, @intCast(c_uint, protos.len)); + } + } } } this.poll_ref.ref(this.handlers.vm); this.detached = false; this.socket = socket; - socket.ext(**anyopaque).?.* = bun.cast(**anyopaque, this); + + if (this.wrapped == .none) { + socket.ext(**anyopaque).?.* = bun.cast(**anyopaque, this); + } const handlers = this.handlers; const callback = handlers.onOpen; @@ -1174,7 +1261,7 @@ fn NewSocket(comptime ssl: bool) type { // the handlers must be kept alive for the duration of the function call // that way if we need to call the error handler, we can var scope = handlers.enter(socket.context()); - defer scope.exit(ssl); + defer scope.exit(ssl, this.wrapped); const globalObject = handlers.globalObject; const this_value = this.getThisValue(globalObject); @@ -1211,7 +1298,7 @@ fn NewSocket(comptime ssl: bool) type { // the handlers must be kept alive for the duration of the function call // that way if we need to call the error handler, we can var scope = handlers.enter(socket.context()); - defer scope.exit(ssl); + defer scope.exit(ssl, this.wrapped); const globalObject = handlers.globalObject; const this_value = this.getThisValue(globalObject); @@ -1255,7 +1342,6 @@ fn NewSocket(comptime ssl: bool) type { log("onClose", .{}); this.detached = true; defer this.markInactive(); - const handlers = this.handlers; this.poll_ref.unref(handlers.vm); @@ -1265,7 +1351,7 @@ fn NewSocket(comptime ssl: bool) type { // the handlers must be kept alive for the duration of the function call // that way if we need to call the error handler, we can var scope = handlers.enter(socket.context()); - defer scope.exit(ssl); + defer scope.exit(ssl, this.wrapped); var globalObject = handlers.globalObject; const this_value = this.getThisValue(globalObject); @@ -1295,7 +1381,7 @@ fn NewSocket(comptime ssl: bool) type { // the handlers must be kept alive for the duration of the function call // that way if we need to call the error handler, we can var scope = handlers.enter(socket.context()); - defer scope.exit(ssl); + defer scope.exit(ssl, this.wrapped); // const encoding = handlers.encoding; const result = callback.callWithThis(globalObject, this_value, &[_]JSValue{ @@ -1476,10 +1562,20 @@ fn NewSocket(comptime ssl: bool) type { } fn writeMaybeCorked(this: *This, buffer: []const u8, is_end: bool) i32 { - if (this.socket.isShutdown() or this.socket.isClosed()) { + if (this.detached or this.socket.isShutdown() or this.socket.isClosed()) { return -1; } // we don't cork yet but we might later + + if (comptime ssl) { + // TLS wrapped but in TCP mode + if (this.wrapped == .tcp) { + const res = this.socket.rawWrite(buffer, is_end); + log("write({d}, {any}) = {d}", .{ buffer.len, is_end, res }); + return res; + } + } + const res = this.socket.write(buffer, is_end); log("write({d}, {any}) = {d}", .{ buffer.len, is_end, res }); return res; @@ -1487,7 +1583,6 @@ fn NewSocket(comptime ssl: bool) type { fn writeOrEnd(this: *This, globalObject: *JSC.JSGlobalObject, args: []const JSC.JSValue, is_end: bool) WriteResult { if (args.len == 0) return .{ .success = .{} }; - if (args.ptr[0].asArrayBuffer(globalObject)) |array_buffer| { var slice = array_buffer.slice(); @@ -1681,9 +1776,6 @@ fn NewSocket(comptime ssl: bool) type { if (result.wrote == result.total) { this.socket.flush(); this.detached = true; - if (!this.socket.isClosed()) { - this.socket.close(0, null); - } this.markInactive(); } break :brk JSValue.jsNumber(result.wrote); @@ -1706,17 +1798,27 @@ fn NewSocket(comptime ssl: bool) type { pub fn finalize(this: *This) callconv(.C) void { log("finalize()", .{}); - if (this.detached) return; - this.detached = true; - if (!this.socket.isClosed()) { - this.socket.close(0, null); + if (!this.detached) { + this.detached = true; + if (!this.socket.isClosed()) { + this.socket.close(0, null); + } + this.markInactive(); + } + + this.poll_ref.unref(JSC.VirtualMachine.get()); + // need to deinit event without being attached + if (this.owned_protos) { + if (this.protos) |protos| { + this.protos = null; + default_allocator.free(protos); + } } + if (this.connection) |connection| { - connection.deinit(); this.connection = null; + connection.deinit(); } - this.markInactive(); - this.poll_ref.unref(JSC.VirtualMachine.get()); } pub fn reload(this: *This, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue { @@ -1756,8 +1858,376 @@ fn NewSocket(comptime ssl: bool) type { return JSValue.jsUndefined(); } + + pub fn getALPNProtocol( + this: *This, + globalObject: *JSC.JSGlobalObject, + ) callconv(.C) JSValue { + if (comptime ssl == false) { + return JSValue.jsBoolean(false); + } + + if (this.detached) { + return JSValue.jsBoolean(false); + } + + var alpn_proto: [*c]const u8 = null; + var alpn_proto_len: u32 = 0; + + var ssl_ptr: *BoringSSL.SSL = @ptrCast(*BoringSSL.SSL, this.socket.getNativeHandle()); + BoringSSL.SSL_get0_alpn_selected(ssl_ptr, &alpn_proto, &alpn_proto_len); + if (alpn_proto == null or alpn_proto_len == 0) { + return JSValue.jsBoolean(false); + } + + const slice = alpn_proto[0..alpn_proto_len]; + if (strings.eql(slice, "h2")) { + return ZigString.static("h2").toValue(globalObject); + } + if (strings.eql(slice, "http/1.1")) { + return ZigString.static("http/1.1").toValue(globalObject); + } + return ZigString.fromUTF8(slice).toValueGC(globalObject); + } + + pub fn setServername( + this: *This, + globalObject: *JSC.JSGlobalObject, + callframe: *JSC.CallFrame, + ) callconv(.C) JSValue { + if (comptime ssl == false) { + return JSValue.jsUndefined(); + } + if (this.detached) { + return JSValue.jsUndefined(); + } + + if (this.handlers.is_server) { + globalObject.throw("Cannot issue SNI from a TLS server-side socket", .{}); + return .zero; + } + + const args = callframe.arguments(1); + if (args.len < 1) { + globalObject.throw("Expected 1 argument", .{}); + return .zero; + } + + const server_name = args.ptr[0]; + if (!server_name.isString()) { + globalObject.throw("Expected \"serverName\" to be a string", .{}); + return .zero; + } + + const slice = server_name.getZigString(globalObject).toSlice(bun.default_allocator); + defer slice.deinit(); + const host = normalizeHost(slice.slice()); + if (host.len > 0) { + var ssl_ptr: *BoringSSL.SSL = @ptrCast(*BoringSSL.SSL, this.socket.getNativeHandle()); + if (ssl_ptr.isInitFinished()) { + // match node.js exceptions + globalObject.throw("Already started.", .{}); + return .zero; + } + var host__ = default_allocator.dupeZ(u8, host) catch unreachable; + defer default_allocator.free(host__); + ssl_ptr.setHostname(host__); + } + + return JSValue.jsUndefined(); + } + + pub fn open( + this: *This, + _: *JSC.JSGlobalObject, + _: *JSC.CallFrame, + ) callconv(.C) JSValue { + JSC.markBinding(@src()); + this.socket.open(!this.handlers.is_server); + return JSValue.jsUndefined(); + } + + // this invalidates the current socket returning 2 new sockets + // one for non-TLS and another for TLS + // handlers for non-TLS are preserved + pub fn wrapTLS( + this: *This, + globalObject: *JSC.JSGlobalObject, + callframe: *JSC.CallFrame, + ) callconv(.C) JSValue { + JSC.markBinding(@src()); + if (comptime ssl) { + return JSValue.jsUndefined(); + } + + if (this.detached) { + return JSValue.jsUndefined(); + } + + const args = callframe.arguments(1); + + if (args.len < 1) { + globalObject.throw("Expected 1 arguments", .{}); + return .zero; + } + + var exception: JSC.C.JSValueRef = null; + + const opts = args.ptr[0]; + if (opts.isEmptyOrUndefinedOrNull() or opts.isBoolean() or !opts.isObject()) { + globalObject.throw("Expected options object", .{}); + return .zero; + } + + var socket_obj = opts.get(globalObject, "socket") orelse { + globalObject.throw("Expected \"socket\" option", .{}); + return .zero; + }; + + var handlers = Handlers.fromJS(globalObject, socket_obj, &exception) orelse { + globalObject.throwValue(exception.?.value()); + return .zero; + }; + + var ssl_opts: ?JSC.API.ServerConfig.SSLConfig = null; + + if (opts.getTruthy(globalObject, "tls")) |tls| { + if (tls.isBoolean()) { + if (tls.toBoolean()) { + ssl_opts = JSC.API.ServerConfig.SSLConfig.zero; + } + } else { + if (JSC.API.ServerConfig.SSLConfig.inJS(globalObject, tls, &exception)) |ssl_config| { + ssl_opts = ssl_config; + } else if (exception != null) { + return .zero; + } + } + } + + if (ssl_opts == null) { + globalObject.throw("Expected \"tls\" option", .{}); + return .zero; + } + + var default_data = JSValue.zero; + if (opts.getTruthy(globalObject, "data")) |default_data_value| { + default_data = default_data_value; + default_data.ensureStillAlive(); + } + + var socket_config = ssl_opts.?; + defer socket_config.deinit(); + const options = socket_config.asUSockets(); + + const protos = socket_config.protos; + const protos_len = socket_config.protos_len; + + const ext_size = @sizeOf(WrappedSocket); + + var tls = handlers.vm.allocator.create(TLSSocket) catch @panic("OOM"); + var handlers_ptr = handlers.vm.allocator.create(Handlers) catch @panic("OOM"); + handlers_ptr.* = handlers; + handlers_ptr.is_server = this.handlers.is_server; + handlers_ptr.protect(); + + tls.* = .{ + .handlers = handlers_ptr, + .this_value = .zero, + .socket = undefined, + .connection = if (this.connection) |c| c.clone() else null, + .wrapped = .tls, + .protos = if (protos) |p| (bun.default_allocator.dupe(u8, p[0..protos_len]) catch unreachable) else null, + }; + + var tls_js_value = tls.getThisValue(globalObject); + TLSSocket.dataSetCached(tls_js_value, globalObject, default_data); + + const TCPHandler = NewWrappedHandler(false); + + // reconfigure context to use the new wrapper handlers + Socket.unsafeConfigure(this.socket.context(), true, true, WrappedSocket, TCPHandler); + const old_context = this.socket.context(); + const TLSHandler = NewWrappedHandler(true); + const new_socket = this.socket.wrapTLS( + options, + ext_size, + true, + WrappedSocket, + TLSHandler, + ) orelse { + handlers_ptr.unprotect(); + handlers.vm.allocator.destroy(handlers_ptr); + bun.default_allocator.destroy(tls); + return JSValue.jsUndefined(); + }; + tls.socket = new_socket; + + var raw = handlers.vm.allocator.create(TLSSocket) catch @panic("OOM"); + var raw_handlers_ptr = handlers.vm.allocator.create(Handlers) catch @panic("OOM"); + this.handlers.unprotect(); + + var cloned_handlers: Handlers = .{ + .vm = globalObject.bunVM(), + .globalObject = globalObject, + .onOpen = this.handlers.onOpen, + .onClose = this.handlers.onClose, + .onData = this.handlers.onData, + .onWritable = this.handlers.onWritable, + .onTimeout = this.handlers.onTimeout, + .onConnectError = this.handlers.onConnectError, + .onEnd = this.handlers.onEnd, + .onError = this.handlers.onError, + .onHandshake = this.handlers.onHandshake, + .binary_type = this.handlers.binary_type, + }; + + raw_handlers_ptr.* = cloned_handlers; + raw_handlers_ptr.is_server = this.handlers.is_server; + raw_handlers_ptr.protect(); + raw.* = .{ + .handlers = raw_handlers_ptr, + .this_value = .zero, + .socket = new_socket, + .connection = if (this.connection) |c| c.clone() else null, + .wrapped = .tcp, + .protos = null, + }; + + var raw_js_value = raw.getThisValue(globalObject); + if (JSSocketType(ssl).dataGetCached(this.getThisValue(globalObject))) |raw_default_data| { + raw_default_data.ensureStillAlive(); + TLSSocket.dataSetCached(raw_js_value, globalObject, raw_default_data); + } + // marks both as active + raw.markActive(); + // this will keep tls alive until socket.open() is called to start TLS certificate and the handshake process + // open is not immediately called because we need to set bunSocketInternal + tls.markActive(); + + // mark both instances on socket data + new_socket.ext(WrappedSocket).?.* = .{ .tcp = raw, .tls = tls }; + + //detach and invalidate the old instance + this.detached = true; + if (this.reffer.has) { + var vm = this.handlers.vm; + this.reffer.unref(vm); + old_context.deinit(ssl); + bun.default_allocator.destroy(this.handlers); + this.poll_ref.unref(vm); + this.has_pending_activity.store(false, .Release); + } + + const array = JSC.JSValue.createEmptyArray(globalObject, 2); + array.putIndex(globalObject, 0, raw_js_value); + array.putIndex(globalObject, 1, tls_js_value); + return array; + } }; } pub const TCPSocket = NewSocket(false); pub const TLSSocket = NewSocket(true); + +pub const WrappedSocket = extern struct { + // both shares the same socket but one behaves as TLS and the other as TCP + tls: *TLSSocket, + tcp: *TLSSocket, +}; + +pub fn NewWrappedHandler(comptime tls: bool) type { + const Socket = uws.NewSocketHandler(true); + return struct { + pub fn onOpen( + this: WrappedSocket, + socket: Socket, + ) void { + // only TLS will call onOpen + if (comptime tls) { + TLSSocket.onOpen(this.tls, socket); + } + } + + pub fn onEnd( + this: WrappedSocket, + socket: Socket, + ) void { + if (comptime tls) { + TLSSocket.onEnd(this.tls, socket); + } else { + TLSSocket.onEnd(this.tcp, socket); + } + } + + pub fn onHandshake( + this: WrappedSocket, + socket: Socket, + success: i32, + ssl_error: uws.us_bun_verify_error_t, + ) void { + // only TLS will call onHandshake + if (comptime tls) { + TLSSocket.onHandshake(this.tls, socket, success, ssl_error); + } + } + + pub fn onClose( + this: WrappedSocket, + socket: Socket, + err: c_int, + data: ?*anyopaque, + ) void { + if (comptime tls) { + TLSSocket.onClose(this.tls, socket, err, data); + } else { + TLSSocket.onClose(this.tcp, socket, err, data); + } + } + + pub fn onData( + this: WrappedSocket, + socket: Socket, + data: []const u8, + ) void { + if (comptime tls) { + TLSSocket.onData(this.tls, socket, data); + } else { + TLSSocket.onData(this.tcp, socket, data); + } + } + + pub fn onWritable( + this: WrappedSocket, + socket: Socket, + ) void { + if (comptime tls) { + TLSSocket.onWritable(this.tls, socket); + } else { + TLSSocket.onWritable(this.tcp, socket); + } + } + pub fn onTimeout( + this: WrappedSocket, + socket: Socket, + ) void { + if (comptime tls) { + TLSSocket.onTimeout(this.tls, socket); + } else { + TLSSocket.onTimeout(this.tcp, socket); + } + } + + pub fn onConnectError( + this: WrappedSocket, + socket: Socket, + errno: c_int, + ) void { + if (comptime tls) { + TLSSocket.onConnectError(this.tls, socket, errno); + } else { + TLSSocket.onConnectError(this.tcp, socket, errno); + } + } + }; +} diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index 140e62ce4..f52c08301 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -163,6 +163,8 @@ pub const ServerConfig = struct { request_cert: i32 = 0, reject_unauthorized: i32 = 0, ssl_ciphers: [*c]const u8 = null, + protos: [*c]const u8 = null, + protos_len: usize = 0, const log = Output.scoped(.SSLConfig, false); @@ -215,6 +217,7 @@ pub const ServerConfig = struct { "dh_params_file_name", "passphrase", "ssl_ciphers", + "protos", }; inline for (fields) |field| { @@ -270,6 +273,9 @@ pub const ServerConfig = struct { pub fn inJS(global: *JSC.JSGlobalObject, obj: JSC.JSValue, exception: JSC.C.ExceptionRef) ?SSLConfig { var result = zero; + var arena: @import("root").bun.ArenaAllocator = @import("root").bun.ArenaAllocator.init(bun.default_allocator); + defer arena.deinit(); + if (!obj.isObject()) { JSC.throwInvalidArguments("tls option expects an object", .{}, global, exception); return null; @@ -301,7 +307,6 @@ pub const ServerConfig = struct { var i: u32 = 0; var valid_count: u32 = 0; - var arena: @import("root").bun.ArenaAllocator = @import("root").bun.ArenaAllocator.init(bun.default_allocator); while (i < count) : (i += 1) { const item = js_obj.getIndex(global, i); if (JSC.Node.StringOrBuffer.fromJS(global, arena.allocator(), item, exception)) |sb| { @@ -317,7 +322,6 @@ pub const ServerConfig = struct { valid_count += 1; any = true; } else { - arena.deinit(); // mark and free all CA's result.cert = native_array; result.deinit(); @@ -325,7 +329,6 @@ pub const ServerConfig = struct { } } else { global.throwInvalidArguments("key argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile", .{}); - arena.deinit(); // mark and free all keys result.key = native_array; result.deinit(); @@ -333,8 +336,6 @@ pub const ServerConfig = struct { } } - arena.deinit(); - if (valid_count == 0) { bun.default_allocator.free(native_array); } else { @@ -356,7 +357,6 @@ pub const ServerConfig = struct { } } else { const native_array = bun.default_allocator.alloc([*c]const u8, 1) catch unreachable; - var arena: @import("root").bun.ArenaAllocator = @import("root").bun.ArenaAllocator.init(bun.default_allocator); if (JSC.Node.StringOrBuffer.fromJS(global, arena.allocator(), js_obj, exception)) |sb| { const sliced = sb.slice(); if (sliced.len > 0) { @@ -369,14 +369,11 @@ pub const ServerConfig = struct { } } else { global.throwInvalidArguments("key argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile", .{}); - arena.deinit(); // mark and free all certs result.key = native_array; result.deinit(); return null; } - - arena.deinit(); } } @@ -394,6 +391,22 @@ pub const ServerConfig = struct { } } + if (obj.getTruthy(global, "ALPNProtocols")) |protocols| { + if (JSC.Node.StringOrBuffer.fromJS(global, arena.allocator(), protocols, exception)) |sb| { + const sliced = sb.slice(); + if (sliced.len > 0) { + result.protos = bun.default_allocator.dupeZ(u8, sliced) catch unreachable; + result.protos_len = sliced.len; + } + + any = true; + } else { + global.throwInvalidArguments("ALPNProtocols argument must be an string, Buffer or TypedArray", .{}); + result.deinit(); + return null; + } + } + if (obj.getTruthy(global, "cert")) |js_obj| { if (js_obj.jsType().isArray()) { const count = js_obj.getLength(global); @@ -403,7 +416,6 @@ pub const ServerConfig = struct { var i: u32 = 0; var valid_count: u32 = 0; - var arena: @import("root").bun.ArenaAllocator = @import("root").bun.ArenaAllocator.init(bun.default_allocator); while (i < count) : (i += 1) { const item = js_obj.getIndex(global, i); if (JSC.Node.StringOrBuffer.fromJS(global, arena.allocator(), item, exception)) |sb| { @@ -419,7 +431,6 @@ pub const ServerConfig = struct { valid_count += 1; any = true; } else { - arena.deinit(); // mark and free all CA's result.cert = native_array; result.deinit(); @@ -427,7 +438,6 @@ pub const ServerConfig = struct { } } else { global.throwInvalidArguments("cert argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile", .{}); - arena.deinit(); // mark and free all certs result.cert = native_array; result.deinit(); @@ -435,8 +445,6 @@ pub const ServerConfig = struct { } } - arena.deinit(); - if (valid_count == 0) { bun.default_allocator.free(native_array); } else { @@ -458,7 +466,6 @@ pub const ServerConfig = struct { } } else { const native_array = bun.default_allocator.alloc([*c]const u8, 1) catch unreachable; - var arena: @import("root").bun.ArenaAllocator = @import("root").bun.ArenaAllocator.init(bun.default_allocator); if (JSC.Node.StringOrBuffer.fromJS(global, arena.allocator(), js_obj, exception)) |sb| { const sliced = sb.slice(); if (sliced.len > 0) { @@ -471,14 +478,11 @@ pub const ServerConfig = struct { } } else { global.throwInvalidArguments("cert argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile", .{}); - arena.deinit(); // mark and free all certs result.cert = native_array; result.deinit(); return null; } - - arena.deinit(); } } @@ -518,7 +522,6 @@ pub const ServerConfig = struct { var i: u32 = 0; var valid_count: u32 = 0; - var arena: @import("root").bun.ArenaAllocator = @import("root").bun.ArenaAllocator.init(bun.default_allocator); while (i < count) : (i += 1) { const item = js_obj.getIndex(global, i); if (JSC.Node.StringOrBuffer.fromJS(global, arena.allocator(), item, exception)) |sb| { @@ -534,7 +537,6 @@ pub const ServerConfig = struct { valid_count += 1; any = true; } else { - arena.deinit(); // mark and free all CA's result.cert = native_array; result.deinit(); @@ -542,7 +544,6 @@ pub const ServerConfig = struct { } } else { global.throwInvalidArguments("ca argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile", .{}); - arena.deinit(); // mark and free all CA's result.cert = native_array; result.deinit(); @@ -550,8 +551,6 @@ pub const ServerConfig = struct { } } - arena.deinit(); - if (valid_count == 0) { bun.default_allocator.free(native_array); } else { @@ -573,7 +572,6 @@ pub const ServerConfig = struct { } } else { const native_array = bun.default_allocator.alloc([*c]const u8, 1) catch unreachable; - var arena: @import("root").bun.ArenaAllocator = @import("root").bun.ArenaAllocator.init(bun.default_allocator); if (JSC.Node.StringOrBuffer.fromJS(global, arena.allocator(), js_obj, exception)) |sb| { const sliced = sb.slice(); if (sliced.len > 0) { @@ -586,13 +584,11 @@ pub const ServerConfig = struct { } } else { JSC.throwInvalidArguments("ca argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile", .{}, global, exception); - arena.deinit(); // mark and free all certs result.ca = native_array; result.deinit(); return null; } - arena.deinit(); } } diff --git a/src/bun.js/api/sockets.classes.ts b/src/bun.js/api/sockets.classes.ts index da07741a3..0c7847e19 100644 --- a/src/bun.js/api/sockets.classes.ts +++ b/src/bun.js/api/sockets.classes.ts @@ -15,10 +15,21 @@ function generate(ssl) { authorized: { getter: "getAuthorized", }, + alpnProtocol: { + getter: "getALPNProtocol", + }, write: { fn: "write", length: 3, }, + wrapTLS: { + fn: "wrapTLS", + length: 1, + }, + open: { + fn: "open", + length: 0, + }, end: { fn: "end", length: 3, @@ -82,6 +93,11 @@ function generate(ssl) { fn: "reload", length: 1, }, + + setServername: { + fn: "setServername", + length: 1, + }, }, finalize: true, construct: true, diff --git a/src/bun.js/bindings/JSSink.cpp b/src/bun.js/bindings/JSSink.cpp index 19bf05599..5f99d3792 100644 --- a/src/bun.js/bindings/JSSink.cpp +++ b/src/bun.js/bindings/JSSink.cpp @@ -1,6 +1,6 @@ // AUTO-GENERATED FILE. DO NOT EDIT. -// Generated by 'make generate-sink' at 2023-06-25T17:34:54.187Z +// Generated by 'make generate-sink' at 2023-07-02T16:19:51.440Z // To regenerate this file, run: // // make generate-sink diff --git a/src/bun.js/bindings/JSSink.h b/src/bun.js/bindings/JSSink.h index 9bf5554c4..41d7065dc 100644 --- a/src/bun.js/bindings/JSSink.h +++ b/src/bun.js/bindings/JSSink.h @@ -1,6 +1,6 @@ // AUTO-GENERATED FILE. DO NOT EDIT. -// Generated by 'make generate-sink' at 2023-06-25T17:34:54.186Z +// Generated by 'make generate-sink' at 2023-07-02T16:19:51.438Z // #pragma once diff --git a/src/bun.js/bindings/JSSinkLookupTable.h b/src/bun.js/bindings/JSSinkLookupTable.h index f8518bc5e..e4ed81629 100644 --- a/src/bun.js/bindings/JSSinkLookupTable.h +++ b/src/bun.js/bindings/JSSinkLookupTable.h @@ -1,4 +1,4 @@ -// Automatically generated from src/bun.js/bindings/JSSink.cpp using /Users/silas/Workspace/opensource/bun/src/bun.js/WebKit/Source/JavaScriptCore/create_hash_table. DO NOT EDIT! +// Automatically generated from src/bun.js/bindings/JSSink.cpp using /home/cirospaciari/Repos/bun/src/bun.js/WebKit/Source/JavaScriptCore/create_hash_table. DO NOT EDIT! diff --git a/src/bun.js/bindings/ZigGeneratedClasses.cpp b/src/bun.js/bindings/ZigGeneratedClasses.cpp index b7461b5f0..866970e4d 100644 --- a/src/bun.js/bindings/ZigGeneratedClasses.cpp +++ b/src/bun.js/bindings/ZigGeneratedClasses.cpp @@ -16872,6 +16872,9 @@ extern "C" void* TCPSocketClass__construct(JSC::JSGlobalObject*, JSC::CallFrame* JSC_DECLARE_CUSTOM_GETTER(jsTCPSocketConstructor); extern "C" void TCPSocketClass__finalize(void*); +extern "C" JSC::EncodedJSValue TCPSocketPrototype__getALPNProtocol(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(TCPSocketPrototype__alpnProtocolGetterWrap); + extern "C" JSC::EncodedJSValue TCPSocketPrototype__getAuthorized(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); JSC_DECLARE_CUSTOM_GETTER(TCPSocketPrototype__authorizedGetterWrap); @@ -16896,6 +16899,9 @@ JSC_DECLARE_CUSTOM_GETTER(TCPSocketPrototype__listenerGetterWrap); extern "C" JSC::EncodedJSValue TCPSocketPrototype__getLocalPort(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); JSC_DECLARE_CUSTOM_GETTER(TCPSocketPrototype__localPortGetterWrap); +extern "C" EncodedJSValue TCPSocketPrototype__open(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); +JSC_DECLARE_HOST_FUNCTION(TCPSocketPrototype__openCallback); + extern "C" JSC::EncodedJSValue TCPSocketPrototype__getReadyState(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); JSC_DECLARE_CUSTOM_GETTER(TCPSocketPrototype__readyStateGetterWrap); @@ -16908,6 +16914,9 @@ JSC_DECLARE_HOST_FUNCTION(TCPSocketPrototype__reloadCallback); extern "C" JSC::EncodedJSValue TCPSocketPrototype__getRemoteAddress(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); JSC_DECLARE_CUSTOM_GETTER(TCPSocketPrototype__remoteAddressGetterWrap); +extern "C" EncodedJSValue TCPSocketPrototype__setServername(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); +JSC_DECLARE_HOST_FUNCTION(TCPSocketPrototype__setServernameCallback); + extern "C" EncodedJSValue TCPSocketPrototype__shutdown(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(TCPSocketPrototype__shutdownCallback); @@ -16917,12 +16926,16 @@ JSC_DECLARE_HOST_FUNCTION(TCPSocketPrototype__timeoutCallback); extern "C" EncodedJSValue TCPSocketPrototype__unref(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(TCPSocketPrototype__unrefCallback); +extern "C" EncodedJSValue TCPSocketPrototype__wrapTLS(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); +JSC_DECLARE_HOST_FUNCTION(TCPSocketPrototype__wrapTLSCallback); + extern "C" EncodedJSValue TCPSocketPrototype__write(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(TCPSocketPrototype__writeCallback); STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTCPSocketPrototype, JSTCPSocketPrototype::Base); static const HashTableValue JSTCPSocketPrototypeTableValues[] = { + { "alpnProtocol"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TCPSocketPrototype__alpnProtocolGetterWrap, 0 } }, { "authorized"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TCPSocketPrototype__authorizedGetterWrap, 0 } }, { "data"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TCPSocketPrototype__dataGetterWrap, TCPSocketPrototype__dataSetterWrap } }, { "end"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TCPSocketPrototype__endCallback, 3 } }, @@ -16930,13 +16943,16 @@ static const HashTableValue JSTCPSocketPrototypeTableValues[] = { { "getAuthorizationError"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TCPSocketPrototype__getAuthorizationErrorCallback, 0 } }, { "listener"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TCPSocketPrototype__listenerGetterWrap, 0 } }, { "localPort"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TCPSocketPrototype__localPortGetterWrap, 0 } }, + { "open"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TCPSocketPrototype__openCallback, 0 } }, { "readyState"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TCPSocketPrototype__readyStateGetterWrap, 0 } }, { "ref"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TCPSocketPrototype__refCallback, 0 } }, { "reload"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TCPSocketPrototype__reloadCallback, 1 } }, { "remoteAddress"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TCPSocketPrototype__remoteAddressGetterWrap, 0 } }, + { "setServername"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TCPSocketPrototype__setServernameCallback, 1 } }, { "shutdown"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TCPSocketPrototype__shutdownCallback, 1 } }, { "timeout"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TCPSocketPrototype__timeoutCallback, 1 } }, { "unref"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TCPSocketPrototype__unrefCallback, 0 } }, + { "wrapTLS"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TCPSocketPrototype__wrapTLSCallback, 1 } }, { "write"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TCPSocketPrototype__writeCallback, 3 } } }; @@ -16954,6 +16970,18 @@ JSC_DEFINE_CUSTOM_GETTER(jsTCPSocketConstructor, (JSGlobalObject * lexicalGlobal return JSValue::encode(globalObject->JSTCPSocketConstructor()); } +JSC_DEFINE_CUSTOM_GETTER(TCPSocketPrototype__alpnProtocolGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + auto& vm = lexicalGlobalObject->vm(); + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + JSTCPSocket* thisObject = jsCast<JSTCPSocket*>(JSValue::decode(thisValue)); + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + JSC::EncodedJSValue result = TCPSocketPrototype__getALPNProtocol(thisObject->wrapped(), globalObject); + RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_AND_RETURN(throwScope, result); +} + JSC_DEFINE_CUSTOM_GETTER(TCPSocketPrototype__authorizedGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) { auto& vm = lexicalGlobalObject->vm(); @@ -17113,6 +17141,33 @@ JSC_DEFINE_CUSTOM_GETTER(TCPSocketPrototype__localPortGetterWrap, (JSGlobalObjec RELEASE_AND_RETURN(throwScope, result); } +JSC_DEFINE_HOST_FUNCTION(TCPSocketPrototype__openCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + auto& vm = lexicalGlobalObject->vm(); + + JSTCPSocket* thisObject = jsDynamicCast<JSTCPSocket*>(callFrame->thisValue()); + + if (UNLIKELY(!thisObject)) { + auto throwScope = DECLARE_THROW_SCOPE(vm); + return throwVMTypeError(lexicalGlobalObject, throwScope); + } + + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + +#ifdef BUN_DEBUG + /** View the file name of the JS file that called this function + * from a debugger */ + SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm); + const char* fileName = sourceOrigin.string().utf8().data(); + static const char* lastFileName = nullptr; + if (lastFileName != fileName) { + lastFileName = fileName; + } +#endif + + return TCPSocketPrototype__open(thisObject->wrapped(), lexicalGlobalObject, callFrame); +} + JSC_DEFINE_CUSTOM_GETTER(TCPSocketPrototype__readyStateGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) { auto& vm = lexicalGlobalObject->vm(); @@ -17210,6 +17265,33 @@ extern "C" EncodedJSValue TCPSocketPrototype__remoteAddressGetCachedValue(JSC::E return JSValue::encode(thisObject->m_remoteAddress.get()); } +JSC_DEFINE_HOST_FUNCTION(TCPSocketPrototype__setServernameCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + auto& vm = lexicalGlobalObject->vm(); + + JSTCPSocket* thisObject = jsDynamicCast<JSTCPSocket*>(callFrame->thisValue()); + + if (UNLIKELY(!thisObject)) { + auto throwScope = DECLARE_THROW_SCOPE(vm); + return throwVMTypeError(lexicalGlobalObject, throwScope); + } + + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + +#ifdef BUN_DEBUG + /** View the file name of the JS file that called this function + * from a debugger */ + SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm); + const char* fileName = sourceOrigin.string().utf8().data(); + static const char* lastFileName = nullptr; + if (lastFileName != fileName) { + lastFileName = fileName; + } +#endif + + return TCPSocketPrototype__setServername(thisObject->wrapped(), lexicalGlobalObject, callFrame); +} + JSC_DEFINE_HOST_FUNCTION(TCPSocketPrototype__shutdownCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { auto& vm = lexicalGlobalObject->vm(); @@ -17291,6 +17373,33 @@ JSC_DEFINE_HOST_FUNCTION(TCPSocketPrototype__unrefCallback, (JSGlobalObject * le return TCPSocketPrototype__unref(thisObject->wrapped(), lexicalGlobalObject, callFrame); } +JSC_DEFINE_HOST_FUNCTION(TCPSocketPrototype__wrapTLSCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + auto& vm = lexicalGlobalObject->vm(); + + JSTCPSocket* thisObject = jsDynamicCast<JSTCPSocket*>(callFrame->thisValue()); + + if (UNLIKELY(!thisObject)) { + auto throwScope = DECLARE_THROW_SCOPE(vm); + return throwVMTypeError(lexicalGlobalObject, throwScope); + } + + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + +#ifdef BUN_DEBUG + /** View the file name of the JS file that called this function + * from a debugger */ + SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm); + const char* fileName = sourceOrigin.string().utf8().data(); + static const char* lastFileName = nullptr; + if (lastFileName != fileName) { + lastFileName = fileName; + } +#endif + + return TCPSocketPrototype__wrapTLS(thisObject->wrapped(), lexicalGlobalObject, callFrame); +} + JSC_DEFINE_HOST_FUNCTION(TCPSocketPrototype__writeCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { auto& vm = lexicalGlobalObject->vm(); @@ -17479,6 +17588,9 @@ extern "C" void* TLSSocketClass__construct(JSC::JSGlobalObject*, JSC::CallFrame* JSC_DECLARE_CUSTOM_GETTER(jsTLSSocketConstructor); extern "C" void TLSSocketClass__finalize(void*); +extern "C" JSC::EncodedJSValue TLSSocketPrototype__getALPNProtocol(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(TLSSocketPrototype__alpnProtocolGetterWrap); + extern "C" JSC::EncodedJSValue TLSSocketPrototype__getAuthorized(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); JSC_DECLARE_CUSTOM_GETTER(TLSSocketPrototype__authorizedGetterWrap); @@ -17503,6 +17615,9 @@ JSC_DECLARE_CUSTOM_GETTER(TLSSocketPrototype__listenerGetterWrap); extern "C" JSC::EncodedJSValue TLSSocketPrototype__getLocalPort(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); JSC_DECLARE_CUSTOM_GETTER(TLSSocketPrototype__localPortGetterWrap); +extern "C" EncodedJSValue TLSSocketPrototype__open(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); +JSC_DECLARE_HOST_FUNCTION(TLSSocketPrototype__openCallback); + extern "C" JSC::EncodedJSValue TLSSocketPrototype__getReadyState(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); JSC_DECLARE_CUSTOM_GETTER(TLSSocketPrototype__readyStateGetterWrap); @@ -17515,6 +17630,9 @@ JSC_DECLARE_HOST_FUNCTION(TLSSocketPrototype__reloadCallback); extern "C" JSC::EncodedJSValue TLSSocketPrototype__getRemoteAddress(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); JSC_DECLARE_CUSTOM_GETTER(TLSSocketPrototype__remoteAddressGetterWrap); +extern "C" EncodedJSValue TLSSocketPrototype__setServername(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); +JSC_DECLARE_HOST_FUNCTION(TLSSocketPrototype__setServernameCallback); + extern "C" EncodedJSValue TLSSocketPrototype__shutdown(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(TLSSocketPrototype__shutdownCallback); @@ -17524,12 +17642,16 @@ JSC_DECLARE_HOST_FUNCTION(TLSSocketPrototype__timeoutCallback); extern "C" EncodedJSValue TLSSocketPrototype__unref(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(TLSSocketPrototype__unrefCallback); +extern "C" EncodedJSValue TLSSocketPrototype__wrapTLS(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); +JSC_DECLARE_HOST_FUNCTION(TLSSocketPrototype__wrapTLSCallback); + extern "C" EncodedJSValue TLSSocketPrototype__write(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(TLSSocketPrototype__writeCallback); STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTLSSocketPrototype, JSTLSSocketPrototype::Base); static const HashTableValue JSTLSSocketPrototypeTableValues[] = { + { "alpnProtocol"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TLSSocketPrototype__alpnProtocolGetterWrap, 0 } }, { "authorized"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TLSSocketPrototype__authorizedGetterWrap, 0 } }, { "data"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TLSSocketPrototype__dataGetterWrap, TLSSocketPrototype__dataSetterWrap } }, { "end"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TLSSocketPrototype__endCallback, 3 } }, @@ -17537,13 +17659,16 @@ static const HashTableValue JSTLSSocketPrototypeTableValues[] = { { "getAuthorizationError"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TLSSocketPrototype__getAuthorizationErrorCallback, 0 } }, { "listener"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TLSSocketPrototype__listenerGetterWrap, 0 } }, { "localPort"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TLSSocketPrototype__localPortGetterWrap, 0 } }, + { "open"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TLSSocketPrototype__openCallback, 0 } }, { "readyState"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TLSSocketPrototype__readyStateGetterWrap, 0 } }, { "ref"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TLSSocketPrototype__refCallback, 0 } }, { "reload"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TLSSocketPrototype__reloadCallback, 1 } }, { "remoteAddress"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TLSSocketPrototype__remoteAddressGetterWrap, 0 } }, + { "setServername"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TLSSocketPrototype__setServernameCallback, 1 } }, { "shutdown"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TLSSocketPrototype__shutdownCallback, 1 } }, { "timeout"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TLSSocketPrototype__timeoutCallback, 1 } }, { "unref"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TLSSocketPrototype__unrefCallback, 0 } }, + { "wrapTLS"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TLSSocketPrototype__wrapTLSCallback, 1 } }, { "write"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, TLSSocketPrototype__writeCallback, 3 } } }; @@ -17561,6 +17686,18 @@ JSC_DEFINE_CUSTOM_GETTER(jsTLSSocketConstructor, (JSGlobalObject * lexicalGlobal return JSValue::encode(globalObject->JSTLSSocketConstructor()); } +JSC_DEFINE_CUSTOM_GETTER(TLSSocketPrototype__alpnProtocolGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + auto& vm = lexicalGlobalObject->vm(); + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + JSTLSSocket* thisObject = jsCast<JSTLSSocket*>(JSValue::decode(thisValue)); + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + JSC::EncodedJSValue result = TLSSocketPrototype__getALPNProtocol(thisObject->wrapped(), globalObject); + RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_AND_RETURN(throwScope, result); +} + JSC_DEFINE_CUSTOM_GETTER(TLSSocketPrototype__authorizedGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) { auto& vm = lexicalGlobalObject->vm(); @@ -17720,6 +17857,33 @@ JSC_DEFINE_CUSTOM_GETTER(TLSSocketPrototype__localPortGetterWrap, (JSGlobalObjec RELEASE_AND_RETURN(throwScope, result); } +JSC_DEFINE_HOST_FUNCTION(TLSSocketPrototype__openCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + auto& vm = lexicalGlobalObject->vm(); + + JSTLSSocket* thisObject = jsDynamicCast<JSTLSSocket*>(callFrame->thisValue()); + + if (UNLIKELY(!thisObject)) { + auto throwScope = DECLARE_THROW_SCOPE(vm); + return throwVMTypeError(lexicalGlobalObject, throwScope); + } + + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + +#ifdef BUN_DEBUG + /** View the file name of the JS file that called this function + * from a debugger */ + SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm); + const char* fileName = sourceOrigin.string().utf8().data(); + static const char* lastFileName = nullptr; + if (lastFileName != fileName) { + lastFileName = fileName; + } +#endif + + return TLSSocketPrototype__open(thisObject->wrapped(), lexicalGlobalObject, callFrame); +} + JSC_DEFINE_CUSTOM_GETTER(TLSSocketPrototype__readyStateGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) { auto& vm = lexicalGlobalObject->vm(); @@ -17817,6 +17981,33 @@ extern "C" EncodedJSValue TLSSocketPrototype__remoteAddressGetCachedValue(JSC::E return JSValue::encode(thisObject->m_remoteAddress.get()); } +JSC_DEFINE_HOST_FUNCTION(TLSSocketPrototype__setServernameCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + auto& vm = lexicalGlobalObject->vm(); + + JSTLSSocket* thisObject = jsDynamicCast<JSTLSSocket*>(callFrame->thisValue()); + + if (UNLIKELY(!thisObject)) { + auto throwScope = DECLARE_THROW_SCOPE(vm); + return throwVMTypeError(lexicalGlobalObject, throwScope); + } + + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + +#ifdef BUN_DEBUG + /** View the file name of the JS file that called this function + * from a debugger */ + SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm); + const char* fileName = sourceOrigin.string().utf8().data(); + static const char* lastFileName = nullptr; + if (lastFileName != fileName) { + lastFileName = fileName; + } +#endif + + return TLSSocketPrototype__setServername(thisObject->wrapped(), lexicalGlobalObject, callFrame); +} + JSC_DEFINE_HOST_FUNCTION(TLSSocketPrototype__shutdownCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { auto& vm = lexicalGlobalObject->vm(); @@ -17898,6 +18089,33 @@ JSC_DEFINE_HOST_FUNCTION(TLSSocketPrototype__unrefCallback, (JSGlobalObject * le return TLSSocketPrototype__unref(thisObject->wrapped(), lexicalGlobalObject, callFrame); } +JSC_DEFINE_HOST_FUNCTION(TLSSocketPrototype__wrapTLSCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + auto& vm = lexicalGlobalObject->vm(); + + JSTLSSocket* thisObject = jsDynamicCast<JSTLSSocket*>(callFrame->thisValue()); + + if (UNLIKELY(!thisObject)) { + auto throwScope = DECLARE_THROW_SCOPE(vm); + return throwVMTypeError(lexicalGlobalObject, throwScope); + } + + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + +#ifdef BUN_DEBUG + /** View the file name of the JS file that called this function + * from a debugger */ + SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm); + const char* fileName = sourceOrigin.string().utf8().data(); + static const char* lastFileName = nullptr; + if (lastFileName != fileName) { + lastFileName = fileName; + } +#endif + + return TLSSocketPrototype__wrapTLS(thisObject->wrapped(), lexicalGlobalObject, callFrame); +} + JSC_DEFINE_HOST_FUNCTION(TLSSocketPrototype__writeCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { auto& vm = lexicalGlobalObject->vm(); diff --git a/src/bun.js/bindings/generated_classes.zig b/src/bun.js/bindings/generated_classes.zig index 04a72d7ed..a220b6814 100644 --- a/src/bun.js/bindings/generated_classes.zig +++ b/src/bun.js/bindings/generated_classes.zig @@ -4426,6 +4426,9 @@ pub const JSTCPSocket = struct { @compileLog("TCPSocket.finalize is not a finalizer"); } + if (@TypeOf(TCPSocket.getALPNProtocol) != GetterType) + @compileLog("Expected TCPSocket.getALPNProtocol to be a getter"); + if (@TypeOf(TCPSocket.getAuthorized) != GetterType) @compileLog("Expected TCPSocket.getAuthorized to be a getter"); @@ -4446,6 +4449,8 @@ pub const JSTCPSocket = struct { if (@TypeOf(TCPSocket.getLocalPort) != GetterType) @compileLog("Expected TCPSocket.getLocalPort to be a getter"); + if (@TypeOf(TCPSocket.open) != CallbackType) + @compileLog("Expected TCPSocket.open to be a callback but received " ++ @typeName(@TypeOf(TCPSocket.open))); if (@TypeOf(TCPSocket.getReadyState) != GetterType) @compileLog("Expected TCPSocket.getReadyState to be a getter"); @@ -4456,18 +4461,23 @@ pub const JSTCPSocket = struct { if (@TypeOf(TCPSocket.getRemoteAddress) != GetterType) @compileLog("Expected TCPSocket.getRemoteAddress to be a getter"); + if (@TypeOf(TCPSocket.setServername) != CallbackType) + @compileLog("Expected TCPSocket.setServername to be a callback but received " ++ @typeName(@TypeOf(TCPSocket.setServername))); if (@TypeOf(TCPSocket.shutdown) != CallbackType) @compileLog("Expected TCPSocket.shutdown to be a callback but received " ++ @typeName(@TypeOf(TCPSocket.shutdown))); if (@TypeOf(TCPSocket.timeout) != CallbackType) @compileLog("Expected TCPSocket.timeout to be a callback but received " ++ @typeName(@TypeOf(TCPSocket.timeout))); if (@TypeOf(TCPSocket.unref) != CallbackType) @compileLog("Expected TCPSocket.unref to be a callback but received " ++ @typeName(@TypeOf(TCPSocket.unref))); + if (@TypeOf(TCPSocket.wrapTLS) != CallbackType) + @compileLog("Expected TCPSocket.wrapTLS to be a callback but received " ++ @typeName(@TypeOf(TCPSocket.wrapTLS))); if (@TypeOf(TCPSocket.write) != CallbackType) @compileLog("Expected TCPSocket.write to be a callback but received " ++ @typeName(@TypeOf(TCPSocket.write))); if (!JSC.is_bindgen) { @export(TCPSocket.end, .{ .name = "TCPSocketPrototype__end" }); @export(TCPSocket.finalize, .{ .name = "TCPSocketClass__finalize" }); @export(TCPSocket.flush, .{ .name = "TCPSocketPrototype__flush" }); + @export(TCPSocket.getALPNProtocol, .{ .name = "TCPSocketPrototype__getALPNProtocol" }); @export(TCPSocket.getAuthorizationError, .{ .name = "TCPSocketPrototype__getAuthorizationError" }); @export(TCPSocket.getAuthorized, .{ .name = "TCPSocketPrototype__getAuthorized" }); @export(TCPSocket.getData, .{ .name = "TCPSocketPrototype__getData" }); @@ -4476,12 +4486,15 @@ pub const JSTCPSocket = struct { @export(TCPSocket.getReadyState, .{ .name = "TCPSocketPrototype__getReadyState" }); @export(TCPSocket.getRemoteAddress, .{ .name = "TCPSocketPrototype__getRemoteAddress" }); @export(TCPSocket.hasPendingActivity, .{ .name = "TCPSocket__hasPendingActivity" }); + @export(TCPSocket.open, .{ .name = "TCPSocketPrototype__open" }); @export(TCPSocket.ref, .{ .name = "TCPSocketPrototype__ref" }); @export(TCPSocket.reload, .{ .name = "TCPSocketPrototype__reload" }); @export(TCPSocket.setData, .{ .name = "TCPSocketPrototype__setData" }); + @export(TCPSocket.setServername, .{ .name = "TCPSocketPrototype__setServername" }); @export(TCPSocket.shutdown, .{ .name = "TCPSocketPrototype__shutdown" }); @export(TCPSocket.timeout, .{ .name = "TCPSocketPrototype__timeout" }); @export(TCPSocket.unref, .{ .name = "TCPSocketPrototype__unref" }); + @export(TCPSocket.wrapTLS, .{ .name = "TCPSocketPrototype__wrapTLS" }); @export(TCPSocket.write, .{ .name = "TCPSocketPrototype__write" }); } } @@ -4581,6 +4594,9 @@ pub const JSTLSSocket = struct { @compileLog("TLSSocket.finalize is not a finalizer"); } + if (@TypeOf(TLSSocket.getALPNProtocol) != GetterType) + @compileLog("Expected TLSSocket.getALPNProtocol to be a getter"); + if (@TypeOf(TLSSocket.getAuthorized) != GetterType) @compileLog("Expected TLSSocket.getAuthorized to be a getter"); @@ -4601,6 +4617,8 @@ pub const JSTLSSocket = struct { if (@TypeOf(TLSSocket.getLocalPort) != GetterType) @compileLog("Expected TLSSocket.getLocalPort to be a getter"); + if (@TypeOf(TLSSocket.open) != CallbackType) + @compileLog("Expected TLSSocket.open to be a callback but received " ++ @typeName(@TypeOf(TLSSocket.open))); if (@TypeOf(TLSSocket.getReadyState) != GetterType) @compileLog("Expected TLSSocket.getReadyState to be a getter"); @@ -4611,18 +4629,23 @@ pub const JSTLSSocket = struct { if (@TypeOf(TLSSocket.getRemoteAddress) != GetterType) @compileLog("Expected TLSSocket.getRemoteAddress to be a getter"); + if (@TypeOf(TLSSocket.setServername) != CallbackType) + @compileLog("Expected TLSSocket.setServername to be a callback but received " ++ @typeName(@TypeOf(TLSSocket.setServername))); if (@TypeOf(TLSSocket.shutdown) != CallbackType) @compileLog("Expected TLSSocket.shutdown to be a callback but received " ++ @typeName(@TypeOf(TLSSocket.shutdown))); if (@TypeOf(TLSSocket.timeout) != CallbackType) @compileLog("Expected TLSSocket.timeout to be a callback but received " ++ @typeName(@TypeOf(TLSSocket.timeout))); if (@TypeOf(TLSSocket.unref) != CallbackType) @compileLog("Expected TLSSocket.unref to be a callback but received " ++ @typeName(@TypeOf(TLSSocket.unref))); + if (@TypeOf(TLSSocket.wrapTLS) != CallbackType) + @compileLog("Expected TLSSocket.wrapTLS to be a callback but received " ++ @typeName(@TypeOf(TLSSocket.wrapTLS))); if (@TypeOf(TLSSocket.write) != CallbackType) @compileLog("Expected TLSSocket.write to be a callback but received " ++ @typeName(@TypeOf(TLSSocket.write))); if (!JSC.is_bindgen) { @export(TLSSocket.end, .{ .name = "TLSSocketPrototype__end" }); @export(TLSSocket.finalize, .{ .name = "TLSSocketClass__finalize" }); @export(TLSSocket.flush, .{ .name = "TLSSocketPrototype__flush" }); + @export(TLSSocket.getALPNProtocol, .{ .name = "TLSSocketPrototype__getALPNProtocol" }); @export(TLSSocket.getAuthorizationError, .{ .name = "TLSSocketPrototype__getAuthorizationError" }); @export(TLSSocket.getAuthorized, .{ .name = "TLSSocketPrototype__getAuthorized" }); @export(TLSSocket.getData, .{ .name = "TLSSocketPrototype__getData" }); @@ -4631,12 +4654,15 @@ pub const JSTLSSocket = struct { @export(TLSSocket.getReadyState, .{ .name = "TLSSocketPrototype__getReadyState" }); @export(TLSSocket.getRemoteAddress, .{ .name = "TLSSocketPrototype__getRemoteAddress" }); @export(TLSSocket.hasPendingActivity, .{ .name = "TLSSocket__hasPendingActivity" }); + @export(TLSSocket.open, .{ .name = "TLSSocketPrototype__open" }); @export(TLSSocket.ref, .{ .name = "TLSSocketPrototype__ref" }); @export(TLSSocket.reload, .{ .name = "TLSSocketPrototype__reload" }); @export(TLSSocket.setData, .{ .name = "TLSSocketPrototype__setData" }); + @export(TLSSocket.setServername, .{ .name = "TLSSocketPrototype__setServername" }); @export(TLSSocket.shutdown, .{ .name = "TLSSocketPrototype__shutdown" }); @export(TLSSocket.timeout, .{ .name = "TLSSocketPrototype__timeout" }); @export(TLSSocket.unref, .{ .name = "TLSSocketPrototype__unref" }); + @export(TLSSocket.wrapTLS, .{ .name = "TLSSocketPrototype__wrapTLS" }); @export(TLSSocket.write, .{ .name = "TLSSocketPrototype__write" }); } } diff --git a/src/bun.js/bindings/webcore/JSEventEmitter.cpp b/src/bun.js/bindings/webcore/JSEventEmitter.cpp index 1957b404b..231ae0db4 100644 --- a/src/bun.js/bindings/webcore/JSEventEmitter.cpp +++ b/src/bun.js/bindings/webcore/JSEventEmitter.cpp @@ -149,7 +149,7 @@ static const HashTableValue JSEventEmitterPrototypeTableValues[] = { { "on"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsEventEmitterPrototypeFunction_addListener, 2 } }, { "once"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsEventEmitterPrototypeFunction_addOnceListener, 2 } }, { "prependListener"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsEventEmitterPrototypeFunction_prependListener, 2 } }, - { "prependOnce"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsEventEmitterPrototypeFunction_prependOnceListener, 2 } }, + { "prependOnceListener"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsEventEmitterPrototypeFunction_prependOnceListener, 2 } }, { "removeListener"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsEventEmitterPrototypeFunction_removeListener, 2 } }, { "off"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsEventEmitterPrototypeFunction_removeListener, 2 } }, { "removeAllListeners"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsEventEmitterPrototypeFunction_removeAllListeners, 1 } }, |