// clang-format off #include "_libusockets.h" #include "libusockets.h" #include #include #include #include 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 static inline std::string_view stringViewFromC(const char* message, size_t length) { if(length) { return std::string_view(message, length); } return std::string_view(); } using TLSWebSocket = uWS::WebSocket; using TCPWebSocket = uWS::WebSocket; extern "C" { void uws_loop_date_header_timer_update(us_loop_t *loop) { uWS::LoopData *loopData = uWS::Loop::data(loop); loopData->updateDate(); } uws_app_t *uws_create_app(int ssl, struct us_bun_socket_context_options_t options) { if (ssl) { uWS::SocketContextOptions socket_context_options; memcpy(&socket_context_options, &options, sizeof(uWS::SocketContextOptions)); return (uws_app_t *)uWS::SSLApp::create(socket_context_options); } return (uws_app_t *)new uWS::App(); } void uws_app_clear_routes(int ssl, uws_app_t *app) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->clearRoutes(); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->clearRoutes(); } } void uws_app_get(int ssl, uws_app_t *app, const char *pattern_ptr, size_t pattern_len, uws_method_handler handler, void *user_data) { std::string_view pattern = std::string_view(pattern_ptr, pattern_len); if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; if (handler == nullptr) { uwsApp->get(pattern, nullptr); return; } uwsApp->get(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; if (handler == nullptr) { uwsApp->get(pattern, nullptr); return; } uwsApp->get(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } } void uws_app_post(int ssl, uws_app_t *app, const char *pattern_ptr, size_t pattern_len, uws_method_handler handler, void *user_data) { std::string_view pattern = std::string_view(pattern_ptr, pattern_len); if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; if (handler == nullptr) { uwsApp->post(pattern, nullptr); return; } uwsApp->post(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; if (handler == nullptr) { uwsApp->post(pattern, nullptr); return; } uwsApp->post(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } } void uws_app_options(int ssl, uws_app_t *app, const char *pattern_ptr, size_t pattern_len, uws_method_handler handler, void *user_data) { std::string_view pattern = std::string_view(pattern_ptr, pattern_len); if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; if (handler == nullptr) { uwsApp->options(pattern, nullptr); return; } uwsApp->options(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; if (handler == nullptr) { uwsApp->options(pattern, nullptr); return; } uwsApp->options(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } } extern "C" void uws_res_clear_corked_socket(us_loop_t *loop) { uWS::LoopData *loopData = uWS::Loop::data(loop); void *corkedSocket = loopData->getCorkedSocket(); if (corkedSocket) { if (loopData->isCorkedSSL()) { ((uWS::AsyncSocket *) corkedSocket)->uncork(); } else { ((uWS::AsyncSocket *) corkedSocket)->uncork(); } } } void uws_app_delete(int ssl, uws_app_t *app, const char *pattern_ptr, size_t pattern_len, uws_method_handler handler, void *user_data) { std::string_view pattern = std::string_view(pattern_ptr, pattern_len); if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; if (handler == nullptr) { uwsApp->del(pattern, nullptr); return; } uwsApp->del(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; if (handler == nullptr) { uwsApp->del(pattern, nullptr); return; } uwsApp->del(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } } void uws_app_patch(int ssl, uws_app_t *app, const char *pattern_ptr, size_t pattern_len, uws_method_handler handler, void *user_data) { std::string_view pattern = std::string_view(pattern_ptr, pattern_len); if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; if (handler == nullptr) { uwsApp->patch(pattern, nullptr); return; } uwsApp->patch(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; if (handler == nullptr) { uwsApp->patch(pattern, nullptr); return; } uwsApp->patch(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } } void uws_app_put(int ssl, uws_app_t *app, const char *pattern_ptr, size_t pattern_len, uws_method_handler handler, void *user_data) { std::string_view pattern = std::string_view(pattern_ptr, pattern_len); if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; if (handler == nullptr) { uwsApp->put(pattern, nullptr); return; } uwsApp->put(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; if (handler == nullptr) { uwsApp->put(pattern, nullptr); return; } uwsApp->put(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } } void uws_app_head(int ssl, uws_app_t *app, const char *pattern_ptr, size_t pattern_len, uws_method_handler handler, void *user_data) { std::string_view pattern = std::string_view(pattern_ptr, pattern_len); if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; if (handler == nullptr) { uwsApp->head(pattern, nullptr); return; } uwsApp->head(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; if (handler == nullptr) { uwsApp->head(pattern, nullptr); return; } uwsApp->head(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } } void uws_app_connect(int ssl, uws_app_t *app, const char *pattern_ptr, size_t pattern_len, uws_method_handler handler, void *user_data) { std::string_view pattern = std::string_view(pattern_ptr, pattern_len); if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; if (handler == nullptr) { uwsApp->connect(pattern, nullptr); return; } uwsApp->connect(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; if (handler == nullptr) { uwsApp->connect(pattern, nullptr); return; } uwsApp->connect(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } } void uws_app_trace(int ssl, uws_app_t *app, const char *pattern_ptr, size_t pattern_len, uws_method_handler handler, void *user_data) { std::string_view pattern = std::string_view(pattern_ptr, pattern_len); if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; if (handler == nullptr) { uwsApp->trace(pattern, nullptr); return; } uwsApp->trace(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; if (handler == nullptr) { uwsApp->trace(pattern, nullptr); return; } uwsApp->trace(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } } size_t uws_res_get_buffered_amount(int ssl, uws_res_t *res) nonnull_fn_decl; size_t uws_res_get_buffered_amount(int ssl, uws_res_t *res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; return uwsRes->getBufferedAmount(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; return uwsRes->getBufferedAmount(); } } void uws_app_any(int ssl, uws_app_t *app, const char *pattern_ptr, size_t pattern_len, uws_method_handler handler, void *user_data) { std::string_view pattern = std::string_view(pattern_ptr, pattern_len); if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; if (handler == nullptr) { uwsApp->any(pattern, nullptr); return; } uwsApp->any(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; if (handler == nullptr) { uwsApp->any(pattern, nullptr); return; } uwsApp->any(pattern, [handler, user_data](auto *res, auto *req) { handler((uws_res_t *)res, (uws_req_t *)req, user_data); }); } } void uws_app_run(int ssl, uws_app_t *app) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->run(); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->run(); } } void uws_app_close(int ssl, uws_app_t *app) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->close(); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->close(); } } void uws_app_close_idle(int ssl, uws_app_t *app) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->closeIdle(); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->closeIdle(); } } void uws_app_set_on_clienterror(int ssl, uws_app_t *app, void (*handler)(void *user_data, int is_ssl, struct us_socket_t *rawSocket, uint8_t errorCode, char *rawPacket, int rawPacketLength), void *user_data) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; if (handler == nullptr) { uwsApp->setOnClientError(nullptr); return; } uwsApp->setOnClientError([handler, user_data](int is_ssl, struct us_socket_t *rawSocket, uint8_t errorCode, char *rawPacket, int rawPacketLength) { handler(user_data, is_ssl, rawSocket, errorCode, rawPacket, rawPacketLength); }); } else { uWS::App *uwsApp = (uWS::App *)app; if (handler == nullptr) { uwsApp->setOnClientError(nullptr); return; } uwsApp->setOnClientError([handler, user_data](int is_ssl, struct us_socket_t *rawSocket, uint8_t errorCode, char *rawPacket, int rawPacketLength) { handler(user_data, is_ssl, rawSocket, errorCode, rawPacket, rawPacketLength); }); } } void uws_app_listen(int ssl, uws_app_t *app, int port, uws_listen_handler handler, void *user_data) { uws_app_listen_config_t config; config.port = port; config.host = nullptr; config.options = 0; if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->listen(port, [handler, user_data](struct us_listen_socket_t *listen_socket) { handler((struct us_listen_socket_t *)listen_socket, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->listen(port, [handler, user_data](struct us_listen_socket_t *listen_socket) { handler((struct us_listen_socket_t *)listen_socket, 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) { std::string hostname = host && host[0] ? std::string(host, strlen(host)) : ""; if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->listen( hostname, port, options, [handler, user_data](struct us_listen_socket_t *listen_socket) { handler((struct us_listen_socket_t *)listen_socket, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->listen( hostname, port, options, [handler, user_data](struct us_listen_socket_t *listen_socket) { handler((struct us_listen_socket_t *)listen_socket, user_data); }); } } /* callback, path to unix domain socket */ 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) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->listen(0,[handler, domain, user_data](struct us_listen_socket_t *listen_socket) { handler((struct us_listen_socket_t *)listen_socket, domain, 0, user_data); }, {domain, pathlen}); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->listen(0, [handler, domain, user_data](struct us_listen_socket_t *listen_socket) { handler((struct us_listen_socket_t *)listen_socket, domain, 0, user_data); }, {domain, pathlen}); } } /* callback, path to unix domain socket */ 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) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->listen( options, [handler, domain, options, user_data](struct us_listen_socket_t *listen_socket) { handler((struct us_listen_socket_t *)listen_socket, domain, options, user_data); }, {domain, pathlen}); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->listen( options, [handler, domain, options, user_data](struct us_listen_socket_t *listen_socket) { handler((struct us_listen_socket_t *)listen_socket, domain, options, user_data); }, {domain, pathlen}); } } void uws_app_domain(int ssl, uws_app_t *app, const char *server_name) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->domain(server_name); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->domain(server_name); } } void uws_app_set_max_http_header_size(int ssl, uws_app_t *app, uint64_t max_header_size) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->setMaxHTTPHeaderSize(max_header_size); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->setMaxHTTPHeaderSize(max_header_size); } } void uws_app_set_flags(int ssl, uws_app_t *app, bool require_host_header, bool use_strict_method_validation) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->setFlags(require_host_header, use_strict_method_validation); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->setFlags(require_host_header, use_strict_method_validation); } } void uws_app_destroy(int ssl, uws_app_t *app) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; delete uwsApp; } else { uWS::App *uwsApp = (uWS::App *)app; delete uwsApp; } } bool uws_constructor_failed(int ssl, uws_app_t *app) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; if (!uwsApp) return true; return uwsApp->constructorFailed(); } uWS::App *uwsApp = (uWS::App *)app; if (!uwsApp) return true; return uwsApp->constructorFailed(); } unsigned int uws_num_subscribers(int ssl, uws_app_t *app, const char *topic, size_t topic_length) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; return uwsApp->numSubscribers(stringViewFromC(topic, topic_length)); } uWS::App *uwsApp = (uWS::App *)app; return uwsApp->numSubscribers(stringViewFromC(topic, 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) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; return uwsApp->publish(stringViewFromC(topic, topic_length), stringViewFromC(message, message_length), (uWS::OpCode)(unsigned char)opcode, compress); } uWS::App *uwsApp = (uWS::App *)app; return uwsApp->publish(stringViewFromC(topic, topic_length), stringViewFromC(message, message_length), (uWS::OpCode)(unsigned char)opcode, compress); } void *uws_get_native_handle(int ssl, uws_app_t *app) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; return uwsApp->getNativeHandle(); } uWS::App *uwsApp = (uWS::App *)app; return uwsApp->getNativeHandle(); } void uws_remove_server_name(int ssl, uws_app_t *app, const char *hostname_pattern) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->removeServerName(hostname_pattern); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->removeServerName(hostname_pattern); } } void uws_add_server_name(int ssl, uws_app_t *app, const char *hostname_pattern) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->addServerName(hostname_pattern); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->addServerName(hostname_pattern); } } int uws_add_server_name_with_options( int ssl, uws_app_t *app, const char *hostname_pattern, struct us_bun_socket_context_options_t options) { uWS::SocketContextOptions sco; memcpy(&sco, &options, sizeof(uWS::SocketContextOptions)); bool success = false; if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->addServerName(hostname_pattern, sco, &success); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->addServerName(hostname_pattern, sco, &success); } return !success; } void uws_missing_server_name(int ssl, uws_app_t *app, uws_missing_server_handler handler, void *user_data) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->missingServerName( [handler, user_data](auto hostname) { handler(hostname, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->missingServerName( [handler, user_data](auto hostname) { handler(hostname, user_data); }); } } void uws_filter(int ssl, uws_app_t *app, uws_filter_handler handler, void *user_data) { if (ssl) { uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->filter([handler, user_data](auto res, auto i) { handler((uws_res_t *)res, i, user_data); }); } else { uWS::App *uwsApp = (uWS::App *)app; uwsApp->filter([handler, user_data](auto res, auto i) { handler((uws_res_t *)res, i, user_data); }); } } void uws_ws(int ssl, uws_app_t *app, void *upgradeContext, const char *pattern, size_t pattern_length, size_t id, const uws_socket_behavior_t *behavior_) { uws_socket_behavior_t behavior = *behavior_; if (ssl) { auto generic_handler = uWS::SSLApp::WebSocketBehavior{ .compression = (uWS::CompressOptions)(uint64_t)behavior.compression, .maxPayloadLength = behavior.maxPayloadLength, .idleTimeout = behavior.idleTimeout, .maxBackpressure = behavior.maxBackpressure, .closeOnBackpressureLimit = behavior.closeOnBackpressureLimit, .resetIdleTimeoutOnSend = behavior.resetIdleTimeoutOnSend, .sendPingsAutomatically = behavior.sendPingsAutomatically, .maxLifetime = behavior.maxLifetime, }; if (behavior.upgrade) generic_handler.upgrade = [behavior, upgradeContext, id](auto *res, auto *req, auto *context) { behavior.upgrade(upgradeContext, (uws_res_t *)res, (uws_req_t *)req, (uws_socket_context_t *)context, id); }; if (behavior.open) generic_handler.open = [behavior](auto *ws) { behavior.open((uws_websocket_t *)ws); }; if (behavior.message) generic_handler.message = [behavior](auto *ws, auto message, auto opcode) { behavior.message((uws_websocket_t *)ws, message.data(), message.length(), (uws_opcode_t)opcode); }; if (behavior.drain) generic_handler.drain = [behavior](auto *ws) { behavior.drain((uws_websocket_t *)ws); }; if (behavior.ping) generic_handler.ping = [behavior](auto *ws, auto message) { behavior.ping((uws_websocket_t *)ws, message.data(), message.length()); }; if (behavior.pong) generic_handler.pong = [behavior](auto *ws, auto message) { behavior.pong((uws_websocket_t *)ws, message.data(), message.length()); }; if (behavior.close) generic_handler.close = [behavior](auto *ws, int code, auto message) { behavior.close((uws_websocket_t *)ws, code, message.data(), message.length()); }; uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; uwsApp->ws(std::string(pattern, pattern_length), std::move(generic_handler)); } else { auto generic_handler = uWS::App::WebSocketBehavior{ .compression = (uWS::CompressOptions)(uint64_t)behavior.compression, .maxPayloadLength = behavior.maxPayloadLength, .idleTimeout = behavior.idleTimeout, .maxBackpressure = behavior.maxBackpressure, .closeOnBackpressureLimit = behavior.closeOnBackpressureLimit, .resetIdleTimeoutOnSend = behavior.resetIdleTimeoutOnSend, .sendPingsAutomatically = behavior.sendPingsAutomatically, .maxLifetime = behavior.maxLifetime, }; if (behavior.upgrade) generic_handler.upgrade = [behavior, upgradeContext, id](auto *res, auto *req, auto *context) { behavior.upgrade(upgradeContext, (uws_res_t *)res, (uws_req_t *)req, (uws_socket_context_t *)context, id); }; if (behavior.open) generic_handler.open = [behavior](auto *ws) { behavior.open((uws_websocket_t *)ws); }; if (behavior.message) generic_handler.message = [behavior](auto *ws, auto message, auto opcode) { behavior.message((uws_websocket_t *)ws, message.data(), message.length(), (uws_opcode_t)opcode); }; if (behavior.drain) generic_handler.drain = [behavior](auto *ws) { behavior.drain((uws_websocket_t *)ws); }; if (behavior.ping) generic_handler.ping = [behavior](auto *ws, auto message) { behavior.ping((uws_websocket_t *)ws, message.data(), message.length()); }; if (behavior.pong) generic_handler.pong = [behavior](auto *ws, auto message) { behavior.pong((uws_websocket_t *)ws, message.data(), message.length()); }; if (behavior.close) generic_handler.close = [behavior](auto *ws, int code, auto message) { behavior.close((uws_websocket_t *)ws, code, message.data(), message.length()); }; uWS::App *uwsApp = (uWS::App *)app; uwsApp->ws(std::string(pattern, pattern_length), std::move(generic_handler)); } } void *uws_ws_get_user_data(int ssl, uws_websocket_t *ws) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return *uws->getUserData(); } TCPWebSocket *uws = (TCPWebSocket *)ws; return *uws->getUserData(); } void uws_ws_close(int ssl, uws_websocket_t *ws) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; uws->close(); } else { TCPWebSocket *uws = (TCPWebSocket *)ws; uws->close(); } } uws_sendstatus_t uws_ws_send(int ssl, uws_websocket_t *ws, const char *message, size_t length, uws_opcode_t opcode) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return (uws_sendstatus_t)uws->send(stringViewFromC(message, length), (uWS::OpCode)(unsigned char)opcode); } TCPWebSocket *uws = (TCPWebSocket *)ws; return (uws_sendstatus_t)uws->send(stringViewFromC(message, length), (uWS::OpCode)(unsigned char)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) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return (uws_sendstatus_t)uws->send(stringViewFromC(message, length), (uWS::OpCode)(unsigned char)opcode, compress, fin); } else { TCPWebSocket *uws = (TCPWebSocket *)ws; return (uws_sendstatus_t)uws->send(stringViewFromC(message, length), (uWS::OpCode)(unsigned char)opcode, compress, fin); } } uws_sendstatus_t uws_ws_send_fragment(int ssl, uws_websocket_t *ws, const char *message, size_t length, bool compress) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return (uws_sendstatus_t)uws->sendFragment( stringViewFromC(message, length), compress); } TCPWebSocket *uws = (TCPWebSocket *)ws; return (uws_sendstatus_t)uws->sendFragment(stringViewFromC(message, length), compress); } uws_sendstatus_t uws_ws_send_first_fragment(int ssl, uws_websocket_t *ws, const char *message, size_t length, bool compress) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return (uws_sendstatus_t)uws->sendFirstFragment( stringViewFromC(message, length), uWS::OpCode::BINARY, compress); } TCPWebSocket *uws = (TCPWebSocket *)ws; return (uws_sendstatus_t)uws->sendFirstFragment( stringViewFromC(message, length), uWS::OpCode::BINARY, 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) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return (uws_sendstatus_t)uws->sendFirstFragment( stringViewFromC(message, length), (uWS::OpCode)(unsigned char)opcode, compress); } TCPWebSocket *uws = (TCPWebSocket *)ws; return (uws_sendstatus_t)uws->sendFirstFragment( stringViewFromC(message, length), (uWS::OpCode)(unsigned char)opcode, compress); } uws_sendstatus_t uws_ws_send_last_fragment(int ssl, uws_websocket_t *ws, const char *message, size_t length, bool compress) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return (uws_sendstatus_t)uws->sendLastFragment( stringViewFromC(message, length), compress); } TCPWebSocket *uws = (TCPWebSocket *)ws; return (uws_sendstatus_t)uws->sendLastFragment( stringViewFromC(message, length), compress); } void uws_ws_end(int ssl, uws_websocket_t *ws, int code, const char *message, size_t length) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; uws->end(code, stringViewFromC(message, length)); } else { TCPWebSocket *uws = (TCPWebSocket *)ws; uws->end(code, stringViewFromC(message, length)); } } void uws_ws_cork(int ssl, uws_websocket_t *ws, void (*handler)(void *user_data), void *user_data) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; uws->cork([handler, user_data]() { handler(user_data); }); } else { TCPWebSocket *uws = (TCPWebSocket *)ws; uws->cork([handler, user_data]() { handler(user_data); }); } } bool uws_ws_subscribe(int ssl, uws_websocket_t *ws, const char *topic, size_t length) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return uws->subscribe(stringViewFromC(topic, length)); } TCPWebSocket *uws = (TCPWebSocket *)ws; return uws->subscribe(stringViewFromC(topic, length)); } bool uws_ws_unsubscribe(int ssl, uws_websocket_t *ws, const char *topic, size_t length) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return uws->unsubscribe(stringViewFromC(topic, length)); } TCPWebSocket *uws = (TCPWebSocket *)ws; return uws->unsubscribe(stringViewFromC(topic, length)); } bool uws_ws_is_subscribed(int ssl, uws_websocket_t *ws, const char *topic, size_t length) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return uws->isSubscribed(stringViewFromC(topic, length)); } TCPWebSocket *uws = (TCPWebSocket *)ws; return uws->isSubscribed(stringViewFromC(topic, 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) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; uws->iterateTopics([callback, user_data](auto topic) { callback(topic.data(), topic.length(), user_data); }); } else { TCPWebSocket *uws = (TCPWebSocket *)ws; uws->iterateTopics([callback, user_data](auto topic) { callback(topic.data(), topic.length(), 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) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return uws->publish(stringViewFromC(topic, topic_length), stringViewFromC(message, message_length)); } TCPWebSocket *uws = (TCPWebSocket *)ws; return uws->publish(stringViewFromC(topic, topic_length), stringViewFromC(message, 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) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return uws->publish(stringViewFromC(topic, topic_length), stringViewFromC(message, message_length), (uWS::OpCode)(unsigned char)opcode, compress); } TCPWebSocket *uws = (TCPWebSocket *)ws; return uws->publish(stringViewFromC(topic, topic_length), stringViewFromC(message, message_length), (uWS::OpCode)(unsigned char)opcode, compress); } size_t uws_ws_get_buffered_amount(int ssl, uws_websocket_t *ws) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; return uws->getBufferedAmount(); } TCPWebSocket *uws = (TCPWebSocket *)ws; return uws->getBufferedAmount(); } size_t uws_ws_get_remote_address(int ssl, uws_websocket_t *ws, const char **dest) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; std::string_view value = uws->getRemoteAddress(); *dest = value.data(); return value.length(); } TCPWebSocket *uws = (TCPWebSocket *)ws; std::string_view value = uws->getRemoteAddress(); *dest = value.data(); return value.length(); } size_t uws_ws_get_remote_address_as_text(int ssl, uws_websocket_t *ws, const char **dest) { if (ssl) { TLSWebSocket *uws = (TLSWebSocket *)ws; std::string_view value = uws->getRemoteAddressAsText(); *dest = value.data(); return value.length(); } TCPWebSocket *uws = (TCPWebSocket *)ws; std::string_view value = uws->getRemoteAddressAsText(); *dest = value.data(); return value.length(); } void uws_res_end(int ssl, uws_res_r res, const char *data, size_t length, bool close_connection) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->clearOnWritableAndAborted(); uwsRes->end(stringViewFromC(data, length), close_connection); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->clearOnWritableAndAborted(); uwsRes->end(stringViewFromC(data, length), close_connection); } } void uws_res_end_stream(int ssl, uws_res_r res, bool close_connection) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->clearOnWritableAndAborted(); uwsRes->sendTerminatingChunk(close_connection); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->clearOnWritableAndAborted(); uwsRes->sendTerminatingChunk(close_connection); } } void uws_res_pause(int ssl, uws_res_r res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->pause(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->pause(); } } void uws_res_resume(int ssl, uws_res_r res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->resume(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->resume(); } } void uws_res_write_continue(int ssl, uws_res_r res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->writeContinue(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->writeContinue(); } } void uws_res_write_status(int ssl, uws_res_r res, const char *status, size_t length) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->writeStatus(stringViewFromC(status, length)); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->writeStatus(stringViewFromC(status, length)); } } void uws_res_mark_wrote_content_length_header(int ssl, uws_res_r res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->getHttpResponseData()->state |= uWS::HttpResponseData::HTTP_WROTE_CONTENT_LENGTH_HEADER; } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->getHttpResponseData()->state |= uWS::HttpResponseData::HTTP_WROTE_CONTENT_LENGTH_HEADER; } } void uws_res_write_mark(int ssl, uws_res_r res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->writeMark(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->writeMark(); } } 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) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->writeHeader(stringViewFromC(key, key_length), stringViewFromC(value, value_length)); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->writeHeader(stringViewFromC(key, key_length), stringViewFromC(value, value_length)); } } void uws_res_write_header_int(int ssl, uws_res_r res, const char *key, size_t key_length, uint64_t value) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->writeHeader(stringViewFromC(key, key_length), value); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->writeHeader(stringViewFromC(key, key_length), value); } } void uws_res_end_sendfile(int ssl, uws_res_r res, uint64_t offset, bool close_connection) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto *data = uwsRes->getHttpResponseData(); data->offset = offset; data->state |= uWS::HttpResponseData::HTTP_END_CALLED; data->markDone(uwsRes); uwsRes->resetTimeout(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto *data = uwsRes->getHttpResponseData(); data->offset = offset; data->state |= uWS::HttpResponseData::HTTP_END_CALLED; data->markDone(uwsRes); uwsRes->resetTimeout(); } } void uws_res_reset_timeout(int ssl, uws_res_r res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->resetTimeout(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->resetTimeout(); } } void uws_res_timeout(int ssl, uws_res_r res, uint8_t seconds) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->setTimeout(seconds); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->setTimeout(seconds); } } void uws_res_end_without_body(int ssl, uws_res_r res, bool close_connection) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto *data = uwsRes->getHttpResponseData(); if (close_connection) { if (!(data->state & uWS::HttpResponseData::HTTP_CONNECTION_CLOSE)) { uwsRes->writeHeader("Connection", "close"); } data->state |= uWS::HttpResponseData::HTTP_CONNECTION_CLOSE; } if (!(data->state & uWS::HttpResponseData::HTTP_END_CALLED)) { uwsRes->AsyncSocket::write("\r\n", 2); } data->state |= uWS::HttpResponseData::HTTP_END_CALLED; data->markDone(uwsRes); uwsRes->resetTimeout(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto *data = uwsRes->getHttpResponseData(); if (close_connection) { if (!(data->state & uWS::HttpResponseData::HTTP_CONNECTION_CLOSE)) { uwsRes->writeHeader("Connection", "close"); } data->state |= uWS::HttpResponseData::HTTP_CONNECTION_CLOSE; } if (!(data->state & uWS::HttpResponseData::HTTP_END_CALLED)) { // Some HTTP clients require the complete "
\r\n\r\n" to be sent. // If not, they may throw a ConnectionError. uwsRes->AsyncSocket::write("\r\n", 2); } data->state |= uWS::HttpResponseData::HTTP_END_CALLED; data->markDone(uwsRes); uwsRes->resetTimeout(); } } 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) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; if (*length < 16 * 1024 && *length > 0) { if (uwsRes->canCork()) { uwsRes->uWS::AsyncSocket::cork(); } } return uwsRes->write(stringViewFromC(data, *length), length); } uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; if (*length < 16 * 1024 && *length > 0) { if (uwsRes->canCork()) { uwsRes->uWS::AsyncSocket::cork(); } } return uwsRes->write(stringViewFromC(data, *length), length); } 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) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; return uwsRes->getWriteOffset(); } uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; return uwsRes->getWriteOffset(); } 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) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; return uwsRes->hasResponded(); } uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; return uwsRes->hasResponded(); } void uws_res_on_writable(int ssl, uws_res_r res, bool (*handler)(uws_res_r res, uint64_t, void *optional_data), void *optional_data) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto onWritable = reinterpret_cast*, uint64_t, void*)>(handler); uwsRes->onWritable(optional_data, onWritable); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto onWritable = reinterpret_cast*, uint64_t, void*)>(handler); uwsRes->onWritable(optional_data, onWritable); } } void uws_res_clear_on_writable(int ssl, uws_res_r res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->clearOnWritable(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->clearOnWritable(); } } void uws_res_on_aborted(int ssl, uws_res_r res, void (*handler)(uws_res_r res, void *optional_data), void *optional_data) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto* onAborted = reinterpret_cast*, void*)>(handler); if (handler) { uwsRes->onAborted(optional_data, onAborted); } else { uwsRes->clearOnAborted(); } } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto* onAborted = reinterpret_cast*, void*)>(handler); if (handler) { uwsRes->onAborted(optional_data, onAborted); } else { uwsRes->clearOnAborted(); } } } void uws_res_on_timeout(int ssl, uws_res_r res, void (*handler)(uws_res_r res, void *optional_data), void *optional_data) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto* onTimeout = reinterpret_cast*, void*)>(handler); if (handler) { uwsRes->onTimeout(optional_data, onTimeout); } else { uwsRes->clearOnTimeout(); } } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto* onTimeout = reinterpret_cast*, void*)>(handler); if (handler) { uwsRes->onTimeout(optional_data, onTimeout); } else { uwsRes->clearOnTimeout(); } } } 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 *optional_data), void *optional_data) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto onData = reinterpret_cast* response, const char* chunk, size_t chunk_length, bool, void*)>(handler); if (handler) { uwsRes->onData(optional_data, onData); } else { uwsRes->onData(optional_data, nullptr); } } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto onData = reinterpret_cast* response, const char* chunk, size_t chunk_length, bool, void*)>(handler); if (handler) { uwsRes->onData(optional_data, onData); } else { uwsRes->onData(optional_data, nullptr); } } } bool uws_req_is_ancient(uws_req_t *res) { uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; return uwsReq->isAncient(); } bool uws_req_get_yield(uws_req_t *res) { uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; return uwsReq->getYield(); } void uws_req_set_yield(uws_req_t *res, bool yield) { uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; return uwsReq->setYield(yield); } size_t uws_req_get_url(uws_req_t *res, const char **dest) { uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; std::string_view value = uwsReq->getFullUrl(); *dest = value.data(); return value.length(); } size_t uws_req_get_method(uws_req_t *res, const char **dest) { uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; std::string_view value = uwsReq->getMethod(); *dest = value.data(); 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) { uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; std::string_view value = uwsReq->getHeader( stringViewFromC(lower_case_header, lower_case_header_length)); *dest = value.data(); return value.length(); } void uws_req_for_each_header(uws_req_t *res, uws_get_headers_server_handler handler, void *user_data) { uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; for (auto header : *uwsReq) { handler(header.first.data(), header.first.length(), header.second.data(), header.second.length(), user_data); } } size_t uws_req_get_query(uws_req_t *res, const char *key, size_t key_length, const char **dest) { uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; std::string_view value = uwsReq->getQuery(stringViewFromC(key, key_length)); *dest = value.data(); return value.length(); } size_t uws_req_get_parameter(uws_req_t *res, unsigned short index, const char **dest) { uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; std::string_view value = uwsReq->getParameter(index); *dest = value.data(); return value.length(); } us_socket_t *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, 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) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; return uwsRes->template upgrade( data ? std::move(data) : NULL, stringViewFromC(sec_web_socket_key, sec_web_socket_key_length), stringViewFromC(sec_web_socket_protocol, sec_web_socket_protocol_length), stringViewFromC(sec_web_socket_extensions, sec_web_socket_extensions_length), (struct us_socket_context_t *)ws); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; return uwsRes->template upgrade( data ? std::move(data) : NULL, stringViewFromC(sec_web_socket_key, sec_web_socket_key_length), stringViewFromC(sec_web_socket_protocol, sec_web_socket_protocol_length), stringViewFromC(sec_web_socket_extensions, sec_web_socket_extensions_length), (struct us_socket_context_t *)ws); } } struct us_loop_t *uws_get_loop() { return (struct us_loop_t *)uWS::Loop::get(); } struct us_loop_t *uws_get_loop_with_native(void *existing_native_loop) { return (struct us_loop_t *)uWS::Loop::get(existing_native_loop); } void uws_loop_addPostHandler(us_loop_t *loop, void *ctx_, void (*cb)(void *ctx, us_loop_t *loop)) { uWS::Loop *uwsLoop = (uWS::Loop *)loop; uwsLoop->addPostHandler(ctx_, [ctx_, cb](uWS::Loop *uwsLoop_) { cb(ctx_, (us_loop_t *)uwsLoop_); }); } void uws_loop_removePostHandler(us_loop_t *loop, void *key) { uWS::Loop *uwsLoop = (uWS::Loop *)loop; uwsLoop->removePostHandler(key); } void uws_loop_addPreHandler(us_loop_t *loop, void *ctx_, void (*cb)(void *ctx, us_loop_t *loop)) { uWS::Loop *uwsLoop = (uWS::Loop *)loop; uwsLoop->addPreHandler(ctx_, [ctx_, cb](uWS::Loop *uwsLoop_) { cb(ctx_, (us_loop_t *)uwsLoop_); }); } void uws_loop_removePreHandler(us_loop_t *loop, void *ctx_) { uWS::Loop *uwsLoop = (uWS::Loop *)loop; uwsLoop->removePreHandler(ctx_); } void uws_loop_defer(us_loop_t *loop, void *ctx, void (*cb)(void *ctx)) { uWS::Loop *uwsLoop = (uWS::Loop *)loop; uwsLoop->defer([ctx, cb]() { cb(ctx); }); } void uws_res_uncork(int ssl, uws_res_r res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->uncork(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->uncork(); } } void us_socket_mark_needs_more_not_ssl(uws_res_r 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_r res, uint64_t offset) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->setWriteOffset(offset); //TODO: when updated to master this will bechanged to overrideWriteOffset } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->setWriteOffset(offset); //TODO: when updated to master this will bechanged to overrideWriteOffset } } __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) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->cork([ctx, corker]() { corker(ctx); }); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->cork([ctx, corker]() { corker(ctx); }); } } void uws_res_prepare_for_sendfile(int ssl, uws_res_r res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->writeMark(); auto pair = uwsRes->getSendBuffer(2); char *ptr = pair.first; ptr[0] = '\r'; ptr[1] = '\n'; uwsRes->uncork(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->writeMark(); auto pair = uwsRes->getSendBuffer(2); char *ptr = pair.first; ptr[0] = '\r'; ptr[1] = '\n'; uwsRes->uncork(); } } 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) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto pair = uwsRes->tryEnd(stringViewFromC(bytes, len), total_len, close); if (pair.first) { uwsRes->clearOnWritableAndAborted(); } return pair.first; } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; auto pair = uwsRes->tryEnd(stringViewFromC(bytes, len), total_len, close); if (pair.first) { uwsRes->clearOnWritableAndAborted(); } return pair.first; } } int uws_res_state(int ssl, uws_res_r res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; return uwsRes->getHttpResponseData()->state; } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; return uwsRes->getHttpResponseData()->state; } } void uws_res_flush_headers(int ssl, uws_res_r res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->flushHeaders(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; uwsRes->flushHeaders(); } } void *uws_res_get_native_handle(int ssl, uws_res_r res) { if (ssl) { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; return uwsRes->getNativeHandle(); } else { uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; return uwsRes->getNativeHandle(); } } size_t uws_ws_memory_cost(int ssl, uws_websocket_t *ws) { if (ssl) { return ((TLSWebSocket*)ws)->memoryCost(); } else { return ((TCPWebSocket*)ws)->memoryCost(); } } 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); } LIBUS_SOCKET_DESCRIPTOR us_socket_get_fd(us_socket_r s) { return us_poll_fd(&s->p); } // Gets the remote address and port // Returns 0 if failure / unix socket 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 // AsyncSocket::getRemoteAddress // AsyncSocket::addressAsText // To get { ip, port, is_ipv6 } for Bun.serve().requestIP() static thread_local char b[64]; auto length = us_get_remote_address_info(b, (us_socket_t *)res, dest, port, (int*)is_ipv6); if (length == 0) return 0; if (length == 4) { ares_inet_ntop(AF_INET, b, &b[4], 64 - 4); *dest = &b[4]; *is_ipv6 = false; return strlen(*dest); } else { ares_inet_ntop(AF_INET6, b, &b[16], 64 - 16); *dest = &b[16]; *is_ipv6 = true; return strlen(*dest); } } uint64_t uws_res_get_local_address_info(uws_res_r res, const char **dest, int *port, bool *is_ipv6) { static thread_local char b[64]; auto length = us_get_local_address_info(b, (us_socket_t *)res, dest, port, (int*)is_ipv6); if (length == 0) return 0; if (length == 4) { ares_inet_ntop(AF_INET, b, &b[4], 64 - 4); *dest = &b[4]; *is_ipv6 = false; return strlen(*dest); } else { ares_inet_ntop(AF_INET6, b, &b[16], 64 - 16); *dest = &b[16]; *is_ipv6 = true; return strlen(*dest); } } // we need to manually call this at thread exit extern "C" void bun_clear_loop_at_thread_exit() { uWS::Loop::clearLoopAtThreadExit(); } }