diff --git a/webserver.cc b/webserver.cc index c230e4f..7c51bf4 100644 --- a/webserver.cc +++ b/webserver.cc @@ -14,10 +14,11 @@ namespace fs = boost::filesystem; namespace pEp { Webserver::Webserver(net::ip::address addr, unsigned short port, const std::string& doc_root) - : _ioc(1) - , _acceptor(_ioc, {addr, port}) - , _doc_root(doc_root) - , _running(false) + : _ioc{1} + , _acceptor{_ioc, {addr, port}} + , _doc_root{doc_root} + , _generic_handler{} + , _running{false} { } @@ -54,7 +55,7 @@ beast::string_view Webserver::mime_type(beast::string_view path) void Webserver::add_url_handler(const std::string& url_regex, handler_t handler) { std::lock_guard< std::mutex > lock(_mtx); - _urls.emplace(std::pair< std::string, Handling >(url_regex, {boost::regex(url_regex), handler})); + _urls.emplace(url_regex, Handling{boost::regex(url_regex), handler}); } @@ -65,6 +66,18 @@ void Webserver::remove_url_handler(const std::string& url_regex) } +void Webserver::add_generic_url_handler(handler_t handler) +{ + _generic_handler = handler; +} + + +void Webserver::remove_generic_url_handler() +{ + _generic_handler = nullptr; +} + + void Webserver::deliver_status(tcp::socket *socket, Webserver::request req, http::status status) { http::response< http::string_body > res{status, req.version()}; @@ -127,9 +140,10 @@ Webserver::handler_t Webserver::find_handler(request& req, boost::cmatch& m) return it->second.handler; } - return nullptr; + return _generic_handler; // might be empty std::function! } + void Webserver::do_session(tcp::socket *socket) { beast::error_code ec; @@ -146,51 +160,35 @@ void Webserver::do_session(tcp::socket *socket) throw std::ios_base::failure(ec.message()); } - switch (req.method()) { - case http::verb::post: { + const auto method = req.method(); + switch (method) + { + case http::verb::post: // fall through + case http::verb::get: + { boost::cmatch m; Webserver::handler_t handler = find_handler(req, m); if (handler) { Webserver::response *res = handler(m, req); - if (!res) { - deliver_status(socket, req, http::status::not_found); - } - else { + if (res) { http::write(*socket, *res, ec); delete res; } - } - else { - deliver_status(socket, req, http::status::not_found); - } - } - break; - - case http::verb::get: { - boost::cmatch m; - Webserver::handler_t handler = find_handler(req, m); - - if (handler) { - Webserver::response *res = handler(m, req); - if (!res) { - deliver_status(socket, req, http::status::not_found); - } else { - http::write(*socket, *res, ec); - delete res; + deliver_status(socket, req, http::status::not_found); } } else { - if(!_doc_root.empty()) + if(method == http::verb::get && !_doc_root.empty()) { deliver_file(socket, req); }else{ deliver_status(socket, req, http::status::not_found); } } + break; } - break; default: deliver_status(socket, req, http::status::method_not_allowed); diff --git a/webserver.hh b/webserver.hh index 2b9de00..75825be 100644 --- a/webserver.hh +++ b/webserver.hh @@ -42,6 +42,7 @@ namespace pEp { tcp::acceptor _acceptor; std::string _doc_root; std::unordered_map< std::string, Handling > _urls; + handler_t _generic_handler; bool _running; std::mutex _mtx; @@ -57,6 +58,10 @@ namespace pEp { void add_url_handler (const std::string& url_regex, handler_t handler); void remove_url_handler(const std::string& url_regex); + // the generic handler will be called if the URL does not match any registered handlers + void add_generic_url_handler (handler_t handler); + void remove_generic_url_handler(); + void run(); void shutdown();