Skip to content

Commit

Permalink
Fixes #14333 (#14679)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarred-Sumner authored Oct 19, 2024
1 parent 522c9fa commit 67b4478
Show file tree
Hide file tree
Showing 11 changed files with 396 additions and 187 deletions.
5 changes: 3 additions & 2 deletions packages/bun-usockets/src/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,13 @@ void us_socket_context_add_server_name(int ssl, struct us_socket_context_t *cont
}
#endif
}
void us_bun_socket_context_add_server_name(int ssl, struct us_socket_context_t *context, const char *hostname_pattern, struct us_bun_socket_context_options_t options, void *user) {
int us_bun_socket_context_add_server_name(int ssl, struct us_socket_context_t *context, const char *hostname_pattern, struct us_bun_socket_context_options_t options, void *user) {
#ifndef LIBUS_NO_SSL
if (ssl) {
us_bun_internal_ssl_socket_context_add_server_name((struct us_internal_ssl_socket_context_t *) context, hostname_pattern, options, user);
return us_bun_internal_ssl_socket_context_add_server_name((struct us_internal_ssl_socket_context_t *) context, hostname_pattern, options, user);
}
#endif
return 0;
}

/* Remove SNI context */
Expand Down
27 changes: 20 additions & 7 deletions packages/bun-usockets/src/crypto/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,11 @@ create_ssl_context_from_options(struct us_socket_context_options_t options) {
}
}

if (ERR_peek_error() != 0) {
free_ssl_context(ssl_context);
return NULL;
}

