mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-19 16:56:34 +00:00
Berry 'webserver.remove_route' to revert 'webserver.on' (#23452)
This commit is contained in:
parent
7ce3ba376c
commit
40bc108ba1
@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Provide serial upload port from VSC to PIO (#23436)
|
||||
- Berry support for `sortedmap` (#23441)
|
||||
- Berry `introspect.module` option to not cache module entry
|
||||
- Berry `webserver.remove_route` to revert `webserver.on`
|
||||
|
||||
### Breaking Changed
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
extern int w_webserver_member(bvm *vm);
|
||||
extern int w_webserver_on(bvm *vm);
|
||||
extern int w_webserver_remove_route(bvm *vm);
|
||||
extern int w_webserver_state(bvm *vm);
|
||||
|
||||
extern int w_webserver_check_privileged_access(bvm *vm);
|
||||
@ -95,11 +96,24 @@ static const berry_webserver_cb_t berry_callback_array[WEBSERVER_REQ_HANDLER_HOO
|
||||
// -1 if no more available
|
||||
berry_webserver_cb_t be_webserver_allocate_hook(bvm *vm, int32_t slot, bvalue *f) {
|
||||
if (slot < 0 || slot >= WEBSERVER_REQ_HANDLER_HOOK_MAX) return NULL; // invalid call, avoid a crash
|
||||
if (be_isgcobj(f)) {
|
||||
be_gc_fix_set(vm, f->v.gc, btrue); // mark the function as non-gc
|
||||
}
|
||||
be_webserver_cb_hooks[slot].vm = vm;
|
||||
be_webserver_cb_hooks[slot].f = *f;
|
||||
return berry_callback_array[slot];
|
||||
}
|
||||
|
||||
bbool be_webserver_deallocate_hook(bvm *vm, int32_t slot) {
|
||||
if (slot < 0 || slot >= WEBSERVER_REQ_HANDLER_HOOK_MAX) return bfalse; // invalid call, avoid a crash
|
||||
bvalue f = be_webserver_cb_hooks[slot].f;
|
||||
if (be_isgcobj(&f)) {
|
||||
be_gc_fix_set(vm, f.v.gc, bfalse); // remove the marker for non-gc
|
||||
}
|
||||
var_setnil(&be_webserver_cb_hooks[slot].f);
|
||||
return btrue;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* `be_webserver_cb_deinit`:
|
||||
* Clean any callback for this VM
|
||||
@ -144,6 +158,7 @@ module webserver (scope: global) {
|
||||
member, func(w_webserver_member)
|
||||
|
||||
on, func(w_webserver_on)
|
||||
remove_route, func(w_webserver_remove_route)
|
||||
state, func(w_webserver_state)
|
||||
|
||||
check_privileged_access, func(w_webserver_check_privileged_access)
|
||||
|
@ -646,6 +646,13 @@ void WebServer_on(const char * prefix, void (*func)(void), uint8_t method = HTTP
|
||||
#endif // ESP32
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
void WebServer_removeRoute(const char * prefix, uint8_t method = HTTP_ANY) {
|
||||
if (Webserver == nullptr) { return; }
|
||||
Webserver->removeRoute(prefix, (HTTPMethod) method);
|
||||
}
|
||||
#endif // ESP32
|
||||
|
||||
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
||||
|
||||
// Always listens to all interfaces, so we don't need an IP address anymore
|
||||
|
@ -78,7 +78,8 @@ static uint8_t be_webserver_method[WEBSERVER_REQ_HANDLER_HOOK_MAX];
|
||||
extern "C" {
|
||||
typedef void (*berry_webserver_cb_t)(void);
|
||||
extern berry_webserver_cb_t be_webserver_allocate_hook(bvm *vm, int32_t num, bvalue *f);
|
||||
// Berry: `webserver.on(prefix:string, callback:closure) -> nil`
|
||||
extern bbool be_webserver_deallocate_hook(bvm *vm, int32_t slot);
|
||||
// Berry: `webserver.on(prefix:string, callback:closure [, method:int]) -> nil`
|
||||
//
|
||||
// WARNING - this should be called only when receiving `web_add_handler` event.
|
||||
// If called before the WebServer is set up and Wifi on, it will crash.
|
||||
@ -119,9 +120,6 @@ extern "C" {
|
||||
// AddLog(LOG_LEVEL_INFO, ">>>: slot found = %i", slot);
|
||||
|
||||
bvalue *v = be_indexof(vm, 2);
|
||||
if (be_isgcobj(v)) {
|
||||
be_gc_fix_set(vm, v->v.gc, btrue); // mark the function as non-gc
|
||||
}
|
||||
berry_webserver_cb_t cb = be_webserver_allocate_hook(vm, slot, v);
|
||||
if (cb == NULL) { be_raise(vm, kInternalError, nullptr); }
|
||||
be_webserver_prefix[slot] = prefix;
|
||||
@ -133,6 +131,45 @@ extern "C" {
|
||||
be_raise(vm, kTypeError, nullptr);
|
||||
}
|
||||
|
||||
// Berry: `webserver.remove_handler(prefix:string [, method:int]) -> nil`
|
||||
//
|
||||
// Remove a handler already added with `webserver.on()`
|
||||
// Does nothing if the handler does not exist or was already removed
|
||||
//
|
||||
int32_t w_webserver_remove_route(struct bvm *vm);
|
||||
int32_t w_webserver_remove_route(struct bvm *vm) {
|
||||
int32_t argc = be_top(vm); // Get the number of arguments
|
||||
bbool good = bfalse;
|
||||
if (argc >= 1 && be_isstring(vm, 1) && (argc < 2 || be_isint(vm, 2)) ) { // optional second argument must be int
|
||||
uint8_t method = HTTP_ANY; // default method if not specified
|
||||
const char * prefix = be_tostring(vm, 1);
|
||||
if (argc >= 2) {
|
||||
method = be_toint(vm, 2);
|
||||
}
|
||||
|
||||
// find the slot that matches the prefix/method
|
||||
int32_t slot;
|
||||
for (slot = 0; slot < WEBSERVER_REQ_HANDLER_HOOK_MAX; slot++) {
|
||||
if (be_webserver_prefix[slot] == prefix && be_webserver_method[slot] == method) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (slot < WEBSERVER_REQ_HANDLER_HOOK_MAX) {
|
||||
// remove from handler
|
||||
WebServer_removeRoute(be_webserver_prefix[slot].c_str(), be_webserver_method[slot]);
|
||||
// mark slot as free
|
||||
be_webserver_prefix[slot] = "";
|
||||
// Deallocate cb slot
|
||||
be_webserver_deallocate_hook(vm, slot);
|
||||
good = btrue;
|
||||
}
|
||||
be_pushbool(vm, good);
|
||||
be_return(vm); // return, all good
|
||||
}
|
||||
be_raise(vm, kTypeError, nullptr);
|
||||
}
|
||||
|
||||
// Berry: `webserver.state() -> int`
|
||||
//
|
||||
int32_t w_webserver_state(struct bvm *vm);
|
||||
|
Loading…
x
Reference in New Issue
Block a user