diff --git a/mongoose.c b/mongoose.c index 223a4e4f..f34eb139 100644 --- a/mongoose.c +++ b/mongoose.c @@ -821,6 +821,7 @@ size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt, + struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) { struct mg_fd *fd = (struct mg_fd *) mg_calloc(1, sizeof(*fd)); if (fd != NULL) { @@ -1048,6 +1049,7 @@ struct mg_fs mg_fs_fat = {ff_stat, ff_list, ff_open, ff_close, ff_read, + struct packed_file { const char *data; size_t size; @@ -2676,6 +2678,7 @@ void mg_iobuf_free(struct mg_iobuf *io) { + static const char *escapeseq(int esc) { return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\""; } @@ -4096,7 +4099,7 @@ struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds, unsigned flags, void (*fn)(void *), void *arg) { struct mg_timer *t = (struct mg_timer *) mg_calloc(1, sizeof(*t)); if (t != NULL) { - flags |= MG_TIMER_AUTODELETE; // We have mg_calloc-ed it, so autodelete + flags |= MG_TIMER_AUTODELETE; // We have alloc'ed it, so autodelete mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg); } return t; @@ -7864,6 +7867,7 @@ void mg_queue_del(struct mg_queue *q, size_t len) { + void mg_rpc_add(struct mg_rpc **head, struct mg_str method, void (*fn)(struct mg_rpc_req *), void *fn_data) { struct mg_rpc *rpc = (struct mg_rpc *) mg_calloc(1, sizeof(*rpc)); @@ -9381,6 +9385,7 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) { + #ifndef MG_MAX_SSI_DEPTH #define MG_MAX_SSI_DEPTH 5 #endif @@ -9481,6 +9486,7 @@ void mg_http_serve_ssi(struct mg_connection *c, const char *root, #endif + struct mg_str mg_str_s(const char *s) { struct mg_str str = {(char *) s, s == NULL ? 0 : strlen(s)}; return str; @@ -9669,6 +9675,7 @@ bool mg_str_to_num(struct mg_str str, int base, void *val, size_t val_len) { + void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms, unsigned flags, void (*fn)(void *), void *arg) { t->period_ms = ms, t->expire = 0; @@ -13999,6 +14006,7 @@ void mg_tls_ctx_free(struct mg_mgr *mgr) { + #if MG_TLS == MG_TLS_MBED #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 @@ -14251,6 +14259,7 @@ void mg_tls_ctx_free(struct mg_mgr *mgr) { + #if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL static int tls_err_cb(const char *s, size_t len, void *c) { @@ -14540,6 +14549,7 @@ void mg_tls_ctx_free(struct mg_mgr *mgr) { + #if MG_TLS == MG_TLS_BUILTIN #define NS_INTERNAL static @@ -14859,6 +14869,48 @@ NS_INTERNAL BI_CTX *bi_initialize(void) { return ctx; } +#if 0 +/** + * @brief Close the bigint context and free any resources. + * + * Free up any used memory - a check is done if all objects were not + * properly freed. + * @param ctx [in] The bigint session context. + */ +NS_INTERNAL void bi_terminate(BI_CTX *ctx) { + bi_depermanent(ctx->bi_radix); + bi_free(ctx, ctx->bi_radix); + + if (ctx->active_count != 0) { +#ifdef CONFIG_SSL_FULL_MODE + printf("bi_terminate: there were %d un-freed bigints\n", ctx->active_count); +#endif + abort(); + } + + bi_clear_cache(ctx); + mg_free(ctx); +} + +/** + *@brief Clear the memory cache. + */ +NS_INTERNAL void bi_clear_cache(BI_CTX *ctx) { + bigint *p, *pn; + + if (ctx->free_list == NULL) return; + + for (p = ctx->free_list; p != NULL; p = pn) { + pn = p->next; + mg_free(p->comps); + mg_free(p); + } + + ctx->free_count = 0; + ctx->free_list = NULL; +} +#endif + /** * @brief Increment the number of references to this object. * It does not do a full copy. diff --git a/src/fs.c b/src/fs.c index 58b4b578..9d00c8e1 100644 --- a/src/fs.c +++ b/src/fs.c @@ -1,6 +1,7 @@ #include "fs.h" #include "printf.h" #include "str.h" +#include "util.h" struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) { struct mg_fd *fd = (struct mg_fd *) mg_calloc(1, sizeof(*fd)); diff --git a/src/fs_packed.c b/src/fs_packed.c index 7ce5b17e..bcb09fc7 100644 --- a/src/fs_packed.c +++ b/src/fs_packed.c @@ -1,6 +1,7 @@ #include "fs.h" #include "printf.h" #include "str.h" +#include "util.h" struct packed_file { const char *data; diff --git a/src/json.c b/src/json.c index 0c78fa33..bfcc0c88 100644 --- a/src/json.c +++ b/src/json.c @@ -1,6 +1,7 @@ #include "json.h" #include "base64.h" #include "fmt.h" +#include "util.h" static const char *escapeseq(int esc) { return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\""; diff --git a/src/net.c b/src/net.c index 84315989..c46212ff 100644 --- a/src/net.c +++ b/src/net.c @@ -219,7 +219,7 @@ struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds, unsigned flags, void (*fn)(void *), void *arg) { struct mg_timer *t = (struct mg_timer *) mg_calloc(1, sizeof(*t)); if (t != NULL) { - flags |= MG_TIMER_AUTODELETE; // We have mg_calloc-ed it, so autodelete + flags |= MG_TIMER_AUTODELETE; // We have alloc'ed it, so autodelete mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg); } return t; diff --git a/src/rpc.c b/src/rpc.c index 0e19ebb2..84b6c178 100644 --- a/src/rpc.c +++ b/src/rpc.c @@ -1,5 +1,6 @@ #include "rpc.h" #include "printf.h" +#include "util.h" void mg_rpc_add(struct mg_rpc **head, struct mg_str method, void (*fn)(struct mg_rpc_req *), void *fn_data) { diff --git a/src/ssi.c b/src/ssi.c index c5bd2cb5..5c2e11a1 100644 --- a/src/ssi.c +++ b/src/ssi.c @@ -1,6 +1,7 @@ #include "log.h" #include "printf.h" #include "ssi.h" +#include "util.h" #ifndef MG_MAX_SSI_DEPTH #define MG_MAX_SSI_DEPTH 5 diff --git a/src/str.c b/src/str.c index fc8f715f..75e5cd38 100644 --- a/src/str.c +++ b/src/str.c @@ -1,4 +1,5 @@ #include "str.h" +#include "util.h" struct mg_str mg_str_s(const char *s) { struct mg_str str = {(char *) s, s == NULL ? 0 : strlen(s)}; diff --git a/src/timer.c b/src/timer.c index 8253452a..6649c651 100644 --- a/src/timer.c +++ b/src/timer.c @@ -1,5 +1,6 @@ #include "arch.h" #include "timer.h" +#include "util.h" void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms, unsigned flags, void (*fn)(void *), void *arg) { diff --git a/src/tls_mbed.c b/src/tls_mbed.c index 566010a5..707fdb31 100644 --- a/src/tls_mbed.c +++ b/src/tls_mbed.c @@ -2,6 +2,7 @@ #include "printf.h" #include "profile.h" #include "tls.h" +#include "util.h" #if MG_TLS == MG_TLS_MBED diff --git a/src/tls_openssl.c b/src/tls_openssl.c index 33b8e0ae..37838d95 100644 --- a/src/tls_openssl.c +++ b/src/tls_openssl.c @@ -1,5 +1,6 @@ #include "printf.h" #include "tls.h" +#include "util.h" #if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL diff --git a/src/tls_rsa.c b/src/tls_rsa.c index 7122dd6a..5543549a 100644 --- a/src/tls_rsa.c +++ b/src/tls_rsa.c @@ -1,5 +1,6 @@ #include "tls.h" #include "tls_rsa.h" +#include "util.h" #if MG_TLS == MG_TLS_BUILTIN @@ -320,6 +321,48 @@ NS_INTERNAL BI_CTX *bi_initialize(void) { return ctx; } +#if 0 +/** + * @brief Close the bigint context and free any resources. + * + * Free up any used memory - a check is done if all objects were not + * properly freed. + * @param ctx [in] The bigint session context. + */ +NS_INTERNAL void bi_terminate(BI_CTX *ctx) { + bi_depermanent(ctx->bi_radix); + bi_free(ctx, ctx->bi_radix); + + if (ctx->active_count != 0) { +#ifdef CONFIG_SSL_FULL_MODE + printf("bi_terminate: there were %d un-freed bigints\n", ctx->active_count); +#endif + abort(); + } + + bi_clear_cache(ctx); + mg_free(ctx); +} + +/** + *@brief Clear the memory cache. + */ +NS_INTERNAL void bi_clear_cache(BI_CTX *ctx) { + bigint *p, *pn; + + if (ctx->free_list == NULL) return; + + for (p = ctx->free_list; p != NULL; p = pn) { + pn = p->next; + mg_free(p->comps); + mg_free(p); + } + + ctx->free_count = 0; + ctx->free_list = NULL; +} +#endif + /** * @brief Increment the number of references to this object. * It does not do a full copy. diff --git a/test/unit_test.c b/test/unit_test.c index 432051aa..e11fa4af 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -1168,7 +1168,7 @@ static void test_http_server(void) { struct mg_str data = mg_file_read(&mg_fs_posix, "./data/ca.pem"); ASSERT(fetch(&mgr, buf, url, "GET /ca.pem HTTP/1.0\r\n\n") == 200); ASSERT(cmpbody(buf, data.buf) == 0); - free((void *) data.buf); + mg_free((void *) data.buf); } { @@ -1248,7 +1248,7 @@ static void test_http_server(void) { s = mg_file_read(&mg_fs_posix, "uploaded.txt"); ASSERT(s.buf != NULL); ASSERT(strcmp(s.buf, "hello\nworld") == 0); - free((void *) s.buf); + mg_free((void *) s.buf); remove("uploaded.txt"); } @@ -2112,7 +2112,7 @@ static void test_str(void) { { struct mg_str s = mg_strdup(mg_str("a")); ASSERT(mg_strcmp(s, mg_str("a")) == 0); - free((void *) s.buf); + mg_free((void *) s.buf); } { @@ -2228,11 +2228,11 @@ static void test_str(void) { p = mg_mprintf("[%s,%M,%s]", "null", pf1, 2, 3, "hi"); ASSERT(strcmp(p, "[null,5,hi]") == 0); - free(p); + mg_free(p); p = mg_mprintf("[%M,%d]", pf2, 10, 7); ASSERT(strcmp(p, "[9876543210,7]") == 0); - free(p); + mg_free(p); mg_xprintf(mg_pfn_iobuf, &io, "[%M", pf2, 10); mg_xprintf(mg_pfn_iobuf, &io, ","); @@ -2433,7 +2433,7 @@ static void test_str(void) { static void fn1(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_ERROR) { - free(*(char **) c->fn_data); // See #2263 + mg_free(*(char **) c->fn_data); // See #2263 *(char **) c->fn_data = mg_mprintf("%s", (char *) ev_data); } (void) c; @@ -2454,7 +2454,7 @@ static void test_dns_error(const char *dns_server_url, const char *errstr) { mg_mgr_free(&mgr); // MG_DEBUG(("buf: [%s] [%s]", buf, errstr)); ASSERT(buf != NULL && strcmp(buf, errstr) == 0); - free(buf); + mg_free(buf); } static void test_dns(void) { @@ -2541,7 +2541,7 @@ static void test_util(void) { data = mg_file_read(&mg_fs_posix, "data.txt"); ASSERT(data.buf != NULL); ASSERT(strcmp(data.buf, "hi") == 0); - free((void *) data.buf); + mg_free((void *) data.buf); remove("data.txt"); ASSERT(mg_aton(mg_str("0"), &a) == false); ASSERT(mg_aton(mg_str("0.0.0."), &a) == false); @@ -2653,7 +2653,7 @@ static void test_util(void) { { s = mg_mprintf("%3d", 123); ASSERT(strcmp(s, "123") == 0); - free(s); + mg_free(s); } { @@ -3077,13 +3077,13 @@ static void test_packed(void) { // printf("---> %s\n", buf); ASSERT(fetch(&mgr, buf, url, "GET /Makefile HTTP/1.0\n\n") == 200); ASSERT(cmpbody(buf, data.buf) == 0); - free((void *) data.buf); + mg_free((void *) data.buf); // Load file deeper in the FS tree directly data = mg_file_read(&mg_fs_posix, "data/ssi.h"); ASSERT(fetch(&mgr, buf, url, "GET /data/ssi.h HTTP/1.0\n\n") == 200); ASSERT(cmpbody(buf, data.buf) == 0); - free((void *) data.buf); + mg_free((void *) data.buf); // List root dir ASSERT(fetch(&mgr, buf, url, "GET / HTTP/1.0\n\n") == 200); @@ -3384,14 +3384,14 @@ static void test_json(void) { ASSERT(str != NULL); // printf("---> [%s]\n", str); ASSERT(strcmp(str, "b") == 0); - free(str); + mg_free(str); json = mg_str("{\"a\": \"hi\\nthere\",\"b\": [12345, true]}"); str = mg_json_get_str(json, "$.a"); ASSERT(str != NULL); ASSERT(strcmp(str, "hi\nthere") == 0); - free(str); + mg_free(str); ASSERT(mg_json_get_long(json, "$.foo", -42) == -42); ASSERT(mg_json_get_long(json, "$.b[0]", -42) == 12345); @@ -3410,10 +3410,10 @@ static void test_json(void) { json = mg_str("[\"YWJj\", \"0100026869\"]"); ASSERT((str = mg_json_get_b64(json, "$[0]", &len)) != NULL); ASSERT(len == 3 && memcmp(str, "abc", (size_t) len) == 0); - free(str); + mg_free(str); ASSERT((str = mg_json_get_hex(json, "$[1]", &len)) != NULL); ASSERT(len == 5 && memcmp(str, "\x01\x00\x02hi", (size_t) len) == 0); - free(str); + mg_free(str); json = mg_str("{\"a\":[1,2,3], \"ab\": 2}"); ASSERT(mg_json_get_long(json, "$.a[0]", -42) == 1); diff --git a/tutorials/core/multi-threaded/main.c b/tutorials/core/multi-threaded/main.c index 6200e18e..9b421601 100644 --- a/tutorials/core/multi-threaded/main.c +++ b/tutorials/core/multi-threaded/main.c @@ -33,7 +33,7 @@ static void *thread_function(void *param) { struct thread_data *p = (struct thread_data *) param; sleep(2); // Simulate long execution mg_wakeup(p->mgr, p->conn_id, "hi!", 3); // Respond to parent - free((void *) p->message.buf); // Free all resources that were + mg_free((void *) p->message.buf); // Free all resources that were free(p); // passed to us return NULL; } diff --git a/tutorials/http/device-dashboard/net.c b/tutorials/http/device-dashboard/net.c index d47daae7..db58bb11 100644 --- a/tutorials/http/device-dashboard/net.c +++ b/tutorials/http/device-dashboard/net.c @@ -156,10 +156,10 @@ static void handle_settings_set(struct mg_connection *c, struct mg_str body) { settings.log_level = (int) mg_json_get_long(body, "$.log_level", 0); settings.brightness = mg_json_get_long(body, "$.brightness", 0); if (s && strlen(s) < MAX_DEVICE_NAME) { - free(settings.device_name); + mg_free(settings.device_name); settings.device_name = s; } else { - free(s); + mg_free(s); } s_settings = settings; // Save to the device flash mg_http_reply(c, 200, s_json_header, diff --git a/tutorials/http/uart-bridge/esp32/main/main.c b/tutorials/http/uart-bridge/esp32/main/main.c index 7efe36cf..660c8efe 100644 --- a/tutorials/http/uart-bridge/esp32/main/main.c +++ b/tutorials/http/uart-bridge/esp32/main/main.c @@ -26,9 +26,9 @@ void app_main(void) { char *ssid = mg_json_get_str(json, "$.ssid"); char *pass = mg_json_get_str(json, "$.pass"); while (!wifi_init(ssid, pass)) (void) 0; - free(ssid); - free(pass); - free((void *) json.buf); + mg_free(ssid); + mg_free(pass); + mg_free((void *) json.buf); } else { // If WiFi is not configured, run CLI until configured MG_INFO(("WiFi is not configured, running CLI. Press enter")); diff --git a/tutorials/http/uart-bridge/net.c b/tutorials/http/uart-bridge/net.c index 1a4c6cea..d7f80177 100644 --- a/tutorials/http/uart-bridge/net.c +++ b/tutorials/http/uart-bridge/net.c @@ -157,7 +157,7 @@ static void timer_fn(void *param) { static void update_string(struct mg_str json, const char *path, char **value) { char *jval; if ((jval = mg_json_get_str(json, path)) != NULL) { - free(*value); + mg_free(*value); *value = strdup(jval); } } @@ -189,7 +189,7 @@ void uart_bridge_fn(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_OPEN && c->is_listening) { struct mg_str config = mg_file_read(&mg_fs_posix, "config.json"); if (config.buf != NULL) config_apply(config); - free(config.buf); + mg_free(config.buf); s_state.tcp.url = strdup(DEFAULT_TCP); s_state.websocket.url = strdup(DEFAULT_WEBSOCKET); s_state.mqtt.url = strdup(DEFAULT_MQTT); diff --git a/tutorials/http/video-stream/main.c b/tutorials/http/video-stream/main.c index 3c8b34f0..76475cd6 100644 --- a/tutorials/http/video-stream/main.c +++ b/tutorials/http/video-stream/main.c @@ -44,7 +44,7 @@ static void broadcast_mjpeg_frame(struct mg_mgr *mgr) { mg_send(c, data.buf, data.len); mg_send(c, "\r\n", 2); } - free((void *) data.buf); + mg_free((void *) data.buf); } static void timer_callback(void *arg) { diff --git a/tutorials/mqtt/mqtt-dashboard/device/net.c b/tutorials/mqtt/mqtt-dashboard/device/net.c index 6f0ccc22..82cf85ee 100644 --- a/tutorials/mqtt/mqtt-dashboard/device/net.c +++ b/tutorials/mqtt/mqtt-dashboard/device/net.c @@ -43,7 +43,7 @@ static void set_device_id(void) { struct mg_str id = mg_file_read(&mg_fs_posix, "/etc/machine-id"); if (id.buf != NULL) { mg_snprintf(buf, sizeof(buf), "%s", id.buf); - free((void *) id.buf); + mg_free((void *) id.buf); } #endif @@ -118,7 +118,7 @@ static void subscribe(struct mg_connection *c) { sub_opts.qos = s_qos; mg_mqtt_sub(c, &sub_opts); MG_INFO(("%lu SUBSCRIBED to %.*s", c->id, (int) subt.len, subt.buf)); - free(rx_topic); + mg_free(rx_topic); } static void rpc_config_set(struct mg_rpc_req *r) { @@ -169,7 +169,7 @@ static void rpc_ota_upload(struct mg_rpc_req *r) { } else { mg_rpc_ok(r, "%m", MG_ESC("ok")); } - free(buf); + mg_free(buf); } } diff --git a/tutorials/mqtt/mqtt-server/main.c b/tutorials/mqtt/mqtt-server/main.c index 5d188c27..226f34ac 100644 --- a/tutorials/mqtt/mqtt-server/main.c +++ b/tutorials/mqtt/mqtt-server/main.c @@ -78,7 +78,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) { struct mg_str topic; int num_topics = 0; while ((pos = mg_mqtt_next_sub(mm, &topic, &qos, pos)) > 0) { - struct sub *sub = calloc(1, sizeof(*sub)); + struct sub *sub = (struct sub *)calloc(1, sizeof(*sub)); sub->c = c; sub->topic = mg_strdup(topic); sub->qos = qos; @@ -128,7 +128,9 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) { next = sub->next; if (c != sub->c) continue; MG_INFO(("UNSUB %p [%.*s]", c->fd, (int) sub->topic.len, sub->topic.buf)); + mg_free(sub->topic.buf); LIST_DELETE(struct sub, &s_subs, sub); + free(sub); } } } diff --git a/tutorials/tcp/modbus-dashboard/main.c b/tutorials/tcp/modbus-dashboard/main.c index 004afbef..00136082 100644 --- a/tutorials/tcp/modbus-dashboard/main.c +++ b/tutorials/tcp/modbus-dashboard/main.c @@ -22,7 +22,7 @@ bool web_load_settings(void *buf, size_t len) { } else { memcpy(buf, data.buf, len); } - free((void *) data.buf); + mg_free((void *) data.buf); return ok; } diff --git a/tutorials/tcp/modbus-dashboard/net.c b/tutorials/tcp/modbus-dashboard/net.c index a7130ad4..8bb5c954 100644 --- a/tutorials/tcp/modbus-dashboard/net.c +++ b/tutorials/tcp/modbus-dashboard/net.c @@ -41,7 +41,7 @@ static void setfromjson(struct mg_str json, const char *jsonpath, char *buf, size_t len) { char *val = mg_json_get_str(json, jsonpath); if (val != NULL) mg_snprintf(buf, len, "%s", val); - free(val); + mg_free(val); } static void handle_settings_set(struct mg_connection *c, struct mg_str body) { @@ -159,7 +159,7 @@ static struct mg_connection *start_modbus_request(struct mg_mgr *mgr, cd->id = cid; // Store parent connection ID cd->expiration_time = mg_millis() + timeout; } - free(url); + mg_free(url); return c; } diff --git a/tutorials/tcpip/pcap-driver/main.c b/tutorials/tcpip/pcap-driver/main.c index 100cc1e9..fd8a79e2 100644 --- a/tutorials/tcpip/pcap-driver/main.c +++ b/tutorials/tcpip/pcap-driver/main.c @@ -104,7 +104,7 @@ static void fn2(struct mg_connection *c, int ev, void *ev_data) { } else if (ev == MG_EV_CONNECT) { mg_printf(c, "GET %s HTTP/1.1\r\n\r\n", mg_url_uri((char *) c->fn_data)); } else if (ev == MG_EV_CLOSE) { - free(c->fn_data); + mg_free(c->fn_data); } } diff --git a/tutorials/tcpip/tap-driver/main.c b/tutorials/tcpip/tap-driver/main.c index 008ae9a3..79e47bbb 100644 --- a/tutorials/tcpip/tap-driver/main.c +++ b/tutorials/tcpip/tap-driver/main.c @@ -48,12 +48,12 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { if (ev == MG_TCPIP_EV_ST_CHG) { MG_INFO(("State change: %u", *(uint8_t *) ev_data)); } else if (ev == MG_TCPIP_EV_DHCP_DNS) { - free(s_dns); + mg_free(s_dns); s_dns = mg_mprintf("udp://%M:53", mg_print_ip4, (uint32_t *) ev_data); ifp->mgr->dns4.url = s_dns; MG_INFO(("Set DNS to %s", ifp->mgr->dns4.url)); } else if (ev == MG_TCPIP_EV_DHCP_SNTP) { - free(s_sntp); + mg_free(s_sntp); s_sntp = mg_mprintf("udp://%M:123", mg_print_ip4, (uint32_t *) ev_data); MG_INFO(("Set SNTP to %s", s_sntp)); } @@ -128,8 +128,8 @@ int main(int argc, char *argv[]) { web_init(&mgr); while (s_signo == 0) mg_mgr_poll(&mgr, 100); // Infinite event loop - free(s_dns); - free(s_sntp); + mg_free(s_dns); + mg_free(s_sntp); mg_mgr_free(&mgr); close(fd); printf("Exiting on signal %d\n", s_signo); diff --git a/tutorials/websocket/websocket-client/main.c b/tutorials/websocket/websocket-client/main.c index a0456012..8742a5b3 100644 --- a/tutorials/websocket/websocket-client/main.c +++ b/tutorials/websocket/websocket-client/main.c @@ -9,14 +9,15 @@ static const char *s_url = "ws://localhost:8000/websocket"; static const char *s_ca_path = "ca.pem"; +static struct mg_str s_ca; // Print websocket response and signal that we're done static void fn(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_OPEN) { c->is_hexdumping = 1; } else if (c->is_tls && ev == MG_EV_CONNECT) { - struct mg_str ca = mg_file_read(&mg_fs_posix, s_ca_path); - struct mg_tls_opts opts = {.ca = ca, .name = mg_url_host(s_url)}; + s_ca = mg_file_read(&mg_fs_posix, s_ca_path); + struct mg_tls_opts opts = {.ca = s_ca, .name = mg_url_host(s_url)}; mg_tls_init(c, &opts); } else if (ev == MG_EV_ERROR) { // On error, log error message @@ -32,6 +33,10 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_ERROR || ev == MG_EV_CLOSE || ev == MG_EV_WS_MSG) { *(bool *) c->fn_data = true; // Signal that we're done + if (c->is_tls) { + mg_free(s_ca.buf); + s_ca.buf = NULL; + } } } diff --git a/tutorials/websocket/websocket-server/main.c b/tutorials/websocket/websocket-server/main.c index 0420ac68..752ec4bc 100644 --- a/tutorials/websocket/websocket-server/main.c +++ b/tutorials/websocket/websocket-server/main.c @@ -10,6 +10,7 @@ static const char *s_web_root = "."; static const char *s_ca_path = "ca.pem"; static const char *s_cert_path = "cert.pem"; static const char *s_key_path = "key.pem"; +struct mg_str s_ca, s_cert, s_key; // This RESTful server implements the following endpoints: // /websocket - upgrade to Websocket, and implement websocket echo server @@ -19,15 +20,15 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_OPEN) { // c->is_hexdumping = 1; } else if(c->is_tls && ev == MG_EV_ACCEPT) { - struct mg_str ca = mg_file_read(&mg_fs_posix, s_ca_path); - struct mg_str cert = mg_file_read(&mg_fs_posix, s_cert_path); - struct mg_str key = mg_file_read(&mg_fs_posix, s_key_path); - struct mg_tls_opts opts = {.ca = ca, .cert = cert, .key = key}; + s_ca = mg_file_read(&mg_fs_posix, s_ca_path); + s_cert = mg_file_read(&mg_fs_posix, s_cert_path); + s_key = mg_file_read(&mg_fs_posix, s_key_path); + struct mg_tls_opts opts = {.ca = s_ca, .cert = s_cert, .key = s_key}; mg_tls_init(c, &opts); } else if (ev == MG_EV_HTTP_MSG) { struct mg_http_message *hm = (struct mg_http_message *) ev_data; if (mg_match(hm->uri, mg_str("/websocket"), NULL)) { - // Upgrade to websocket. From now on, a connection is a full-duplex + // Upgrade to websocket. From now on, connection is full-duplex // Websocket connection, which will receive MG_EV_WS_MSG events. mg_ws_upgrade(c, hm, NULL); } else if (mg_match(hm->uri, mg_str("/rest"), NULL)) { @@ -42,6 +43,10 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) { // Got websocket frame. Received data is wm->data. Echo it back! struct mg_ws_message *wm = (struct mg_ws_message *) ev_data; mg_ws_send(c, wm->data.buf, wm->data.len, WEBSOCKET_OP_TEXT); + } else if (ev == MG_EV_CLOSE && c->is_tls) { + mg_free(s_ca.buf); + mg_free(s_cert.buf); + mg_free(s_key.buf); } } diff --git a/tutorials/webui/webui-plain/main.c b/tutorials/webui/webui-plain/main.c index 5a6b079f..c0d6325c 100644 --- a/tutorials/webui/webui-plain/main.c +++ b/tutorials/webui/webui-plain/main.c @@ -24,8 +24,8 @@ static struct config { static void update_config(struct mg_str json, const char *path, char **value) { char *jval; if ((jval = mg_json_get_str(json, path)) != NULL) { - free(*value); - *value = strdup(jval); + mg_free(*value); + *value = jval; } } @@ -61,5 +61,8 @@ int main(void) { mg_http_listen(&mgr, s_http_addr, fn, NULL); // Create HTTP listener for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop mg_mgr_free(&mgr); + mg_free(s_config.url); + mg_free(s_config.pub); + mg_free(s_config.sub); return 0; }