/* This must be free'd with free_ssl_context, not SSL_CTX_free */
return ssl_context;
}
Expand Down Expand Up @@ -1106,6 +1111,8 @@ int us_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
SSL_CTX *create_ssl_context_from_bun_options(
struct us_bun_socket_context_options_t options,
enum create_bun_socket_error_t *err) {
ERR_clear_error();

/* Create the context */
SSL_CTX *ssl_context = SSL_CTX_new(TLS_method());

Expand Down Expand Up @@ -1211,6 +1218,9 @@ SSL_CTX *create_ssl_context_from_bun_options(
return NULL;
}

// It may return spurious errors here.
ERR_clear_error();

if (options.reject_unauthorized) {
SSL_CTX_set_verify(ssl_context,
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
Expand Down Expand Up @@ -1336,30 +1346,33 @@ void us_internal_ssl_socket_context_add_server_name(
}
}

void us_bun_internal_ssl_socket_context_add_server_name(
int us_bun_internal_ssl_socket_context_add_server_name(
struct us_internal_ssl_socket_context_t *context,
const char *hostname_pattern,
struct us_bun_socket_context_options_t options, void *user) {

/* Try and construct an SSL_CTX from options */
enum create_bun_socket_error_t err = CREATE_BUN_SOCKET_ERROR_NONE;
SSL_CTX *ssl_context = create_ssl_context_from_bun_options(options, &err);
if (ssl_context == NULL) {
return -1;
}

/* Attach the user data to this context */
if (1 != SSL_CTX_set_ex_data(ssl_context, 0, user)) {
#if BUN_DEBUG
printf("CANNOT SET EX DATA!\n");
abort();
#endif
return -1;
}

/* We do not want to hold any nullptr's in our SNI tree */
if (ssl_context) {
if (sni_add(context->sni, hostname_pattern, ssl_context)) {
/* If we already had that name, ignore */
free_ssl_context(ssl_context);
}
if (sni_add(context->sni, hostname_pattern, ssl_context)) {
/* If we already had that name, ignore */
free_ssl_context(ssl_context);
}

return 0;
}

void us_internal_ssl_socket_context_on_server_name(
Expand Down
2 changes: 1 addition & 1 deletion packages/bun-usockets/src/internal/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ void us_internal_ssl_socket_context_add_server_name(
us_internal_ssl_socket_context_r context,
const char *hostname_pattern, struct us_socket_context_options_t options,
void *user);
void us_bun_internal_ssl_socket_context_add_server_name(
int us_bun_internal_ssl_socket_context_add_server_name(
us_internal_ssl_socket_context_r context,
const char *hostname_pattern,
struct us_bun_socket_context_options_t options, void *user);
Expand Down
2 changes: 1 addition & 1 deletion packages/bun-usockets/src/libusockets.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ unsigned short us_socket_context_timestamp(int ssl, us_socket_context_r context)

/* Adds SNI domain and cert in asn1 format */
void us_socket_context_add_server_name(int ssl, us_socket_context_r context, const char *hostname_pattern, struct us_socket_context_options_t options, void *user);
void us_bun_socket_context_add_server_name(int ssl, us_socket_context_r context, const char *hostname_pattern, struct us_bun_socket_context_options_t options, void *user);
int us_bun_socket_context_add_server_name(int ssl, us_socket_context_r context, const char *hostname_pattern, struct us_bun_socket_context_options_t options, void *user);
void us_socket_context_remove_server_name(int ssl, us_socket_context_r context, const char *hostname_pattern);
void us_socket_context_on_server_name(int ssl, us_socket_context_r context, void (*cb)(us_socket_context_r context, const char *hostname));
void *us_socket_server_name_userdata(int ssl, us_socket_r s);
Expand Down
19 changes: 17 additions & 2 deletions packages/bun-uws/src/App.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,17 @@ struct TemplatedApp {


/* Server name */
TemplatedApp &&addServerName(std::string hostname_pattern, SocketContextOptions options = {}) {
TemplatedApp &&addServerName(std::string hostname_pattern, SocketContextOptions options = {}, bool *success = nullptr) {

/* Do nothing if not even on SSL */
if constexpr (SSL) {
/* First we create a new router for this domain */
auto *domainRouter = new HttpRouter<typename HttpContextData<SSL>::RouterData>();

us_bun_socket_context_add_server_name(SSL, (struct us_socket_context_t *) httpContext, hostname_pattern.c_str(), options, domainRouter);
int result = us_bun_socket_context_add_server_name(SSL, (struct us_socket_context_t *) httpContext, hostname_pattern.c_str(), options, domainRouter);
if (success) {
*success = result == 0;
}
}

return std::move(*this);
Expand Down Expand Up @@ -238,6 +241,18 @@ struct TemplatedApp {
httpContext = HttpContext<SSL>::create(Loop::get(), options);
}

TemplatedApp(HttpContext<SSL> &context) {
httpContext = &context;
}

static TemplatedApp<SSL>* create(SocketContextOptions options = {}) {
auto* httpContext = HttpContext<SSL>::create(Loop::get(), options);
if (!httpContext) {
return nullptr;
}
return new TemplatedApp<SSL>(*httpContext);
}

bool constructorFailed() {
return !httpContext;
}
Expand Down
5 changes: 4 additions & 1 deletion src/bake/DevServer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,10 @@ pub fn init(options: Options) !*DevServer {
else
null;

const app = App.create(.{});
const app = App.create(.{}) orelse {
Output.prettyErrorln("Failed to create app", .{});
return error.AppInitialization;
};

const separate_ssr_graph = if (options.framework.server_components) |sc| sc.separate_ssr_graph else false;

Expand Down
123 changes: 33 additions & 90 deletions src/bun.js/api/BunObject.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3334,8 +3334,6 @@ pub fn serve(
break :brk config;
};

var exception_value: *JSC.JSValue = undefined;

if (config.allow_hot) {
if (globalObject.bunVM().hotMap()) |hot| {
if (config.id.len == 0) {
Expand Down Expand Up @@ -3370,98 +3368,43 @@ pub fn serve(
}
}

// Listen happens on the next tick!
// This is so we can return a Server object
if (config.ssl_config != null) {
if (config.development) {
var server = JSC.API.DebugHTTPSServer.init(config, globalObject.ptr());
exception_value = &server.thisObject;
server.listen();
if (!server.thisObject.isEmpty()) {
exception_value.unprotect();
globalObject.throwValue(server.thisObject);
server.thisObject = JSC.JSValue.zero;
server.deinit();
return .zero;
}
const obj = server.toJS(globalObject);
obj.protect();

server.thisObject = obj;

if (config.allow_hot) {
if (globalObject.bunVM().hotMap()) |hot| {
hot.insert(config.id, server);
}
}
return obj;
} else {
var server = JSC.API.HTTPSServer.init(config, globalObject.ptr());
exception_value = &server.thisObject;
server.listen();
if (!exception_value.isEmpty()) {
exception_value.unprotect();
globalObject.throwValue(exception_value.*);
server.thisObject = JSC.JSValue.zero;
server.deinit();
return .zero;
}
const obj = server.toJS(globalObject);
obj.protect();
server.thisObject = obj;

if (config.allow_hot) {
if (globalObject.bunVM().hotMap()) |hot| {
hot.insert(config.id, server);
}
}
return obj;
}
} else {
if (config.development) {
var server = JSC.API.DebugHTTPServer.init(config, globalObject.ptr());
exception_value = &server.thisObject;
server.listen();
if (!exception_value.isEmpty()) {
exception_value.unprotect();
globalObject.throwValue(exception_value.*);
server.thisObject = JSC.JSValue.zero;
server.deinit();
return .zero;
}
const obj = server.toJS(globalObject);
obj.protect();
server.thisObject = obj;
switch (config.ssl_config != null) {
inline else => |has_ssl_config| {
switch (config.development) {
inline else => |development| {
const ServerType = comptime switch (development) {
true => switch (has_ssl_config) {
true => JSC.API.DebugHTTPSServer,
false => JSC.API.DebugHTTPServer,
},
false => switch (has_ssl_config) {
true => JSC.API.HTTPSServer,
false => JSC.API.HTTPServer,
},
};

if (config.allow_hot) {
if (globalObject.bunVM().hotMap()) |hot| {
hot.insert(config.id, server);
}
}
return obj;
} else {
var server = JSC.API.HTTPServer.init(config, globalObject.ptr());
exception_value = &server.thisObject;
server.listen();
if (!exception_value.isEmpty()) {
exception_value.unprotect();
globalObject.throwValue(exception_value.*);
server.thisObject = JSC.JSValue.zero;
server.deinit();
return .zero;
}
const obj = server.toJS(globalObject);
obj.protect();
var server = ServerType.init(config, globalObject);
if (globalObject.hasException()) {
return .zero;
}
server.listen();
if (globalObject.hasException()) {
return .zero;
}
const obj = server.toJS(globalObject);
obj.protect();

server.thisObject = obj;
server.thisObject = obj;

if (config.allow_hot) {
if (globalObject.bunVM().hotMap()) |hot| {
hot.insert(config.id, server);
}
if (config.allow_hot) {
if (globalObject.bunVM().hotMap()) |hot| {
hot.insert(config.id, server);
}
}
return obj;
},
}
return obj;
}
},
}

unreachable;
Expand Down
Loading

0 comments on commit 67b4478

Please sign in to comment.