From 5d1574ffd47b4b8a6453407b056d8d6c08357048 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Thu, 8 Dec 2022 13:25:37 +0100 Subject: [PATCH] feat: store pastes in data file & memory --- src/entry.c | 6 +-- src/main.cpp | 136 +++++++++++++++++++-------------------------------- 2 files changed, 51 insertions(+), 91 deletions(-) diff --git a/src/entry.c b/src/entry.c index 5bbf7b5..e4747df 100644 --- a/src/entry.c +++ b/src/entry.c @@ -30,11 +30,7 @@ uint64_t entry_new(Entry **entry_ptr, EntryType type, const char *string) { Entry *entry = malloc(entry_size); entry->type = type; - if (string != NULL) { - memcpy(entry->string, string, str_len + 1); - } else { - entry->string[0] = '\0'; - } + memcpy(entry->string, string, str_len + 1); *entry_ptr = entry; return entry_size; diff --git a/src/main.cpp b/src/main.cpp index e01e4b5..fd1036b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,65 +33,52 @@ static const std::string index_page = R"( return crow::response(crow::status::UNAUTHORIZED); \ } -crow::response add_redirect(std::string base_url, Trie *trie, const char *url, - bool secure) { +crow::response add_entry_set_key(std::string base_url, Trie *trie, + const char *key, const char *body, + EntryType type) { Entry *new_entry; - uint64_t entry_size = entry_new(&new_entry, Redirect, url); + uint64_t entry_size = entry_new(&new_entry, type, body); + + // The key already gets copied into the trie, so this pointer is safe to use + // ever after unlocking the trie + trie_wlock(trie); + TrieExitCode status = trie_add(trie, key, new_entry, entry_size); + trie_unlock(trie); + + switch (status) { + case Ok: + return crow::response(base_url + key); + case AlreadyPresent: + return crow::response(crow::status::CONFLICT); + default: + return crow::response(crow::status::INTERNAL_SERVER_ERROR); + } +} + +crow::response add_entry(std::string base_url, Trie *trie, const char *body, + EntryType type, bool secure) { + Entry *new_entry; + uint64_t entry_size = entry_new(&new_entry, type, body); // The key already gets copied into the trie, so this pointer is safe to use // ever after unlocking the trie trie_wlock(trie); char *key; - TrieExitCode res = trie_add_random(trie, &key, new_entry, entry_size, secure); + TrieExitCode status = + trie_add_random(trie, &key, new_entry, entry_size, secure); trie_unlock(trie); - if (res != Ok) { - return crow::response(crow::status::INTERNAL_SERVER_ERROR); - } - std::string out = base_url + key; free(key); - return crow::response(out); -} - -bool store_paste(const char *key, const char *body) { - // Write paste contents to file - std::fstream file; - file.open(std::string("pastes/") + key, std::ios_base::out); - - if (!file.is_open()) { - return false; - } - - file << body; - file.close(); - - return true; -} - -crow::response add_paste(std::string base_url, Trie *trie, const char *body, - bool secure) { - Entry *new_entry; - uint64_t entry_size = entry_new(&new_entry, Paste, ""); - - trie_wlock(trie); - char *key; - TrieExitCode res = trie_add_random(trie, &key, new_entry, entry_size, secure); - trie_unlock(trie); - - if (res != Ok) { + switch (status) { + case Ok: + return crow::response(out); + case AlreadyPresent: + return crow::response(crow::status::CONFLICT); + default: return crow::response(crow::status::INTERNAL_SERVER_ERROR); } - - if (!store_paste(key, body)) { - return crow::response(crow::status::INTERNAL_SERVER_ERROR); - } - - std::string out = base_url + key; - free(key); - - return crow::response(out); } int main() { @@ -135,17 +122,22 @@ int main() { TrieExitCode status = trie_search(trie, (void **)&entry, key.c_str()); if (status == Ok) { - if (entry->type == Redirect) { + switch (entry->type) { + case Redirect: res.redirect(entry->string); - } else if (entry->type == Paste) { - res.set_static_file_info("pastes/" + key); + break; + case Paste: + res.write(entry->string); + break; + default: + res.code = 500; } } else { res.code = 404; } - res.end(); trie_unlock(trie); + res.end(); }); // Add a new Redirect with a short randomly generated key @@ -154,7 +146,7 @@ int main() { [api_key, base_url, trie](const crow::request req) { AUTH(); - return add_redirect(base_url, trie, req.body.c_str(), false); + return add_entry(base_url, trie, req.body.c_str(), Redirect, false); }); // Add a new Redirect with a long randomly generated key @@ -163,7 +155,7 @@ int main() { [api_key, base_url, trie](const crow::request req) { AUTH(); - return add_redirect(base_url, trie, req.body.c_str(), true); + return add_entry(base_url, trie, req.body.c_str(), Redirect, true); }); // Add a new Redirect with a given key @@ -172,23 +164,8 @@ int main() { [api_key, base_url, trie](const crow::request &req, std::string key) { AUTH(); - Entry *new_entry; - uint64_t entry_size = - entry_new(&new_entry, Redirect, req.body.c_str()); - - trie_wlock(trie); - TrieExitCode status = - trie_add(trie, key.c_str(), new_entry, entry_size); - trie_unlock(trie); - - switch (status) { - case Ok: - return crow::response(base_url + key); - case AlreadyPresent: - return crow::response(crow::status::CONFLICT); - default: - return crow::response(crow::status::INTERNAL_SERVER_ERROR); - } + return add_entry_set_key(base_url, trie, key.c_str(), + req.body.c_str(), Redirect); }); // Add a new Paste with a short randomly generated key @@ -197,7 +174,7 @@ int main() { [api_key, base_url, trie](const crow::request &req) { AUTH(); - return add_paste(base_url, trie, req.body.c_str(), false); + return add_entry(base_url, trie, req.body.c_str(), Paste, false); }); // Add a new Paste with a long randomly generated key @@ -206,7 +183,7 @@ int main() { [api_key, base_url, trie](const crow::request &req) { AUTH(); - return add_paste(base_url, trie, req.body.c_str(), true); + return add_entry(base_url, trie, req.body.c_str(), Paste, true); }); // Add a paste with a given key @@ -215,21 +192,8 @@ int main() { [api_key, base_url, trie](const crow::request &req, std::string key) { AUTH(); - Entry *new_entry; - uint64_t entry_size = entry_new(&new_entry, Paste, ""); - trie_wlock(trie); - TrieExitCode status = - trie_add(trie, key.c_str(), new_entry, entry_size); - trie_unlock(trie); - - switch (status) { - case Ok: - return crow::response(base_url + key); - case AlreadyPresent: - return crow::response(crow::status::CONFLICT); - default: - return crow::response(crow::status::INTERNAL_SERVER_ERROR); - } + return add_entry_set_key(base_url, trie, key.c_str(), + req.body.c_str(), Paste); }); app.port(18080).multithreaded().run(); }