Compare commits
3 Commits
83072d5441
...
a68e32c949
Author | SHA1 | Date |
---|---|---|
Jef Roosens | a68e32c949 | |
Jef Roosens | f789847fc5 | |
Jef Roosens | 97d4008db2 |
|
@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
* LSM
|
* LSM
|
||||||
* Binary tree iterators
|
* Binary tree iterators
|
||||||
* Trie iterators
|
* Trie iterators
|
||||||
|
* Store iterators
|
||||||
|
|
||||||
## [0.2.0](https://git.rustybever.be/Chewing_Bever/lander/src/tag/0.2.0)
|
## [0.2.0](https://git.rustybever.be/Chewing_Bever/lander/src/tag/0.2.0)
|
||||||
|
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -71,7 +71,7 @@ run: $(BIN)
|
||||||
valgrind: $(BIN)
|
valgrind: $(BIN)
|
||||||
LANDER_API_KEY=test \
|
LANDER_API_KEY=test \
|
||||||
LANDER_DATA_DIR=data \
|
LANDER_DATA_DIR=data \
|
||||||
valgrind --track-origins=yes '$(BUILD_DIR)/$(BIN_FILENAME)'
|
valgrind --track-origins=yes --leak-check=full '$(BUILD_DIR)/$(BIN_FILENAME)'
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test: $(TARGETS_TEST)
|
test: $(TARGETS_TEST)
|
||||||
|
|
|
@ -13,6 +13,7 @@ typedef struct lander_gctx {
|
||||||
lsm_store *store;
|
lsm_store *store;
|
||||||
struct {
|
struct {
|
||||||
ltm_template *paste;
|
ltm_template *paste;
|
||||||
|
ltm_template *index;
|
||||||
} templates;
|
} templates;
|
||||||
} lander_gctx;
|
} lander_gctx;
|
||||||
|
|
||||||
|
@ -32,6 +33,7 @@ typedef enum lander_entry_type : uint8_t {
|
||||||
lander_entry_type_redirect = 0,
|
lander_entry_type_redirect = 0,
|
||||||
lander_entry_type_paste = 1,
|
lander_entry_type_paste = 1,
|
||||||
lander_entry_type_file = 2,
|
lander_entry_type_file = 2,
|
||||||
|
lander_entry_type_index = 3,
|
||||||
} lander_entry_type;
|
} lander_entry_type;
|
||||||
|
|
||||||
void *lander_gctx_init();
|
void *lander_gctx_init();
|
||||||
|
@ -42,7 +44,7 @@ void lander_ctx_reset(lander_ctx *ctx);
|
||||||
|
|
||||||
void lander_ctx_free(lander_ctx *ctx);
|
void lander_ctx_free(lander_ctx *ctx);
|
||||||
|
|
||||||
lnm_http_step_err lander_get_index(lnm_http_conn *conn);
|
lnm_http_step_err lander_get_root(lnm_http_conn *conn);
|
||||||
|
|
||||||
lnm_http_step_err lander_get_entry(lnm_http_conn *conn);
|
lnm_http_step_err lander_get_entry(lnm_http_conn *conn);
|
||||||
|
|
||||||
|
@ -58,6 +60,8 @@ lnm_http_step_err lander_remove_entry(lnm_http_conn *conn);
|
||||||
|
|
||||||
lnm_http_step_err lander_post_file(lnm_http_conn *conn);
|
lnm_http_step_err lander_post_file(lnm_http_conn *conn);
|
||||||
|
|
||||||
|
lnm_http_step_err lander_post_index(lnm_http_conn *conn);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store the requested header as an attribute, if it's present.
|
* Store the requested header as an attribute, if it's present.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -98,6 +98,11 @@ lsm_error lsm_entry_attr_insert_uint8_t(lsm_entry_handle *handle, uint8_t type,
|
||||||
lsm_error lsm_entry_attr_remove(lsm_str **out, lsm_entry_handle *handle,
|
lsm_error lsm_entry_attr_remove(lsm_str **out, lsm_entry_handle *handle,
|
||||||
uint8_t type);
|
uint8_t type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a pointer to the entry's key.
|
||||||
|
*/
|
||||||
|
void lsm_entry_key(const lsm_str **out, lsm_entry_handle *handle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A store consisting of LSM entries.
|
* A store consisting of LSM entries.
|
||||||
*
|
*
|
||||||
|
@ -228,4 +233,40 @@ lsm_error lsm_entry_data_read(uint64_t *out, char *buf,
|
||||||
*/
|
*/
|
||||||
uint64_t lsm_entry_data_len(lsm_entry_handle *handle);
|
uint64_t lsm_entry_data_len(lsm_entry_handle *handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an in-flight iterator over an LSM store.
|
||||||
|
*/
|
||||||
|
typedef struct lsm_store_iterator lsm_store_iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize an iterator to iterate over all entries with keys starting
|
||||||
|
* with the given prefix.
|
||||||
|
*
|
||||||
|
* @param out pointer to store iterator pointer in
|
||||||
|
* @param trie trie to iterate
|
||||||
|
* @param prefix prefix of the keys; a zero-length string means iterating over
|
||||||
|
* the entire trie; NULL is interpreted as a zero-length string
|
||||||
|
*/
|
||||||
|
lsm_error lsm_store_iter(lsm_store_iterator **out, lsm_store *store,
|
||||||
|
const lsm_str *prefix);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advance the iterator, returning a read handle to the next entry. The caller
|
||||||
|
* is responsible for closing this handle.
|
||||||
|
*/
|
||||||
|
lsm_error lsm_store_iter_next_read(lsm_entry_handle **out,
|
||||||
|
lsm_store_iterator *iter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advance the iterator, returning a write handle to the next entry. The caller
|
||||||
|
* is responsible for closing this handle.
|
||||||
|
*/
|
||||||
|
/* lsm_error lsm_store_iter_next_write(lsm_entry_handle **out,
|
||||||
|
* lsm_store_iterator *iter); */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the given iterator.
|
||||||
|
*/
|
||||||
|
void lsm_store_iter_free(lsm_store_iterator *iter);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -178,6 +178,15 @@ lsm_error lsm_str_split(lsm_str *s, lsm_str *s2, uint64_t index);
|
||||||
* @param s string to append s2 to
|
* @param s string to append s2 to
|
||||||
* @param s2 string to append to s
|
* @param s2 string to append to s
|
||||||
*/
|
*/
|
||||||
lsm_error lsm_str_append(lsm_str *s, lsm_str *s2);
|
lsm_error lsm_str_append(lsm_str *s, const lsm_str *s2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as `lsm_str_append`, but it takes a C-style string instead.
|
||||||
|
*
|
||||||
|
* @param s string to append c_str to
|
||||||
|
* @param c_str char buffer to append
|
||||||
|
* @param len length of c_str
|
||||||
|
*/
|
||||||
|
lsm_error lsm_str_append_c(lsm_str *s, const char *c_str, uint64_t len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,6 +34,11 @@ typedef struct lsm_entry {
|
||||||
uint64_t idx_file_offset;
|
uint64_t idx_file_offset;
|
||||||
} lsm_entry;
|
} lsm_entry;
|
||||||
|
|
||||||
|
struct lsm_store_iterator {
|
||||||
|
lsm_trie_iterator *iter;
|
||||||
|
lsm_store *store;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate and initialize a new lsm_entry object.
|
* Allocate and initialize a new lsm_entry object.
|
||||||
*
|
*
|
||||||
|
|
|
@ -316,3 +316,7 @@ lsm_error lsm_entry_data_open_read(lsm_entry_handle *handle) {
|
||||||
|
|
||||||
return lsm_error_ok;
|
return lsm_error_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lsm_entry_key(const lsm_str **out, lsm_entry_handle *handle) {
|
||||||
|
*out = handle->wrapper->entry->key;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include "lsm/store.h"
|
||||||
|
#include "lsm/store_internal.h"
|
||||||
|
|
||||||
|
lsm_error lsm_store_iter(lsm_store_iterator **out, lsm_store *store,
|
||||||
|
const lsm_str *prefix) {
|
||||||
|
lsm_trie_iterator *trie_iter;
|
||||||
|
LSM_RES(lsm_trie_iter(&trie_iter, store->trie, prefix));
|
||||||
|
|
||||||
|
lsm_store_iterator *iter = calloc(1, sizeof(lsm_store_iterator));
|
||||||
|
|
||||||
|
if (iter == NULL) {
|
||||||
|
lsm_trie_iter_free(trie_iter);
|
||||||
|
|
||||||
|
return lsm_error_failed_alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter->iter = trie_iter;
|
||||||
|
iter->store = store;
|
||||||
|
|
||||||
|
*out = iter;
|
||||||
|
|
||||||
|
return lsm_error_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
lsm_error lsm_store_iter_next_read(lsm_entry_handle **out,
|
||||||
|
lsm_store_iterator *iter) {
|
||||||
|
lsm_entry_wrapper *wrapper = NULL;
|
||||||
|
|
||||||
|
// Traverse through the trie until a node is found with a filled data field
|
||||||
|
do {
|
||||||
|
// Exits function if iterator is done
|
||||||
|
LSM_RES(lsm_trie_iter_next((void **)&wrapper, iter->iter));
|
||||||
|
|
||||||
|
// TODO error handling?
|
||||||
|
pthread_rwlock_rdlock(&wrapper->lock);
|
||||||
|
|
||||||
|
if (wrapper->entry == NULL) {
|
||||||
|
pthread_rwlock_unlock(&wrapper->lock);
|
||||||
|
|
||||||
|
wrapper = NULL;
|
||||||
|
}
|
||||||
|
} while (wrapper == NULL);
|
||||||
|
|
||||||
|
lsm_entry_handle *handle;
|
||||||
|
LSM_RES2(lsm_entry_handle_init(&handle),
|
||||||
|
pthread_rwlock_unlock(&wrapper->lock));
|
||||||
|
|
||||||
|
handle->wrapper = wrapper;
|
||||||
|
handle->store = iter->store;
|
||||||
|
*out = handle;
|
||||||
|
|
||||||
|
return lsm_error_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lsm_store_iter_free(lsm_store_iterator *iter) {
|
||||||
|
lsm_trie_iter_free(iter->iter);
|
||||||
|
free(iter);
|
||||||
|
}
|
|
@ -215,15 +215,15 @@ bool lsm_str_eq(const lsm_str *s1, const lsm_str *s2) {
|
||||||
return memcmp(lsm_str_ptr(s1), lsm_str_ptr(s2), s1->len) == 0;
|
return memcmp(lsm_str_ptr(s1), lsm_str_ptr(s2), s1->len) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lsm_error lsm_str_append(lsm_str *s, lsm_str *s2) {
|
lsm_error lsm_str_append_c(lsm_str *s, const char *c_str, uint64_t len) {
|
||||||
if (s2->len == 0) {
|
if (len == 0) {
|
||||||
return lsm_error_ok;
|
return lsm_error_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t new_len = s->len + s2->len;
|
uint64_t new_len = s->len + len;
|
||||||
|
|
||||||
if (new_len <= 8) {
|
if (new_len <= 8) {
|
||||||
memcpy(&s->data.val[s->len], s2->data.val, s2->len);
|
memcpy(&s->data.val[s->len], c_str, len);
|
||||||
} else {
|
} else {
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
|
@ -243,11 +243,15 @@ lsm_error lsm_str_append(lsm_str *s, lsm_str *s2) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&buf[s->len], lsm_str_ptr(s2), s2->len);
|
memcpy(&buf[s->len], c_str, len);
|
||||||
s->data.ptr = buf;
|
s->data.ptr = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->len += s2->len;
|
s->len += len;
|
||||||
|
|
||||||
return lsm_error_ok;
|
return lsm_error_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lsm_error lsm_str_append(lsm_str *s, const lsm_str *s2) {
|
||||||
|
return lsm_str_append_c(s, lsm_str_ptr(s2), s2->len);
|
||||||
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ static const char index_page[] =
|
||||||
" </body>\n"
|
" </body>\n"
|
||||||
"</html>\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_loop_ctx *ctx = conn->ctx;
|
||||||
|
|
||||||
lnm_http_res_body_set_buf(&ctx->res, (char *)index_page,
|
lnm_http_res_body_set_buf(&ctx->res, (char *)index_page,
|
||||||
|
@ -73,7 +73,9 @@ lnm_err lander_entry_data_streamer(uint64_t *written, char *buf,
|
||||||
return lnm_err_ok;
|
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;
|
lnm_http_loop_ctx *ctx = conn->ctx;
|
||||||
lander_ctx *c_ctx = ctx->c;
|
lander_ctx *c_ctx = ctx->c;
|
||||||
|
|
||||||
|
@ -84,7 +86,8 @@ lnm_err lander_template_streamer(size_t *written, char *buf, lnm_http_conn *conn
|
||||||
return lnm_err_ok;
|
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_handle *entry = data;
|
||||||
|
|
||||||
lsm_entry_data_read(written, buf, entry, len);
|
lsm_entry_data_read(written, buf, entry, len);
|
||||||
|
@ -98,9 +101,11 @@ lnm_http_step_err lander_get_paste(lnm_http_conn *conn) {
|
||||||
lander_ctx *c_ctx = ctx->c;
|
lander_ctx *c_ctx = ctx->c;
|
||||||
|
|
||||||
ltm_template_instantiate(&c_ctx->instance, c_gctx->templates.paste);
|
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(c_ctx->instance, ltm_instance_block_type_buf,
|
||||||
ltm_instance_block_add_var_fn(c_ctx->instance, "paste", lander_data_to_template, c_ctx->entry, lsm_entry_data_len(c_ctx->entry));
|
* 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,
|
lnm_http_res_body_set_fn(&ctx->res, lander_template_streamer,
|
||||||
ltm_instance_size(c_ctx->instance));
|
ltm_instance_size(c_ctx->instance));
|
||||||
|
@ -138,6 +143,93 @@ lnm_http_step_err lander_get_file(lnm_http_conn *conn) {
|
||||||
return lnm_http_step_err_done;
|
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:
|
||||||
|
case lander_entry_type_paste:
|
||||||
|
ltm_instance_block_add_nested(&nested, c_ctx->instance,
|
||||||
|
t == lander_entry_type_file ? "file"
|
||||||
|
: "paste");
|
||||||
|
|
||||||
|
ltm_instance_block_add_var(
|
||||||
|
nested, "full_key", ltm_instance_block_type_buf,
|
||||||
|
(void *)lsm_str_ptr(entry_key), lsm_str_len(entry_key));
|
||||||
|
|
||||||
|
// Add the filename as the link name if known, or just the key otherwise
|
||||||
|
lsm_str *filename;
|
||||||
|
if (lsm_entry_attr_get(&filename, handle, lander_attr_type_file_name) ==
|
||||||
|
lsm_error_ok) {
|
||||||
|
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_step_err lander_get_entry(lnm_http_conn *conn) {
|
||||||
lnm_http_loop_ctx *ctx = conn->ctx;
|
lnm_http_loop_ctx *ctx = conn->ctx;
|
||||||
lander_ctx *c_ctx = ctx->c;
|
lander_ctx *c_ctx = ctx->c;
|
||||||
|
@ -179,6 +271,9 @@ lnm_http_step_err lander_get_entry(lnm_http_conn *conn) {
|
||||||
case lander_entry_type_file:
|
case lander_entry_type_file:
|
||||||
res = lander_get_file(conn);
|
res = lander_get_file(conn);
|
||||||
break;
|
break;
|
||||||
|
case lander_entry_type_index:
|
||||||
|
res = lander_get_index(conn);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -124,3 +124,21 @@ lnm_http_step_err lander_post_file(lnm_http_conn *conn) {
|
||||||
|
|
||||||
return lnm_http_step_err_done;
|
return lnm_http_step_err_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
49
src/main.c
49
src/main.c
|
@ -11,11 +11,39 @@
|
||||||
|
|
||||||
const char *lander_server = "lander/" LANDER_VERSION;
|
const char *lander_server = "lander/" LANDER_VERSION;
|
||||||
const char *paste_template =
|
const char *paste_template =
|
||||||
"<!doctype html>\n"
|
"<!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"
|
"<head><link rel=\"stylesheet\" "
|
||||||
"<script src=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js\"></script>\n"
|
"href=\"https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/"
|
||||||
"<script>hljs.highlightAll();</script></head>\n"
|
"styles/stackoverflow-dark.min.css\">\n"
|
||||||
"<body><h1>{{ header }}</h1><pre><code>{{ paste }}</code></pre></body>";
|
"<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>\n"
|
||||||
|
"<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"
|
||||||
|
"<h2>Pastes</h2>\n"
|
||||||
|
"<ul>\n"
|
||||||
|
"{{ paste start }}\n"
|
||||||
|
"<li><a href=\"/{{ full_key }}\">{{ filename }}</a></li>\n"
|
||||||
|
"{{ paste end }}\n"
|
||||||
|
"</ul>\n"
|
||||||
|
"</body>\n";
|
||||||
|
|
||||||
lnm_http_loop *loop_init(lander_gctx *gctx, const char *api_key) {
|
lnm_http_loop *loop_init(lander_gctx *gctx, const char *api_key) {
|
||||||
lnm_http_loop *hl;
|
lnm_http_loop *hl;
|
||||||
|
@ -27,7 +55,7 @@ lnm_http_loop *loop_init(lander_gctx *gctx, const char *api_key) {
|
||||||
lnm_http_loop_set_api_key(hl, api_key);
|
lnm_http_loop_set_api_key(hl, api_key);
|
||||||
lnm_http_loop_set_server(hl, lander_server);
|
lnm_http_loop_set_server(hl, lander_server);
|
||||||
|
|
||||||
lnm_http_step_init(&step, lander_get_index);
|
lnm_http_step_init(&step, lander_get_root);
|
||||||
lnm_http_route_init_literal(&route, lnm_http_method_get, "/", step);
|
lnm_http_route_init_literal(&route, lnm_http_method_get, "/", step);
|
||||||
lnm_http_loop_route_add(hl, route);
|
lnm_http_loop_route_add(hl, route);
|
||||||
|
|
||||||
|
@ -57,6 +85,14 @@ lnm_http_loop *loop_init(lander_gctx *gctx, const char *api_key) {
|
||||||
lnm_http_step_append(&step, step, lander_stream_body_to_entry);
|
lnm_http_step_append(&step, step, lander_stream_body_to_entry);
|
||||||
lnm_http_loop_route_add(hl, route);
|
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_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_step_init(&step, lnm_http_loop_step_auth);
|
||||||
lnm_http_route_init_regex(&route, lnm_http_method_delete, "^/([^/]+)$", 1,
|
lnm_http_route_init_regex(&route, lnm_http_method_delete, "^/([^/]+)$", 1,
|
||||||
step);
|
step);
|
||||||
|
@ -100,6 +136,7 @@ int main() {
|
||||||
c_gctx->data_dir = data_dir_s;
|
c_gctx->data_dir = data_dir_s;
|
||||||
|
|
||||||
ltm_template_compile(&c_gctx->templates.paste, paste_template);
|
ltm_template_compile(&c_gctx->templates.paste, paste_template);
|
||||||
|
ltm_template_compile(&c_gctx->templates.index, index_template);
|
||||||
|
|
||||||
lsm_str *data_dir;
|
lsm_str *data_dir;
|
||||||
lsm_str_init_copy(&data_dir, (char *)data_dir_s);
|
lsm_str_init_copy(&data_dir, (char *)data_dir_s);
|
||||||
|
|
Loading…
Reference in New Issue