runtime: http_set_handler self-registers via dlsym
El programs that define `fn handle_request(method, path, body) -> String`
can now use http_serve directly without C-level glue. http_set_handler
falls back to dlsym(RTLD_DEFAULT, name) when the named handler isn't
already in the registry, picks up the El-compiled symbol, and registers
it transparently.
Closes the gap that made http_serve unusable from pure El. Verified
with a real El server on :17890 — POST /hello with body returned
{"method":"POST","path":"/hello","echo":"test body"} via curl.
dist/platform/elc rebuilt; .prev3 preserved.
This commit is contained in:
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -27,6 +27,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <dlfcn.h> /* dlsym for http_set_handler fallback */
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
@@ -616,6 +617,24 @@ void http_set_handler(el_val_t name) {
|
||||
pthread_mutex_lock(&_http_handler_mu);
|
||||
free(_http_active_handler);
|
||||
_http_active_handler = el_strdup(n ? n : "");
|
||||
/* If the name is not yet in the registry, try dlsym lookup against
|
||||
* the running binary's symbol table. Every El `fn name(...)` compiles
|
||||
* to a global C symbol with that exact name, so El programs can self-
|
||||
* register their own handlers just by calling http_set_handler("name"). */
|
||||
if (n && *n) {
|
||||
int found = 0;
|
||||
for (size_t i = 0; i < _http_handler_count; i++) {
|
||||
if (strcmp(_http_handlers[i].name, n) == 0) { found = 1; break; }
|
||||
}
|
||||
if (!found) {
|
||||
void* sym = dlsym(RTLD_DEFAULT, n);
|
||||
if (sym && _http_handler_count < sizeof(_http_handlers) / sizeof(_http_handlers[0])) {
|
||||
_http_handlers[_http_handler_count].name = el_strdup(n);
|
||||
_http_handlers[_http_handler_count].fn = (http_handler_fn)sym;
|
||||
_http_handler_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&_http_handler_mu);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user