feat(lander): PoC index pages

This commit is contained in:
Jef Roosens 2024-03-09 21:01:14 +01:00
parent 222b277eef
commit e91631dd42
Signed by: Jef Roosens
GPG key ID: B75D4F293C7052DB
10 changed files with 196 additions and 24 deletions

View file

@ -33,7 +33,7 @@ void lander_ctx_reset(lander_ctx *ctx) {
if (ctx->instance != NULL) {
ltm_instance_free(ctx->instance);
ctx->instance = NULL;
}
}

View file

@ -21,7 +21,7 @@ static const char index_page[] =
" </body>\n"
"</html>\n";
lnm_http_step_err lander_get_index(lnm_http_conn *conn) {
lnm_http_step_err lander_get_root(lnm_http_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx;
lnm_http_res_body_set_buf(&ctx->res, (char *)index_page,
@ -74,7 +74,9 @@ lnm_err lander_entry_data_streamer(uint64_t *written, char *buf,
return lnm_err_ok;
}
lnm_err lander_template_streamer(size_t *written, char *buf, lnm_http_conn *conn, uint64_t offset, uint64_t len) {
lnm_err lander_template_streamer(size_t *written, char *buf,
lnm_http_conn *conn, uint64_t offset,
uint64_t len) {
lnm_http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c;
@ -85,9 +87,10 @@ lnm_err lander_template_streamer(size_t *written, char *buf, lnm_http_conn *conn
return lnm_err_ok;
}
ltm_err lander_data_to_template(size_t *written, char *buf, size_t len, void *data) {
ltm_err lander_data_to_template(size_t *written, char *buf, size_t len,
void *data) {
lsm_entry_handle *entry = data;
lsm_entry_data_read(written, buf, entry, len);
return ltm_err_ok;
@ -99,9 +102,11 @@ lnm_http_step_err lander_get_paste(lnm_http_conn *conn) {
lander_ctx *c_ctx = ctx->c;
ltm_template_instantiate(&c_ctx->instance, c_gctx->templates.paste);
/* ltm_instance_block_add_var(c_ctx->instance, ltm_instance_block_type_buf, lsm_str_ptr(c_ctx->entry)) */
ltm_instance_block_add_var_fn(c_ctx->instance, "paste", lander_data_to_template, c_ctx->entry, lsm_entry_data_len(c_ctx->entry));
/* ltm_instance_block_add_var(c_ctx->instance, ltm_instance_block_type_buf,
* lsm_str_ptr(c_ctx->entry)) */
ltm_instance_block_add_var_fn(c_ctx->instance, "paste",
lander_data_to_template, c_ctx->entry,
lsm_entry_data_len(c_ctx->entry));
lnm_http_res_body_set_fn(&ctx->res, lander_template_streamer,
ltm_instance_size(c_ctx->instance));
@ -123,6 +128,88 @@ lnm_http_step_err lander_get_file(lnm_http_conn *conn) {
return lnm_http_step_err_done;
}
lnm_http_step_err lander_get_index(lnm_http_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx;
lander_gctx *c_gctx = ctx->g->c;
lander_ctx *c_ctx = ctx->c;
ltm_template_instantiate(&c_ctx->instance, c_gctx->templates.index);
const lsm_str *key;
lsm_entry_key(&key, c_ctx->entry);
ltm_instance_block_add_var(c_ctx->instance, "title_key",
ltm_instance_block_type_buf,
(void *)lsm_str_ptr(key), lsm_str_len(key));
lsm_str *prefix;
lsm_str_init_copy_n(&prefix, lsm_str_ptr(key), lsm_str_len(key));
lsm_str_append_c(prefix, "_", 1);
uint64_t prefix_len = lsm_str_len(prefix);
lsm_store_iterator *iter;
lsm_store_iter(&iter, c_gctx->store, prefix);
lsm_entry_handle *handle;
while (lsm_store_iter_next_read(&handle, iter) == lsm_error_ok) {
const lsm_str *entry_key;
lsm_entry_key(&entry_key, handle);
lander_entry_type t;
lsm_entry_attr_get_uint8_t((uint8_t *)&t, handle,
lander_attr_type_entry_type);
ltm_instance *nested;
switch (t) {
case lander_entry_type_redirect:
ltm_instance_block_add_nested(&nested, c_ctx->instance, "redirect");
ltm_instance_block_add_var(
nested, "full_key", ltm_instance_block_type_buf,
(void *)lsm_str_ptr(entry_key), lsm_str_len(entry_key));
ltm_instance_block_add_var(nested, "short_key",
ltm_instance_block_type_buf,
(void *)(lsm_str_ptr(entry_key) + prefix_len),
lsm_str_len(entry_key) - prefix_len);
break;
case lander_entry_type_file:
ltm_instance_block_add_nested(&nested, c_ctx->instance, "file");
ltm_instance_block_add_var(
nested, "full_key", ltm_instance_block_type_buf,
(void *)lsm_str_ptr(entry_key), lsm_str_len(entry_key));
lsm_str *filename;
if (lsm_entry_attr_get(&filename, handle, lander_attr_type_file_name)) {
ltm_instance_block_add_var(
nested, "filename", ltm_instance_block_type_buf,
(void *)lsm_str_ptr(filename), lsm_str_len(filename));
} else {
ltm_instance_block_add_var(
nested, "filename", ltm_instance_block_type_buf,
(void *)(lsm_str_ptr(entry_key) + prefix_len),
lsm_str_len(entry_key) - prefix_len);
}
break;
}
// TODO this should be done after writing the template
lsm_entry_close(handle);
}
lnm_http_res_body_set_fn(&ctx->res, lander_template_streamer,
ltm_instance_size(c_ctx->instance));
lnm_http_res_add_header(&ctx->res, lnm_http_header_content_type, "text/html",
false);
lsm_store_iter_free(iter);
lsm_str_free(prefix);
return lnm_http_step_err_done;
}
lnm_http_step_err lander_get_entry(lnm_http_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c;
@ -164,6 +251,9 @@ lnm_http_step_err lander_get_entry(lnm_http_conn *conn) {
case lander_entry_type_file:
res = lander_get_file(conn);
break;
case lander_entry_type_index:
res = lander_get_index(conn);
break;
default:
ctx->res.status = lnm_http_status_internal_server_error;
res = lnm_http_step_err_res;

View file

@ -147,3 +147,21 @@ lnm_http_step_err lander_post_file(lnm_http_conn *conn) {
lnm_http_step_err lander_post_file_secure(lnm_http_conn *conn) {
return __lander_post_file(conn, true);
}
lnm_http_step_err lander_post_index(lnm_http_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c;
if (!lander_insert_entry(ctx)) {
return lnm_http_step_err_res;
}
lsm_entry_attr_insert_uint8_t(c_ctx->entry, lander_attr_type_entry_type,
lander_entry_type_index);
/* lander_header_to_attr(ctx, "X-Lander-Content-Type", */
/* lander_attr_type_content_type); */
/* lander_header_to_attr(ctx, "X-Lander-Filename",
* lander_attr_type_file_name); */
return lnm_http_step_err_done;
}

View file

@ -9,12 +9,34 @@
#include "lander.h"
const char *lander_server = "lander/" LANDER_VERSION;
const char *paste_template =
"<!doctype html>\n"
"<head><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/stackoverflow-dark.min.css\">\n"
"<script src=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js\"></script>\n"
"<script>hljs.highlightAll();</script></head>\n"
"<body><h1>{{ header }}</h1><pre><code>{{ paste }}</code></pre></body>";
const char *paste_template =
"<!doctype html>\n"
"<head><link rel=\"stylesheet\" "
"href=\"https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/"
"styles/stackoverflow-dark.min.css\">\n"
"<script "
"src=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/"
"highlight.min.js\"></script>\n"
"<script>hljs.highlightAll();</script></head>\n"
"<body><h1>{{ header }}</h1><pre><code>{{ paste }}</code></pre></body>";
const char *index_template =
"<!doctype html>\n"
"<body>\n"
"<h1>Index /{{ title_key }}</h1>\n"
"<h2>Redirects</h2>"
"<ul>\n"
"{{ redirect start }}\n"
"<li><a href=\"/{{ full_key }}\">{{ short_key }}</a></li>\n"
"{{ redirect end }}\n"
"</ul>\n"
"<h2>Files</h2>"
"<ul>\n"
"{{ file start }}\n"
"<li><a href=\"/{{ full_key }}\">{{ filename }}</a></li>\n"
"{{ file end }}\n"
"</ul>\n"
"</body>\n";
lnm_http_loop *loop_init(lander_gctx *gctx, const char *api_key) {
lnm_http_loop *hl;
@ -29,7 +51,7 @@ lnm_http_loop *loop_init(lander_gctx *gctx, const char *api_key) {
lnm_http_route *route;
lnm_http_router_add(&route, router, lnm_http_method_get, "/");
lnm_http_route_step_append(route, lander_get_index, false);
lnm_http_route_step_append(route, lander_get_root, false);
lnm_http_router_add(&route, router, lnm_http_method_get, "/:key");
lnm_http_route_step_append(route, lander_get_entry, false);
@ -44,6 +66,7 @@ lnm_http_loop *loop_init(lander_gctx *gctx, const char *api_key) {
lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false);
lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false);
<<<<<<< HEAD
lnm_http_router_add(&route, router, lnm_http_method_post, "/sl/");
lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
lnm_http_route_step_append(route, lander_post_redirect_secure, false);
@ -88,6 +111,20 @@ lnm_http_loop *loop_init(lander_gctx *gctx, const char *api_key) {
lnm_http_loop_router_set(hl, router);
lnm_http_step_init(&step, lnm_http_loop_step_auth);
lnm_http_route_init_regex(&route, lnm_http_method_post, "^/i(l?)/([^/]+)$", 2,
step);
lnm_http_step_append(&step, step, lander_post_index);
/* lnm_http_step_append(&step, step, lnm_http_loop_step_body_to_buf); */
/* lnm_http_step_append(&step, step, lander_post_redirect_body_to_attr); */
lnm_http_loop_route_add(hl, route);
lnm_http_step_init(&step, lnm_http_loop_step_auth);
lnm_http_route_init_regex(&route, lnm_http_method_delete, "^/([^/]+)$", 1,
step);
lnm_http_step_append(&step, step, lander_remove_entry);
lnm_http_loop_route_add(hl, route);
return hl;
}
@ -125,6 +162,7 @@ int main() {
c_gctx->data_dir = data_dir_s;
ltm_template_compile(&c_gctx->templates.paste, paste_template);
ltm_template_compile(&c_gctx->templates.index, index_template);
lsm_str *data_dir;
lsm_str_init_copy(&data_dir, (char *)data_dir_s);