Dash levels

This commit is contained in:
cpq committed 2026-05-20 07:05:28 +01:00
1 parent 5c3ffdb570
commit 1536b6a38b
5 files changed
+254 -51

No files matched your search

+31 -21
View File
@@ -29,19 +29,22 @@ static struct mg_str trimq(struct mg_str s) { // Trim double quotes
return s;
}
static void mg_dash_broadcast(struct mg_mgr *mgr, const char *fmt, ...) {
static void mg_dash_broadcast(struct mg_mgr *mgr, int level, const char *fmt,
...) {
struct mg_connection *c;
va_list ap;
for (c = mgr->conns; c != NULL; c = c->next) {
int user_level = *(int *) c->data;
if (!c->is_websocket) continue;
if (level > 0 && user_level < level) continue;
if (c->send.len > MG_DASH_MAX_SEND_BUF_SIZE) {
MG_ERROR(("%lu buffered data %lu > MG_DASH_MAX_SEND_BUF_SIZE, throttled",
c->id, c->send.len));
continue;
mg_error(c, "%lu buffered data %lu > MG_DASH_MAX_SEND_BUF_SIZE", c->id,
c->send.len);
} else {
va_start(ap, fmt);
mg_ws_vprintf(c, WEBSOCKET_OP_TEXT, fmt, &ap);
va_end(ap);
}
va_start(ap, fmt);
mg_ws_vprintf(c, WEBSOCKET_OP_TEXT, fmt, &ap);
va_end(ap);
}
}
@@ -125,6 +128,7 @@ static size_t mg_print_field_set(mg_pfn_t fn, void *arg, va_list *ap) {
static size_t mg_dash_print_name(mg_pfn_t fn, void *arg, va_list *ap) {
struct mg_dash *dash = va_arg(*ap, struct mg_dash *);
struct mg_str *name = va_arg(*ap, struct mg_str *);
int level = va_arg(*ap, int);
struct mg_field_set *set = mg_dash_find_field_set(dash, *name);
size_t n = 0;
if (name->len == 0) {
@@ -132,6 +136,7 @@ static size_t mg_dash_print_name(mg_pfn_t fn, void *arg, va_list *ap) {
const char *comma = "";
n += mg_xprintf(fn, arg, "{");
for (fs = dash->sets; fs != NULL; fs = fs->next) {
if (fs->read_level > 0 && level < fs->read_level) continue;
if (fs->reader) fs->reader();
n += mg_xprintf(fn, arg, comma);
n += mg_xprintf(fn, arg, "%m:", MG_ESC(fs->name));
@@ -139,7 +144,8 @@ static size_t mg_dash_print_name(mg_pfn_t fn, void *arg, va_list *ap) {
comma = ",";
}
n += mg_xprintf(fn, arg, "}");
} else if (set != NULL) {
} else if (set != NULL &&
(set->read_level <= 0 || level >= set->read_level)) {
if (set->reader) set->reader();
n += mg_xprintf(fn, arg, "%M", mg_print_field_set, set);
} else {
@@ -151,15 +157,16 @@ static size_t mg_dash_print_name(mg_pfn_t fn, void *arg, va_list *ap) {
static size_t mg_dash_print(mg_pfn_t fn, void *arg, va_list *ap) {
struct mg_str *req = va_arg(*ap, struct mg_str *);
struct mg_dash *dash = va_arg(*ap, struct mg_dash *);
int level = va_arg(*ap, int);
struct mg_str name = trimq(mg_json_get_tok(*req, "$.params"));
return mg_xprintf(fn, arg, "%M", mg_dash_print_name, dash, &name);
return mg_xprintf(fn, arg, "%M", mg_dash_print_name, dash, &name, level);
}
void mg_dash_send_change(struct mg_mgr *mgr, struct mg_field_set *set) {
if (set->reader) set->reader();
mg_dash_broadcast(mgr, "{%m:%m,%m:{%m:%M}}", MG_ESC("method"),
MG_ESC("change"), MG_ESC("params"), MG_ESC(set->name),
mg_print_field_set, set);
mg_dash_broadcast(mgr, set->read_level, "{%m:%m,%m:{%m:%M}}",
MG_ESC("method"), MG_ESC("change"), MG_ESC("params"),
MG_ESC(set->name), mg_print_field_set, set);
}
static int mg_dash_parse_field(struct mg_str json, struct mg_field *f) {
@@ -189,14 +196,14 @@ static int mg_dash_parse_field(struct mg_str json, struct mg_field *f) {
}
static int mg_dash_apply(struct mg_connection *c, struct mg_dash *dash,
struct mg_str json) {
struct mg_str json, int level) {
struct mg_str key, val;
size_t ofs = 0;
int total_count = 0;
while ((ofs = mg_json_next(json, ofs, &key, &val)) > 0) {
struct mg_field_set *set = mg_dash_find_field_set(dash, trimq(key));
int count = 0;
if (set != NULL) {
if (set != NULL && (set->write_level <= 0 || level >= set->write_level)) {
size_t i;
for (i = 0; set->fields[i].name != NULL; i++) {
if (mg_dash_parse_field(val, &set->fields[i])) count++;
@@ -206,7 +213,7 @@ static int mg_dash_apply(struct mg_connection *c, struct mg_dash *dash,
mg_dash_send_change(c->mgr, set);
total_count += count;
}
} else {
} else if (set == NULL) {
MG_ERROR(("UNKNOWN SET: [%.*s]", key.len, key.buf));
}
}
@@ -218,11 +225,12 @@ static void mg_dash_process_msg(struct mg_connection *c,
struct mg_dash *dash) {
struct mg_str req = wm->data;
struct mg_str method = trimq(mg_json_get_tok(req, "$.method"));
int level = *(int *) c->data;
if (mg_match(method, mg_str("get"), NULL)) {
mg_dash_success(c, req, "%M", mg_dash_print, &req, dash);
mg_dash_success(c, req, "%M", mg_dash_print, &req, dash, level);
} else if (mg_match(method, mg_str("set"), NULL)) {
struct mg_str params = trimq(mg_json_get_tok(req, "$.params"));
int count = mg_dash_apply(c, dash, params);
int count = mg_dash_apply(c, dash, params, level);
mg_dash_success(c, req, "%d", count);
} else {
mg_dash_error(c, req, "%s", "unknown method");
@@ -511,7 +519,8 @@ void mg_dash_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
c->is_resp = 0;
} else if (ev == MG_EV_HTTP_MSG && c->data[0] == '\0') {
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
// struct mg_dash_user *u = mg_dash_authenticate(hm, dash);
struct mg_dash_user *u = mg_dash_authenticate(hm, dash);
int level = u == NULL ? 0 : u->level;
struct mg_str parts[5];
memset(parts, 0, sizeof(parts));
@@ -522,6 +531,7 @@ void mg_dash_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
mg_ws_printf(c, WEBSOCKET_OP_TEXT, "{%m:%m}", MG_ESC("method"),
MG_ESC("logout"));
} else if (mg_match(hm->uri, mg_str("/api/websocket"), NULL)) {
*(int *) c->data = level;
mg_ws_upgrade(c, hm, NULL);
} else if (mg_match(hm->uri, mg_str("/fs/#"), NULL)) {
struct mg_str name = mg_dash_file_name(hm);
@@ -539,9 +549,9 @@ void mg_dash_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
} else if (mg_match(hm->uri, mg_str("/api/get/#"), parts) ||
mg_match(hm->uri, mg_str("/api/get"), NULL)) {
mg_http_reply(c, 200, MG_JSON_HEADERS, "%M\n", mg_dash_print_name, dash,
&parts[0]);
&parts[0], level);
} else if (mg_match(hm->uri, mg_str("/api/set"), NULL)) {
int count = mg_dash_apply(c, dash, hm->body);
int count = mg_dash_apply(c, dash, hm->body, level);
mg_http_reply(c, 200, MG_JSON_HEADERS, "%d\n", count);
} else if (mg_match(hm->uri, mg_str("/"), NULL)) {
struct mg_http_serve_opts opts;
@@ -565,7 +575,7 @@ void mg_dash_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
for (fs = dash->sets; fs != NULL; fs = fs->next) {
mg_dash_send_change(c->mgr, fs);
}
mg_dash_broadcast(c->mgr, "{%m:%m}", MG_ESC("method"), MG_ESC("ready"));
mg_dash_broadcast(c->mgr, 0, "{%m:%m}", MG_ESC("method"), MG_ESC("ready"));
} else if (ev == MG_EV_WS_MSG) {
// Add this to automatically handle "get" and "set" JSON-RPC calls
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;