diff --git a/test_webserver.cc b/test_webserver.cc index 84b04c9..7bcd18b 100644 --- a/test_webserver.cc +++ b/test_webserver.cc @@ -5,10 +5,44 @@ int main() { - std::cout << "starting webserver\n"; + std::cout << "serving http://127.0.0.1:8080/test.html\n"; pEp::Webserver web{net::ip::address::from_string("127.0.0.1"), 8080, "htdocs"}; - std::cout << "listening on localhost.8080\n"; + + std::cout << "adding handler for http://127.0.0.1:8080/handler/sample\n"; + web.add_url_handler("/handler/(?\\w+)", + [](boost::cmatch m, pEp::Webserver::request& req)->pEp::Webserver::response* { + pEp::Webserver::response *res = new pEp::Webserver::response; + +// https://www.boost.org/doc/libs/1_73_0/libs/beast/doc/html/beast/ref/boost__beast__http__response.html + + res->set(http::field::content_type, "text/json; charset=utf-8"); + res->keep_alive(req.keep_alive()); + + res->body() = + "{" + "\"Herausgeber\": \"Xema\"," + "\"Nummer\": \"1234-5678-9012-3456\"," + "\"Deckung\": 2e+6," + "\"Waehrung\": \"EURO\"," + "\"Inhaber\":" + "{" + "\"Name\": \"Mustermann\"," + "\"Vorname\": \"Max\"," + "\"maennlich\": true," + "\"Hobbys\": [\"Reiten\", \"Golfen\", \"Lesen\"]," + "\"Alter\": 42," + "\"Kinder\": []," + "\"Partner\": null" + "}" + "}"; + + res->prepare_payload(); + return res; + } + ); + web.run(); + return 0; } diff --git a/webserver.cc b/webserver.cc index 028f8a5..7a07c03 100644 --- a/webserver.cc +++ b/webserver.cc @@ -59,7 +59,7 @@ void Webserver::remove_url_handler(std::string url_regex) { void Webserver::deliver_status(tcp::socket *socket, Webserver::request req, http::status status) { http::response< http::string_body > res{status, req.version()}; - res.set(http::field::content_type, "text/html"); + res.set(http::field::content_type, "text/html; charset=utf-8"); res.keep_alive(req.keep_alive()); std::stringstream s; s << "" << int(status) << " " << status << ""; @@ -75,11 +75,7 @@ void Webserver::deliver_file(tcp::socket *socket, Webserver::request req) { static boost::regex file{"/([\\w\\d]{1,100}\\.[\\w\\d]{1,4})"}; boost::cmatch m; - // there's a strange bug without this string variable d - // req.target().data() may end with '\x10' - std::string d = req.target().data(); - if (d.back() == '\x10') - d.pop_back(); + std::string d{req.target().data(), req.target().length()}; if (boost::regex_match(d.c_str(), m, file)) { fs::path p{_doc_root}; p /= m[1]; @@ -110,12 +106,13 @@ void Webserver::deliver_file(tcp::socket *socket, Webserver::request req) } } -Webserver::handler_t Webserver::find_handler(request& r, boost::cmatch& m) +Webserver::handler_t Webserver::find_handler(request& req, boost::cmatch& m) { std::lock_guard< std::mutex > lock(_mtx); for (auto it=_urls.begin(); it!=_urls.end(); ++it) { - if (boost::regex_match(r.target().data(), m, it->second.regex)) + std::string d{req.target().data(), req.target().length()}; + if (boost::regex_match(d.c_str(), m, it->second.regex)) return it->second.handler; } @@ -159,9 +156,25 @@ void Webserver::do_session(tcp::socket *socket) } break; - case http::verb::get: - deliver_file(socket, req); - 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; + } + } + else { + deliver_file(socket, req); + } + } + break; default: deliver_status(socket, req, http::status::method_not_allowed); diff --git a/webserver.hh b/webserver.hh index fab5f13..2344a2b 100644 --- a/webserver.hh +++ b/webserver.hh @@ -60,7 +60,7 @@ namespace pEp { protected: void deliver_status(tcp::socket *socket, request req, http::status status); void deliver_file(tcp::socket *socket, request req); - handler_t find_handler(request& r, boost::cmatch& m); + handler_t find_handler(request& req, boost::cmatch& m); void do_session(tcp::socket *socket); }; };