mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-29 08:19:42 +08:00
83 lines
2.8 KiB
C
83 lines
2.8 KiB
C
// Copyright (c) 2020 Cesanta Software Limited
|
|
// All rights reserved
|
|
|
|
#include "mjson.h" // JSON parsing and printing
|
|
#include "mongoose.h"
|
|
|
|
// This is a configuration structure we're going to show on a dashboard
|
|
static struct config {
|
|
int value1;
|
|
char *value2;
|
|
} s_config = {123, NULL};
|
|
|
|
// Stringifies the config. A caller must free() it.
|
|
static char *stringify_config(struct config *cfg) {
|
|
char *s = NULL;
|
|
mjson_printf(mjson_print_dynamic_buf, &s, "{%Q:%d,%Q:%Q}", "value1",
|
|
cfg->value1, "value2", cfg->value2);
|
|
return s;
|
|
}
|
|
|
|
// Update config structure. Return true if changed, false otherwise
|
|
static bool update_config(struct mg_http_message *hm, struct config *cfg) {
|
|
bool changed = false;
|
|
char buf[256];
|
|
double dv;
|
|
if (mjson_get_number(hm->body.ptr, hm->body.len, "$.value1", &dv)) {
|
|
s_config.value1 = dv;
|
|
changed = true;
|
|
}
|
|
if (mjson_get_string(hm->body.ptr, hm->body.len, "$.value2", buf,
|
|
sizeof(buf)) > 0) {
|
|
free(s_config.value2);
|
|
s_config.value2 = strdup(buf);
|
|
changed = true;
|
|
}
|
|
return changed;
|
|
}
|
|
|
|
// Notify all config watchers about the config change
|
|
static void notify_config_change(struct mg_mgr *mgr) {
|
|
struct mg_connection *c;
|
|
char *s = stringify_config(&s_config);
|
|
for (c = mgr->conns; c != NULL; c = c->next) {
|
|
if (c->label[0] == 'W') mg_http_printf_chunk(c, "%s\n", s);
|
|
}
|
|
free(s);
|
|
}
|
|
|
|
// HTTP request handler function. It implements the following endpoints:
|
|
// /api/config/get - returns current config
|
|
// /api/config/set - updates current config
|
|
// /api/config/watch - does not return. Sends config as it changes in
|
|
// chunks all other URI - serves web_root/ directory
|
|
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
if (ev == MG_EV_HTTP_MSG) {
|
|
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
if (mg_http_match_uri(hm, "/api/config/get")) {
|
|
char *s = stringify_config(&s_config);
|
|
mg_printf(c, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s\n",
|
|
(int) strlen(s) + 1, s);
|
|
free(s);
|
|
} else if (mg_http_match_uri(hm, "/api/config/set")) {
|
|
if (update_config(hm, &s_config)) notify_config_change(fn_data);
|
|
mg_printf(c, "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
|
|
} else if (mg_http_match_uri(hm, "/api/config/watch")) {
|
|
c->label[0] = 'W'; // Mark ourselves as a config watcher
|
|
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
|
} else {
|
|
struct mg_http_serve_opts opts = {.root_dir = "web_root"};
|
|
mg_http_serve_dir(c, ev_data, &opts);
|
|
}
|
|
}
|
|
}
|
|
|
|
int main(void) {
|
|
struct mg_mgr mgr;
|
|
mg_mgr_init(&mgr);
|
|
mg_http_listen(&mgr, "http://localhost:8000", cb, &mgr);
|
|
for (;;) mg_mgr_poll(&mgr, 1000);
|
|
mg_mgr_free(&mgr);
|
|
return 0;
|
|
}
|