Skip to content

Commit

Permalink
Merge branch 'master' of github.com:motis-project/net
Browse files Browse the repository at this point in the history
# Conflicts:
#	CMakeLists.txt
#	include/net/web_server/query_router.h
  • Loading branch information
felixguendling committed Jul 2, 2024
2 parents bd85552 + 7ac868a commit f13c939
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 12 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ target_link_libraries(web-server
boost
boost-iostreams
utl
boost-url
)
target_include_directories(web-server SYSTEM PUBLIC include)
if(MSVC)
Expand Down
34 changes: 33 additions & 1 deletion include/net/web_server/query_router.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "boost/beast/http/status.hpp"
#include "boost/json.hpp"
#include "boost/url/url_view.hpp"

#include "net/web_server/web_server.h"

Expand All @@ -19,7 +20,9 @@ using request = web_server::http_req_t;
using reply = web_server::http_res_t;

struct route_request : public web_server::http_req_t {
route_request(request req) : web_server::http_req_t(req) {}
route_request(request req, boost::urls::url_view const url)
: web_server::http_req_t(req), url_{url} {}
boost::urls::url_view url_;
std::vector<std::string> path_params_;
std::string username_, password_;
};
Expand All @@ -42,6 +45,11 @@ concept JsonRouteHandler =
{ f(arg) } -> JSON;
};

template <typename Fn>
concept UrlRouteHandler = requires(boost::urls::url_view const& url, Fn f) {
{ f(url) } -> std::convertible_to<boost::json::value>;
};

struct query_router {
using route_request_handler = std::function<void(
route_request const&, web_server::http_res_cb_t, bool)>;
Expand Down Expand Up @@ -100,6 +108,30 @@ struct query_router {
});
}

template <UrlRouteHandler Fn>
query_router& route(std::string method, std::string const& path_regex,
Fn&& fn) {
return route(std::move(method), path_regex,
[fn = std::forward<Fn>(fn)](
route_request req, web_server::http_res_cb_t const& cb,
bool is_ssl) {
try {
auto res = net::web_server::string_res_t{
boost::beast::http::status::ok, req.version()};
res.body() = boost::json::serialize(fn(req.url_));
res.keep_alive(req.keep_alive());
cb(res);
} catch (std::exception const& e) {
std::cout << "exception: " << e.what() << "\n";
auto res = net::web_server::empty_res_t{
boost::beast::http::status::internal_server_error,
req.version()};
res.keep_alive(req.keep_alive());
cb(res);
}
});
}

void operator()(web_server::http_req_t, web_server::http_res_cb_t const&,
bool);
void reply_hook(std::function<void(web_server::http_res_t&)> reply_hook);
Expand Down
25 changes: 14 additions & 11 deletions src/web_server/query_router.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
#include <utility>

#include "boost/algorithm/string/predicate.hpp"
#include "boost/url.hpp"

#include "net/base64.h"
#include "net/web_server/enable_cors.h"
#include "net/web_server/responses.h"
#include "net/web_server/url_decode.h"

namespace url = boost::urls;

namespace net {

query_router& query_router::route(std::string method,
Expand Down Expand Up @@ -49,26 +52,26 @@ void query_router::serve_files(std::filesystem::path const& p) {
void query_router::operator()(web_server::http_req_t req,
web_server::http_res_cb_t const& cb,
bool is_ssl) {
std::cmatch match;
auto route = std::find_if(
std::begin(routes_), std::end(routes_),
[&match, &req](handler const& route) {
return (route.method_ == "*" || route.method_ == req.method_string()) &&
std::regex_match(
&*std::begin(req.target()),
(&*std::begin(req.target())) + req.target().size(), match,
route.path_);
auto const url = url::url_view{req.target()};
auto const path = url.path();

auto match = std::cmatch{};
auto route =
std::find_if(begin(routes_), end(routes_), [&](handler const& h) {
return (h.method_ == "*" || h.method_ == req.method_string()) &&
std::regex_match(path.c_str(), path.c_str() + path.size(), match,
h.path_);
});

if (route == std::end(routes_)) {
if (route == end(routes_)) {
auto rep = reply{not_found_response(req)};
if (reply_hook_) {
reply_hook_(rep);
}
return cb(std::move(rep));
}

route_request route_req(req);
route_request route_req(req, url);
for (unsigned i = 1; i < match.size(); ++i) {
route_req.path_params_.push_back(match[i]);
}
Expand Down

0 comments on commit f13c939

Please sign in to comment.