mirror of
https://github.com/oven-sh/bun
synced 2026-02-03 07:28:53 +00:00
Compare commits
5 Commits
dylan/byte
...
jarred/fas
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9c818df68 | ||
|
|
42fb8405c3 | ||
|
|
d9b199406e | ||
|
|
fcebe72044 | ||
|
|
efce576072 |
@@ -1106,8 +1106,11 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
-Werror=sometimes-uninitialized
|
||||
-Werror=unused
|
||||
-Wno-unused-function
|
||||
-Wno-nullability-completeness
|
||||
-Werror
|
||||
-fsanitize=null
|
||||
)
|
||||
target_link_libraries(${bun} PRIVATE -fsanitize=null)
|
||||
else()
|
||||
target_compile_options(${bun} PUBLIC /Od /Z7)
|
||||
endif()
|
||||
@@ -1133,6 +1136,7 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
-Werror=nonnull
|
||||
-Werror=move
|
||||
-Werror=sometimes-uninitialized
|
||||
-Wno-nullability-completeness
|
||||
-Werror
|
||||
)
|
||||
else()
|
||||
|
||||
@@ -101,6 +101,9 @@ struct addrinfo_result {
|
||||
int error;
|
||||
};
|
||||
|
||||
#define us_internal_ssl_socket_context_r struct us_internal_ssl_socket_context_t *nonnull_arg
|
||||
#define us_internal_ssl_socket_r struct us_internal_ssl_socket_t *nonnull_arg
|
||||
|
||||
extern int Bun__addrinfo_get(struct us_loop_t* loop, const char* host, struct addrinfo_request** ptr);
|
||||
extern int Bun__addrinfo_set(struct addrinfo_request* ptr, struct us_connecting_socket_t* socket);
|
||||
extern void Bun__addrinfo_freeRequest(struct addrinfo_request* addrinfo_req, int error);
|
||||
@@ -110,19 +113,19 @@ extern struct addrinfo_result *Bun__addrinfo_getRequestResult(struct addrinfo_re
|
||||
/* Loop related */
|
||||
void us_internal_dispatch_ready_poll(struct us_poll_t *p, int error,
|
||||
int events);
|
||||
void us_internal_timer_sweep(struct us_loop_t *loop);
|
||||
void us_internal_free_closed_sockets(struct us_loop_t *loop);
|
||||
void us_internal_timer_sweep(us_loop_r loop);
|
||||
void us_internal_free_closed_sockets(us_loop_r loop);
|
||||
void us_internal_loop_link(struct us_loop_t *loop,
|
||||
struct us_socket_context_t *context);
|
||||
void us_internal_loop_unlink(struct us_loop_t *loop,
|
||||
struct us_socket_context_t *context);
|
||||
void us_internal_loop_data_init(struct us_loop_t *loop,
|
||||
void (*wakeup_cb)(struct us_loop_t *loop),
|
||||
void (*pre_cb)(struct us_loop_t *loop),
|
||||
void (*post_cb)(struct us_loop_t *loop));
|
||||
void us_internal_loop_data_free(struct us_loop_t *loop);
|
||||
void us_internal_loop_pre(struct us_loop_t *loop);
|
||||
void us_internal_loop_post(struct us_loop_t *loop);
|
||||
void (*wakeup_cb)(us_loop_r loop),
|
||||
void (*pre_cb)(us_loop_r loop),
|
||||
void (*post_cb)(us_loop_r loop));
|
||||
void us_internal_loop_data_free(us_loop_r loop);
|
||||
void us_internal_loop_pre(us_loop_r loop);
|
||||
void us_internal_loop_post(us_loop_r loop);
|
||||
|
||||
/* Asyncs (old) */
|
||||
struct us_internal_async *us_internal_create_async(struct us_loop_t *loop,
|
||||
@@ -139,22 +142,22 @@ int us_internal_poll_type(struct us_poll_t *p);
|
||||
void us_internal_poll_set_type(struct us_poll_t *p, int poll_type);
|
||||
|
||||
/* SSL loop data */
|
||||
void us_internal_init_loop_ssl_data(struct us_loop_t *loop);
|
||||
void us_internal_free_loop_ssl_data(struct us_loop_t *loop);
|
||||
void us_internal_init_loop_ssl_data(us_loop_r loop);
|
||||
void us_internal_free_loop_ssl_data(us_loop_r loop);
|
||||
|
||||
/* Socket context related */
|
||||
void us_internal_socket_context_link_socket(struct us_socket_context_t *context,
|
||||
struct us_socket_t *s);
|
||||
void us_internal_socket_context_link_socket(us_socket_context_r context,
|
||||
us_socket_r s);
|
||||
void us_internal_socket_context_unlink_socket(int ssl,
|
||||
struct us_socket_context_t *context, struct us_socket_t *s);
|
||||
us_socket_context_r context, us_socket_r s);
|
||||
|
||||
void us_internal_socket_after_resolve(struct us_connecting_socket_t *s);
|
||||
void us_internal_socket_after_open(struct us_socket_t *s, int error);
|
||||
void us_internal_socket_after_open(us_socket_r s, int error);
|
||||
struct us_internal_ssl_socket_t *
|
||||
us_internal_ssl_socket_close(struct us_internal_ssl_socket_t *s, int code,
|
||||
us_internal_ssl_socket_close(us_internal_ssl_socket_r s, int code,
|
||||
void *reason);
|
||||
|
||||
int us_internal_handle_dns_results(struct us_loop_t *loop);
|
||||
int us_internal_handle_dns_results(us_loop_r loop);
|
||||
|
||||
/* Sockets are polls */
|
||||
struct us_socket_t {
|
||||
@@ -248,9 +251,9 @@ struct us_listen_socket_t {
|
||||
|
||||
/* Listen sockets are keps in their own list */
|
||||
void us_internal_socket_context_link_listen_socket(
|
||||
struct us_socket_context_t *context, struct us_listen_socket_t *s);
|
||||
us_socket_context_r context, struct us_listen_socket_t *s);
|
||||
void us_internal_socket_context_unlink_listen_socket(int ssl,
|
||||
struct us_socket_context_t *context, struct us_listen_socket_t *s);
|
||||
us_socket_context_r context, struct us_listen_socket_t *s);
|
||||
|
||||
struct us_socket_context_t {
|
||||
alignas(LIBUS_EXT_ALIGNMENT) struct us_loop_t *loop;
|
||||
@@ -290,31 +293,31 @@ typedef void (*us_internal_on_handshake_t)(
|
||||
void us_internal_socket_context_free(int ssl, struct us_socket_context_t *context);
|
||||
/* SNI functions */
|
||||
void us_internal_ssl_socket_context_add_server_name(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
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(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
const char *hostname_pattern,
|
||||
struct us_bun_socket_context_options_t options, void *user);
|
||||
void us_internal_ssl_socket_context_remove_server_name(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
const char *hostname_pattern);
|
||||
void us_internal_ssl_socket_context_on_server_name(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
void (*cb)(struct us_internal_ssl_socket_context_t *, const char *));
|
||||
void *
|
||||
us_internal_ssl_socket_get_sni_userdata(struct us_internal_ssl_socket_t *s);
|
||||
us_internal_ssl_socket_get_sni_userdata(us_internal_ssl_socket_r s);
|
||||
void *us_internal_ssl_socket_context_find_server_name_userdata(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
const char *hostname_pattern);
|
||||
|
||||
void *
|
||||
us_internal_ssl_socket_get_native_handle(struct us_internal_ssl_socket_t *s);
|
||||
us_internal_ssl_socket_get_native_handle(us_internal_ssl_socket_r s);
|
||||
void *us_internal_ssl_socket_context_get_native_handle(
|
||||
struct us_internal_ssl_socket_context_t *context);
|
||||
us_internal_ssl_socket_context_r context);
|
||||
struct us_bun_verify_error_t
|
||||
us_internal_verify_error(struct us_internal_ssl_socket_t *s);
|
||||
us_internal_verify_error(us_internal_ssl_socket_r s);
|
||||
struct us_internal_ssl_socket_context_t *us_internal_create_ssl_socket_context(
|
||||
struct us_loop_t *loop, int context_ext_size,
|
||||
struct us_socket_context_options_t options);
|
||||
@@ -324,109 +327,109 @@ us_internal_bun_create_ssl_socket_context(
|
||||
struct us_bun_socket_context_options_t options);
|
||||
|
||||
void us_internal_ssl_socket_context_free(
|
||||
struct us_internal_ssl_socket_context_t *context);
|
||||
us_internal_ssl_socket_context_r context);
|
||||
void us_internal_ssl_socket_context_on_open(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
struct us_internal_ssl_socket_t *(*on_open)(
|
||||
struct us_internal_ssl_socket_t *s, int is_client, char *ip,
|
||||
us_internal_ssl_socket_r s, int is_client, char *ip,
|
||||
int ip_length));
|
||||
|
||||
void us_internal_ssl_socket_context_on_close(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
struct us_internal_ssl_socket_t *(*on_close)(
|
||||
struct us_internal_ssl_socket_t *s, int code, void *reason));
|
||||
us_internal_ssl_socket_r s, int code, void *reason));
|
||||
|
||||
void us_internal_ssl_socket_context_on_data(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
struct us_internal_ssl_socket_t *(*on_data)(
|
||||
struct us_internal_ssl_socket_t *s, char *data, int length));
|
||||
us_internal_ssl_socket_r s, char *data, int length));
|
||||
|
||||
void us_internal_update_handshake(struct us_internal_ssl_socket_t *s);
|
||||
int us_internal_renegotiate(struct us_internal_ssl_socket_t *s);
|
||||
void us_internal_trigger_handshake_callback(struct us_internal_ssl_socket_t *s,
|
||||
void us_internal_update_handshake(us_internal_ssl_socket_r s);
|
||||
int us_internal_renegotiate(us_internal_ssl_socket_r s);
|
||||
void us_internal_trigger_handshake_callback(us_internal_ssl_socket_r s,
|
||||
int success);
|
||||
void us_internal_on_ssl_handshake(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
us_internal_on_handshake_t onhandshake, void *custom_data);
|
||||
|
||||
void us_internal_ssl_socket_context_on_writable(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
struct us_internal_ssl_socket_t *(*on_writable)(
|
||||
struct us_internal_ssl_socket_t *s));
|
||||
us_internal_ssl_socket_r s));
|
||||
|
||||
void us_internal_ssl_socket_context_on_timeout(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
struct us_internal_ssl_socket_t *(*on_timeout)(
|
||||
struct us_internal_ssl_socket_t *s));
|
||||
us_internal_ssl_socket_r s));
|
||||
|
||||
void us_internal_ssl_socket_context_on_long_timeout(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
struct us_internal_ssl_socket_t *(*on_timeout)(
|
||||
struct us_internal_ssl_socket_t *s));
|
||||
us_internal_ssl_socket_r s));
|
||||
|
||||
void us_internal_ssl_socket_context_on_end(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
struct us_internal_ssl_socket_t *(*on_end)(
|
||||
struct us_internal_ssl_socket_t *s));
|
||||
us_internal_ssl_socket_r s));
|
||||
|
||||
void us_internal_ssl_socket_context_on_connect_error(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
struct us_internal_ssl_socket_t *(*on_connect_error)(
|
||||
struct us_internal_ssl_socket_t *s, int code));
|
||||
us_internal_ssl_socket_r s, int code));
|
||||
|
||||
void us_internal_ssl_socket_context_on_socket_connect_error(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
us_internal_ssl_socket_context_r context,
|
||||
struct us_internal_ssl_socket_t *(*on_socket_connect_error)(
|
||||
struct us_internal_ssl_socket_t *s, int code));
|
||||
us_internal_ssl_socket_r s, int code));
|
||||
|
||||
struct us_listen_socket_t *us_internal_ssl_socket_context_listen(
|
||||
struct us_internal_ssl_socket_context_t *context, const char *host,
|
||||
us_internal_ssl_socket_context_r context, const char *host,
|
||||
int port, int options, int socket_ext_size);
|
||||
|
||||
struct us_listen_socket_t *us_internal_ssl_socket_context_listen_unix(
|
||||
struct us_internal_ssl_socket_context_t *context, const char *path,
|
||||
us_internal_ssl_socket_context_r context, const char *path,
|
||||
size_t pathlen, int options, int socket_ext_size);
|
||||
|
||||
struct us_connecting_socket_t *us_internal_ssl_socket_context_connect(
|
||||
struct us_internal_ssl_socket_context_t *context, const char *host,
|
||||
us_internal_ssl_socket_context_r context, const char *host,
|
||||
int port, int options, int socket_ext_size, int* is_resolved);
|
||||
|
||||
struct us_internal_ssl_socket_t *us_internal_ssl_socket_context_connect_unix(
|
||||
struct us_internal_ssl_socket_context_t *context, const char *server_path,
|
||||
us_internal_ssl_socket_context_r context, const char *server_path,
|
||||
size_t pathlen, int options, int socket_ext_size);
|
||||
|
||||
int us_internal_ssl_socket_write(struct us_internal_ssl_socket_t *s,
|
||||
int us_internal_ssl_socket_write(us_internal_ssl_socket_r s,
|
||||
const char *data, int length, int msg_more);
|
||||
int us_internal_ssl_socket_raw_write(struct us_internal_ssl_socket_t *s,
|
||||
int us_internal_ssl_socket_raw_write(us_internal_ssl_socket_r s,
|
||||
const char *data, int length,
|
||||
int msg_more);
|
||||
|
||||
void us_internal_ssl_socket_timeout(struct us_internal_ssl_socket_t *s,
|
||||
void us_internal_ssl_socket_timeout(us_internal_ssl_socket_r s,
|
||||
unsigned int seconds);
|
||||
void *
|
||||
us_internal_ssl_socket_context_ext(struct us_internal_ssl_socket_context_t *s);
|
||||
struct us_internal_ssl_socket_context_t *
|
||||
us_internal_ssl_socket_get_context(struct us_internal_ssl_socket_t *s);
|
||||
void *us_internal_ssl_socket_ext(struct us_internal_ssl_socket_t *s);
|
||||
us_internal_ssl_socket_get_context(us_internal_ssl_socket_r s);
|
||||
void *us_internal_ssl_socket_ext(us_internal_ssl_socket_r s);
|
||||
void *us_internal_connecting_ssl_socket_ext(struct us_connecting_socket_t *c);
|
||||
int us_internal_ssl_socket_is_shut_down(struct us_internal_ssl_socket_t *s);
|
||||
int us_internal_ssl_socket_is_closed(struct us_internal_ssl_socket_t *s);
|
||||
void us_internal_ssl_socket_shutdown(struct us_internal_ssl_socket_t *s);
|
||||
int us_internal_ssl_socket_is_shut_down(us_internal_ssl_socket_r s);
|
||||
int us_internal_ssl_socket_is_closed(us_internal_ssl_socket_r s);
|
||||
void us_internal_ssl_socket_shutdown(us_internal_ssl_socket_r s);
|
||||
|
||||
struct us_internal_ssl_socket_t *us_internal_ssl_socket_context_adopt_socket(
|
||||
struct us_internal_ssl_socket_context_t *context,
|
||||
struct us_internal_ssl_socket_t *s, int ext_size);
|
||||
us_internal_ssl_socket_context_r context,
|
||||
us_internal_ssl_socket_r s, int ext_size);
|
||||
|
||||
struct us_internal_ssl_socket_t *us_internal_ssl_socket_wrap_with_tls(
|
||||
struct us_socket_t *s, struct us_bun_socket_context_options_t options,
|
||||
us_socket_r s, struct us_bun_socket_context_options_t options,
|
||||
struct us_socket_events_t events, int socket_ext_size);
|
||||
struct us_internal_ssl_socket_context_t *
|
||||
us_internal_create_child_ssl_socket_context(
|
||||
struct us_internal_ssl_socket_context_t *context, int context_ext_size);
|
||||
us_internal_ssl_socket_context_r context, int context_ext_size);
|
||||
struct us_loop_t *us_internal_ssl_socket_context_loop(
|
||||
struct us_internal_ssl_socket_context_t *context);
|
||||
us_internal_ssl_socket_context_r context);
|
||||
struct us_internal_ssl_socket_t *
|
||||
us_internal_ssl_socket_open(struct us_internal_ssl_socket_t *s, int is_client,
|
||||
us_internal_ssl_socket_open(us_internal_ssl_socket_r s, int is_client,
|
||||
char *ip, int ip_length);
|
||||
|
||||
int us_raw_root_certs(struct us_cert_string_t **out);
|
||||
|
||||
@@ -35,6 +35,25 @@
|
||||
#ifndef LIBUSOCKETS_H
|
||||
#define LIBUSOCKETS_H
|
||||
|
||||
#ifdef BUN_DEBUG
|
||||
#define nonnull_arg _Nonnull
|
||||
#else
|
||||
#define nonnull_arg
|
||||
#endif
|
||||
|
||||
#ifdef BUN_DEBUG
|
||||
#define nonnull_fn_decl
|
||||
#else
|
||||
#ifndef nonnull_fn_decl
|
||||
#define nonnull_fn_decl __attribute__((nonnull))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define us_loop_r struct us_loop_t *nonnull_arg
|
||||
#define us_socket_r struct us_socket_t *nonnull_arg
|
||||
#define us_poll_r struct us_poll_t *nonnull_arg
|
||||
#define us_socket_context_r struct us_socket_context_t *nonnull_arg
|
||||
|
||||
|
||||
/* 512kb shared receive buffer */
|
||||
#define LIBUS_RECV_BUFFER_LENGTH 524288
|
||||
@@ -124,11 +143,11 @@ struct us_udp_packet_buffer_t *us_create_udp_packet_buffer();
|
||||
/* Creates a (heavy-weight) UDP socket with a user space ring buffer. Again, this one is heavy weight and
|
||||
* shoud be reused. One entire QUIC server can be implemented using only one single UDP socket so weight
|
||||
* is not a concern as is the case for TCP sockets which are 1-to-1 with TCP connections. */
|
||||
//struct us_udp_socket_t *us_create_udp_socket(struct us_loop_t *loop, void (*read_cb)(struct us_udp_socket_t *), unsigned short port);
|
||||
//struct us_udp_socket_t *us_create_udp_socket(us_loop_r loop, void (*read_cb)(struct us_udp_socket_t *), unsigned short port);
|
||||
|
||||
//struct us_udp_socket_t *us_create_udp_socket(struct us_loop_t *loop, void (*data_cb)(struct us_udp_socket_t *, struct us_udp_packet_buffer_t *, int), void (*drain_cb)(struct us_udp_socket_t *), char *host, unsigned short port);
|
||||
//struct us_udp_socket_t *us_create_udp_socket(us_loop_r loop, void (*data_cb)(struct us_udp_socket_t *, struct us_udp_packet_buffer_t *, int), void (*drain_cb)(struct us_udp_socket_t *), char *host, unsigned short port);
|
||||
|
||||
struct us_udp_socket_t *us_create_udp_socket(struct us_loop_t *loop, void (*data_cb)(struct us_udp_socket_t *, void *, int), void (*drain_cb)(struct us_udp_socket_t *), void (*close_cb)(struct us_udp_socket_t *), const char *host, unsigned short port, void *user);
|
||||
struct us_udp_socket_t *us_create_udp_socket(us_loop_r loop, void (*data_cb)(struct us_udp_socket_t *, void *, int), void (*drain_cb)(struct us_udp_socket_t *), void (*close_cb)(struct us_udp_socket_t *), const char *host, unsigned short port, void *user);
|
||||
|
||||
void us_udp_socket_close(struct us_udp_socket_t *s);
|
||||
|
||||
@@ -141,7 +160,7 @@ int us_udp_socket_bind(struct us_udp_socket_t *s, const char *hostname, unsigned
|
||||
/* Public interfaces for timers */
|
||||
|
||||
/* Create a new high precision, low performance timer. May fail and return null */
|
||||
struct us_timer_t *us_create_timer(struct us_loop_t *loop, int fallthrough, unsigned int ext_size);
|
||||
struct us_timer_t *us_create_timer(us_loop_r loop, int fallthrough, unsigned int ext_size);
|
||||
|
||||
/* Returns user data extension for this timer */
|
||||
void *us_timer_ext(struct us_timer_t *timer);
|
||||
@@ -175,17 +194,17 @@ struct us_bun_verify_error_t {
|
||||
};
|
||||
|
||||
struct us_socket_events_t {
|
||||
struct us_socket_t *(*on_open)(struct us_socket_t *, int is_client, char *ip, int ip_length);
|
||||
struct us_socket_t *(*on_data)(struct us_socket_t *, char *data, int length);
|
||||
struct us_socket_t *(*on_writable)(struct us_socket_t *);
|
||||
struct us_socket_t *(*on_close)(struct us_socket_t *, int code, void *reason);
|
||||
struct us_socket_t *(*on_open)(us_socket_r, int is_client, char *ip, int ip_length);
|
||||
struct us_socket_t *(*on_data)(us_socket_r, char *data, int length);
|
||||
struct us_socket_t *(*on_writable)(us_socket_r);
|
||||
struct us_socket_t *(*on_close)(us_socket_r, int code, void *reason);
|
||||
//void (*on_timeout)(struct us_socket_context *);
|
||||
struct us_socket_t *(*on_timeout)(struct us_socket_t *);
|
||||
struct us_socket_t *(*on_long_timeout)(struct us_socket_t *);
|
||||
struct us_socket_t *(*on_end)(struct us_socket_t *);
|
||||
struct us_socket_t *(*on_timeout)(us_socket_r);
|
||||
struct us_socket_t *(*on_long_timeout)(us_socket_r);
|
||||
struct us_socket_t *(*on_end)(us_socket_r);
|
||||
struct us_connecting_socket_t *(*on_connect_error)(struct us_connecting_socket_t *, int code);
|
||||
struct us_socket_t *(*on_connecting_socket_error)(struct us_socket_t *, int code);
|
||||
void (*on_handshake)(struct us_socket_t*, int success, struct us_bun_verify_error_t verify_error, void* custom_data);
|
||||
struct us_socket_t *(*on_connecting_socket_error)(us_socket_r, int code);
|
||||
void (*on_handshake)(us_socket_r, int success, struct us_bun_verify_error_t verify_error, void* custom_data);
|
||||
};
|
||||
|
||||
|
||||
@@ -211,70 +230,70 @@ struct us_bun_socket_context_options_t {
|
||||
};
|
||||
|
||||
/* Return 15-bit timestamp for this context */
|
||||
unsigned short us_socket_context_timestamp(int ssl, struct us_socket_context_t *context);
|
||||
unsigned short us_socket_context_timestamp(int ssl, us_socket_context_r context) nonnull_fn_decl;
|
||||
|
||||
/* Adds SNI domain and cert in asn1 format */
|
||||
void us_socket_context_add_server_name(int ssl, struct us_socket_context_t *context, const char *hostname_pattern, struct us_socket_context_options_t options, void *user);
|
||||
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);
|
||||
void us_socket_context_remove_server_name(int ssl, struct us_socket_context_t *context, const char *hostname_pattern);
|
||||
void us_socket_context_on_server_name(int ssl, struct us_socket_context_t *context, void (*cb)(struct us_socket_context_t *, const char *hostname));
|
||||
void *us_socket_server_name_userdata(int ssl, struct us_socket_t *s);
|
||||
void *us_socket_context_find_server_name_userdata(int ssl, struct us_socket_context_t *context, const char *hostname_pattern);
|
||||
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);
|
||||
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);
|
||||
void *us_socket_context_find_server_name_userdata(int ssl, us_socket_context_r context, const char *hostname_pattern);
|
||||
|
||||
/* Returns the underlying SSL native handle, such as SSL_CTX or nullptr */
|
||||
void *us_socket_context_get_native_handle(int ssl, struct us_socket_context_t *context);
|
||||
void *us_socket_context_get_native_handle(int ssl, us_socket_context_r context);
|
||||
|
||||
/* A socket context holds shared callbacks and user data extension for associated sockets */
|
||||
struct us_socket_context_t *us_create_socket_context(int ssl, struct us_loop_t *loop,
|
||||
int ext_size, struct us_socket_context_options_t options);
|
||||
struct us_socket_context_t *us_create_socket_context(int ssl, us_loop_r loop,
|
||||
int ext_size, struct us_socket_context_options_t options) nonnull_fn_decl;
|
||||
struct us_socket_context_t *us_create_bun_socket_context(int ssl, struct us_loop_t *loop,
|
||||
int ext_size, struct us_bun_socket_context_options_t options);
|
||||
int ext_size, struct us_bun_socket_context_options_t options) nonnull_fn_decl;
|
||||
|
||||
/* Delete resources allocated at creation time (will call unref now and only free when ref count == 0). */
|
||||
void us_socket_context_free(int ssl, struct us_socket_context_t *context);
|
||||
void us_socket_context_ref(int ssl, struct us_socket_context_t *context);
|
||||
void us_socket_context_unref(int ssl, struct us_socket_context_t *context);
|
||||
void us_socket_context_free(int ssl, us_socket_context_r context) nonnull_fn_decl;
|
||||
void us_socket_context_ref(int ssl, us_socket_context_r context) nonnull_fn_decl;
|
||||
void us_socket_context_unref(int ssl, us_socket_context_r context) nonnull_fn_decl;
|
||||
|
||||
struct us_bun_verify_error_t us_socket_verify_error(int ssl, struct us_socket_t *context);
|
||||
/* Setters of various async callbacks */
|
||||
void us_socket_context_on_open(int ssl, struct us_socket_context_t *context,
|
||||
struct us_socket_t *(*on_open)(struct us_socket_t *s, int is_client, char *ip, int ip_length));
|
||||
void us_socket_context_on_close(int ssl, struct us_socket_context_t *context,
|
||||
struct us_socket_t *(*on_close)(struct us_socket_t *s, int code, void *reason));
|
||||
void us_socket_context_on_data(int ssl, struct us_socket_context_t *context,
|
||||
struct us_socket_t *(*on_data)(struct us_socket_t *s, char *data, int length));
|
||||
void us_socket_context_on_writable(int ssl, struct us_socket_context_t *context,
|
||||
struct us_socket_t *(*on_writable)(struct us_socket_t *s));
|
||||
void us_socket_context_on_timeout(int ssl, struct us_socket_context_t *context,
|
||||
struct us_socket_t *(*on_timeout)(struct us_socket_t *s));
|
||||
void us_socket_context_on_long_timeout(int ssl, struct us_socket_context_t *context,
|
||||
struct us_socket_t *(*on_timeout)(struct us_socket_t *s));
|
||||
void us_socket_context_on_open(int ssl, us_socket_context_r context,
|
||||
struct us_socket_t *(*on_open)(us_socket_r s, int is_client, char *ip, int ip_length));
|
||||
void us_socket_context_on_close(int ssl, us_socket_context_r context,
|
||||
struct us_socket_t *(*on_close)(us_socket_r s, int code, void *reason));
|
||||
void us_socket_context_on_data(int ssl, us_socket_context_r context,
|
||||
struct us_socket_t *(*on_data)(us_socket_r s, char *data, int length));
|
||||
void us_socket_context_on_writable(int ssl, us_socket_context_r context,
|
||||
struct us_socket_t *(*on_writable)(us_socket_r s));
|
||||
void us_socket_context_on_timeout(int ssl, us_socket_context_r context,
|
||||
struct us_socket_t *(*on_timeout)(us_socket_r s));
|
||||
void us_socket_context_on_long_timeout(int ssl, us_socket_context_r context,
|
||||
struct us_socket_t *(*on_timeout)(us_socket_r s));
|
||||
/* This one is only used for when a connecting socket fails in a late stage. */
|
||||
void us_socket_context_on_connect_error(int ssl, struct us_socket_context_t *context,
|
||||
void us_socket_context_on_connect_error(int ssl, us_socket_context_r context,
|
||||
struct us_connecting_socket_t *(*on_connect_error)(struct us_connecting_socket_t *s, int code));
|
||||
void us_socket_context_on_socket_connect_error(int ssl, struct us_socket_context_t *context,
|
||||
struct us_socket_t *(*on_connect_error)(struct us_socket_t *s, int code));
|
||||
void us_socket_context_on_socket_connect_error(int ssl, us_socket_context_r context,
|
||||
struct us_socket_t *(*on_connect_error)(us_socket_r s, int code));
|
||||
|
||||
void us_socket_context_on_handshake(int ssl, struct us_socket_context_t *context, void (*on_handshake)(struct us_socket_t *, int success, struct us_bun_verify_error_t verify_error, void* custom_data), void* custom_data);
|
||||
void us_socket_context_on_handshake(int ssl, us_socket_context_r context, void (*on_handshake)(struct us_socket_t *, int success, struct us_bun_verify_error_t verify_error, void* custom_data), void* custom_data);
|
||||
|
||||
/* Emitted when a socket has been half-closed */
|
||||
void us_socket_context_on_end(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_end)(struct us_socket_t *s));
|
||||
void us_socket_context_on_end(int ssl, us_socket_context_r context, struct us_socket_t *(*on_end)(us_socket_r s));
|
||||
|
||||
/* Returns user data extension for this socket context */
|
||||
void *us_socket_context_ext(int ssl, struct us_socket_context_t *context);
|
||||
void *us_socket_context_ext(int ssl, us_socket_context_r context);
|
||||
|
||||
/* Closes all open sockets, including listen sockets. Does not invalidate the socket context. */
|
||||
void us_socket_context_close(int ssl, struct us_socket_context_t *context);
|
||||
void us_socket_context_close(int ssl, us_socket_context_r context);
|
||||
|
||||
/* Listen for connections. Acts as the main driving cog in a server. Will call set async callbacks. */
|
||||
struct us_listen_socket_t *us_socket_context_listen(int ssl, struct us_socket_context_t *context,
|
||||
struct us_listen_socket_t *us_socket_context_listen(int ssl, us_socket_context_r context,
|
||||
const char *host, int port, int options, int socket_ext_size);
|
||||
|
||||
struct us_listen_socket_t *us_socket_context_listen_unix(int ssl, struct us_socket_context_t *context,
|
||||
struct us_listen_socket_t *us_socket_context_listen_unix(int ssl, us_socket_context_r context,
|
||||
const char *path, size_t pathlen, int options, int socket_ext_size);
|
||||
|
||||
/* listen_socket.c/.h */
|
||||
void us_listen_socket_close(int ssl, struct us_listen_socket_t *ls);
|
||||
void us_listen_socket_close(int ssl, struct us_listen_socket_t *ls) nonnull_fn_decl;
|
||||
|
||||
/*
|
||||
Returns one of
|
||||
@@ -285,156 +304,156 @@ void us_listen_socket_close(int ssl, struct us_listen_socket_t *ls);
|
||||
This is the slow path where we must either go through DNS resolution or create multiple sockets
|
||||
per the happy eyeballs algorithm
|
||||
*/
|
||||
void *us_socket_context_connect(int ssl, struct us_socket_context_t *context,
|
||||
const char *host, int port, int options, int socket_ext_size, int *is_connecting);
|
||||
void *us_socket_context_connect(int ssl, struct us_socket_context_t * nonnull_arg context,
|
||||
const char *host, int port, int options, int socket_ext_size, int *is_connecting) __attribute__((nonnull(2)));
|
||||
|
||||
struct us_socket_t *us_socket_context_connect_unix(int ssl, struct us_socket_context_t *context,
|
||||
const char *server_path, size_t pathlen, int options, int socket_ext_size);
|
||||
struct us_socket_t *us_socket_context_connect_unix(int ssl, us_socket_context_r context,
|
||||
const char *server_path, size_t pathlen, int options, int socket_ext_size) __attribute__((nonnull(2)));
|
||||
|
||||
/* Is this socket established? Can be used to check if a connecting socket has fired the on_open event yet.
|
||||
* Can also be used to determine if a socket is a listen_socket or not, but you probably know that already. */
|
||||
int us_socket_is_established(int ssl, struct us_socket_t *s);
|
||||
int us_socket_is_established(int ssl, us_socket_r s) nonnull_fn_decl;
|
||||
|
||||
void us_connecting_socket_free(struct us_connecting_socket_t *c);
|
||||
void us_connecting_socket_free(struct us_connecting_socket_t *c) nonnull_fn_decl;
|
||||
|
||||
/* Cancel a connecting socket. Can be used together with us_socket_timeout to limit connection times.
|
||||
* Entirely destroys the socket - this function works like us_socket_close but does not trigger on_close event since
|
||||
* you never got the on_open event first. */
|
||||
void us_connecting_socket_close(int ssl, struct us_connecting_socket_t *c);
|
||||
void us_connecting_socket_close(int ssl, struct us_connecting_socket_t *c) nonnull_fn_decl;
|
||||
|
||||
/* Returns the loop for this socket context. */
|
||||
struct us_loop_t *us_socket_context_loop(int ssl, struct us_socket_context_t *context);
|
||||
struct us_loop_t *us_socket_context_loop(int ssl, us_socket_context_r context) nonnull_fn_decl __attribute((returns_nonnull));
|
||||
|
||||
/* Invalidates passed socket, returning a new resized socket which belongs to a different socket context.
|
||||
* Used mainly for "socket upgrades" such as when transitioning from HTTP to WebSocket. */
|
||||
struct us_socket_t *us_socket_context_adopt_socket(int ssl, struct us_socket_context_t *context, struct us_socket_t *s, int ext_size);
|
||||
struct us_socket_t *us_socket_context_adopt_socket(int ssl, us_socket_context_r context, us_socket_r s, int ext_size);
|
||||
|
||||
/* Create a child socket context which acts much like its own socket context with its own callbacks yet still relies on the
|
||||
* parent socket context for some shared resources. Child socket contexts should be used together with socket adoptions and nothing else. */
|
||||
struct us_socket_context_t *us_create_child_socket_context(int ssl, struct us_socket_context_t *context, int context_ext_size);
|
||||
struct us_socket_context_t *us_create_child_socket_context(int ssl, us_socket_context_r context, int context_ext_size);
|
||||
|
||||
/* Public interfaces for loops */
|
||||
|
||||
/* Returns a new event loop with user data extension */
|
||||
struct us_loop_t *us_create_loop(void *hint, void (*wakeup_cb)(struct us_loop_t *loop),
|
||||
void (*pre_cb)(struct us_loop_t *loop), void (*post_cb)(struct us_loop_t *loop), unsigned int ext_size);
|
||||
struct us_loop_t *us_create_loop(void *hint, void (*wakeup_cb)(us_loop_r loop),
|
||||
void (*pre_cb)(us_loop_r loop), void (*post_cb)(us_loop_r loop), unsigned int ext_size);
|
||||
|
||||
/* Frees the loop immediately */
|
||||
void us_loop_free(struct us_loop_t *loop);
|
||||
void us_loop_free(us_loop_r loop) nonnull_fn_decl;
|
||||
|
||||
/* Returns the loop user data extension */
|
||||
void *us_loop_ext(struct us_loop_t *loop);
|
||||
void *us_loop_ext(us_loop_r loop) nonnull_fn_decl;
|
||||
|
||||
/* Blocks the calling thread and drives the event loop until no more non-fallthrough polls are scheduled */
|
||||
void us_loop_run(struct us_loop_t *loop);
|
||||
void us_loop_run(us_loop_r loop) nonnull_fn_decl;
|
||||
|
||||
|
||||
/* Signals the loop from any thread to wake up and execute its wakeup handler from the loop's own running thread.
|
||||
* This is the only fully thread-safe function and serves as the basis for thread safety */
|
||||
void us_wakeup_loop(struct us_loop_t *loop);
|
||||
void us_wakeup_loop(us_loop_r loop) nonnull_fn_decl;
|
||||
|
||||
/* Hook up timers in existing loop */
|
||||
void us_loop_integrate(struct us_loop_t *loop);
|
||||
void us_loop_integrate(us_loop_r loop) nonnull_fn_decl;
|
||||
|
||||
/* Returns the loop iteration number */
|
||||
long long us_loop_iteration_number(struct us_loop_t *loop);
|
||||
long long us_loop_iteration_number(us_loop_r loop) nonnull_fn_decl;
|
||||
|
||||
/* Public interfaces for polls */
|
||||
|
||||
/* A fallthrough poll does not keep the loop running, it falls through */
|
||||
struct us_poll_t *us_create_poll(struct us_loop_t *loop, int fallthrough, unsigned int ext_size);
|
||||
struct us_poll_t *us_create_poll(us_loop_r loop, int fallthrough, unsigned int ext_size);
|
||||
|
||||
/* After stopping a poll you must manually free the memory */
|
||||
void us_poll_free(struct us_poll_t *p, struct us_loop_t *loop);
|
||||
void us_poll_free(us_poll_r p, struct us_loop_t *loop);
|
||||
|
||||
/* Associate this poll with a socket descriptor and poll type */
|
||||
void us_poll_init(struct us_poll_t *p, LIBUS_SOCKET_DESCRIPTOR fd, int poll_type);
|
||||
void us_poll_init(us_poll_r p, LIBUS_SOCKET_DESCRIPTOR fd, int poll_type);
|
||||
|
||||
/* Start, change and stop polling for events */
|
||||
void us_poll_start(struct us_poll_t *p, struct us_loop_t *loop, int events);
|
||||
void us_poll_change(struct us_poll_t *p, struct us_loop_t *loop, int events);
|
||||
void us_poll_stop(struct us_poll_t *p, struct us_loop_t *loop);
|
||||
void us_poll_start(us_poll_r p, us_loop_r loop, int events) nonnull_fn_decl;
|
||||
void us_poll_change(us_poll_r p, us_loop_r loop, int events) nonnull_fn_decl;
|
||||
void us_poll_stop(us_poll_r p, struct us_loop_t *loop) nonnull_fn_decl;
|
||||
|
||||
/* Return what events we are polling for */
|
||||
int us_poll_events(struct us_poll_t *p);
|
||||
int us_poll_events(us_poll_r p) nonnull_fn_decl;
|
||||
|
||||
/* Returns the user data extension of this poll */
|
||||
void *us_poll_ext(struct us_poll_t *p);
|
||||
void *us_poll_ext(us_poll_r p) nonnull_fn_decl;
|
||||
|
||||
/* Get associated socket descriptor from a poll */
|
||||
LIBUS_SOCKET_DESCRIPTOR us_poll_fd(struct us_poll_t *p);
|
||||
LIBUS_SOCKET_DESCRIPTOR us_poll_fd(us_poll_r p) nonnull_fn_decl;
|
||||
|
||||
/* Resize an active poll */
|
||||
struct us_poll_t *us_poll_resize(struct us_poll_t *p, struct us_loop_t *loop, unsigned int ext_size);
|
||||
struct us_poll_t *us_poll_resize(us_poll_r p, us_loop_r loop, unsigned int ext_size) nonnull_fn_decl;
|
||||
|
||||
/* Public interfaces for sockets */
|
||||
|
||||
/* Returns the underlying native handle for a socket, such as SSL or file descriptor.
|
||||
* In the case of file descriptor, the value of pointer is fd. */
|
||||
void *us_socket_get_native_handle(int ssl, struct us_socket_t *s);
|
||||
void *us_socket_get_native_handle(int ssl, us_socket_r s) nonnull_fn_decl;
|
||||
|
||||
/* Write up to length bytes of data. Returns actual bytes written.
|
||||
* Will call the on_writable callback of active socket context on failure to write everything off in one go.
|
||||
* Set hint msg_more if you have more immediate data to write. */
|
||||
int us_socket_write(int ssl, struct us_socket_t *s, const char *data, int length, int msg_more);
|
||||
int us_socket_write(int ssl, us_socket_r s, const char * nonnull_arg data, int length, int msg_more) nonnull_fn_decl;
|
||||
|
||||
/* Special path for non-SSL sockets. Used to send header and payload in one go. Works like us_socket_write. */
|
||||
int us_socket_write2(int ssl, struct us_socket_t *s, const char *header, int header_length, const char *payload, int payload_length);
|
||||
int us_socket_write2(int ssl, us_socket_r s, const char *header, int header_length, const char *payload, int payload_length) nonnull_fn_decl;
|
||||
|
||||
/* Set a low precision, high performance timer on a socket. A socket can only have one single active timer
|
||||
* at any given point in time. Will remove any such pre set timer */
|
||||
void us_socket_timeout(int ssl, struct us_socket_t *s, unsigned int seconds);
|
||||
void us_socket_timeout(int ssl, us_socket_r s, unsigned int seconds) nonnull_fn_decl;
|
||||
|
||||
/* Set a low precision, high performance timer on a socket. Suitable for per-minute precision. */
|
||||
void us_socket_long_timeout(int ssl, struct us_socket_t *s, unsigned int minutes);
|
||||
void us_socket_long_timeout(int ssl, us_socket_r s, unsigned int minutes) nonnull_fn_decl;
|
||||
|
||||
/* Return the user data extension of this socket */
|
||||
void *us_socket_ext(int ssl, struct us_socket_t *s);
|
||||
void *us_connecting_socket_ext(int ssl, struct us_connecting_socket_t *c);
|
||||
void *us_socket_ext(int ssl, us_socket_r s) nonnull_fn_decl;
|
||||
void *us_connecting_socket_ext(int ssl, struct us_connecting_socket_t *c) nonnull_fn_decl;
|
||||
|
||||
/* Return the socket context of this socket */
|
||||
struct us_socket_context_t *us_socket_context(int ssl, struct us_socket_t *s);
|
||||
struct us_socket_context_t *us_socket_context(int ssl, us_socket_r s) nonnull_fn_decl __attribute__((returns_nonnull));
|
||||
|
||||
/* Withdraw any msg_more status and flush any pending data */
|
||||
void us_socket_flush(int ssl, struct us_socket_t *s);
|
||||
void us_socket_flush(int ssl, us_socket_r s) nonnull_fn_decl;
|
||||
|
||||
/* Shuts down the connection by sending FIN and/or close_notify */
|
||||
void us_socket_shutdown(int ssl, struct us_socket_t *s);
|
||||
void us_socket_shutdown(int ssl, us_socket_r s) nonnull_fn_decl;
|
||||
|
||||
/* Shuts down the connection in terms of read, meaning next event loop
|
||||
* iteration will catch the socket being closed. Can be used to defer closing
|
||||
* to next event loop iteration. */
|
||||
void us_socket_shutdown_read(int ssl, struct us_socket_t *s);
|
||||
void us_socket_shutdown_read(int ssl, us_socket_r s) nonnull_fn_decl;
|
||||
|
||||
/* Returns whether the socket has been shut down or not */
|
||||
int us_socket_is_shut_down(int ssl, struct us_socket_t *s);
|
||||
int us_socket_is_shut_down(int ssl, us_socket_r s) nonnull_fn_decl;
|
||||
|
||||
/* Returns whether this socket has been closed. Only valid if memory has not yet been released. */
|
||||
int us_socket_is_closed(int ssl, struct us_socket_t *s);
|
||||
int us_socket_is_closed(int ssl, us_socket_r s) nonnull_fn_decl;
|
||||
|
||||
/* Immediately closes the socket */
|
||||
struct us_socket_t *us_socket_close(int ssl, struct us_socket_t *s, int code, void *reason);
|
||||
struct us_socket_t *us_socket_close(int ssl, us_socket_r s, int code, void *reason) __attribute__((nonnull(2)));
|
||||
|
||||
/* Returns local port or -1 on failure. */
|
||||
int us_socket_local_port(int ssl, struct us_socket_t *s);
|
||||
int us_socket_local_port(int ssl, us_socket_r s) nonnull_fn_decl;
|
||||
|
||||
/* Copy remote (IP) address of socket, or fail with zero length. */
|
||||
void us_socket_remote_address(int ssl, struct us_socket_t *s, char *buf, int *length);
|
||||
void us_socket_local_address(int ssl, struct us_socket_t *s, char *buf, int *length);
|
||||
void us_socket_remote_address(int ssl, us_socket_r s, char *nonnull_arg buf, int *nonnull_arg length) nonnull_fn_decl;
|
||||
void us_socket_local_address(int ssl, us_socket_r s, char *nonnull_arg buf, int *nonnull_arg length) nonnull_fn_decl;
|
||||
|
||||
/* Bun extras */
|
||||
struct us_socket_t *us_socket_pair(struct us_socket_context_t *ctx, int socket_ext_size, LIBUS_SOCKET_DESCRIPTOR* fds);
|
||||
struct us_socket_t *us_socket_from_fd(struct us_socket_context_t *ctx, int socket_ext_size, LIBUS_SOCKET_DESCRIPTOR fd);
|
||||
struct us_socket_t *us_socket_attach(int ssl, LIBUS_SOCKET_DESCRIPTOR client_fd, struct us_socket_context_t *ctx, int flags, int socket_ext_size);
|
||||
struct us_socket_t *us_socket_wrap_with_tls(int ssl, struct us_socket_t *s, struct us_bun_socket_context_options_t options, struct us_socket_events_t events, int socket_ext_size);
|
||||
int us_socket_raw_write(int ssl, struct us_socket_t *s, const char *data, int length, int msg_more);
|
||||
struct us_socket_t *us_socket_wrap_with_tls(int ssl, us_socket_r s, struct us_bun_socket_context_options_t options, struct us_socket_events_t events, int socket_ext_size);
|
||||
int us_socket_raw_write(int ssl, us_socket_r s, const char *data, int length, int msg_more);
|
||||
struct us_socket_t* us_socket_open(int ssl, struct us_socket_t * s, int is_client, char* ip, int ip_length);
|
||||
int us_raw_root_certs(struct us_cert_string_t**out);
|
||||
unsigned int us_get_remote_address_info(char *buf, struct us_socket_t *s, const char **dest, int *port, int *is_ipv6);
|
||||
int us_socket_get_error(int ssl, struct us_socket_t *s);
|
||||
unsigned int us_get_remote_address_info(char *buf, us_socket_r s, const char **dest, int *port, int *is_ipv6);
|
||||
int us_socket_get_error(int ssl, us_socket_r s);
|
||||
|
||||
void us_socket_ref(struct us_socket_t *s);
|
||||
void us_socket_unref(struct us_socket_t *s);
|
||||
void us_socket_ref(us_socket_r s);
|
||||
void us_socket_unref(us_socket_r s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1455,7 +1455,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
|
||||
fn drainMicrotasks(this: *const RequestContext) void {
|
||||
if (this.isAsync()) return;
|
||||
if(this.server) |server| server.vm.drainMicrotasks();
|
||||
if (this.server) |server| server.vm.drainMicrotasks();
|
||||
}
|
||||
|
||||
pub fn setAbortHandler(this: *RequestContext) void {
|
||||
@@ -1484,7 +1484,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
var class_name = value.getClassInfoName() orelse bun.String.empty;
|
||||
defer class_name.deref();
|
||||
|
||||
if(ctx.server) |server| {
|
||||
if (ctx.server) |server| {
|
||||
const globalThis: *JSC.JSGlobalObject = server.globalThis;
|
||||
|
||||
Output.enableBuffering();
|
||||
@@ -1516,7 +1516,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
return;
|
||||
}
|
||||
|
||||
if(ctx.server == null) {
|
||||
if (ctx.server == null) {
|
||||
ctx.renderMissingInvalidResponse(value);
|
||||
return;
|
||||
}
|
||||
@@ -1588,7 +1588,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
this.request_body = null;
|
||||
}
|
||||
|
||||
if(this.server) |server| {
|
||||
if (this.server) |server| {
|
||||
this.server = null;
|
||||
server.request_pool_allocator.put(this);
|
||||
server.onRequestComplete();
|
||||
@@ -1784,7 +1784,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
}
|
||||
this.detachResponse();
|
||||
this.endRequestStreamingAndDrain();
|
||||
this.deref();
|
||||
this.deref();
|
||||
}
|
||||
|
||||
/// Drain a partial response buffer
|
||||
@@ -1911,9 +1911,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
this.signal = null;
|
||||
defer signal.unref();
|
||||
if (!signal.aborted()) {
|
||||
const reason = JSC.WebCore.AbortSignal.createAbortError(JSC.ZigString.static("The user aborted a request"), &JSC.ZigString.Empty, globalThis);
|
||||
reason.ensureStillAlive();
|
||||
_ = signal.signal(reason);
|
||||
signal.signal(globalThis, .ConnectionClosed);
|
||||
any_js_calls = true;
|
||||
}
|
||||
}
|
||||
@@ -1928,7 +1926,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
if (this.isDeadRequest()) {
|
||||
this.finalizeWithoutDeinit();
|
||||
} else {
|
||||
if(this.endRequestStreaming()) {
|
||||
if (this.endRequestStreaming()) {
|
||||
any_js_calls = true;
|
||||
}
|
||||
|
||||
@@ -1973,13 +1971,10 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
this.signal = null;
|
||||
defer signal.unref();
|
||||
if (this.flags.aborted and !signal.aborted()) {
|
||||
const reason = JSC.WebCore.AbortSignal.createAbortError(JSC.ZigString.static("The user aborted a request"), &JSC.ZigString.Empty, globalThis);
|
||||
reason.ensureStillAlive();
|
||||
_ = signal.signal(reason);
|
||||
signal.signal(globalThis, .ConnectionClosed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Case 1:
|
||||
// User called .blob(), .json(), text(), or .arrayBuffer() on the Request object
|
||||
// but we received nothing or the connection was aborted
|
||||
@@ -1989,7 +1984,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
// Case 3:
|
||||
// Stream was not consumed and the connection was aborted or ended
|
||||
_ = this.endRequestStreaming();
|
||||
|
||||
|
||||
if (this.byte_stream) |stream| {
|
||||
ctxLog("finalizeWithoutDeinit: stream != null", .{});
|
||||
|
||||
@@ -2306,9 +2301,9 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
if (comptime can_sendfile) {
|
||||
return this.renderSendFile(blob);
|
||||
}
|
||||
if(this.server) |server| {
|
||||
this.ref();
|
||||
this.blob.Blob.doReadFileInternal(*RequestContext, this, onReadFile, server.globalThis);
|
||||
if (this.server) |server| {
|
||||
this.ref();
|
||||
this.blob.Blob.doReadFileInternal(*RequestContext, this, onReadFile, server.globalThis);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2320,7 +2315,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
}
|
||||
|
||||
if (result == .err) {
|
||||
if(this.server) |server| {
|
||||
if (this.server) |server| {
|
||||
this.runErrorHandler(result.err.toErrorInstance(server.globalThis));
|
||||
}
|
||||
return;
|
||||
@@ -2475,7 +2470,6 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
streamLog("returned a promise", .{});
|
||||
this.drainMicrotasks();
|
||||
|
||||
|
||||
switch (promise.status(globalThis.vm())) {
|
||||
.Pending => {
|
||||
streamLog("promise still Pending", .{});
|
||||
@@ -2577,7 +2571,6 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
request_object.request_context.setRequest(req);
|
||||
assert(ctx.server != null);
|
||||
|
||||
|
||||
request_object.ensureURL() catch {
|
||||
request_object.url = bun.String.empty;
|
||||
};
|
||||
@@ -2608,15 +2601,15 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
fn endRequestStreamingAndDrain(this: *RequestContext) void {
|
||||
assert(this.server != null);
|
||||
|
||||
if(this.endRequestStreaming()) {
|
||||
if (this.endRequestStreaming()) {
|
||||
this.server.?.vm.drainMicrotasks();
|
||||
}
|
||||
}
|
||||
fn endRequestStreaming(this: *RequestContext) bool {
|
||||
assert(this.server != null);
|
||||
// if we cannot, we have to reject pending promises
|
||||
// first, we reject the request body promise
|
||||
if (this.request_body) |body| {
|
||||
// if we cannot, we have to reject pending promises
|
||||
// first, we reject the request body promise
|
||||
if (this.request_body) |body| {
|
||||
// User called .blob(), .json(), text(), or .arrayBuffer() on the Request object
|
||||
// but we received nothing or the connection was aborted
|
||||
if (body.value == .Locked) {
|
||||
@@ -2629,7 +2622,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
fn detachResponse(this: *RequestContext) void {
|
||||
if (this.resp) |resp| {
|
||||
this.resp = null;
|
||||
|
||||
|
||||
if (this.flags.is_waiting_for_request_body) {
|
||||
this.flags.is_waiting_for_request_body = false;
|
||||
resp.clearOnData();
|
||||
@@ -2807,8 +2800,8 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
resp.body.value = .{ .Used = {} };
|
||||
}
|
||||
}
|
||||
|
||||
if(req.isAbortedOrEnded()) {
|
||||
|
||||
if (req.isAbortedOrEnded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2883,7 +2876,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
|
||||
req.endStream(true);
|
||||
if (comptime debug_mode) {
|
||||
if(req.server) |server| {
|
||||
if (req.server) |server| {
|
||||
if (!err.isEmptyOrUndefinedOrNull()) {
|
||||
var exception_list: std.ArrayList(Api.JsException) = std.ArrayList(Api.JsException).init(req.allocator);
|
||||
defer exception_list.deinit();
|
||||
@@ -3148,7 +3141,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
}
|
||||
|
||||
fn finishRunningErrorHandler(this: *RequestContext, value: JSC.JSValue, status: u16) void {
|
||||
if(this.server == null) return this.renderProductionError(status);
|
||||
if (this.server == null) return this.renderProductionError(status);
|
||||
var vm: *JSC.VirtualMachine = this.server.?.vm;
|
||||
const globalThis = this.server.?.globalThis;
|
||||
if (comptime debug_mode) {
|
||||
@@ -3182,7 +3175,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
status: u16,
|
||||
) void {
|
||||
JSC.markBinding(@src());
|
||||
if(this.server) |server| {
|
||||
if (this.server) |server| {
|
||||
if (!server.config.onError.isEmpty() and !this.flags.has_called_error_handler) {
|
||||
this.flags.has_called_error_handler = true;
|
||||
const result = server.config.onError.call(
|
||||
@@ -3565,7 +3558,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
|
||||
}
|
||||
const max_request_body_preallocate_length = 1024 * 256;
|
||||
pub fn onStartBuffering(this: *RequestContext) void {
|
||||
if(this.server) |server| {
|
||||
if (this.server) |server| {
|
||||
ctxLog("onStartBuffering", .{});
|
||||
// TODO: check if is someone calling onStartBuffering other than onStartBufferingCallback
|
||||
// if is not, this should be removed and only keep protect + setAbortHandler
|
||||
@@ -5511,7 +5504,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
|
||||
// obviously invalid pointer marks it as used
|
||||
upgrader.upgrade_context = @as(*uws.uws_socket_context_s, @ptrFromInt(std.math.maxInt(usize)));
|
||||
// set the abort handler so we can receive onAbort to deref the context
|
||||
upgrader.setAbortHandler();
|
||||
upgrader.setAbortHandler();
|
||||
// after upgrading we should not use the response anymore
|
||||
upgrader.resp = null;
|
||||
request.upgrader = null;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
#include "ExceptionCode.h"
|
||||
#include "JSDOMException.h"
|
||||
#include "JavaScriptCore/Error.h"
|
||||
#include "JavaScriptCore/ErrorType.h"
|
||||
#include "JavaScriptCore/ObjectConstructor.h"
|
||||
#include "JavaScriptCore/WriteBarrier.h"
|
||||
#include "root.h"
|
||||
#include "headers-handwritten.h"
|
||||
#include "BunClientData.h"
|
||||
@@ -12,6 +18,42 @@
|
||||
#include "wtf/text/MakeString.h"
|
||||
#include "wtf/text/WTFString.h"
|
||||
#include <cstdio>
|
||||
#include "AbortSignal.h"
|
||||
|
||||
#include "NodeError.h"
|
||||
#include "JavaScriptCore/ErrorInstanceInlines.h"
|
||||
#include "JSDOMException.h"
|
||||
static JSC::JSObject* createErrorPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::ErrorType type, WTF::ASCIILiteral name, WTF::ASCIILiteral code)
|
||||
{
|
||||
JSC::JSObject* prototype;
|
||||
|
||||
switch (type) {
|
||||
case JSC::ErrorType::TypeError:
|
||||
prototype = JSC::constructEmptyObject(globalObject, globalObject->m_typeErrorStructure.prototype(globalObject));
|
||||
break;
|
||||
case JSC::ErrorType::RangeError:
|
||||
prototype = JSC::constructEmptyObject(globalObject, globalObject->m_rangeErrorStructure.prototype(globalObject));
|
||||
break;
|
||||
case JSC::ErrorType::Error:
|
||||
prototype = JSC::constructEmptyObject(globalObject, globalObject->errorPrototype());
|
||||
break;
|
||||
default: {
|
||||
RELEASE_ASSERT_NOT_REACHED_WITH_MESSAGE("TODO: Add support for more error types");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
prototype->putDirect(vm, vm.propertyNames->name, jsString(vm, String(name)), 0);
|
||||
prototype->putDirect(vm, WebCore::builtinNames(vm).codePublicName(), jsString(vm, String(code)), 0);
|
||||
|
||||
return prototype;
|
||||
}
|
||||
|
||||
static JSC::Structure* createErrorStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::ErrorType type, WTF::ASCIILiteral name, WTF::ASCIILiteral code)
|
||||
{
|
||||
JSC::JSObject* prototype = createErrorPrototype(vm, globalObject, type, name, code);
|
||||
return JSC::ErrorInstance::createStructure(vm, globalObject, prototype);
|
||||
}
|
||||
|
||||
JSC::EncodedJSValue JSC__JSValue__createTypeError(const ZigString* message, const ZigString* arg1, JSC::JSGlobalObject* globalObject);
|
||||
JSC::EncodedJSValue JSC__JSValue__createRangeError(const ZigString* message, const ZigString* arg1, JSC::JSGlobalObject* globalObject);
|
||||
@@ -20,10 +62,118 @@ extern "C" JSC::EncodedJSValue Bun__ERR_INVALID_ARG_TYPE(JSC::JSGlobalObject* gl
|
||||
extern "C" JSC::EncodedJSValue Bun__ERR_MISSING_ARGS(JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue arg1, JSC::EncodedJSValue arg2, JSC::EncodedJSValue arg3);
|
||||
extern "C" JSC::EncodedJSValue Bun__ERR_IPC_CHANNEL_CLOSED(JSC::JSGlobalObject* globalObject);
|
||||
|
||||
// clang-format on
|
||||
|
||||
namespace Bun {
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
struct NodeErrorData {
|
||||
JSC::ErrorType type;
|
||||
WTF::ASCIILiteral name;
|
||||
WTF::ASCIILiteral code;
|
||||
};
|
||||
static constexpr NodeErrorData errors[NODE_ERROR_COUNT] = {
|
||||
#define DECLARE_ERROR_WITH_CODE_ENUM(E, name, code) { JSC::ErrorType::E, #name ""_s, #code ""_s },
|
||||
FOR_EACH_NODE_ERROR_WITH_CODE(DECLARE_ERROR_WITH_CODE_ENUM)
|
||||
#undef DECLARE_ERROR_WITH_CODE_ENUM
|
||||
};
|
||||
|
||||
const ClassInfo NodeErrorCache::s_info = { "NodeErrorCache"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(NodeErrorCache) };
|
||||
|
||||
NodeErrorCache::NodeErrorCache(VM& vm, Structure* structure)
|
||||
: Base(vm, structure)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
void NodeErrorCache::visitChildrenImpl(JSCell* cell, Visitor& visitor)
|
||||
{
|
||||
auto* thisObject = jsCast<NodeErrorCache*>(cell);
|
||||
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
|
||||
Base::visitChildren(thisObject, visitor);
|
||||
}
|
||||
|
||||
DEFINE_VISIT_CHILDREN_WITH_MODIFIER(JS_EXPORT_PRIVATE, NodeErrorCache);
|
||||
|
||||
Structure* NodeErrorCache::createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
|
||||
{
|
||||
return Structure::create(vm, globalObject, jsNull(), TypeInfo(InternalFieldTupleType, StructureFlags), info(), 0, 0);
|
||||
}
|
||||
|
||||
NodeErrorCache* NodeErrorCache::create(VM& vm, Structure* structure)
|
||||
{
|
||||
NodeErrorCache* object = new (NotNull, allocateCell<NodeErrorCache>(vm)) NodeErrorCache(vm, structure);
|
||||
object->finishCreation(vm);
|
||||
return object;
|
||||
}
|
||||
|
||||
void NodeErrorCache::finishCreation(VM& vm)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
ASSERT(inherits(info()));
|
||||
|
||||
for (unsigned i = 0; i < NODE_ERROR_COUNT; i++) {
|
||||
this->internalField(i).clear();
|
||||
}
|
||||
}
|
||||
|
||||
static NodeErrorCache* errorCache(Zig::GlobalObject* globalObject)
|
||||
{
|
||||
return static_cast<NodeErrorCache*>(globalObject->nodeErrorCache());
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
static Structure* createErrorStructure(JSC::VM& vm, JSGlobalObject* globalObject, JSC::ErrorType type, WTF::ASCIILiteral name, WTF::ASCIILiteral code)
|
||||
{
|
||||
auto* prototype = createErrorPrototype(vm, globalObject, type, name, code);
|
||||
return ErrorInstance::createStructure(vm, globalObject, prototype);
|
||||
}
|
||||
|
||||
JSObject* NodeErrorCache::createError(VM& vm, Zig::GlobalObject* globalObject, NodeErrorCode code, JSValue message, JSValue options)
|
||||
{
|
||||
auto* cache = errorCache(globalObject);
|
||||
if (!cache->internalField(static_cast<unsigned>(code))) {
|
||||
const auto& data = errors[code];
|
||||
auto* structure = createErrorStructure(vm, globalObject, data.type, data.name, data.code);
|
||||
cache->internalField(static_cast<unsigned>(code)).set(vm, cache, structure);
|
||||
}
|
||||
|
||||
auto* structure = jsCast<Structure*>(cache->internalField(static_cast<unsigned>(code)).get());
|
||||
return JSC::ErrorInstance::create(globalObject, structure, message, options, nullptr, JSC::RuntimeType::TypeNothing, errors[code].type, true);
|
||||
}
|
||||
|
||||
JSObject* createError(VM& vm, Zig::GlobalObject* globalObject, NodeErrorCode code, const String& message)
|
||||
{
|
||||
return errorCache(globalObject)->createError(vm, globalObject, code, jsString(vm, message), jsUndefined());
|
||||
}
|
||||
|
||||
JSObject* createError(VM& vm, JSC::JSGlobalObject* globalObject, NodeErrorCode code, JSValue message)
|
||||
{
|
||||
if (auto* zigGlobalObject = jsDynamicCast<Zig::GlobalObject*>(globalObject))
|
||||
return createError(vm, zigGlobalObject, code, message, jsUndefined());
|
||||
|
||||
auto* structure = createErrorStructure(vm, globalObject, errors[code].type, errors[code].name, errors[code].code);
|
||||
return JSC::ErrorInstance::create(globalObject, structure, message, jsUndefined(), nullptr, JSC::RuntimeType::TypeNothing, errors[code].type, true);
|
||||
}
|
||||
|
||||
JSC::JSObject* createError(VM& vm, Zig::GlobalObject* globalObject, NodeErrorCode code, JSValue message, JSValue options)
|
||||
{
|
||||
return errorCache(globalObject)->createError(vm, globalObject, code, message, options);
|
||||
}
|
||||
|
||||
JSObject* createError(JSC::JSGlobalObject* globalObject, NodeErrorCode code, const String& message)
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
return createError(vm, globalObject, code, jsString(vm, message));
|
||||
}
|
||||
|
||||
JSObject* createError(Zig::JSGlobalObject* globalObject, NodeErrorCode code, JSC::JSValue message)
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
return createError(vm, globalObject, code, message);
|
||||
}
|
||||
|
||||
WTF::String JSValueToStringSafe(JSC::JSGlobalObject* globalObject, JSValue arg)
|
||||
{
|
||||
ASSERT(!arg.isEmpty());
|
||||
@@ -45,48 +195,6 @@ WTF::String JSValueToStringSafe(JSC::JSGlobalObject* globalObject, JSValue arg)
|
||||
return arg.toString(globalObject)->getString(globalObject);
|
||||
}
|
||||
|
||||
JSC::JSValue createErrorWithCode(JSC::JSGlobalObject* globalObject, String message, ASCIILiteral code)
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
JSC::JSObject* result = JSC::createError(globalObject, message);
|
||||
JSC::EnsureStillAliveScope ensureAlive(result);
|
||||
auto typeError = JSC::JSValue(result).asCell()->getObject();
|
||||
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
typeError->putDirect(vm, clientData->builtinNames().codePublicName(), jsString(vm, String(code)), 0);
|
||||
|
||||
return typeError;
|
||||
}
|
||||
|
||||
JSC::JSValue createTypeErrorWithCode(JSC::JSGlobalObject* globalObject, String message, ASCIILiteral code)
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
JSC::JSObject* result = JSC::createTypeError(globalObject, message);
|
||||
JSC::EnsureStillAliveScope ensureAlive(result);
|
||||
auto typeError = JSC::JSValue(result).asCell()->getObject();
|
||||
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
typeError->putDirect(vm, clientData->builtinNames().codePublicName(), jsString(vm, String(code)), 0);
|
||||
|
||||
return typeError;
|
||||
}
|
||||
|
||||
JSC::JSValue createRangeErrorWithCode(JSC::JSGlobalObject* globalObject, String message, ASCIILiteral code)
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
JSC::JSObject* result = JSC::createRangeError(globalObject, message);
|
||||
JSC::EnsureStillAliveScope ensureAlive(result);
|
||||
auto typeError = JSC::JSValue(result).asCell()->getObject();
|
||||
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
typeError->putDirect(vm, clientData->builtinNames().codePublicName(), jsString(vm, String(code)), 0);
|
||||
|
||||
return typeError;
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_INVALID_ARG_TYPE, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
@@ -117,7 +225,7 @@ extern "C" JSC::EncodedJSValue Bun__ERR_INVALID_ARG_TYPE(JSC::JSGlobalObject* gl
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
auto message = makeString("The \""_s, arg_name, "\" argument must be of type "_s, expected_type, ". Received "_s, actual_value);
|
||||
return JSC::JSValue::encode(createTypeErrorWithCode(globalObject, message, "ERR_INVALID_ARG_TYPE"_s));
|
||||
return JSValue::encode(createError(globalObject, NodeErrorCode::ERR_INVALID_ARG_TYPE, message));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_OUT_OF_RANGE, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
@@ -141,17 +249,17 @@ JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_OUT_OF_RANGE, (JSC::JSGlobalObject * glo
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
auto message = makeString("The value of \""_s, arg_name, "\" is out of range. It must be "_s, range, ". Received "_s, input);
|
||||
return JSC::JSValue::encode(createRangeErrorWithCode(globalObject, message, "ERR_OUT_OF_RANGE"_s));
|
||||
return JSC::JSValue::encode(createError(globalObject, NodeErrorCode::ERR_OUT_OF_RANGE, message));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_IPC_DISCONNECTED, (JSC::JSGlobalObject * globalObject, JSC::CallFrame*))
|
||||
{
|
||||
return JSC::JSValue::encode(createErrorWithCode(globalObject, "IPC channel is already disconnected"_s, "ERR_IPC_DISCONNECTED"_s));
|
||||
return JSC::JSValue::encode(createError(globalObject, NodeErrorCode::ERR_IPC_DISCONNECTED, "IPC channel is already disconnected"_s));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_SERVER_NOT_RUNNING, (JSC::JSGlobalObject * globalObject, JSC::CallFrame*))
|
||||
{
|
||||
return JSC::JSValue::encode(createErrorWithCode(globalObject, "Server is not running."_s, "ERR_SERVER_NOT_RUNNING"_s));
|
||||
return JSC::JSValue::encode(createError(globalObject, NodeErrorCode::ERR_SERVER_NOT_RUNNING, "Server is not running."_s));
|
||||
}
|
||||
|
||||
extern "C" JSC::EncodedJSValue Bun__ERR_MISSING_ARGS(JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue arg1, JSC::EncodedJSValue arg2, JSC::EncodedJSValue arg3)
|
||||
@@ -170,7 +278,7 @@ extern "C" JSC::EncodedJSValue Bun__ERR_MISSING_ARGS(JSC::JSGlobalObject* global
|
||||
if (arg2 == 0) {
|
||||
// 1 arg name passed
|
||||
auto message = makeString("The \""_s, name1, "\" argument must be specified"_s);
|
||||
return JSC::JSValue::encode(createTypeErrorWithCode(globalObject, message, "ERR_MISSING_ARGS"_s));
|
||||
return JSC::JSValue::encode(createError(globalObject, NodeErrorCode::ERR_MISSING_ARGS, message));
|
||||
}
|
||||
|
||||
auto name2 = JSValue::decode(arg2).toWTFString(globalObject);
|
||||
@@ -179,7 +287,7 @@ extern "C" JSC::EncodedJSValue Bun__ERR_MISSING_ARGS(JSC::JSGlobalObject* global
|
||||
if (arg3 == 0) {
|
||||
// 2 arg names passed
|
||||
auto message = makeString("The \""_s, name1, "\" and \""_s, name2, "\" arguments must be specified"_s);
|
||||
return JSC::JSValue::encode(createTypeErrorWithCode(globalObject, message, "ERR_MISSING_ARGS"_s));
|
||||
return JSC::JSValue::encode(createError(globalObject, NodeErrorCode::ERR_MISSING_ARGS, message));
|
||||
}
|
||||
|
||||
auto name3 = JSValue::decode(arg3).toWTFString(globalObject);
|
||||
@@ -187,7 +295,7 @@ extern "C" JSC::EncodedJSValue Bun__ERR_MISSING_ARGS(JSC::JSGlobalObject* global
|
||||
|
||||
// 3 arg names passed
|
||||
auto message = makeString("The \""_s, name1, "\", \""_s, name2, "\", and \""_s, name3, "\" arguments must be specified"_s);
|
||||
return JSC::JSValue::encode(createTypeErrorWithCode(globalObject, message, "ERR_MISSING_ARGS"_s));
|
||||
return JSC::JSValue::encode(createError(globalObject, NodeErrorCode::ERR_MISSING_ARGS, message));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_IPC_CHANNEL_CLOSED, (JSC::JSGlobalObject * globalObject, JSC::CallFrame*))
|
||||
@@ -196,12 +304,37 @@ JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_IPC_CHANNEL_CLOSED, (JSC::JSGlobalObject
|
||||
}
|
||||
extern "C" JSC::EncodedJSValue Bun__ERR_IPC_CHANNEL_CLOSED(JSC::JSGlobalObject* globalObject)
|
||||
{
|
||||
return JSC::JSValue::encode(createErrorWithCode(globalObject, "Channel closed."_s, "ERR_IPC_CHANNEL_CLOSED"_s));
|
||||
return JSC::JSValue::encode(createError(globalObject, NodeErrorCode::ERR_IPC_CHANNEL_CLOSED, "Channel closed."_s));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_SOCKET_BAD_TYPE, (JSC::JSGlobalObject * globalObject, JSC::CallFrame*))
|
||||
{
|
||||
return JSC::JSValue::encode(createTypeErrorWithCode(globalObject, "Bad socket type specified. Valid types are: udp4, udp6"_s, "ERR_SOCKET_BAD_TYPE"_s));
|
||||
return JSC::JSValue::encode(createError(globalObject, NodeErrorCode::ERR_SOCKET_BAD_TYPE, "Bad socket type specified. Valid types are: udp4, udp6"_s));
|
||||
}
|
||||
|
||||
} // namespace Bun
|
||||
|
||||
JSC::JSValue WebCore::toJS(JSC::JSGlobalObject* globalObject, CommonAbortReason abortReason)
|
||||
{
|
||||
switch (abortReason) {
|
||||
case CommonAbortReason::Timeout: {
|
||||
return createError(globalObject, Bun::NodeErrorCode::ABORT_ERR, "The operation timed out"_s);
|
||||
}
|
||||
case CommonAbortReason::UserAbort: {
|
||||
return createError(globalObject, Bun::NodeErrorCode::ABORT_ERR, "The operation was aborted by the user"_s);
|
||||
}
|
||||
case CommonAbortReason::ConnectionClosed: {
|
||||
return createError(globalObject, Bun::NodeErrorCode::ABORT_ERR, "The connection was closed"_s);
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RELEASE_ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
extern "C" JSC::EncodedJSValue WebCore__CommonAbortReason__toJS(JSC::JSGlobalObject* globalObject, WebCore::CommonAbortReason abortReason)
|
||||
{
|
||||
return JSC::JSValue::encode(WebCore::toJS(globalObject, abortReason));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include "ZigGlobalObject.h"
|
||||
#include "root.h"
|
||||
#include <JavaScriptCore/JSInternalFieldObjectImpl.h>
|
||||
#include <JavaScriptCore/JSInternalFieldObjectImplInlines.h>
|
||||
#include "BunClientData.h"
|
||||
|
||||
namespace Bun {
|
||||
|
||||
// clang-format off
|
||||
#define FOR_EACH_NODE_ERROR_WITH_CODE(macro) \
|
||||
macro(TypeError, TypeError, ERR_INVALID_ARG_TYPE) \
|
||||
macro(RangeError, RangeError, ERR_OUT_OF_RANGE) \
|
||||
macro(Error, Error, ERR_IPC_DISCONNECTED) \
|
||||
macro(Error, Error, ERR_SERVER_NOT_RUNNING) \
|
||||
macro(TypeError, TypeError, ERR_MISSING_ARGS) \
|
||||
macro(Error, Error, ERR_IPC_CHANNEL_CLOSED) \
|
||||
macro(TypeError, TypeError, ERR_SOCKET_BAD_TYPE) \
|
||||
macro(Error, AbortError, ABORT_ERR)
|
||||
|
||||
|
||||
#define COUNT_ERROR_WITH_CODE_ENUM(E, name, code) +1
|
||||
static constexpr size_t NODE_ERROR_COUNT = 0 FOR_EACH_NODE_ERROR_WITH_CODE(COUNT_ERROR_WITH_CODE_ENUM);
|
||||
#undef COUNT_ERROR_WITH_CODE_ENUM
|
||||
using namespace JSC;
|
||||
// clang-format on
|
||||
|
||||
enum NodeErrorCode : uint8_t {
|
||||
#define DECLARE_ERROR_WITH_CODE_ENUM(E, name, code) code,
|
||||
FOR_EACH_NODE_ERROR_WITH_CODE(DECLARE_ERROR_WITH_CODE_ENUM)
|
||||
#undef DECLARE_ERROR_WITH_CODE_ENUM
|
||||
};
|
||||
|
||||
class NodeErrorCache : public JSC::JSInternalFieldObjectImpl<NODE_ERROR_COUNT> {
|
||||
public:
|
||||
using Base = JSInternalFieldObjectImpl<NODE_ERROR_COUNT>;
|
||||
using Field = NodeErrorCode;
|
||||
|
||||
DECLARE_EXPORT_INFO;
|
||||
|
||||
static size_t allocationSize(Checked<size_t> inlineCapacity)
|
||||
{
|
||||
ASSERT_UNUSED(inlineCapacity, inlineCapacity == 0U);
|
||||
return sizeof(NodeErrorCache);
|
||||
}
|
||||
|
||||
template<typename, SubspaceAccess mode>
|
||||
static GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
|
||||
{
|
||||
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
|
||||
return nullptr;
|
||||
return WebCore::subspaceForImpl<NodeErrorCache, WebCore::UseCustomHeapCellType::No>(
|
||||
vm,
|
||||
[](auto& spaces) { return spaces.m_clientSubspaceForNodeErrors.get(); },
|
||||
[](auto& spaces, auto&& space) { spaces.m_clientSubspaceForNodeErrors = std::forward<decltype(space)>(space); },
|
||||
[](auto& spaces) { return spaces.m_subspaceForNodeErrors.get(); },
|
||||
[](auto& spaces, auto&& space) { spaces.m_subspaceForNodeErrors = std::forward<decltype(space)>(space); });
|
||||
}
|
||||
|
||||
static NodeErrorCache* create(VM& vm, Structure* structure);
|
||||
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject);
|
||||
|
||||
JSObject* createError(VM& vm, Zig::GlobalObject* globalObject, NodeErrorCode code, JSValue message, JSValue options);
|
||||
|
||||
private:
|
||||
JS_EXPORT_PRIVATE NodeErrorCache(VM&, Structure*);
|
||||
DECLARE_VISIT_CHILDREN_WITH_MODIFIER(JS_EXPORT_PRIVATE);
|
||||
void finishCreation(VM&);
|
||||
};
|
||||
|
||||
JSC::JSObject* createError(Zig::GlobalObject* globalObject, NodeErrorCode code, const WTF::String& message);
|
||||
JSC::JSObject* createError(JSC::JSGlobalObject* globalObject, NodeErrorCode code, const WTF::String& message);
|
||||
JSC::JSObject* createError(Zig::GlobalObject* globalObject, NodeErrorCode code, JSC::JSValue message);
|
||||
JSC::JSObject* createError(VM& vm, Zig::GlobalObject* globalObject, NodeErrorCode code, JSValue message, JSValue options = jsUndefined());
|
||||
JSC::JSValue toJS(JSC::JSGlobalObject*, NodeErrorCode);
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_INVALID_ARG_TYPE, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame));
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_OUT_OF_RANGE, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame));
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_IPC_DISCONNECTED, (JSC::JSGlobalObject * globalObject, JSC::CallFrame*));
|
||||
|
||||
@@ -146,6 +146,7 @@
|
||||
#include "UtilInspect.h"
|
||||
#include "Base64Helpers.h"
|
||||
#include "wtf/text/OrdinalNumber.h"
|
||||
#include "NodeError.h"
|
||||
|
||||
#if ENABLE(REMOTE_INSPECTOR)
|
||||
#include "JavaScriptCore/RemoteInspectorServer.h"
|
||||
@@ -2695,6 +2696,15 @@ void GlobalObject::finishCreation(VM& vm)
|
||||
init.set(Bun::createUtilInspectOptionsStructure(init.vm, init.owner));
|
||||
});
|
||||
|
||||
m_nodeErrorCache.initLater(
|
||||
[](const Initializer<JSObject>& init) {
|
||||
auto* structure = NodeErrorCache::createStructure(
|
||||
init.vm,
|
||||
init.owner);
|
||||
|
||||
init.set(NodeErrorCache::create(init.vm, structure));
|
||||
});
|
||||
|
||||
m_utilInspectStylizeColorFunction.initLater(
|
||||
[](const Initializer<JSFunction>& init) {
|
||||
JSC::MarkedArgumentBuffer args;
|
||||
@@ -3553,6 +3563,8 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
|
||||
thisObject->mockModule.mockWithImplementationCleanupDataStructure.visit(visitor);
|
||||
thisObject->mockModule.withImplementationCleanupFunction.visit(visitor);
|
||||
|
||||
thisObject->m_nodeErrorCache.visit(visitor);
|
||||
|
||||
for (auto& barrier : thisObject->m_thenables) {
|
||||
visitor.append(barrier);
|
||||
}
|
||||
|
||||
@@ -402,6 +402,9 @@ public:
|
||||
//
|
||||
LazyProperty<JSGlobalObject, JSC::JSFunction> m_errorConstructorPrepareStackTraceInternalValue;
|
||||
|
||||
LazyProperty<JSGlobalObject, JSObject> m_nodeErrorCache;
|
||||
JSObject* nodeErrorCache() const { return m_nodeErrorCache.getInitializedOnMainThread(this); }
|
||||
|
||||
Structure* memoryFootprintStructure()
|
||||
{
|
||||
return m_memoryFootprintStructure.getInitializedOnMainThread(this);
|
||||
|
||||
@@ -5547,49 +5547,6 @@ extern "C" WebCore__AbortSignal* WebCore__AbortSignal__fromJS(JSC__JSValue value
|
||||
|
||||
return reinterpret_cast<WebCore__AbortSignal*>(&object->wrapped());
|
||||
}
|
||||
static auto ABORT_ERROR_NAME = MAKE_STATIC_STRING_IMPL("AbortError");
|
||||
extern "C" JSC__JSValue WebCore__AbortSignal__createAbortError(const ZigString* message, const ZigString* arg1,
|
||||
JSC__JSGlobalObject* globalObject)
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
ZigString code = *arg1;
|
||||
JSC::JSObject* error = Zig::getErrorInstance(message, globalObject).asCell()->getObject();
|
||||
|
||||
error->putDirect(
|
||||
vm, vm.propertyNames->name,
|
||||
JSC::JSValue(JSC::jsOwnedString(vm, ABORT_ERROR_NAME)),
|
||||
0);
|
||||
|
||||
if (code.len > 0) {
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
JSC::JSValue codeValue = Zig::toJSStringValue(code, globalObject);
|
||||
error->putDirect(vm, clientData->builtinNames().codePublicName(), codeValue, 0);
|
||||
}
|
||||
|
||||
return JSC::JSValue::encode(error);
|
||||
}
|
||||
|
||||
static auto TIMEOUT_ERROR_NAME = MAKE_STATIC_STRING_IMPL("TimeoutError");
|
||||
extern "C" JSC__JSValue WebCore__AbortSignal__createTimeoutError(const ZigString* message, const ZigString* arg1,
|
||||
JSC__JSGlobalObject* globalObject)
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
ZigString code = *arg1;
|
||||
JSC::JSObject* error = Zig::getErrorInstance(message, globalObject).asCell()->getObject();
|
||||
|
||||
error->putDirect(
|
||||
vm, vm.propertyNames->name,
|
||||
JSC::JSValue(JSC::jsOwnedString(vm, TIMEOUT_ERROR_NAME)),
|
||||
0);
|
||||
|
||||
if (code.len > 0) {
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
JSC::JSValue codeValue = Zig::toJSStringValue(code, globalObject);
|
||||
error->putDirect(vm, clientData->builtinNames().codePublicName(), codeValue, 0);
|
||||
}
|
||||
|
||||
return JSC::JSValue::encode(error);
|
||||
}
|
||||
|
||||
CPP_DECL double JSC__JSValue__getUnixTimestamp(JSC__JSValue timeValue)
|
||||
{
|
||||
|
||||
@@ -2003,6 +2003,18 @@ pub fn PromiseCallback(comptime Type: type, comptime CallbackFunction: fn (*Type
|
||||
}.callback;
|
||||
}
|
||||
|
||||
pub const CommonAbortReason = enum(u8) {
|
||||
Timeout = 1,
|
||||
UserAbort = 2,
|
||||
ConnectionClosed = 3,
|
||||
|
||||
pub fn toJS(this: CommonAbortReason, global: *JSGlobalObject) JSValue {
|
||||
return WebCore__CommonAbortReason__toJS(global, this);
|
||||
}
|
||||
|
||||
extern fn WebCore__CommonAbortReason__toJS(*JSGlobalObject, CommonAbortReason) JSValue;
|
||||
};
|
||||
|
||||
pub const AbortSignal = extern opaque {
|
||||
pub const shim = Shimmer("WebCore", "AbortSignal", @This());
|
||||
const cppFn = shim.cppFn;
|
||||
@@ -2042,12 +2054,15 @@ pub const AbortSignal = extern opaque {
|
||||
return cppFn("cleanNativeBindings", .{ this, ctx });
|
||||
}
|
||||
|
||||
extern fn WebCore__AbortSignal__signal(*AbortSignal, *JSC.JSGlobalObject, CommonAbortReason) void;
|
||||
|
||||
pub fn signal(
|
||||
this: *AbortSignal,
|
||||
reason: JSValue,
|
||||
) *AbortSignal {
|
||||
globalObject: *JSC.JSGlobalObject,
|
||||
reason: CommonAbortReason,
|
||||
) void {
|
||||
bun.Analytics.Features.abort_signal += 1;
|
||||
return cppFn("signal", .{ this, reason });
|
||||
return WebCore__AbortSignal__signal(this, globalObject, reason);
|
||||
}
|
||||
|
||||
/// This function is not threadsafe. aborted is a boolean, not an atomic!
|
||||
@@ -2095,15 +2110,7 @@ pub const AbortSignal = extern opaque {
|
||||
return WebCore__AbortSignal__new(global);
|
||||
}
|
||||
|
||||
pub fn createAbortError(message: *const ZigString, code: *const ZigString, global: *JSGlobalObject) JSValue {
|
||||
return cppFn("createAbortError", .{ message, code, global });
|
||||
}
|
||||
|
||||
pub fn createTimeoutError(message: *const ZigString, code: *const ZigString, global: *JSGlobalObject) JSValue {
|
||||
return cppFn("createTimeoutError", .{ message, code, global });
|
||||
}
|
||||
|
||||
pub const Extern = [_][]const u8{ "createAbortError", "createTimeoutError", "create", "ref", "unref", "signal", "abortReason", "aborted", "addListener", "fromJS", "toJS", "cleanNativeBindings" };
|
||||
pub const Extern = [_][]const u8{ "create", "ref", "unref", "signal", "abortReason", "aborted", "addListener", "fromJS", "toJS", "cleanNativeBindings" };
|
||||
};
|
||||
|
||||
pub const JSPromise = extern struct {
|
||||
|
||||
2
src/bun.js/bindings/headers.h
generated
2
src/bun.js/bindings/headers.h
generated
@@ -231,8 +231,6 @@ CPP_DECL JSC__JSValue WebCore__AbortSignal__abortReason(WebCore__AbortSignal* ar
|
||||
CPP_DECL WebCore__AbortSignal* WebCore__AbortSignal__addListener(WebCore__AbortSignal* arg0, void* arg1, void(* ArgFn2)(void* arg0, JSC__JSValue JSValue1));
|
||||
CPP_DECL void WebCore__AbortSignal__cleanNativeBindings(WebCore__AbortSignal* arg0, void* arg1);
|
||||
CPP_DECL JSC__JSValue WebCore__AbortSignal__create(JSC__JSGlobalObject* arg0);
|
||||
CPP_DECL JSC__JSValue WebCore__AbortSignal__createAbortError(const ZigString* arg0, const ZigString* arg1, JSC__JSGlobalObject* arg2);
|
||||
CPP_DECL JSC__JSValue WebCore__AbortSignal__createTimeoutError(const ZigString* arg0, const ZigString* arg1, JSC__JSGlobalObject* arg2);
|
||||
CPP_DECL WebCore__AbortSignal* WebCore__AbortSignal__fromJS(JSC__JSValue JSValue0);
|
||||
CPP_DECL WebCore__AbortSignal* WebCore__AbortSignal__ref(WebCore__AbortSignal* arg0);
|
||||
CPP_DECL WebCore__AbortSignal* WebCore__AbortSignal__signal(WebCore__AbortSignal* arg0, JSC__JSValue JSValue1);
|
||||
|
||||
2
src/bun.js/bindings/headers.zig
generated
2
src/bun.js/bindings/headers.zig
generated
@@ -143,8 +143,6 @@ pub extern fn WebCore__AbortSignal__abortReason(arg0: ?*bindings.AbortSignal) JS
|
||||
pub extern fn WebCore__AbortSignal__addListener(arg0: ?*bindings.AbortSignal, arg1: ?*anyopaque, ArgFn2: ?*const fn (?*anyopaque, JSC__JSValue) callconv(.C) void) ?*bindings.AbortSignal;
|
||||
pub extern fn WebCore__AbortSignal__cleanNativeBindings(arg0: ?*bindings.AbortSignal, arg1: ?*anyopaque) void;
|
||||
pub extern fn WebCore__AbortSignal__create(arg0: *bindings.JSGlobalObject) JSC__JSValue;
|
||||
pub extern fn WebCore__AbortSignal__createAbortError(arg0: [*c]const ZigString, arg1: [*c]const ZigString, arg2: *bindings.JSGlobalObject) JSC__JSValue;
|
||||
pub extern fn WebCore__AbortSignal__createTimeoutError(arg0: [*c]const ZigString, arg1: [*c]const ZigString, arg2: *bindings.JSGlobalObject) JSC__JSValue;
|
||||
pub extern fn WebCore__AbortSignal__fromJS(JSValue0: JSC__JSValue) ?*bindings.AbortSignal;
|
||||
pub extern fn WebCore__AbortSignal__ref(arg0: ?*bindings.AbortSignal) ?*bindings.AbortSignal;
|
||||
pub extern fn WebCore__AbortSignal__signal(arg0: ?*bindings.AbortSignal, JSValue1: JSC__JSValue) ?*bindings.AbortSignal;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "Event.h"
|
||||
#include "EventNames.h"
|
||||
#include "JSDOMException.h"
|
||||
#include "JavaScriptCore/JSCJSValue.h"
|
||||
#include "ScriptExecutionContext.h"
|
||||
#include "WebCoreOpaqueRoot.h"
|
||||
#include "wtf/DebugHeap.h"
|
||||
@@ -112,6 +113,20 @@ AbortSignal::AbortSignal(ScriptExecutionContext* context, Aborted aborted, JSC::
|
||||
|
||||
AbortSignal::~AbortSignal() = default;
|
||||
|
||||
JSValue AbortSignal::jsReason(JSC::JSGlobalObject& globalObject)
|
||||
{
|
||||
JSValue existingValue = m_reason.getValue(jsUndefined());
|
||||
if (existingValue.isUndefined()) {
|
||||
if (m_commonReason != CommonAbortReason::None) {
|
||||
existingValue = toJS(&globalObject, m_commonReason);
|
||||
m_commonReason = CommonAbortReason::None;
|
||||
m_reason.setWeakly(existingValue);
|
||||
}
|
||||
}
|
||||
|
||||
return existingValue;
|
||||
}
|
||||
|
||||
void AbortSignal::addSourceSignal(AbortSignal& signal)
|
||||
{
|
||||
if (signal.isDependent()) {
|
||||
@@ -164,6 +179,16 @@ void AbortSignal::signalAbort(JSC::JSValue reason)
|
||||
dependentSignal->signalAbort(reason);
|
||||
}
|
||||
|
||||
void AbortSignal::signalAbort(JSC::JSGlobalObject* globalObject, CommonAbortReason reason)
|
||||
{
|
||||
// 1. If signal's aborted flag is set, then return.
|
||||
if (m_aborted)
|
||||
return;
|
||||
|
||||
m_commonReason = reason;
|
||||
signalAbort(toJS(globalObject, reason));
|
||||
}
|
||||
|
||||
void AbortSignal::cleanNativeBindings(void* ref)
|
||||
{
|
||||
auto callbacks = std::exchange(m_native_callbacks, {});
|
||||
@@ -183,7 +208,7 @@ void AbortSignal::signalFollow(AbortSignal& signal)
|
||||
return;
|
||||
|
||||
if (signal.aborted()) {
|
||||
signalAbort(signal.reason().getValue());
|
||||
signalAbort(signal.jsReason(*scriptExecutionContext()->jsGlobalObject()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,7 +228,8 @@ void AbortSignal::eventListenersDidChange()
|
||||
uint32_t AbortSignal::addAbortAlgorithmToSignal(AbortSignal& signal, Ref<AbortAlgorithm>&& algorithm)
|
||||
{
|
||||
if (signal.aborted()) {
|
||||
algorithm->handleEvent(signal.m_reason.getValue());
|
||||
// TODO: Null check.
|
||||
algorithm->handleEvent(signal.jsReason(*signal.scriptExecutionContext()->jsGlobalObject()));
|
||||
return 0;
|
||||
}
|
||||
return signal.addAlgorithm([algorithm = WTFMove(algorithm)](JSC::JSValue value) mutable {
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "ContextDestructionObserver.h"
|
||||
#include "EventTarget.h"
|
||||
#include "JSValueInWrappedObject.h"
|
||||
#include "JavaScriptCore/JSGlobalObject.h"
|
||||
#include "ZigGlobalObject.h"
|
||||
#include "wtf/DebugHeap.h"
|
||||
#include "wtf/FastMalloc.h"
|
||||
#include <wtf/Function.h>
|
||||
@@ -46,6 +48,15 @@ class WebCoreOpaqueRoot;
|
||||
|
||||
DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(AbortSignal);
|
||||
|
||||
enum class CommonAbortReason : uint8_t {
|
||||
None,
|
||||
Timeout,
|
||||
UserAbort,
|
||||
ConnectionClosed,
|
||||
};
|
||||
|
||||
JSC::JSValue toJS(JSC::JSGlobalObject*, CommonAbortReason);
|
||||
|
||||
class AbortSignal final : public RefCounted<AbortSignal>, public EventTargetWithInlineData, private ContextDestructionObserver {
|
||||
WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(AbortSignal);
|
||||
|
||||
@@ -61,11 +72,13 @@ public:
|
||||
static uint32_t addAbortAlgorithmToSignal(AbortSignal&, Ref<AbortAlgorithm>&&);
|
||||
static void removeAbortAlgorithmFromSignal(AbortSignal&, uint32_t algorithmIdentifier);
|
||||
|
||||
void signalAbort(JSC::JSGlobalObject* globalObject, CommonAbortReason reason);
|
||||
void signalAbort(JSC::JSValue reason);
|
||||
void signalFollow(AbortSignal&);
|
||||
|
||||
bool aborted() const { return m_aborted; }
|
||||
const JSValueInWrappedObject& reason() const { return m_reason; }
|
||||
JSValue jsReason(JSC::JSGlobalObject& globalObject);
|
||||
|
||||
void cleanNativeBindings(void* ref);
|
||||
void addNativeCallback(NativeCallbackTuple callback) { m_native_callbacks.append(callback); }
|
||||
@@ -89,8 +102,10 @@ public:
|
||||
AbortSignalSet& sourceSignals() { return m_sourceSignals; }
|
||||
|
||||
private:
|
||||
enum class Aborted : bool { No,
|
||||
Yes };
|
||||
enum class Aborted : bool {
|
||||
No,
|
||||
Yes
|
||||
};
|
||||
explicit AbortSignal(ScriptExecutionContext*, Aborted = Aborted::No, JSC::JSValue reason = JSC::jsUndefined());
|
||||
|
||||
void setHasActiveTimeoutTimer(bool hasActiveTimeoutTimer) { m_hasActiveTimeoutTimer = hasActiveTimeoutTimer; }
|
||||
@@ -112,6 +127,7 @@ private:
|
||||
AbortSignalSet m_sourceSignals;
|
||||
AbortSignalSet m_dependentSignals;
|
||||
JSValueInWrappedObject m_reason;
|
||||
CommonAbortReason m_commonReason { CommonAbortReason::None };
|
||||
Vector<NativeCallbackTuple, 2> m_native_callbacks;
|
||||
uint32_t m_algorithmIdentifier { 0 };
|
||||
bool m_aborted { false };
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMockWithImplementationCleanupData;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForProcessObject;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInternalModuleRegistry;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNodeErrors;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBunInspectorConnection;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSNextTickQueue;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNAPIFunction;
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForMockWithImplementationCleanupData;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForProcessObject;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForInternalModuleRegistry;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForNodeErrors;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForBunInspectorConnection;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForJSNextTickQueue;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForNAPIFunction;
|
||||
|
||||
@@ -225,7 +225,7 @@ static inline JSValue jsAbortSignal_reasonGetter(JSGlobalObject& lexicalGlobalOb
|
||||
auto& vm = JSC::getVM(&lexicalGlobalObject);
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
auto& impl = thisObject.wrapped();
|
||||
RELEASE_AND_RETURN(throwScope, (toJS<IDLAny>(lexicalGlobalObject, throwScope, impl.reason())));
|
||||
RELEASE_AND_RETURN(throwScope, (toJS<IDLAny>(lexicalGlobalObject, throwScope, impl.jsReason(lexicalGlobalObject))));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortSignal_reason, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
|
||||
|
||||
@@ -399,10 +399,12 @@ extern "C" void WebWorker__dispatchExit(Zig::GlobalObject* globalObject, Worker*
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
vm.setHasTerminationRequest();
|
||||
|
||||
while (!vm.hasOneRef())
|
||||
vm.deref();
|
||||
// clang-tidy is smart enough to realize that deref() leads to freeing
|
||||
// but it's not smart enough to realize that `hasOneRef()` ensures its safety
|
||||
while (!vm.hasOneRef()) // NOLINT
|
||||
vm.deref(); // NOLINT
|
||||
|
||||
vm.deref();
|
||||
vm.deref(); // NOLINT
|
||||
}
|
||||
}
|
||||
extern "C" void WebWorker__dispatchOnline(Worker* worker, Zig::GlobalObject* globalObject)
|
||||
|
||||
@@ -535,7 +535,7 @@ pub const FSWatcher = struct {
|
||||
listener.ensureStillAlive();
|
||||
var args = [_]JSC.JSValue{
|
||||
EventType.@"error".toJS(this.globalThis),
|
||||
if (err.isEmptyOrUndefinedOrNull()) JSC.WebCore.AbortSignal.createAbortError(JSC.ZigString.static("The user aborted a request"), &JSC.ZigString.Empty, this.globalThis) else err,
|
||||
JSC.CommonAbortReason.UserAbort.toJS(this.globalThis),
|
||||
};
|
||||
_ = listener.callWithGlobalThis(
|
||||
this.globalThis,
|
||||
|
||||
@@ -321,10 +321,24 @@ pub const Body = struct {
|
||||
Message: bun.String,
|
||||
JSValue: JSC.Strong,
|
||||
|
||||
pub fn toStreamError(this: *@This(), globalObject: *JSC.JSGlobalObject) JSC.WebCore.StreamResult.StreamError {
|
||||
return switch (this.*) {
|
||||
.Aborted => .{
|
||||
.AbortReason = JSC.CommonAbortReason.UserAbort,
|
||||
},
|
||||
.Timeout => .{
|
||||
.AbortReason = JSC.CommonAbortReason.Timeout,
|
||||
},
|
||||
else => .{
|
||||
.JSValue = this.toJS(globalObject),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn toJS(this: *@This(), globalObject: *JSC.JSGlobalObject) JSC.JSValue {
|
||||
const js_value = switch (this.*) {
|
||||
.Timeout => JSC.WebCore.AbortSignal.createTimeoutError(JSC.ZigString.static("The operation timed out"), &JSC.ZigString.Empty, globalObject),
|
||||
.Aborted => JSC.WebCore.AbortSignal.createAbortError(JSC.ZigString.static("The user aborted a request"), &JSC.ZigString.Empty, globalObject),
|
||||
.Timeout => JSC.CommonAbortReason.Timeout.toJS(globalObject),
|
||||
.Aborted => JSC.CommonAbortReason.UserAbort.toJS(globalObject),
|
||||
.SystemError => |system_error| system_error.toErrorInstance(globalObject),
|
||||
.Message => |message| message.toErrorInstance(globalObject),
|
||||
// do a early return in this case we don't need to create a new Strong
|
||||
@@ -927,12 +941,12 @@ pub const Body = struct {
|
||||
}
|
||||
}
|
||||
|
||||
// The Promise version goes before the ReadableStream version incase the Promise version is used too.
|
||||
// Avoid creating unnecessary duplicate JSValue.
|
||||
if (strong_readable.get()) |readable| {
|
||||
if (readable.ptr == .Bytes) {
|
||||
readable.ptr.Bytes.onData(
|
||||
.{
|
||||
.err = .{ .JSValue = this.Error.toJS(global) },
|
||||
},
|
||||
.{ .err = this.Error.toStreamError(global) },
|
||||
bun.default_allocator,
|
||||
);
|
||||
} else {
|
||||
|
||||
@@ -1262,7 +1262,7 @@ pub const Fetch = struct {
|
||||
if (signal.aborted()) {
|
||||
this.abort_reason = signal.abortReason();
|
||||
if (this.abort_reason.isEmptyOrUndefinedOrNull()) {
|
||||
return JSC.WebCore.AbortSignal.createAbortError(JSC.ZigString.static("The user aborted a request"), &JSC.ZigString.Empty, this.global_this);
|
||||
return JSC.CommonAbortReason.UserAbort.toJS(this.global_this);
|
||||
}
|
||||
this.abort_reason.protect();
|
||||
return this.abort_reason;
|
||||
|
||||
@@ -660,7 +660,7 @@ pub const DrainResult = union(enum) {
|
||||
|
||||
pub const StreamResult = union(Tag) {
|
||||
pending: *Pending,
|
||||
err: union(Err) { Error: Syscall.Error, JSValue: JSC.JSValue },
|
||||
err: StreamError,
|
||||
done: void,
|
||||
owned: bun.ByteList,
|
||||
owned_and_done: bun.ByteList,
|
||||
@@ -682,9 +682,28 @@ pub const StreamResult = union(Tag) {
|
||||
}
|
||||
}
|
||||
|
||||
pub const Err = enum {
|
||||
Error,
|
||||
JSValue,
|
||||
pub const StreamError = union(enum) {
|
||||
Error: Syscall.Error,
|
||||
AbortReason: JSC.CommonAbortReason,
|
||||
JSValue: JSC.JSValue,
|
||||
|
||||
pub fn toJS(this: *@This(), globalObject: *JSC.JSGlobalObject) JSC.JSValue {
|
||||
return switch (this.*) {
|
||||
.Error => |*err| {
|
||||
const value = err.toJSC(globalObject);
|
||||
value.protect();
|
||||
this.* = .{ .JSValue = value };
|
||||
return value;
|
||||
},
|
||||
.JSValue => this.JSValue,
|
||||
.AbortReason => |reason| {
|
||||
const value = reason.toJS(globalObject);
|
||||
value.protect();
|
||||
this.* = .{ .JSValue = value };
|
||||
return value;
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Tag = enum {
|
||||
@@ -943,11 +962,9 @@ pub const StreamResult = union(Tag) {
|
||||
defer loop.exit();
|
||||
|
||||
switch (result.*) {
|
||||
.err => |err| {
|
||||
.err => |*err| {
|
||||
const value = brk: {
|
||||
if (err == .Error) break :brk err.Error.toJSC(globalThis);
|
||||
|
||||
const js_err = err.JSValue;
|
||||
const js_err = err.toJS(globalThis);
|
||||
js_err.ensureStillAlive();
|
||||
js_err.unprotect();
|
||||
|
||||
@@ -4332,13 +4349,9 @@ pub const ByteStream = struct {
|
||||
|
||||
if (to_copy.len == 0) {
|
||||
if (stream == .err) {
|
||||
if (stream.err == .Error) {
|
||||
this.pending.result = .{ .err = .{ .Error = stream.err.Error } };
|
||||
}
|
||||
const js_err = stream.err.JSValue;
|
||||
js_err.ensureStillAlive();
|
||||
js_err.protect();
|
||||
this.pending.result = .{ .err = .{ .JSValue = js_err } };
|
||||
this.pending.result = .{
|
||||
.err = stream.err,
|
||||
};
|
||||
} else {
|
||||
this.pending.result = .{
|
||||
.done = {},
|
||||
|
||||
@@ -138,204 +138,7 @@ typedef void (*uws_get_headers_server_handler)(const char *header_name,
|
||||
size_t header_value_size,
|
||||
void *user_data);
|
||||
|
||||
// Basic HTTP
|
||||
uws_app_t *uws_create_app(int ssl,
|
||||
struct us_bun_socket_context_options_t options);
|
||||
|
||||
void uws_app_destroy(int ssl, uws_app_t *app);
|
||||
void uws_app_get(int ssl, uws_app_t *app, const char *pattern,
|
||||
uws_method_handler handler, void *user_data);
|
||||
void uws_app_post(int ssl, uws_app_t *app, const char *pattern,
|
||||
uws_method_handler handler, void *user_data);
|
||||
void uws_app_options(int ssl, uws_app_t *app, const char *pattern,
|
||||
uws_method_handler handler, void *user_data);
|
||||
void uws_app_delete(int ssl, uws_app_t *app, const char *pattern,
|
||||
uws_method_handler handler, void *user_data);
|
||||
void uws_app_patch(int ssl, uws_app_t *app, const char *pattern,
|
||||
uws_method_handler handler, void *user_data);
|
||||
void uws_app_put(int ssl, uws_app_t *app, const char *pattern,
|
||||
uws_method_handler handler, void *user_data);
|
||||
void uws_app_head(int ssl, uws_app_t *app, const char *pattern,
|
||||
uws_method_handler handler, void *user_data);
|
||||
void uws_app_connect(int ssl, uws_app_t *app, const char *pattern,
|
||||
uws_method_handler handler, void *user_data);
|
||||
void uws_app_trace(int ssl, uws_app_t *app, const char *pattern,
|
||||
uws_method_handler handler, void *user_data);
|
||||
void uws_app_any(int ssl, uws_app_t *app, const char *pattern,
|
||||
uws_method_handler handler, void *user_data);
|
||||
|
||||
void uws_app_run(int ssl, uws_app_t *);
|
||||
|
||||
void uws_app_listen(int ssl, uws_app_t *app, int port,
|
||||
uws_listen_handler handler, void *user_data);
|
||||
void uws_app_listen_with_config(int ssl, uws_app_t *app, const char *host,
|
||||
uint16_t port, int32_t options,
|
||||
uws_listen_handler handler, void *user_data);
|
||||
void uws_app_listen_domain(int ssl, uws_app_t *app, const char *domain,
|
||||
size_t pathlen, uws_listen_domain_handler handler,
|
||||
void *user_data);
|
||||
|
||||
void uws_app_listen_domain_with_options(int ssl, uws_app_t *app,
|
||||
const char *domain, size_t pathlen,
|
||||
int options,
|
||||
uws_listen_domain_handler handler,
|
||||
void *user_data);
|
||||
void uws_app_domain(int ssl, uws_app_t *app, const char *server_name);
|
||||
|
||||
bool uws_constructor_failed(int ssl, uws_app_t *app);
|
||||
|
||||
unsigned int uws_num_subscribers(int ssl, uws_app_t *app, const char *topic,
|
||||
size_t topic_length);
|
||||
bool uws_publish(int ssl, uws_app_t *app, const char *topic,
|
||||
size_t topic_length, const char *message,
|
||||
size_t message_length, uws_opcode_t opcode, bool compress);
|
||||
void *uws_get_native_handle(int ssl, uws_app_t *app);
|
||||
void uws_remove_server_name(int ssl, uws_app_t *app,
|
||||
const char *hostname_pattern);
|
||||
void uws_add_server_name(int ssl, uws_app_t *app, const char *hostname_pattern);
|
||||
void uws_add_server_name_with_options(
|
||||
int ssl, uws_app_t *app, const char *hostname_pattern,
|
||||
struct us_bun_socket_context_options_t options);
|
||||
void uws_missing_server_name(int ssl, uws_app_t *app,
|
||||
uws_missing_server_handler handler,
|
||||
void *user_data);
|
||||
void uws_filter(int ssl, uws_app_t *app, uws_filter_handler handler,
|
||||
void *user_data);
|
||||
|
||||
// WebSocket
|
||||
void uws_ws(int ssl, uws_app_t *app, void *upgradeCtx, const char *pattern,
|
||||
size_t pattern_length, size_t id,
|
||||
const uws_socket_behavior_t *behavior);
|
||||
void *uws_ws_get_user_data(int ssl, uws_websocket_t *ws);
|
||||
void uws_ws_close(int ssl, uws_websocket_t *ws);
|
||||
uws_sendstatus_t uws_ws_send(int ssl, uws_websocket_t *ws, const char *message,
|
||||
size_t length, uws_opcode_t opcode);
|
||||
uws_sendstatus_t uws_ws_send_with_options(int ssl, uws_websocket_t *ws,
|
||||
const char *message, size_t length,
|
||||
uws_opcode_t opcode, bool compress,
|
||||
bool fin);
|
||||
uws_sendstatus_t uws_ws_send_fragment(int ssl, uws_websocket_t *ws,
|
||||
const char *message, size_t length,
|
||||
bool compress);
|
||||
uws_sendstatus_t uws_ws_send_first_fragment(int ssl, uws_websocket_t *ws,
|
||||
const char *message, size_t length,
|
||||
bool compress);
|
||||
uws_sendstatus_t
|
||||
uws_ws_send_first_fragment_with_opcode(int ssl, uws_websocket_t *ws,
|
||||
const char *message, size_t length,
|
||||
uws_opcode_t opcode, bool compress);
|
||||
uws_sendstatus_t uws_ws_send_last_fragment(int ssl, uws_websocket_t *ws,
|
||||
const char *message, size_t length,
|
||||
bool compress);
|
||||
void uws_ws_end(int ssl, uws_websocket_t *ws, int code, const char *message,
|
||||
size_t length);
|
||||
void uws_ws_cork(int ssl, uws_websocket_t *ws, void (*handler)(void *user_data),
|
||||
void *user_data);
|
||||
bool uws_ws_subscribe(int ssl, uws_websocket_t *ws, const char *topic,
|
||||
size_t length);
|
||||
bool uws_ws_unsubscribe(int ssl, uws_websocket_t *ws, const char *topic,
|
||||
size_t length);
|
||||
bool uws_ws_is_subscribed(int ssl, uws_websocket_t *ws, const char *topic,
|
||||
size_t length);
|
||||
void uws_ws_iterate_topics(int ssl, uws_websocket_t *ws,
|
||||
void (*callback)(const char *topic, size_t length,
|
||||
void *user_data),
|
||||
void *user_data);
|
||||
bool uws_ws_publish(int ssl, uws_websocket_t *ws, const char *topic,
|
||||
size_t topic_length, const char *message,
|
||||
size_t message_length);
|
||||
bool uws_ws_publish_with_options(int ssl, uws_websocket_t *ws,
|
||||
const char *topic, size_t topic_length,
|
||||
const char *message, size_t message_length,
|
||||
uws_opcode_t opcode, bool compress);
|
||||
unsigned int uws_ws_get_buffered_amount(int ssl, uws_websocket_t *ws);
|
||||
size_t uws_ws_get_remote_address(int ssl, uws_websocket_t *ws,
|
||||
const char **dest);
|
||||
size_t uws_ws_get_remote_address_as_text(int ssl, uws_websocket_t *ws,
|
||||
const char **dest);
|
||||
|
||||
// Response
|
||||
void uws_res_end(int ssl, uws_res_t *res, const char *data, size_t length,
|
||||
bool close_connection);
|
||||
void uws_res_pause(int ssl, uws_res_t *res);
|
||||
void uws_res_resume(int ssl, uws_res_t *res);
|
||||
void uws_res_write_continwue(int ssl, uws_res_t *res);
|
||||
void uws_res_write_status(int ssl, uws_res_t *res, const char *status,
|
||||
size_t length);
|
||||
void uws_res_write_header(int ssl, uws_res_t *res, const char *key,
|
||||
size_t key_length, const char *value,
|
||||
size_t value_length);
|
||||
|
||||
void uws_res_write_header_int(int ssl, uws_res_t *res, const char *key,
|
||||
size_t key_length, uint64_t value);
|
||||
void uws_res_end_without_body(int ssl, uws_res_t *res, bool close_connection);
|
||||
void uws_res_end_stream(int ssl, uws_res_t *res, bool close_connection);
|
||||
bool uws_res_write(int ssl, uws_res_t *res, const char *data, size_t length);
|
||||
uint64_t uws_res_get_write_offset(int ssl, uws_res_t *res);
|
||||
bool uws_res_has_responded(int ssl, uws_res_t *res);
|
||||
void uws_res_on_writable(int ssl, uws_res_t *res,
|
||||
bool (*handler)(uws_res_t *res, uint64_t,
|
||||
void *opcional_data),
|
||||
void *user_data);
|
||||
void uws_res_on_aborted(int ssl, uws_res_t *res,
|
||||
void (*handler)(uws_res_t *res, void *opcional_data),
|
||||
void *opcional_data);
|
||||
void uws_res_on_data(int ssl, uws_res_t *res,
|
||||
void (*handler)(uws_res_t *res, const char *chunk,
|
||||
size_t chunk_length, bool is_end,
|
||||
void *opcional_data),
|
||||
void *opcional_data);
|
||||
void uws_res_upgrade(int ssl, uws_res_t *res, void *data,
|
||||
const char *sec_web_socket_key,
|
||||
size_t sec_web_socket_key_length,
|
||||
const char *sec_web_socket_protocol,
|
||||
size_t sec_web_socket_protocol_length,
|
||||
const char *sec_web_socket_extensions,
|
||||
size_t sec_web_socket_extensions_length,
|
||||
uws_socket_context_t *ws);
|
||||
|
||||
// Request
|
||||
bool uws_req_is_ancient(uws_req_t *res);
|
||||
bool uws_req_get_yield(uws_req_t *res);
|
||||
void uws_req_set_yield(uws_req_t *res, bool yield);
|
||||
size_t uws_req_get_url(uws_req_t *res, const char **dest);
|
||||
size_t uws_req_get_method(uws_req_t *res, const char **dest);
|
||||
size_t uws_req_get_header(uws_req_t *res, const char *lower_case_header,
|
||||
size_t lower_case_header_length, const char **dest);
|
||||
size_t uws_req_get_query(uws_req_t *res, const char *key, size_t key_length,
|
||||
const char **dest);
|
||||
size_t uws_req_get_parameter(uws_req_t *res, unsigned short index,
|
||||
const char **dest);
|
||||
void uws_req_for_each_header(uws_req_t *res,
|
||||
uws_get_headers_server_handler handler,
|
||||
void *user_data);
|
||||
|
||||
struct us_loop_t *uws_get_loop();
|
||||
struct us_loop_t *uws_get_loop_with_native(void *existing_native_loop);
|
||||
|
||||
void uws_loop_addPostHandler(us_loop_t *loop, void *ctx_,
|
||||
void (*cb)(void *ctx, us_loop_t *loop));
|
||||
void uws_loop_removePostHandler(us_loop_t *loop, void *key);
|
||||
void uws_loop_addPreHandler(us_loop_t *loop, void *key,
|
||||
void (*cb)(void *ctx, us_loop_t *loop));
|
||||
void uws_loop_removePreHandler(us_loop_t *loop, void *ctx_);
|
||||
void uws_loop_defer(us_loop_t *loop, void *ctx, void (*cb)(void *ctx));
|
||||
|
||||
void uws_res_write_headers(int ssl, uws_res_t *res, const StringPointer *names,
|
||||
const StringPointer *values, size_t count,
|
||||
const char *buf);
|
||||
|
||||
void *uws_res_get_native_handle(int ssl, uws_res_t *res);
|
||||
void uws_res_uncork(int ssl, uws_res_t *res);
|
||||
void us_socket_mark_needs_more_not_ssl(uws_res_t *res);
|
||||
int uws_res_state(int ssl, uws_res_t *res);
|
||||
bool uws_res_try_end(int ssl, uws_res_t *res, const char *bytes, size_t len,
|
||||
size_t total_len, bool close);
|
||||
|
||||
void uws_res_prepare_for_sendfile(int ssl, uws_res_t *res);
|
||||
void uws_res_override_write_offset(int ssl, uws_res_t *res, uint64_t offset);
|
||||
|
||||
void uws_app_close(int ssl, uws_app_t *app);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// clang-format off
|
||||
#include "_libusockets.h"
|
||||
#include "libusockets.h"
|
||||
#include <bun-uws/src/App.h>
|
||||
#include <bun-uws/src/AsyncSocket.h>
|
||||
#include <bun-usockets/src/internal/internal.h>
|
||||
@@ -7,6 +8,8 @@
|
||||
|
||||
extern "C" const char* ares_inet_ntop(int af, const char *src, char *dst, size_t size);
|
||||
|
||||
#define uws_res_r uws_res_t* nonnull_arg
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
@@ -1015,7 +1018,7 @@ extern "C"
|
||||
return value.length();
|
||||
}
|
||||
|
||||
void uws_res_end(int ssl, uws_res_t *res, const char *data, size_t length,
|
||||
void uws_res_end(int ssl, uws_res_r res, const char *data, size_t length,
|
||||
bool close_connection)
|
||||
{
|
||||
if (ssl)
|
||||
@@ -1032,7 +1035,7 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void uws_res_end_stream(int ssl, uws_res_t *res, bool close_connection)
|
||||
void uws_res_end_stream(int ssl, uws_res_r res, bool close_connection)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1048,7 +1051,7 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void uws_res_pause(int ssl, uws_res_t *res)
|
||||
void uws_res_pause(int ssl, uws_res_r res)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1062,7 +1065,7 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void uws_res_resume(int ssl, uws_res_t *res)
|
||||
void uws_res_resume(int ssl, uws_res_r res)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1076,7 +1079,7 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void uws_res_write_continue(int ssl, uws_res_t *res)
|
||||
void uws_res_write_continue(int ssl, uws_res_r res)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1090,7 +1093,7 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void uws_res_write_status(int ssl, uws_res_t *res, const char *status,
|
||||
void uws_res_write_status(int ssl, uws_res_r res, const char *status,
|
||||
size_t length)
|
||||
{
|
||||
if (ssl)
|
||||
@@ -1105,7 +1108,7 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void uws_res_write_header(int ssl, uws_res_t *res, const char *key,
|
||||
void uws_res_write_header(int ssl, uws_res_r res, const char *key,
|
||||
size_t key_length, const char *value,
|
||||
size_t value_length)
|
||||
{
|
||||
@@ -1122,7 +1125,7 @@ extern "C"
|
||||
std::string_view(value, value_length));
|
||||
}
|
||||
}
|
||||
void uws_res_write_header_int(int ssl, uws_res_t *res, const char *key,
|
||||
void uws_res_write_header_int(int ssl, uws_res_r res, const char *key,
|
||||
size_t key_length, uint64_t value)
|
||||
{
|
||||
if (ssl)
|
||||
@@ -1137,7 +1140,7 @@ extern "C"
|
||||
uwsRes->writeHeader(std::string_view(key, key_length), value);
|
||||
}
|
||||
}
|
||||
void uws_res_end_sendfile(int ssl, uws_res_t *res, uint64_t offset, bool close_connection)
|
||||
void uws_res_end_sendfile(int ssl, uws_res_r res, uint64_t offset, bool close_connection)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1158,7 +1161,7 @@ extern "C"
|
||||
us_socket_timeout(0, (us_socket_t *)uwsRes, uWS::HTTP_TIMEOUT_S);
|
||||
}
|
||||
}
|
||||
void uws_res_end_without_body(int ssl, uws_res_t *res, bool close_connection)
|
||||
void uws_res_end_without_body(int ssl, uws_res_r res, bool close_connection)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1204,7 +1207,9 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
bool uws_res_write(int ssl, uws_res_t *res, const char *data, size_t length)
|
||||
bool uws_res_write(int ssl, uws_res_r res, const char *data, size_t length) nonnull_fn_decl;
|
||||
|
||||
bool uws_res_write(int ssl, uws_res_r res, const char *data, size_t length)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1214,7 +1219,8 @@ extern "C"
|
||||
uWS::HttpResponse<false> *uwsRes = (uWS::HttpResponse<false> *)res;
|
||||
return uwsRes->write(std::string_view(data, length));
|
||||
}
|
||||
uint64_t uws_res_get_write_offset(int ssl, uws_res_t *res)
|
||||
uint64_t uws_res_get_write_offset(int ssl, uws_res_r res) nonnull_fn_decl;
|
||||
uint64_t uws_res_get_write_offset(int ssl, uws_res_r res)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1225,7 +1231,8 @@ extern "C"
|
||||
return uwsRes->getWriteOffset();
|
||||
}
|
||||
|
||||
bool uws_res_has_responded(int ssl, uws_res_t *res)
|
||||
bool uws_res_has_responded(int ssl, uws_res_r res) nonnull_fn_decl;
|
||||
bool uws_res_has_responded(int ssl, uws_res_r res)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1236,8 +1243,8 @@ extern "C"
|
||||
return uwsRes->hasResponded();
|
||||
}
|
||||
|
||||
void uws_res_on_writable(int ssl, uws_res_t *res,
|
||||
bool (*handler)(uws_res_t *res, uint64_t,
|
||||
void uws_res_on_writable(int ssl, uws_res_r res,
|
||||
bool (*handler)(uws_res_r res, uint64_t,
|
||||
void *opcional_data),
|
||||
void *opcional_data)
|
||||
{
|
||||
@@ -1255,7 +1262,7 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void uws_res_clear_on_writable(int ssl, uws_res_t *res) {
|
||||
void uws_res_clear_on_writable(int ssl, uws_res_r res) {
|
||||
if (ssl) {
|
||||
uWS::HttpResponse<true> *uwsRes = (uWS::HttpResponse<true> *)res;
|
||||
uwsRes->clearOnWritable();
|
||||
@@ -1265,8 +1272,8 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void uws_res_on_aborted(int ssl, uws_res_t *res,
|
||||
void (*handler)(uws_res_t *res, void *opcional_data),
|
||||
void uws_res_on_aborted(int ssl, uws_res_r res,
|
||||
void (*handler)(uws_res_r res, void *opcional_data),
|
||||
void *opcional_data)
|
||||
{
|
||||
if (ssl)
|
||||
@@ -1297,8 +1304,8 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void uws_res_on_data(int ssl, uws_res_t *res,
|
||||
void (*handler)(uws_res_t *res, const char *chunk,
|
||||
void uws_res_on_data(int ssl, uws_res_r res,
|
||||
void (*handler)(uws_res_r res, const char *chunk,
|
||||
size_t chunk_length, bool is_end,
|
||||
void *opcional_data),
|
||||
void *opcional_data)
|
||||
@@ -1359,6 +1366,9 @@ extern "C"
|
||||
return value.length();
|
||||
}
|
||||
|
||||
size_t uws_req_get_header(uws_req_t *res, const char *lower_case_header,
|
||||
size_t lower_case_header_length, const char **dest) nonnull_fn_decl;
|
||||
|
||||
size_t uws_req_get_header(uws_req_t *res, const char *lower_case_header,
|
||||
size_t lower_case_header_length, const char **dest)
|
||||
{
|
||||
@@ -1398,7 +1408,7 @@ extern "C"
|
||||
return value.length();
|
||||
}
|
||||
|
||||
void uws_res_upgrade(int ssl, uws_res_t *res, void *data,
|
||||
void uws_res_upgrade(int ssl, uws_res_r res, void *data,
|
||||
const char *sec_web_socket_key,
|
||||
size_t sec_web_socket_key_length,
|
||||
const char *sec_web_socket_protocol,
|
||||
@@ -1470,9 +1480,12 @@ extern "C"
|
||||
{ cb(ctx); });
|
||||
}
|
||||
|
||||
void uws_res_write_headers(int ssl, uws_res_t *res, const StringPointer *names,
|
||||
void uws_res_write_headers(int ssl, uws_res_r res, const StringPointer *names,
|
||||
const StringPointer *values, size_t count,
|
||||
const char *buf)
|
||||
const char *buf) nonnull_fn_decl;
|
||||
void uws_res_write_headers(int ssl, uws_res_r res, const StringPointer *names,
|
||||
const StringPointer *values, size_t count,
|
||||
const char *buf)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1494,7 +1507,7 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void uws_res_uncork(int ssl, uws_res_t *res)
|
||||
void uws_res_uncork(int ssl, uws_res_r res)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1508,15 +1521,15 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void us_socket_mark_needs_more_not_ssl(uws_res_t *res)
|
||||
void us_socket_mark_needs_more_not_ssl(uws_res_r res)
|
||||
{
|
||||
us_socket_t *s = (us_socket_t *)res;
|
||||
us_socket_r s = (us_socket_t *)res;
|
||||
s->context->loop->data.last_write_failed = 1;
|
||||
us_poll_change(&s->p, s->context->loop,
|
||||
LIBUS_SOCKET_READABLE | LIBUS_SOCKET_WRITABLE);
|
||||
}
|
||||
|
||||
void uws_res_override_write_offset(int ssl, uws_res_t *res, uint64_t offset)
|
||||
void uws_res_override_write_offset(int ssl, uws_res_r res, uint64_t offset)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1528,7 +1541,11 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void uws_res_cork(int ssl, uws_res_t *res, void *ctx,
|
||||
__attribute__((callback (corker, ctx)))
|
||||
void uws_res_cork(int ssl, uws_res_r res, void *ctx,
|
||||
void (*corker)(void *ctx)) nonnull_fn_decl;
|
||||
|
||||
void uws_res_cork(int ssl, uws_res_r res, void *ctx,
|
||||
void (*corker)(void *ctx))
|
||||
{
|
||||
if (ssl)
|
||||
@@ -1545,7 +1562,7 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void uws_res_prepare_for_sendfile(int ssl, uws_res_t *res)
|
||||
void uws_res_prepare_for_sendfile(int ssl, uws_res_r res)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1569,7 +1586,7 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
bool uws_res_try_end(int ssl, uws_res_t *res, const char *bytes, size_t len,
|
||||
bool uws_res_try_end(int ssl, uws_res_r res, const char *bytes, size_t len,
|
||||
size_t total_len, bool close)
|
||||
{
|
||||
if (ssl)
|
||||
@@ -1594,7 +1611,7 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
int uws_res_state(int ssl, uws_res_t *res)
|
||||
int uws_res_state(int ssl, uws_res_r res)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1608,7 +1625,7 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void *uws_res_get_native_handle(int ssl, uws_res_t *res)
|
||||
void *uws_res_get_native_handle(int ssl, uws_res_r res)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
@@ -1622,14 +1639,14 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
void us_socket_sendfile_needs_more(us_socket_t *s) {
|
||||
void us_socket_sendfile_needs_more(us_socket_r s) {
|
||||
s->context->loop->data.last_write_failed = 1;
|
||||
us_poll_change(&s->p, s->context->loop, LIBUS_SOCKET_READABLE | LIBUS_SOCKET_WRITABLE);
|
||||
}
|
||||
|
||||
// Gets the remote address and port
|
||||
// Returns 0 if failure / unix socket
|
||||
uint64_t uws_res_get_remote_address_info(uws_res_t *res, const char **dest, int *port, bool *is_ipv6)
|
||||
uint64_t uws_res_get_remote_address_info(uws_res_r res, const char **dest, int *port, bool *is_ipv6)
|
||||
{
|
||||
// This function is manual inlining + modification of
|
||||
// us_socket_remote_address
|
||||
|
||||
Reference in New Issue
Block a user