summaryrefslogtreecommitdiff
path: root/datastore-leveldb/src/server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'datastore-leveldb/src/server.cpp')
-rw-r--r--datastore-leveldb/src/server.cpp110
1 files changed, 110 insertions, 0 deletions
diff --git a/datastore-leveldb/src/server.cpp b/datastore-leveldb/src/server.cpp
new file mode 100644
index 0000000..83f4cdb
--- /dev/null
+++ b/datastore-leveldb/src/server.cpp
@@ -0,0 +1,110 @@
+#include <csignal>
+#include <forward_list>
+#include <functional>
+#include <chrono>
+#include <thread>
+
+#include <boost/regex.hpp>
+#include <boost/program_options.hpp>
+#include "mongoose.h"
+
+#include "db.h"
+#include "web.h"
+
+typedef void(web_handler_t)(const boost::cmatch&, struct mg_connection *conn);
+
+std::forward_list<std::pair<boost::regex,std::function<web_handler_t>>> web_handler;
+
+struct mg_context *ctx;
+
+int begin_request_handler(struct mg_connection *conn) {
+ boost::cmatch match;
+
+ const struct mg_request_info *request_info = mg_get_request_info(conn);
+
+ std::cout << request_info->request_method << " "
+ << request_info->uri << std::endl;
+ for (auto item = web_handler.begin(); item != web_handler.end(); ++item) {
+ if (boost::regex_match(request_info->uri, match, (*item).first)) {
+ (*item).second(match, conn);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+struct sigaction old_action;
+
+// Stop the server.
+void sigint_handler(int s) {
+ mg_stop(ctx);
+ db_close();
+ exit(0);
+}
+
+namespace po = boost::program_options;
+
+int main(int argc, char **argv) {
+ // Program options
+ po::options_description desc("Program options");
+ desc.add_options()
+ ("wwwroot", po::value<std::string>()->required(), "Path to www root directory")
+ ("port", po::value<int>()->default_value(8080), "HTTP Port")
+ ("help", "Print help message")
+ ;
+
+ po::variables_map vm;
+ po::store(po::parse_command_line(argc, argv, desc), vm);
+ try {
+ po::notify(vm);
+ } catch(boost::program_options::required_option& e) {
+ std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
+ return 1;
+ }
+
+ if (vm.count("help")) {
+ std::cout << "Usage: " << argv[0] << std::endl << std::endl;
+ std::cout << desc << std::endl;
+ return 0;
+ }
+ const char *port = strdup(std::to_string(vm["port"].as<int>()).c_str());
+ const char *wwwroot = strdup(vm["wwwroot"].as<std::string>().c_str());
+
+ // Mongoose options
+ const char *options[] = {
+ "num_threads", "8",
+ "listening_ports", port,
+ "document_root", wwwroot,
+ NULL};
+
+ // Mongoose callbacks
+ struct mg_callbacks callbacks;
+ memset(&callbacks, 0, sizeof(callbacks));
+ callbacks.begin_request = begin_request_handler;
+
+ // Routing
+ web_handler.push_front(std::make_pair(
+ web_handle_api_value_R,
+ web_handle_api_value));
+ web_handler.push_front(std::make_pair(
+ web_handle_api_value_timestamp_R,
+ web_handle_api_value_timestamp));
+ web_handler.push_front(std::make_pair(
+ web_handle_api_range_R,
+ web_handle_api_range));
+ web_handler.push_front(std::make_pair(
+ web_handle_api_range_size_R,
+ web_handle_api_range_size));
+
+ // Signals: handle C-c
+ struct sigaction action;
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = &sigint_handler;
+ sigaction(SIGINT, &action, &old_action);
+
+ // Start the web server.
+ ctx = mg_start(&callbacks, NULL, options);
+ while (1)
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+ return 1;
+}