From c7bdb4da1739ac2434bc4f7df52e0ae845c32e0e Mon Sep 17 00:00:00 2001 From: kamchatka-volcano Date: Fri, 23 Aug 2024 00:56:03 +0500 Subject: [PATCH] -updated router; -updated examples to support changes in hot_teacup library; --- CMakeLists.txt | 4 +- examples/example_guestbook.cpp | 11 ++-- examples/example_route_context.cpp | 4 +- examples/example_route_matcher.cpp | 8 +-- examples/example_route_params.cpp | 2 +- ...xample_route_params_user_defined_types.cpp | 2 +- include/asyncgi/router.h | 50 +++++++++++++++++++ include/asyncgi/types.h | 2 - 8 files changed, 65 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 83cdd91..018b647 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ endif() SealLake_Bundle( NAME asyncgi_sfun GIT_REPOSITORY https://github.com/kamchatka-volcano/sfun.git - GIT_TAG v5.1.0 + GIT_TAG develop DESTINATION include/asyncgi/detail/external DIRECTORIES include/sfun TEXT_REPLACEMENTS @@ -31,7 +31,7 @@ SealLake_Bundle( SealLake_Bundle( NAME asyncgi_whaleroute GIT_REPOSITORY https://github.com/kamchatka-volcano/whaleroute.git - GIT_TAG v3.1.0 + GIT_TAG dev DESTINATION include/asyncgi/detail/external DIRECTORIES include/whaleroute TEXT_REPLACEMENTS diff --git a/examples/example_guestbook.cpp b/examples/example_guestbook.cpp index 9ff5023..ceeae25 100644 --- a/examples/example_guestbook.cpp +++ b/examples/example_guestbook.cpp @@ -46,14 +46,14 @@ http::Response showLoginPage(const http::Request&) http::Response loginAdmin(const http::Request& request) { if (request.formField("login") == "admin" && request.formField("passwd") == "12345") - return {http::Redirect{"/"}, {http::Cookie("admin_id", "ADMIN_SECRET")}}; + return {http::Redirect{"/"}, http::Cookies{{"admin_id", "ADMIN_SECRET"}}}; else return http::Redirect{"/login"}; } http::Response logoutAdmin(const http::Request&) { - return {http::Redirect{"/"}, {http::Cookie("admin_id", "")}}; + return {http::Redirect{"/"}, http::Cookies{{"admin_id", ""}}}; } struct GuestBookMessage { @@ -193,12 +193,11 @@ int main() auto io = asyncgi::IO{4}; auto state = GuestBookState{}; auto router = asyncgi::Router{io}; - router.route(asyncgi::rx{".*"}).process(authorizeAdmin); + router.route("{any}").process(authorizeAdmin); router.route("/", http::RequestMethod::Get).process(showGuestBookPage(state)); router.route("/", http::RequestMethod::Post).process(addMessage(state)); - router.route(asyncgi::rx{"/delete/(.+)"}, http::RequestMethod::Post, AccessRole::Admin) - .process(removeMessage(state)); - router.route(asyncgi::rx{"/delete/(.+)"}, http::RequestMethod::Post, AccessRole::Guest) + router.route("/delete/{str}/", http::RequestMethod::Post, AccessRole::Admin).process(removeMessage(state)); + router.route("/delete/{str}/", http::RequestMethod::Post, AccessRole::Guest) .set(http::ResponseStatus::_401_Unauthorized); router.route("/login", http::RequestMethod::Get, AccessRole::Guest).process(showLoginPage); router.route("/login", http::RequestMethod::Post, AccessRole::Guest).process(loginAdmin); diff --git a/examples/example_route_context.cpp b/examples/example_route_context.cpp index 45d5202..310e32f 100644 --- a/examples/example_route_context.cpp +++ b/examples/example_route_context.cpp @@ -46,7 +46,7 @@ struct LoginPageAuthorize { { if (context.role == AccessRole::Guest) { if (request.formField("login") == "admin" && request.formField("passwd") == "12345") - return {http::Redirect{"/"}, {asyncgi::http::Cookie("admin_id", "ADMIN_SECRET")}}; + return {http::Redirect{"/"}, asyncgi::http::Cookies{{"admin_id", "ADMIN_SECRET"}}}; else return http::Redirect{"/login"}; } @@ -59,7 +59,7 @@ int main() { auto io = asyncgi::IO{4}; //4 threads processing requests auto router = asyncgi::Router{io}; - router.route(asyncgi::rx{".*"}).process(); + router.route("{any}").process(); router.route("/").process( [](const http::Request&, RouteContext& context) -> http::Response { diff --git a/examples/example_route_matcher.cpp b/examples/example_route_matcher.cpp index b73424d..e4a2817 100644 --- a/examples/example_route_matcher.cpp +++ b/examples/example_route_matcher.cpp @@ -42,7 +42,7 @@ struct LoginPageAuthorize { http::Response operator()(const http::Request& request) { if (request.formField("login") == "admin" && request.formField("passwd") == "12345") - return {http::Redirect{"/"}, {asyncgi::http::Cookie("admin_id", "ADMIN_SECRET")}}; + return {http::Redirect{"/"}, asyncgi::http::Cookies{{"admin_id", "ADMIN_SECRET"}}}; return http::Redirect{"/login"}; } @@ -60,7 +60,7 @@ int main() { auto io = asyncgi::IO{4}; auto router = asyncgi::Router{io}; - router.route(asyncgi::rx{".*"}).process(); + router.route("{any}").process(); router.route("/").process( [](const http::Request&, RouteContext& context) -> http::Response { @@ -72,8 +72,8 @@ int main() router.route("/login", http::RequestMethod::Get, AccessRole::Guest).process(); router.route("/login", http::RequestMethod::Post, AccessRole::Guest).process(); - router.route("/login", http::RequestMethod::Get, AccessRole::Admin).set("/", http::RedirectType::Found); - router.route("/login", http::RequestMethod::Post, AccessRole::Admin).set("/", http::RedirectType::Found); + router.route("/login", http::RequestMethod::Get, AccessRole::Admin).set(http::Redirect{"/"}); + router.route("/login", http::RequestMethod::Post, AccessRole::Admin).set(http::Redirect{"/"}); router.route().set(http::ResponseStatus::_404_Not_Found, "Page not found"); auto server = asyncgi::Server{io, router}; diff --git a/examples/example_route_params.cpp b/examples/example_route_params.cpp index df555dc..7b0c554 100644 --- a/examples/example_route_params.cpp +++ b/examples/example_route_params.cpp @@ -107,7 +107,7 @@ int main() auto router = asyncgi::Router{io}; router.route("/", http::RequestMethod::Get).process(state); router.route("/", http::RequestMethod::Post).process(state); - router.route(asyncgi::rx{"/delete/(.+)"}, http::RequestMethod::Post).process(state); + router.route("/delete/{str}", http::RequestMethod::Post).process(state); router.route().set(http::ResponseStatus::_404_Not_Found, "Page not found"); auto server = asyncgi::Server{io, router}; diff --git a/examples/example_route_params_user_defined_types.cpp b/examples/example_route_params_user_defined_types.cpp index c784ff2..a786b8b 100644 --- a/examples/example_route_params_user_defined_types.cpp +++ b/examples/example_route_params_user_defined_types.cpp @@ -119,7 +119,7 @@ int main() auto router = asyncgi::Router{io}; router.route("/", http::RequestMethod::Get).process(state); router.route("/", http::RequestMethod::Post).process(state); - router.route(asyncgi::rx{"/delete/(.+)"}, http::RequestMethod::Post).process(state); + router.route("/delete/{str}", http::RequestMethod::Post).process(state); router.route().set(http::ResponseStatus::_404_Not_Found, "Page not found"); auto server = asyncgi::Server{io, router}; diff --git a/include/asyncgi/router.h b/include/asyncgi/router.h index 2d0f6f2..02efc94 100755 --- a/include/asyncgi/router.h +++ b/include/asyncgi/router.h @@ -7,15 +7,44 @@ #include "types.h" #include "detail/external/sfun/functional.h" #include "detail/external/sfun/interface.h" +#include "detail/external/sfun/string_utils.h" #include "detail/external/sfun/type_traits.h" #include "detail/external/whaleroute/requestrouter.h" +#include "detail/external/whaleroute/routeparam.h" #include "detail/routeresponsecontextaccessor.h" #include "http/request.h" #include "http/response.h" +#include namespace asyncgi { namespace config = whaleroute::config; +constexpr auto routeParamId(std::string_view paramTypeName) +{ + return whaleroute::routeParamId(paramTypeName); +} + +template<> +struct config::RouteParam { + using type = int; + inline static std::string_view name = "int"; + inline static std::string_view regex = R"(\d+)"; +}; + +template<> +struct config::RouteParam { + using type = std::string; + inline static std::string_view name = "str"; + inline static std::string_view regex = R"([\w\$-\.\+!*'\(\)]+)"; +}; + +template<> +struct config::RouteParam { + using type = std::string; + inline static std::string_view name = "path"; + inline static std::string_view regex = R"([\w\$-\.\+!*'\(\)/]+)"; +}; + template class Router; @@ -107,6 +136,27 @@ class Router : public whaleroute::RequestRouter routeParamRegex(std::string_view paramName) const final + { + static const auto routeParamRegex = std::unordered_map{ + {"int", R"(\d+)"}, + {"str", R"([\w\$-\.\+!*'\(\)]+)"}, + {"any", R"([\w\$-\.\+!*'\(\)/]+)"}}; + + auto it = routeParamRegex.find(std::string{paramName}); + if (it == routeParamRegex.end()) + return std::nullopt; + return it->second; + } + private: detail::EventHandlerProxy eventHandler_; }; diff --git a/include/asyncgi/types.h b/include/asyncgi/types.h index 217e055..6923d9a 100755 --- a/include/asyncgi/types.h +++ b/include/asyncgi/types.h @@ -9,8 +9,6 @@ namespace asyncgi { using _ = whaleroute::_; -using rx = whaleroute::rx; -namespace string_literals = whaleroute::string_literals; using TrailingSlashMode = whaleroute::TrailingSlashMode; template using RouteParameters = whaleroute::RouteParameters;