diff options
Diffstat (limited to 'datastore-leveldb/src/server.cpp')
-rw-r--r-- | datastore-leveldb/src/server.cpp | 110 |
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; +} |