From 9a6f0defd12a416a48a63ae394fadd3a5f437b82 Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Sun, 10 May 2026 13:36:05 -0500 Subject: [PATCH] Fix http handler not found: pre-register via el_runtime_register_handler elb links without -rdynamic so dlsym(RTLD_DEFAULT, "handle_request") returns NULL at runtime. http_set_handler stores the name as active but never finds a function pointer, causing every request to return "el-runtime: no http handler registered" even after http_serve is called. Fix: add a __attribute__((constructor)) in web_stubs.c that calls el_runtime_register_handler("handle_request", handle_request) directly, bypassing dlsym entirely. The handler is in the registry before main() runs, so http_lookup_active() finds it on the first request. --- dist/web_stubs.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/dist/web_stubs.c b/dist/web_stubs.c index a5f70ec..a78c371 100644 --- a/dist/web_stubs.c +++ b/dist/web_stubs.c @@ -6,6 +6,31 @@ #include #include "el_runtime.h" +/* Pre-register the El HTTP handler so it is found by http_lookup_active() + * regardless of whether the binary was linked with -rdynamic. + * + * el_runtime's http_set_handler resolves handler names via: + * dlsym(RTLD_DEFAULT, "handle_request") + * but dlsym only searches the dynamic symbol table, which only contains + * user-defined symbols when the executable is linked with -rdynamic. + * elb does not add -rdynamic, so dlsym returns NULL and routes return + * "el-runtime: no http handler registered" even though http_serve is called. + * + * The fix: forward-declare handle_request here and register it directly + * via el_runtime_register_handler before main() runs. This populates the + * handler registry so http_lookup_active() finds it without needing dlsym. + */ +extern el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body); +/* el_runtime_register_handler is intentionally not declared in el_runtime.h + * ("extern lookup works since C symbols are global" — runtime comment). */ +extern void el_runtime_register_handler(const char* name, + el_val_t (*fn)(el_val_t, el_val_t, el_val_t)); + +__attribute__((constructor)) +static void pre_register_http_handlers(void) { + el_runtime_register_handler("handle_request", handle_request); +} + el_val_t http_get_auth(el_val_t url, el_val_t tok) { char bearer[2048]; snprintf(bearer, sizeof(bearer), "Bearer %s", EL_CSTR(tok)); el_val_t hdr_val = EL_STR(bearer); -- 2.52.0