Rework memory management, use per-thread arenas
This commit is contained in:
2
CONFIG.h
2
CONFIG.h
@ -7,4 +7,6 @@
|
|||||||
# define CONFIG_LISTEN_URL "http://localhost:5000"
|
# define CONFIG_LISTEN_URL "http://localhost:5000"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define BUNDLE_ZIP_COMPRESSION 10
|
||||||
|
|
||||||
#endif // CONFIG_H_
|
#endif // CONFIG_H_
|
||||||
|
6
baked.c
6
baked.c
@ -3,10 +3,11 @@
|
|||||||
#include "gebs/gebs.h"
|
#include "gebs/gebs.h"
|
||||||
#include "incbin/incbin.h"
|
#include "incbin/incbin.h"
|
||||||
#include "stb/stb_ds.h"
|
#include "stb/stb_ds.h"
|
||||||
|
#include "zip.h"
|
||||||
|
|
||||||
#include "baked.h"
|
#include "baked.h"
|
||||||
#include "locked.h"
|
#include "locked.h"
|
||||||
#include "zip.h"
|
#include "CONFIG.h"
|
||||||
|
|
||||||
INCBIN(bundle_zip, "./bundle.zip");
|
INCBIN(bundle_zip, "./bundle.zip");
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ void init_baked_resources(void)
|
|||||||
{
|
{
|
||||||
lockx(&baked_resources);
|
lockx(&baked_resources);
|
||||||
|
|
||||||
struct zip_t *zip = zip_stream_open(bundle_zip_data, bundle_zip_size, ZIP_DEFAULT_COMPRESSION_LEVEL, 'r');
|
struct zip_t *zip = zip_stream_open(bundle_zip_data, bundle_zip_size, BUNDLE_ZIP_COMPRESSION, 'r');
|
||||||
size_t n = zip_entries_total(zip);
|
size_t n = zip_entries_total(zip);
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
zip_entry_openbyindex(zip, i);
|
zip_entry_openbyindex(zip, i);
|
||||||
@ -73,7 +74,6 @@ bool get_baked_resource_path(char *key, char *buf, size_t size)
|
|||||||
if (shgeti(baked_resources.value, key) != -1) {
|
if (shgeti(baked_resources.value, key) != -1) {
|
||||||
Baked_Resource_Value brv = shget(baked_resources.value, key);
|
Baked_Resource_Value brv = shget(baked_resources.value, key);
|
||||||
snprintf(buf, size, "/proc/%d/fd/%d", getpid(), brv.memfd);
|
snprintf(buf, size, "/proc/%d/fd/%d", getpid(), brv.memfd);
|
||||||
unlockx(&baked_resources);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
10
build.c
10
build.c
@ -3,6 +3,7 @@
|
|||||||
#define GEBS_IMPLEMENTATION
|
#define GEBS_IMPLEMENTATION
|
||||||
#include "gebs/gebs.h"
|
#include "gebs/gebs.h"
|
||||||
#include "./zip/src/zip.c"
|
#include "./zip/src/zip.c"
|
||||||
|
#include "CONFIG.h"
|
||||||
|
|
||||||
char *prog = NULL;
|
char *prog = NULL;
|
||||||
|
|
||||||
@ -44,7 +45,6 @@ int main(int argc, char ** argv)
|
|||||||
"./routes.h",
|
"./routes.h",
|
||||||
"./baked.c",
|
"./baked.c",
|
||||||
"./baked.h",
|
"./baked.h",
|
||||||
"./clonestr.h",
|
|
||||||
"./commit.h",
|
"./commit.h",
|
||||||
"./timer.c",
|
"./timer.c",
|
||||||
"./timer.h",
|
"./timer.h",
|
||||||
@ -102,7 +102,7 @@ int main(int argc, char ** argv)
|
|||||||
CMD("cc", "-DHAVE_STRDUP", "-DHAVE_FNMATCH_H", "-o", "gpp1", "gpp/gpp.c");
|
CMD("cc", "-DHAVE_STRDUP", "-DHAVE_FNMATCH_H", "-o", "gpp1", "gpp/gpp.c");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct zip_t *zip = zip_open("./bundle.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
struct zip_t *zip = zip_open("./bundle.zip", BUNDLE_ZIP_COMPRESSION, 'w');
|
||||||
defer { zip_close(zip); }
|
defer { zip_close(zip); }
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(bundle_zip_deps)/sizeof(bundle_zip_deps[0]); i++) {
|
for (size_t i = 0; i < sizeof(bundle_zip_deps)/sizeof(bundle_zip_deps[0]); i++) {
|
||||||
@ -125,11 +125,13 @@ int main(int argc, char ** argv)
|
|||||||
#define TARGET "-o", "aboba"
|
#define TARGET "-o", "aboba"
|
||||||
#if MY_DEBUG
|
#if MY_DEBUG
|
||||||
#define CFLAGS "-fsanitize=address", "-fPIC", "-ggdb"
|
#define CFLAGS "-fsanitize=address", "-fPIC", "-ggdb"
|
||||||
#define DEFINES "-DMY_DEBUG=1", "-D_GNU_SOURCE", "-DGEBS_NO_PREFIX", "-DINCBIN_PREFIX=", "-DINCBIN_STYLE=INCBIN_STYLE_SNAKE"
|
#define DEFINES "-DMY_DEBUG=1", "-D_GNU_SOURCE", "-DGEBS_NO_PREFIX", "-DINCBIN_PREFIX=", "-DINCBIN_STYLE=INCBIN_STYLE_SNAKE", \
|
||||||
|
"-DGEBS_ENABLE_PTHREAD_FEATURES"
|
||||||
#define EXTRA_SOURCES "./cJSON/cJSON.c", "./zip/src/zip.c", "./md5-c/md5.c"
|
#define EXTRA_SOURCES "./cJSON/cJSON.c", "./zip/src/zip.c", "./md5-c/md5.c"
|
||||||
#else
|
#else
|
||||||
#define CFLAGS "-fPIC"
|
#define CFLAGS "-fPIC"
|
||||||
#define DEFINES "-DMY_DEBUG=0", "-D_GNU_SOURCE", "-DGEBS_NO_PREFIX", "-DINCBIN_PREFIX=", "-DINCBIN_STYLE=INCBIN_STYLE_SNAKE"
|
#define DEFINES "-DMY_DEBUG=0", "-D_GNU_SOURCE", "-DGEBS_NO_PREFIX", "-DINCBIN_PREFIX=", "-DINCBIN_STYLE=INCBIN_STYLE_SNAKE", \
|
||||||
|
"-DGEBS_ENABLE_PTHREAD_FEATURES"
|
||||||
#define EXTRA_SOURCES "./cJSON/cJSON.c", "./zip/src/zip.c"
|
#define EXTRA_SOURCES "./cJSON/cJSON.c", "./zip/src/zip.c"
|
||||||
#endif
|
#endif
|
||||||
#define SOURCES "./main.c", "./routes.c", "./baked.c", "./timer.c"
|
#define SOURCES "./main.c", "./routes.c", "./baked.c", "./timer.c"
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
#ifndef CLONESTR_H_
|
#ifndef CLONESTR_H_
|
||||||
#define CLONESTR_H_
|
#define CLONESTR_H_
|
||||||
|
|
||||||
#define clonestr(str) \
|
|
||||||
({ \
|
|
||||||
char *__p = malloc(strlen((str))+1); \
|
|
||||||
strcpy(__p, (str)); \
|
|
||||||
(__p); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#endif // CLONESTR_H_
|
#endif // CLONESTR_H_
|
||||||
|
2
gebs
2
gebs
Submodule gebs updated: 596bb1ef76...db8389f7d5
2
locked.h
2
locked.h
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#define locked_init(x) { .value = (x), .lock = PTHREAD_MUTEX_INITIALIZER }
|
#define locked_init(x) { .value = x, .lock = PTHREAD_MUTEX_INITIALIZER }
|
||||||
#define locked(T) struct { T value; pthread_mutex_t lock; }
|
#define locked(T) struct { T value; pthread_mutex_t lock; }
|
||||||
|
|
||||||
#define lockx(x) pthread_mutex_lock(&(x)->lock)
|
#define lockx(x) pthread_mutex_lock(&(x)->lock)
|
||||||
|
147
main.c
147
main.c
@ -9,23 +9,39 @@
|
|||||||
#include "mongoose/mongoose.h"
|
#include "mongoose/mongoose.h"
|
||||||
#define STB_DS_IMPLEMENTATION
|
#define STB_DS_IMPLEMENTATION
|
||||||
#include "stb/stb_ds.h"
|
#include "stb/stb_ds.h"
|
||||||
|
#include "md5-c/md5.h"
|
||||||
|
|
||||||
#include "routes.h"
|
#include "routes.h"
|
||||||
#include "baked.h"
|
#include "baked.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "CONFIG.h"
|
#include "CONFIG.h"
|
||||||
#include "clonestr.h"
|
|
||||||
#include "locked.h"
|
#include "locked.h"
|
||||||
|
|
||||||
static locked(Route *) route_hashtable = locked_init(nil);
|
static locked(Route *) route_hashtable = locked_init(nil);
|
||||||
static locked(char *) baked_dump_path = locked_init(nil);
|
static locked(char *) baked_dump_path = locked_init(nil);
|
||||||
|
|
||||||
|
char *clonestr_alloc(Allocator *alloc, char *s)
|
||||||
|
{
|
||||||
|
char *p = gebs_malloc(alloc, strlen(s)+1);
|
||||||
|
strcpy(p, s);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *zmalloc_alloc(Allocator *alloc, size_t size)
|
||||||
|
{
|
||||||
|
void *p = gebs_malloc(alloc, size);
|
||||||
|
memset(p, 0, size);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
void run_in_thread(void *(*f)(void *), void *p)
|
void run_in_thread(void *(*f)(void *), void *p)
|
||||||
{
|
{
|
||||||
pthread_t tid = 0;
|
pthread_t tid = 0;
|
||||||
|
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
|
||||||
pthread_create(&tid, &attr, f, p);
|
pthread_create(&tid, &attr, f, p);
|
||||||
pthread_attr_destroy(&attr);
|
pthread_attr_destroy(&attr);
|
||||||
}
|
}
|
||||||
@ -33,60 +49,61 @@ void run_in_thread(void *(*f)(void *), void *p)
|
|||||||
void *route_thread_function(void *param)
|
void *route_thread_function(void *param)
|
||||||
{
|
{
|
||||||
Route_Thread_Data *data = (Route_Thread_Data *)param;
|
Route_Thread_Data *data = (Route_Thread_Data *)param;
|
||||||
|
Arena *arena = data->arena;
|
||||||
|
|
||||||
struct mg_http_message http_msg = {0};
|
struct mg_http_message http_msg = {0};
|
||||||
int r = mg_http_parse(data->message.buf, data->message.len, &http_msg);
|
int r = mg_http_parse(data->message.buf, data->message.len, &http_msg);
|
||||||
if (r <= 0) {
|
if (r <= 0) {
|
||||||
Route_Result result = {0};
|
Route_Result *result = zmalloc_alloc((Allocator *)arena, sizeof(*result));
|
||||||
result.status_code = 400;
|
result->arena = arena;
|
||||||
result.type = ROUTE_RESULT_DYNAMIC;
|
result->status_code = 400;
|
||||||
/* list_append(&result.headers, clonestr("Content-Type: text/plain")); */
|
result->type = ROUTE_RESULT_DYNAMIC;
|
||||||
sb_append_nstr(&result.body, "Could not parse HTTP request");
|
sb_append_nstr_alloc(arena, &result->body, "Could not parse HTTP request");
|
||||||
sb_finish(&result.body);
|
sb_finish_alloc(arena, &result->body);
|
||||||
mg_wakeup(data->mgr, data->conn_id, &result, sizeof(result));
|
mg_wakeup(data->mgr, data->conn_id, &result, sizeof(result));
|
||||||
free(data->message.buf);
|
free(data->message.buf);
|
||||||
free(data);
|
free(data);
|
||||||
return nil;
|
pthread_exit(nil);
|
||||||
|
} else {
|
||||||
|
if (mg_match(http_msg.uri, mg_str("/bakedres/*"), nil)) {
|
||||||
|
Route_Result *result = zmalloc_alloc((Allocator *)arena, sizeof(*result));
|
||||||
|
result->arena = arena;
|
||||||
|
result->type = ROUTE_RESULT_STATIC;
|
||||||
|
|
||||||
|
char *p = gebs_malloc(arena, http_msg.uri.len+1);
|
||||||
|
strncpy(p, http_msg.uri.buf, http_msg.uri.len);
|
||||||
|
p[http_msg.uri.len] = 0;
|
||||||
|
|
||||||
|
char *file = basename(p);
|
||||||
|
char *full_path = gebs_malloc(arena, PATH_MAX);
|
||||||
|
|
||||||
|
lockx(&baked_dump_path);
|
||||||
|
snprintf(full_path, PATH_MAX, "%s/%s", baked_dump_path.value, file);
|
||||||
|
unlockx(&baked_dump_path);
|
||||||
|
|
||||||
|
sb_append_nstr_alloc(arena, &result->body, full_path);
|
||||||
|
sb_finish_alloc(arena, &result->body);
|
||||||
|
mg_wakeup(data->mgr, data->conn_id, &result, sizeof(result));
|
||||||
|
free(data->message.buf);
|
||||||
|
free(data);
|
||||||
|
pthread_exit(nil);
|
||||||
|
} else {
|
||||||
|
char key[MG_PATH_MAX] = {0};
|
||||||
|
strncpy(key, http_msg.uri.buf, http_msg.uri.len);
|
||||||
|
lockx(&route_hashtable);
|
||||||
|
ssize_t idx = shgeti(route_hashtable.value, key);
|
||||||
|
|
||||||
|
Route_Result *result = zmalloc_alloc((Allocator *)arena, sizeof(*result));
|
||||||
|
result->arena = arena;
|
||||||
|
route_hashtable.value[idx].value((Allocator *)arena, &http_msg, result, route_hashtable.value[idx].context_data);
|
||||||
|
unlockx(&route_hashtable);
|
||||||
|
mg_wakeup(data->mgr, data->conn_id, &result, sizeof(result));
|
||||||
|
|
||||||
|
free(data->message.buf);
|
||||||
|
free(data);
|
||||||
|
pthread_exit(nil);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mg_match(http_msg.uri, mg_str("/bakedres/*"), nil)) {
|
|
||||||
Route_Result result = {0};
|
|
||||||
result.type = ROUTE_RESULT_STATIC;
|
|
||||||
|
|
||||||
char *p = malloc(http_msg.uri.len+1);
|
|
||||||
strncpy(p, http_msg.uri.buf, http_msg.uri.len);
|
|
||||||
p[http_msg.uri.len] = 0;
|
|
||||||
|
|
||||||
char *file = basename(p);
|
|
||||||
char *full_path = malloc(PATH_MAX);
|
|
||||||
|
|
||||||
lockx(&baked_dump_path);
|
|
||||||
snprintf(full_path, PATH_MAX, "%s/%s", baked_dump_path.value, file);
|
|
||||||
unlockx(&baked_dump_path);
|
|
||||||
|
|
||||||
sb_append_nstr(&result.body, full_path);
|
|
||||||
sb_finish(&result.body);
|
|
||||||
free(full_path);
|
|
||||||
free(p);
|
|
||||||
mg_wakeup(data->mgr, data->conn_id, &result, sizeof(result));
|
|
||||||
free(data->message.buf);
|
|
||||||
free(data);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
char key[MG_PATH_MAX] = {0};
|
|
||||||
strncpy(key, http_msg.uri.buf, http_msg.uri.len);
|
|
||||||
lockx(&route_hashtable);
|
|
||||||
ssize_t idx = shgeti(route_hashtable.value, key);
|
|
||||||
|
|
||||||
Route_Result result = {0};
|
|
||||||
route_hashtable.value[idx].value(&http_msg, &result, route_hashtable.value[idx].context_data);
|
|
||||||
unlockx(&route_hashtable);
|
|
||||||
mg_wakeup(data->mgr, data->conn_id, &result, sizeof(result));
|
|
||||||
|
|
||||||
free(data->message.buf);
|
|
||||||
free(data);
|
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,18 +116,20 @@ void event_handler(struct mg_connection *conn, int ev, void *ev_data)
|
|||||||
data->message = mg_strdup(msg->message);
|
data->message = mg_strdup(msg->message);
|
||||||
data->conn_id = conn->id;
|
data->conn_id = conn->id;
|
||||||
data->mgr = conn->mgr;
|
data->mgr = conn->mgr;
|
||||||
|
data->arena = malloc(sizeof(*data->arena));
|
||||||
|
*data->arena = arena_get();
|
||||||
run_in_thread(&route_thread_function, data);
|
run_in_thread(&route_thread_function, data);
|
||||||
} else if (ev == MG_EV_WAKEUP) {
|
} else if (ev == MG_EV_WAKEUP) {
|
||||||
struct mg_str *data = (struct mg_str *)ev_data;
|
struct mg_str *data = (struct mg_str *)ev_data;
|
||||||
Route_Result *result = (Route_Result *)data->buf;
|
Route_Result *result = *(Route_Result **)data->buf;
|
||||||
|
Arena *arena = result->arena;
|
||||||
|
|
||||||
Gebs_String_Builder sb = {0};
|
Gebs_String_Builder sb = {0};
|
||||||
defer { sb_free(&sb); }
|
nsl_join_alloc(arena, &result->headers, &sb, "\r\n");
|
||||||
nsl_join(&result->headers, &sb, "\r\n");
|
|
||||||
if (result->headers.count > 0) {
|
if (result->headers.count > 0) {
|
||||||
sb_append_nstr(&sb, "\r\n");
|
sb_append_nstr_alloc(arena, &sb, "\r\n");
|
||||||
}
|
}
|
||||||
sb_finish(&sb);
|
sb_finish_alloc(arena, &sb);
|
||||||
|
|
||||||
if (result->type == ROUTE_RESULT_DYNAMIC) {
|
if (result->type == ROUTE_RESULT_DYNAMIC) {
|
||||||
mg_http_reply(conn, result->status_code, sb.items, "%s", result->body.items);
|
mg_http_reply(conn, result->status_code, sb.items, "%s", result->body.items);
|
||||||
@ -119,11 +138,8 @@ void event_handler(struct mg_connection *conn, int ev, void *ev_data)
|
|||||||
mg_http_serve_file(conn, ev_data, path, &(struct mg_http_serve_opts){0});
|
mg_http_serve_file(conn, ev_data, path, &(struct mg_http_serve_opts){0});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < result->headers.count; i++) {
|
arena_destroy(arena);
|
||||||
free(result->headers.items[i]);
|
free(arena);
|
||||||
}
|
|
||||||
list_free(&result->headers);
|
|
||||||
sb_free(&result->body);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,11 +159,11 @@ void init_route_hashtable(void)
|
|||||||
{
|
{
|
||||||
lockx(&route_hashtable);
|
lockx(&route_hashtable);
|
||||||
shdefault(route_hashtable.value, &route_page_not_found);
|
shdefault(route_hashtable.value, &route_page_not_found);
|
||||||
shput(route_hashtable.value, clonestr("/"), &route_home);
|
shput(route_hashtable.value, clonestr_alloc(&default_allocator, "/"), &route_home);
|
||||||
shput(route_hashtable.value, clonestr("/page-missing"), &route_page_not_found);
|
shput(route_hashtable.value, clonestr_alloc(&default_allocator, "/page-missing"), &route_page_not_found);
|
||||||
shput(route_hashtable.value, clonestr("/blog"), &route_blog);
|
shput(route_hashtable.value, clonestr_alloc(&default_allocator, "/blog"), &route_blog);
|
||||||
#if MY_DEBUG
|
#if MY_DEBUG
|
||||||
shput(route_hashtable.value, clonestr("/build-id"), &route_build_id);
|
shput(route_hashtable.value, clonestr_alloc(&default_allocator, "/build-id"), &route_build_id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
baked_resource_each(&route_hashtable_put_blogs, nil);
|
baked_resource_each(&route_hashtable_put_blogs, nil);
|
||||||
@ -250,13 +266,18 @@ void populate_baked_dump(char *baked_dump)
|
|||||||
unlock_baked_resources();
|
unlock_baked_resources();
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile bool alive = true;
|
volatile sig_atomic_t alive = true;
|
||||||
|
|
||||||
void graceful_shutdown(int no) { alive = false; }
|
void graceful_shutdown(int no) { alive = false; }
|
||||||
|
|
||||||
int main(int argc, char ** argv)
|
int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
signal(SIGINT, &graceful_shutdown);
|
struct sigaction sa;
|
||||||
|
sa.sa_handler = &graceful_shutdown;
|
||||||
|
sa.sa_flags = 0;
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sigaction(SIGINT, &sa, nil);
|
||||||
|
|
||||||
start_timer();
|
start_timer();
|
||||||
|
|
||||||
init_baked_resources();
|
init_baked_resources();
|
||||||
|
206
routes.c
206
routes.c
@ -7,10 +7,11 @@
|
|||||||
|
|
||||||
#include "routes.h"
|
#include "routes.h"
|
||||||
#include "baked.h"
|
#include "baked.h"
|
||||||
#include "clonestr.h"
|
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
|
extern char *clonestr_alloc(Allocator *alloc, char *s);
|
||||||
|
|
||||||
#define INTERNAL_SERVER_ERROR_MSG "Internal server error ;(. Try again later..."
|
#define INTERNAL_SERVER_ERROR_MSG "Internal server error ;(. Try again later..."
|
||||||
|
|
||||||
#define META_TAGS \
|
#define META_TAGS \
|
||||||
@ -19,65 +20,61 @@
|
|||||||
"<meta name=\"author\" content=\"kamkow1\">" \
|
"<meta name=\"author\" content=\"kamkow1\">" \
|
||||||
"<meta name=\"application-name\" content=\"aboba\">"
|
"<meta name=\"application-name\" content=\"aboba\">"
|
||||||
|
|
||||||
void make_internal_server_error(Route_Result *result)
|
void make_application_json(Allocator *alloc, Route_Result *result, int code, cJSON *root)
|
||||||
{
|
{
|
||||||
result->status_code = 500;
|
size_t buf_size = 512;
|
||||||
result->type = ROUTE_RESULT_DYNAMIC;
|
char *buf = gebs_malloc(alloc, buf_size);
|
||||||
list_append(&result->headers, "Content-Type: text/plain");
|
|
||||||
sb_append_nstr(&result->body, INTERNAL_SERVER_ERROR_MSG);
|
|
||||||
sb_finish(&result->body);
|
|
||||||
}
|
|
||||||
|
|
||||||
void make_application_json(Route_Result *result, int code, cJSON *root)
|
cJSON_PrintPreallocated(root, buf, buf_size, false);
|
||||||
{
|
|
||||||
char *root_text = cJSON_PrintUnformatted(root);
|
|
||||||
defer { free(root_text); }
|
|
||||||
|
|
||||||
result->status_code = code;
|
result->status_code = code;
|
||||||
result->type = ROUTE_RESULT_DYNAMIC;
|
result->type = ROUTE_RESULT_DYNAMIC;
|
||||||
list_append(&result->headers, clonestr("Content-Type: application/json"));
|
list_append(&result->headers, clonestr_alloc(alloc, "Content-Type: application/json"));
|
||||||
sb_append_nstr(&result->body, root_text);
|
sb_append_nstr_alloc(alloc, &result->body, buf);
|
||||||
sb_finish(&result->body);
|
sb_finish_alloc(alloc, &result->body);
|
||||||
}
|
}
|
||||||
|
|
||||||
void make_text(Route_Result *result, char *subtype, int code, char *in)
|
void make_text(Allocator *alloc, Route_Result *result, char *subtype, int code, char *in)
|
||||||
{
|
{
|
||||||
char type[100];
|
|
||||||
snprintf(type, sizeof(type), "Content-Type: text/%s", subtype);
|
|
||||||
|
|
||||||
result->status_code = code;
|
result->status_code = code;
|
||||||
result->type = ROUTE_RESULT_DYNAMIC;
|
result->type = ROUTE_RESULT_DYNAMIC;
|
||||||
list_append(&result->headers, clonestr(type));
|
list_append_alloc(alloc, &result->headers,
|
||||||
sb_append_nstr(&result->body, in);
|
clonestr_alloc(alloc, fmt("Content-Type: text/%s", subtype)));
|
||||||
|
sb_append_nstr_alloc(alloc, &result->body, in);
|
||||||
sb_finish(&result->body);
|
sb_finish(&result->body);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gpp_run(char *path, NString_List *env, String_Builder *out)
|
void make_internal_server_error(Allocator *alloc, Route_Result *result)
|
||||||
|
{
|
||||||
|
make_text(alloc, result, "plain", 500, INTERNAL_SERVER_ERROR_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gpp_run(Allocator *alloc, char *path, NString_List *env, String_Builder *out)
|
||||||
{
|
{
|
||||||
Cmd cmd = {0};
|
Cmd cmd = {0};
|
||||||
defer { cmd_free(&cmd); }
|
|
||||||
|
|
||||||
char gpp1[PATH_MAX];
|
char gpp1[PATH_MAX];
|
||||||
if (!get_baked_resource_path("gpp1", gpp1, sizeof(gpp1))) {
|
if (!get_baked_resource_path("gpp1", gpp1, sizeof(gpp1))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_append(&cmd, gpp1);
|
cmd_append_alloc(alloc, &cmd, gpp1);
|
||||||
cmd_append(&cmd, "-H");
|
cmd_append_alloc(alloc, &cmd, "-H");
|
||||||
cmd_append(&cmd, "-x");
|
cmd_append_alloc(alloc, &cmd, "-x");
|
||||||
cmd_append(&cmd, "--nostdinc");
|
cmd_append_alloc(alloc, &cmd, "--nostdinc");
|
||||||
cmd_append(&cmd, path);
|
cmd_append_alloc(alloc, &cmd, path);
|
||||||
|
|
||||||
for (size_t i = 0; i < env->count; i++) {
|
for (size_t i = 0; i < env->count; i++) {
|
||||||
cmd_append(&cmd, env->items[i]);
|
cmd_append_alloc(alloc, &cmd, env->items[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd_run_collect(&cmd, out) == 0;
|
return cmd_run_collect_alloc(alloc, &cmd, out) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MY_DEBUG
|
#if MY_DEBUG
|
||||||
void route_build_id(struct mg_http_message *msg, Route_Result *result, void *context_data)
|
void route_build_id(Allocator *alloc, struct mg_http_message *msg, Route_Result *result, void *context_data)
|
||||||
{
|
{
|
||||||
|
// TODO: Somehow use our arena in here. This will require a slight rework of the way cJSON works.
|
||||||
cJSON *root = cJSON_CreateObject();
|
cJSON *root = cJSON_CreateObject();
|
||||||
defer { cJSON_Delete(root); }
|
defer { cJSON_Delete(root); }
|
||||||
|
|
||||||
@ -85,226 +82,215 @@ void route_build_id(struct mg_http_message *msg, Route_Result *result, void *con
|
|||||||
uchar md5_buf[16];
|
uchar md5_buf[16];
|
||||||
md5String(time, md5_buf);
|
md5String(time, md5_buf);
|
||||||
String_Builder sb = {0};
|
String_Builder sb = {0};
|
||||||
defer { sb_free(&sb); }
|
|
||||||
for (size_t i = 0; i < 16; i++) {
|
for (size_t i = 0; i < 16; i++) {
|
||||||
sb_append_nstr(&sb, fmt("%02x", md5_buf[i]));
|
sb_append_nstr_alloc(alloc, &sb, clonestr_alloc(alloc, fmt("%02x", md5_buf[i])));
|
||||||
}
|
}
|
||||||
sb_finish(&sb);
|
sb_finish_alloc(alloc, &sb);
|
||||||
|
|
||||||
cJSON_AddItemToObject(root, "build_id", cJSON_CreateString(sb.items));
|
cJSON_AddItemToObject(root, "build_id", cJSON_CreateString(sb.items));
|
||||||
|
|
||||||
make_application_json(result, 200, root);
|
make_application_json(alloc, result, 200, root);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void route_page_not_found(struct mg_http_message *msg, Route_Result *result, void *context_data)
|
void route_page_not_found(Allocator *alloc, struct mg_http_message *msg, Route_Result *result, void *context_data)
|
||||||
{
|
{
|
||||||
lock_baked_resources();
|
lock_baked_resources();
|
||||||
defer { unlock_baked_resources(); }
|
defer { unlock_baked_resources(); }
|
||||||
NString_List env = {0};
|
NString_List env = {0};
|
||||||
defer { list_free(&env); }
|
|
||||||
|
|
||||||
list_append(&env, fmt("-DURL=%.*s", msg->uri.len, msg->uri.buf));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DURL=%.*s", msg->uri.len, msg->uri.buf)));
|
||||||
|
|
||||||
String_Builder out = {0};
|
String_Builder out = {0};
|
||||||
defer { sb_free(&out); }
|
|
||||||
|
|
||||||
char path[PATH_MAX] = {0};
|
char path[PATH_MAX] = {0};
|
||||||
if (!get_baked_resource_path("page-missing.html", path, sizeof(path))) {
|
if (!get_baked_resource_path("page-missing.html", path, sizeof(path))) {
|
||||||
make_internal_server_error(result);
|
make_internal_server_error(alloc, result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_append(&env, fmt("-DCOMMIT=%s", COMMIT_STRING));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DCOMMIT=%s", COMMIT_STRING)));
|
||||||
char timer[100];
|
char timer[100];
|
||||||
get_timer_string(timer, sizeof(timer));
|
get_timer_string(timer, sizeof(timer));
|
||||||
list_append(&env, fmt("-DRUNNING_SINCE=%s", timer));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DRUNNING_SINCE=%s", timer)));
|
||||||
|
|
||||||
list_append(&env, fmt("-DMETA_TAGS=%s", META_TAGS));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DMETA_TAGS=%s", META_TAGS)));
|
||||||
|
|
||||||
#if MY_DEBUG
|
#if MY_DEBUG
|
||||||
list_append(&env, "-DHOTRELOAD");
|
list_append_alloc(alloc, &env, "-DHOTRELOAD");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool ok = gpp_run(path, &env, &out);
|
bool ok = gpp_run(alloc, path, &env, &out);
|
||||||
sb_finish(&out);
|
sb_finish_alloc(alloc, &out);
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
make_internal_server_error(result);
|
make_internal_server_error(alloc, result);
|
||||||
} else {
|
} else {
|
||||||
make_text(result, "html", 200, out.items);
|
make_text(alloc, result, "html", 200, out.items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void route_home(struct mg_http_message *msg, Route_Result *result, void *context_data)
|
void route_home(Allocator *alloc, struct mg_http_message *msg, Route_Result *result, void *context_data)
|
||||||
{
|
{
|
||||||
lock_baked_resources();
|
lock_baked_resources();
|
||||||
defer { unlock_baked_resources(); }
|
defer { unlock_baked_resources(); }
|
||||||
NString_List env = {0};
|
NString_List env = {0};
|
||||||
defer { list_free(&env); }
|
|
||||||
|
|
||||||
String_Builder out = {0};
|
String_Builder out = {0};
|
||||||
defer { sb_free(&out); }
|
|
||||||
|
|
||||||
char path[PATH_MAX] = {0};
|
char path[PATH_MAX] = {0};
|
||||||
if (!get_baked_resource_path("home.html", path, sizeof(path))) {
|
if (!get_baked_resource_path("home.html", path, sizeof(path))) {
|
||||||
make_internal_server_error(result);
|
make_internal_server_error(alloc, result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_append(&env, fmt("-DCOMMIT=%s", COMMIT_STRING));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DCOMMIT=%s", COMMIT_STRING)));
|
||||||
char timer[100];
|
char timer[100];
|
||||||
get_timer_string(timer, sizeof(timer));
|
get_timer_string(timer, sizeof(timer));
|
||||||
list_append(&env, fmt("-DRUNNING_SINCE=%s", timer));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DRUNNING_SINCE=%s", timer)));
|
||||||
|
|
||||||
list_append(&env, fmt("-DMETA_TAGS=%s", META_TAGS));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DMETA_TAGS=%s", META_TAGS)));
|
||||||
|
|
||||||
#if MY_DEBUG
|
#if MY_DEBUG
|
||||||
list_append(&env, "-DHOTRELOAD");
|
list_append_alloc(alloc, &env, "-DHOTRELOAD");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool ok = gpp_run(path, &env, &out);
|
bool ok = gpp_run(alloc, path, &env, &out);
|
||||||
sb_finish(&out);
|
sb_finish_alloc(alloc, &out);
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
make_internal_server_error(result);
|
make_internal_server_error(alloc, result);
|
||||||
} else {
|
} else {
|
||||||
make_text(result, "html", 200, out.items);
|
make_text(alloc, result, "html", 200, out.items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void route_generic_blog(struct mg_http_message *msg, Route_Result *result, void *context_data)
|
void route_generic_blog(Allocator *alloc, struct mg_http_message *msg, Route_Result *result, void *context_data)
|
||||||
{
|
{
|
||||||
lock_baked_resources();
|
lock_baked_resources();
|
||||||
defer { unlock_baked_resources(); }
|
defer { unlock_baked_resources(); }
|
||||||
NString_List env = {0};
|
NString_List env = {0};
|
||||||
defer { list_free(&env); }
|
|
||||||
|
|
||||||
String_Builder out = {0};
|
String_Builder out = {0};
|
||||||
defer { sb_free(&out); }
|
|
||||||
|
|
||||||
Baked_Resource *resource = (Baked_Resource *)context_data;
|
Baked_Resource *resource = (Baked_Resource *)context_data;
|
||||||
|
|
||||||
char md_path[PATH_MAX] = {0};
|
char md_path[PATH_MAX] = {0};
|
||||||
if (!get_baked_resource_path(resource->key, md_path, sizeof(md_path))) {
|
if (!get_baked_resource_path(resource->key, md_path, sizeof(md_path))) {
|
||||||
make_internal_server_error(result);
|
make_internal_server_error(alloc, result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_append(&env, fmt("-DCOMMIT=%s", COMMIT_STRING));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DCOMMIT=%s", COMMIT_STRING)));
|
||||||
char timer[100];
|
char timer[100];
|
||||||
get_timer_string(timer, sizeof(timer));
|
get_timer_string(timer, sizeof(timer));
|
||||||
list_append(&env, fmt("-DRUNNING_SINCE=%s", timer));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DRUNNING_SINCE=%s", timer)));
|
||||||
|
|
||||||
list_append(&env, fmt("-DMETA_TAGS=%s", META_TAGS));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DMETA_TAGS=%s", META_TAGS)));
|
||||||
|
|
||||||
#if MY_DEBUG
|
#if MY_DEBUG
|
||||||
list_append(&env, "-DHOTRELOAD");
|
list_append_alloc(alloc, &env, "-DHOTRELOAD");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String_Builder md = {0};
|
String_Builder md = {0};
|
||||||
defer { sb_free(&md); }
|
|
||||||
if (!sb_read_file(&md, md_path)) {
|
if (!sb_read_file(&md, md_path)) {
|
||||||
make_internal_server_error(result);
|
make_internal_server_error(alloc, result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String_Builder md_prepared = {0};
|
String_Builder md_prepared = {0};
|
||||||
defer { sb_free(&md_prepared); }
|
|
||||||
for (size_t i = 0; i < md.count; i++) {
|
for (size_t i = 0; i < md.count; i++) {
|
||||||
char c = md.items[i];
|
char c = md.items[i];
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\"': sb_append_nstr(&md_prepared, "\\\""); break;
|
case '\"': sb_append_nstr_alloc(alloc, &md_prepared, "\\\""); break;
|
||||||
case '\'': sb_append_nstr(&md_prepared, "\\\'"); break;
|
case '\'': sb_append_nstr_alloc(alloc, &md_prepared, "\\\'"); break;
|
||||||
case '\\': sb_append_nstr(&md_prepared, "\\\\"); break;
|
case '\\': sb_append_nstr_alloc(alloc, &md_prepared, "\\\\"); break;
|
||||||
case '\a': sb_append_nstr(&md_prepared, "\\a"); break;
|
case '\a': sb_append_nstr_alloc(alloc, &md_prepared, "\\a"); break;
|
||||||
case '\b': sb_append_nstr(&md_prepared, "\\b"); break;
|
case '\b': sb_append_nstr_alloc(alloc, &md_prepared, "\\b"); break;
|
||||||
case '\r': sb_append_nstr(&md_prepared, "\\r"); break;
|
case '\r': sb_append_nstr_alloc(alloc, &md_prepared, "\\r"); break;
|
||||||
case '\n': sb_append_nstr(&md_prepared, "\\n"); break;
|
case '\n': sb_append_nstr_alloc(alloc, &md_prepared, "\\n"); break;
|
||||||
case '\t': sb_append_nstr(&md_prepared, "\\t"); break;
|
case '\t': sb_append_nstr_alloc(alloc, &md_prepared, "\\t"); break;
|
||||||
default:
|
default:
|
||||||
if (iscntrl(md.items[i])) {
|
if (iscntrl(md.items[i])) {
|
||||||
sb_append_nstr(&md_prepared, fmt("\\%03o", c));
|
sb_append_nstr_alloc(alloc, &md_prepared, clonestr_alloc(alloc, fmt("\\%03o", c)));
|
||||||
} else {
|
} else {
|
||||||
sb_append_char(&md_prepared, c);
|
sb_append_char_alloc(alloc, &md_prepared, c);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb_finish(&md_prepared);
|
sb_finish_alloc(alloc, &md_prepared);
|
||||||
|
|
||||||
list_append(&env, fmt("-DBLOG_POST_TITLE=%s", resource->key));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DBLOG_POST_TITLE=%s", resource->key)));
|
||||||
list_append(&env, fmt("-DBLOG_POST_MARKDOWN=%s", md_prepared.items));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DBLOG_POST_MARKDOWN=%s", md_prepared.items)));
|
||||||
|
|
||||||
char tmpl_file[PATH_MAX] = {0};
|
char tmpl_file[PATH_MAX] = {0};
|
||||||
if (!get_baked_resource_path("template-blog.html", tmpl_file, sizeof(tmpl_file))) {
|
if (!get_baked_resource_path("template-blog.html", tmpl_file, sizeof(tmpl_file))) {
|
||||||
make_internal_server_error(result);
|
make_internal_server_error(alloc, result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ok = gpp_run(tmpl_file, &env, &out);
|
bool ok = gpp_run(alloc, tmpl_file, &env, &out);
|
||||||
sb_finish(&out);
|
sb_finish_alloc(alloc, &out);
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
make_internal_server_error(result);
|
make_internal_server_error(alloc, result);
|
||||||
} else {
|
} else {
|
||||||
make_text(result, "html", 200, out.items);
|
make_text(alloc, result, "html", 200, out.items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void collect_blogs(Baked_Resource *resource, void *udata)
|
void collect_blogs(Baked_Resource *resource, void *udata)
|
||||||
{
|
{
|
||||||
struct { Arena *tmp; String_Builder *sb; } *ud = udata;
|
struct { Allocator *alloc; String_Builder *sb; } *ud = udata;
|
||||||
if ((strlen(resource->key) >= strlen("blog-"))
|
if ((strlen(resource->key) >= strlen("blog-"))
|
||||||
&& strncmp(resource->key, "blog-", strlen("blog-")) == 0) {
|
&& strncmp(resource->key, "blog-", strlen("blog-")) == 0) {
|
||||||
sb_append_nstr_alloc(ud->tmp, ud->sb, fmt("<li><a href=\"/%s\">%s</a></li>", resource->key, resource->key));
|
sb_append_nstr_alloc(ud->alloc, ud->sb,
|
||||||
|
clonestr_alloc(ud->alloc, fmt("<li><a href=\"/%s\">%s</a></li>", resource->key, resource->key)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void route_blog(struct mg_http_message *msg, Route_Result *result, void *context_data)
|
void route_blog(Allocator *alloc, struct mg_http_message *msg, Route_Result *result, void *context_data)
|
||||||
{
|
{
|
||||||
|
lock_baked_resources();
|
||||||
|
defer { unlock_baked_resources(); }
|
||||||
NString_List env = {0};
|
NString_List env = {0};
|
||||||
defer { list_free(&env); }
|
|
||||||
|
|
||||||
String_Builder out = {0};
|
String_Builder out = {0};
|
||||||
defer { sb_free(&out); }
|
|
||||||
|
|
||||||
Arena tmp = arena_get();
|
|
||||||
defer { arena_destroy(&tmp); }
|
|
||||||
|
|
||||||
String_Builder sb = {0};
|
String_Builder sb = {0};
|
||||||
struct { Arena *tmp; String_Builder *sb; } collect_blogs_data = {
|
struct { Allocator *alloc; String_Builder *sb; } collect_blogs_data = {
|
||||||
.tmp = &tmp,
|
.alloc = alloc,
|
||||||
.sb = &sb,
|
.sb = &sb,
|
||||||
};
|
};
|
||||||
baked_resource_each(&collect_blogs, &collect_blogs_data);
|
baked_resource_each(&collect_blogs, &collect_blogs_data);
|
||||||
sb_finish_alloc(&tmp, &sb);
|
sb_finish_alloc(alloc, &sb);
|
||||||
list_append(&env, fmt("-DBLOG_POSTS=%s", sb.items));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DBLOG_POSTS=%s", sb.items)));
|
||||||
|
|
||||||
char path[PATH_MAX] = {0};
|
char path[PATH_MAX] = {0};
|
||||||
if (!get_baked_resource_path("blog.html", path, sizeof(path))) {
|
if (!get_baked_resource_path("blog.html", path, sizeof(path))) {
|
||||||
make_internal_server_error(result);
|
make_internal_server_error(alloc, result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_append(&env, fmt("-DCOMMIT=%s", COMMIT_STRING));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DCOMMIT=%s", COMMIT_STRING)));
|
||||||
char timer[100];
|
char timer[100];
|
||||||
get_timer_string(timer, sizeof(timer));
|
get_timer_string(timer, sizeof(timer));
|
||||||
list_append(&env, fmt("-DRUNNING_SINCE=%s", timer));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DRUNNING_SINCE=%s", timer)));
|
||||||
|
|
||||||
list_append(&env, fmt("-DMETA_TAGS=%s", META_TAGS));
|
list_append_alloc(alloc, &env, clonestr_alloc(alloc, fmt("-DMETA_TAGS=%s", META_TAGS)));
|
||||||
|
|
||||||
#if MY_DEBUG
|
#if MY_DEBUG
|
||||||
list_append(&env, "-DHOTRELOAD");
|
list_append_alloc(alloc, &env, "-DHOTRELOAD");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool ok = gpp_run(path, &env, &out);
|
bool ok = gpp_run(alloc, path, &env, &out);
|
||||||
sb_finish(&out);
|
sb_finish_alloc(alloc, &out);
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
make_internal_server_error(result);
|
make_internal_server_error(alloc, result);
|
||||||
} else {
|
} else {
|
||||||
make_text(result, "html", 200, out.items);
|
make_text(alloc, result, "html", 200, out.items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
routes.h
14
routes.h
@ -12,15 +12,17 @@ typedef struct {
|
|||||||
int status_code;
|
int status_code;
|
||||||
NString_List headers;
|
NString_List headers;
|
||||||
String_Builder body;
|
String_Builder body;
|
||||||
|
Arena *arena;
|
||||||
} Route_Result;
|
} Route_Result;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct mg_mgr *mgr;
|
struct mg_mgr *mgr;
|
||||||
ulong conn_id;
|
ulong conn_id;
|
||||||
struct mg_str message;
|
struct mg_str message;
|
||||||
|
Arena *arena;
|
||||||
} Route_Thread_Data;
|
} Route_Thread_Data;
|
||||||
|
|
||||||
typedef void (*Route_Handler)(struct mg_http_message *msg, Route_Result *result, void *context_data);
|
typedef void (*Route_Handler)(Allocator *alloc, struct mg_http_message *msg, Route_Result *result, void *context_data);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *key; // path
|
char *key; // path
|
||||||
@ -29,11 +31,11 @@ typedef struct {
|
|||||||
} Route;
|
} Route;
|
||||||
|
|
||||||
#if MY_DEBUG
|
#if MY_DEBUG
|
||||||
void route_build_id(struct mg_http_message *msg, Route_Result *result, void *context_data);
|
void route_build_id(Allocator *alloc, struct mg_http_message *msg, Route_Result *result, void *context_data);
|
||||||
#endif
|
#endif
|
||||||
void route_page_not_found(struct mg_http_message *msg, Route_Result *result, void *context_data);
|
void route_page_not_found(Allocator *alloc, struct mg_http_message *msg, Route_Result *result, void *context_data);
|
||||||
void route_home(struct mg_http_message *msg, Route_Result *result, void *context_data);
|
void route_home(Allocator *alloc, struct mg_http_message *msg, Route_Result *result, void *context_data);
|
||||||
void route_generic_blog(struct mg_http_message *msg, Route_Result *result, void *context_data);
|
void route_generic_blog(Allocator *alloc, struct mg_http_message *msg, Route_Result *result, void *context_data);
|
||||||
void route_blog(struct mg_http_message *msg, Route_Result *result, void *context_data);
|
void route_blog(Allocator *alloc, struct mg_http_message *msg, Route_Result *result, void *context_data);
|
||||||
|
|
||||||
#endif // ROUTES_H_
|
#endif // ROUTES_H_
|
||||||
|
Reference in New Issue
Block a user