2022-11-15 16:05:47 +01:00
|
|
|
#include "crow.h"
|
2022-11-15 17:25:04 +01:00
|
|
|
|
|
|
|
extern "C" {
|
2022-11-15 17:05:14 +01:00
|
|
|
#include "ternarytrie.h"
|
2022-11-15 17:25:04 +01:00
|
|
|
}
|
2022-11-15 16:05:47 +01:00
|
|
|
|
2022-11-21 12:03:16 +01:00
|
|
|
#define ENV(var, env_var) \
|
|
|
|
const char *var = getenv(env_var); \
|
|
|
|
if (var == NULL) { \
|
|
|
|
printf("Missing environment variable %s.\n", env_var); \
|
|
|
|
return 1; \
|
|
|
|
}
|
2022-11-15 17:05:14 +01:00
|
|
|
|
2022-11-21 12:03:16 +01:00
|
|
|
#define AUTH() \
|
|
|
|
std::string provided_api_key = req.get_header_value("X-Api-Key"); \
|
|
|
|
if (strcmp(api_key, provided_api_key.c_str()) != 0) { \
|
|
|
|
return crow::response(crow::status::UNAUTHORIZED); \
|
2022-11-15 21:12:08 +01:00
|
|
|
}
|
2022-11-15 16:05:47 +01:00
|
|
|
|
2022-11-21 12:03:16 +01:00
|
|
|
int main() {
|
2022-11-21 12:21:01 +01:00
|
|
|
// Initialize random seed for generating URLs
|
|
|
|
srand(time(NULL));
|
|
|
|
|
2022-11-21 12:03:16 +01:00
|
|
|
ENV(api_key, "LANDER_API_KEY");
|
|
|
|
ENV(base_url, "LANDER_BASE_URL");
|
|
|
|
|
2022-11-21 12:21:01 +01:00
|
|
|
const size_t base_url_len = strlen(base_url);
|
|
|
|
|
2022-11-15 21:12:08 +01:00
|
|
|
TernaryTrie *trie = ternarytrie_init();
|
2022-11-15 17:25:04 +01:00
|
|
|
|
2022-11-15 22:49:36 +01:00
|
|
|
std::string file_path = "lander.data";
|
|
|
|
ternarytrie_populate(trie, file_path.c_str());
|
|
|
|
|
2022-11-15 21:12:08 +01:00
|
|
|
crow::SimpleApp app;
|
2022-11-15 17:25:04 +01:00
|
|
|
|
2022-11-21 12:03:16 +01:00
|
|
|
app.loglevel(crow::LogLevel::Warning);
|
2022-11-15 21:12:08 +01:00
|
|
|
|
|
|
|
CROW_ROUTE(app, "/<string>")
|
|
|
|
.methods(crow::HTTPMethod::Get)(
|
|
|
|
[trie](crow::response &res, std::string s) {
|
|
|
|
char *payload = ternarytrie_search(trie, s.c_str());
|
|
|
|
|
|
|
|
if (payload != NULL) {
|
|
|
|
res.redirect(payload);
|
|
|
|
} else {
|
|
|
|
res.code = 404;
|
|
|
|
}
|
|
|
|
|
|
|
|
res.end();
|
|
|
|
});
|
2022-11-21 12:03:16 +01:00
|
|
|
CROW_ROUTE(app, "/").methods(crow::HTTPMethod::Post)(
|
2022-11-21 12:21:01 +01:00
|
|
|
[api_key, base_url, base_url_len, trie](const crow::request req) {
|
2022-11-21 12:03:16 +01:00
|
|
|
AUTH();
|
|
|
|
|
|
|
|
char *key = ternarytrie_add_random(trie, req.body.c_str());
|
|
|
|
|
|
|
|
if (key == NULL) {
|
|
|
|
return crow::response(crow::status::INTERNAL_SERVER_ERROR);
|
|
|
|
}
|
|
|
|
|
2022-11-21 12:21:01 +01:00
|
|
|
// Concatenate base URL & key
|
|
|
|
char *res = (char *)malloc(base_url_len + RANDOM_KEY_LENGTH + 1);
|
|
|
|
memcpy(res, base_url, base_url_len);
|
|
|
|
memcpy(res + base_url_len, key, RANDOM_KEY_LENGTH + 1);
|
|
|
|
|
|
|
|
return crow::response(res);
|
2022-11-21 12:03:16 +01:00
|
|
|
});
|
|
|
|
CROW_ROUTE(app, "/<string>")
|
|
|
|
.methods(crow::HTTPMethod::Post)(
|
2022-11-21 12:21:01 +01:00
|
|
|
[api_key, base_url, base_url_len, trie](const crow::request &req,
|
|
|
|
std::string s) {
|
2022-11-21 12:03:16 +01:00
|
|
|
AUTH();
|
|
|
|
|
2022-11-21 12:21:01 +01:00
|
|
|
bool added = ternarytrie_add(trie, s.c_str(), req.body.c_str());
|
2022-11-21 12:03:16 +01:00
|
|
|
|
2022-11-21 12:21:01 +01:00
|
|
|
if (!added) {
|
2022-11-21 12:03:16 +01:00
|
|
|
return crow::response(crow::status::CONFLICT);
|
|
|
|
}
|
|
|
|
|
2022-11-21 12:21:01 +01:00
|
|
|
// Concatenate base URL & key
|
|
|
|
char *res = (char *)malloc(base_url_len + RANDOM_KEY_LENGTH + 1);
|
|
|
|
memcpy(res, base_url, base_url_len);
|
|
|
|
memcpy(res + base_url_len, s.c_str(), RANDOM_KEY_LENGTH + 1);
|
|
|
|
|
|
|
|
return crow::response(res);
|
2022-11-21 12:03:16 +01:00
|
|
|
});
|
2022-11-15 21:12:08 +01:00
|
|
|
|
|
|
|
app.port(18080).multithreaded().run();
|
2022-11-15 16:05:47 +01:00
|
|
|
}
|