#include "crow.h" extern "C" { #include "ternarytrie.h" } #define ENV(var, env_var) \ const char *var = getenv(env_var); \ if (var == NULL) { \ printf("Missing environment variable %s.\n", env_var); \ return 1; \ } #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); \ } int main() { // Initialize random seed for generating URLs srand(time(NULL)); ENV(api_key, "LANDER_API_KEY"); ENV(base_url, "LANDER_BASE_URL"); const size_t base_url_len = strlen(base_url); TernaryTrie *trie = ternarytrie_init(); std::string file_path = "lander.data"; ternarytrie_populate(trie, file_path.c_str()); crow::SimpleApp app; app.loglevel(crow::LogLevel::Warning); CROW_ROUTE(app, "/") .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(); }); CROW_ROUTE(app, "/").methods(crow::HTTPMethod::Post)( [api_key, base_url, base_url_len, trie](const crow::request req) { AUTH(); char *key = ternarytrie_add_random(trie, req.body.c_str()); if (key == NULL) { return crow::response(crow::status::INTERNAL_SERVER_ERROR); } // 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); }); CROW_ROUTE(app, "/") .methods(crow::HTTPMethod::Post)( [api_key, base_url, base_url_len, trie](const crow::request &req, std::string s) { AUTH(); bool added = ternarytrie_add(trie, s.c_str(), req.body.c_str()); if (!added) { return crow::response(crow::status::CONFLICT); } // 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); }); app.port(18080).multithreaded().run(); }