|
| 1 | +// Copyright (c) 2025 Cesanta Software Limited |
| 2 | +// All rights reserved |
| 3 | + |
| 4 | +#include "mongoose.h" |
| 5 | +#include "o1heap.h" |
| 6 | + |
| 7 | +#define POOL_SIZE (5 * MG_IO_SIZE) |
| 8 | + |
| 9 | +O1HeapInstance *s_mem; |
| 10 | + |
| 11 | +// memory allocation |
| 12 | +void *mg_calloc(size_t count, size_t size) { |
| 13 | + size_t bytes = count * size; |
| 14 | + void *ptr = o1heapAllocate(s_mem, bytes); |
| 15 | + if (ptr != NULL) memset(ptr, 0, bytes); |
| 16 | + if (ptr != NULL) MG_DEBUG(("%lu bytes @%p", bytes, ptr)); |
| 17 | + if (ptr == NULL) MG_ERROR(("Failed to allocate %lu bytes", bytes)); |
| 18 | + return ptr; |
| 19 | +} |
| 20 | + |
| 21 | +void mg_free(void *ptr) { |
| 22 | + o1heapFree(s_mem, ptr); |
| 23 | + if (ptr != NULL) MG_DEBUG(("block @%p", ptr)); |
| 24 | +} |
| 25 | + |
| 26 | +// HTTP request callback |
| 27 | +static void fn(struct mg_connection *c, int ev, void *ev_data) { |
| 28 | + if (ev == MG_EV_HTTP_MSG) { |
| 29 | + struct mg_http_message *hm = (struct mg_http_message *) ev_data; |
| 30 | + if (mg_match(hm->uri, mg_str("/hi"), NULL)) { |
| 31 | + mg_http_reply(c, 200, "Host: foo.com\r\n", "hi\n"); |
| 32 | + } else if (mg_match(hm->uri, mg_str("/echo"), NULL)) { |
| 33 | + mg_http_reply(c, 200, "", "%.*s", (int) hm->body.len, hm->body.buf); |
| 34 | + } else if (mg_match(hm->uri, mg_str("/stats"), NULL)) { |
| 35 | + struct mg_connection *t; |
| 36 | + mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"); |
| 37 | + mg_http_printf_chunk(c, "ID PROTO TYPE LOCAL REMOTE\n"); |
| 38 | + for (t = c->mgr->conns; t != NULL; t = t->next) { |
| 39 | + mg_http_printf_chunk(c, "%-3lu %4s %s %M %M\n", t->id, |
| 40 | + t->is_udp ? "UDP" : "TCP", |
| 41 | + t->is_listening ? "LISTENING" |
| 42 | + : t->is_accepted ? "ACCEPTED " |
| 43 | + : "CONNECTED", |
| 44 | + mg_print_ip, &t->loc, mg_print_ip, &t->rem); |
| 45 | + } |
| 46 | + mg_http_printf_chunk(c, ""); // Don't forget the last empty chunk |
| 47 | + } else { |
| 48 | + struct mg_http_serve_opts opts; |
| 49 | + memset(&opts, 0, sizeof(opts)); |
| 50 | + opts.root_dir = "."; |
| 51 | + mg_http_serve_dir(c, ev_data, &opts); |
| 52 | + } |
| 53 | + } |
| 54 | +} |
| 55 | + |
| 56 | +int main(void) { |
| 57 | + struct mg_mgr mgr; |
| 58 | + |
| 59 | + void *pool = malloc(POOL_SIZE + O1HEAP_ALIGNMENT); |
| 60 | + void *aligned = (void *) (((uintptr_t) pool) & ~(O1HEAP_ALIGNMENT - 1)); |
| 61 | + O1HeapDiagnostics d; |
| 62 | + s_mem = o1heapInit(aligned, POOL_SIZE); |
| 63 | + d = o1heapGetDiagnostics(s_mem); |
| 64 | + MG_INFO( |
| 65 | + ("Created aligned %lu-byte pool @%p, out of a %lu-byte allocated system " |
| 66 | + "memory pool", |
| 67 | + d.capacity, s_mem, POOL_SIZE)); |
| 68 | + |
| 69 | + mg_mgr_init(&mgr); // Initialise event manager |
| 70 | + mg_log_set(MG_LL_DEBUG); // Set debug log level |
| 71 | + mg_http_listen(&mgr, "http://localhost:8000", fn, NULL); // Create listener |
| 72 | + for (;;) { // Event loop |
| 73 | + mg_mgr_poll(&mgr, 1000); |
| 74 | + } |
| 75 | + mg_mgr_free(&mgr); |
| 76 | + return 0; |
| 77 | +} |
0 commit comments