feat: store pastes in data file & memory

generic-data-trie
Jef Roosens 2022-12-08 13:25:37 +01:00
parent d7d4821b66
commit 5d1574ffd4
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
2 changed files with 51 additions and 91 deletions

View File

@ -30,11 +30,7 @@ uint64_t entry_new(Entry **entry_ptr, EntryType type, const char *string) {
Entry *entry = malloc(entry_size); Entry *entry = malloc(entry_size);
entry->type = type; entry->type = type;
if (string != NULL) { memcpy(entry->string, string, str_len + 1);
memcpy(entry->string, string, str_len + 1);
} else {
entry->string[0] = '\0';
}
*entry_ptr = entry; *entry_ptr = entry;
return entry_size; return entry_size;

View File

@ -33,65 +33,52 @@ static const std::string index_page = R"(
return crow::response(crow::status::UNAUTHORIZED); \ return crow::response(crow::status::UNAUTHORIZED); \
} }
crow::response add_redirect(std::string base_url, Trie *trie, const char *url, crow::response add_entry_set_key(std::string base_url, Trie *trie,
bool secure) { const char *key, const char *body,
EntryType type) {
Entry *new_entry; 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 // The key already gets copied into the trie, so this pointer is safe to use
// ever after unlocking the trie // ever after unlocking the trie
trie_wlock(trie); trie_wlock(trie);
char *key; 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); trie_unlock(trie);
if (res != Ok) {
return crow::response(crow::status::INTERNAL_SERVER_ERROR);
}
std::string out = base_url + key; std::string out = base_url + key;
free(key); free(key);
return crow::response(out); switch (status) {
} case Ok:
return crow::response(out);
bool store_paste(const char *key, const char *body) { case AlreadyPresent:
// Write paste contents to file return crow::response(crow::status::CONFLICT);
std::fstream file; default:
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) {
return crow::response(crow::status::INTERNAL_SERVER_ERROR); 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() { int main() {
@ -135,17 +122,22 @@ int main() {
TrieExitCode status = trie_search(trie, (void **)&entry, key.c_str()); TrieExitCode status = trie_search(trie, (void **)&entry, key.c_str());
if (status == Ok) { if (status == Ok) {
if (entry->type == Redirect) { switch (entry->type) {
case Redirect:
res.redirect(entry->string); res.redirect(entry->string);
} else if (entry->type == Paste) { break;
res.set_static_file_info("pastes/" + key); case Paste:
res.write(entry->string);
break;
default:
res.code = 500;
} }
} else { } else {
res.code = 404; res.code = 404;
} }
res.end();
trie_unlock(trie); trie_unlock(trie);
res.end();
}); });
// Add a new Redirect with a short randomly generated key // 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) { [api_key, base_url, trie](const crow::request req) {
AUTH(); 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 // 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) { [api_key, base_url, trie](const crow::request req) {
AUTH(); 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 // 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) { [api_key, base_url, trie](const crow::request &req, std::string key) {
AUTH(); AUTH();
Entry *new_entry; return add_entry_set_key(base_url, trie, key.c_str(),
uint64_t entry_size = req.body.c_str(), Redirect);
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);
}
}); });
// Add a new Paste with a short randomly generated key // 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) { [api_key, base_url, trie](const crow::request &req) {
AUTH(); 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 // 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) { [api_key, base_url, trie](const crow::request &req) {
AUTH(); 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 // 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) { [api_key, base_url, trie](const crow::request &req, std::string key) {
AUTH(); AUTH();
Entry *new_entry; return add_entry_set_key(base_url, trie, key.c_str(),
uint64_t entry_size = entry_new(&new_entry, Paste, ""); req.body.c_str(), 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);
}
}); });
app.port(18080).multithreaded().run(); app.port(18080).multithreaded().run();
} }