Skip to content

Commit

Permalink
-updated router;
Browse files Browse the repository at this point in the history
-updated examples to support changes in hot_teacup library;
  • Loading branch information
kamchatka-volcano committed Aug 24, 2024
1 parent 9556fd6 commit c7bdb4d
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 18 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
11 changes: 5 additions & 6 deletions examples/example_guestbook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -193,12 +193,11 @@ int main()
auto io = asyncgi::IO{4};
auto state = GuestBookState{};
auto router = asyncgi::Router<RouteContext>{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);
Expand Down
4 changes: 2 additions & 2 deletions examples/example_route_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"};
}
Expand All @@ -59,7 +59,7 @@ int main()
{
auto io = asyncgi::IO{4}; //4 threads processing requests
auto router = asyncgi::Router<RouteContext>{io};
router.route(asyncgi::rx{".*"}).process<AdminAuthorizer>();
router.route("{any}").process<AdminAuthorizer>();
router.route("/").process(
[](const http::Request&, RouteContext& context) -> http::Response
{
Expand Down
8 changes: 4 additions & 4 deletions examples/example_route_matcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"};
}
Expand All @@ -60,7 +60,7 @@ int main()
{
auto io = asyncgi::IO{4};
auto router = asyncgi::Router<RouteContext>{io};
router.route(asyncgi::rx{".*"}).process<AdminAuthorizer>();
router.route("{any}").process<AdminAuthorizer>();
router.route("/").process(
[](const http::Request&, RouteContext& context) -> http::Response
{
Expand All @@ -72,8 +72,8 @@ int main()

router.route("/login", http::RequestMethod::Get, AccessRole::Guest).process<LoginPage>();
router.route("/login", http::RequestMethod::Post, AccessRole::Guest).process<LoginPageAuthorize>();
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};
Expand Down
2 changes: 1 addition & 1 deletion examples/example_route_params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ int main()
auto router = asyncgi::Router{io};
router.route("/", http::RequestMethod::Get).process<GuestBookPage>(state);
router.route("/", http::RequestMethod::Post).process<GuestBookAddMessage>(state);
router.route(asyncgi::rx{"/delete/(.+)"}, http::RequestMethod::Post).process<GuestBookRemoveMessage>(state);
router.route("/delete/{str}", http::RequestMethod::Post).process<GuestBookRemoveMessage>(state);
router.route().set(http::ResponseStatus::_404_Not_Found, "Page not found");

auto server = asyncgi::Server{io, router};
Expand Down
2 changes: 1 addition & 1 deletion examples/example_route_params_user_defined_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ int main()
auto router = asyncgi::Router{io};
router.route("/", http::RequestMethod::Get).process<GuestBookPage>(state);
router.route("/", http::RequestMethod::Post).process<GuestBookAddMessage>(state);
router.route(asyncgi::rx{"/delete/(.+)"}, http::RequestMethod::Post).process<GuestBookRemoveMessage>(state);
router.route("/delete/{str}", http::RequestMethod::Post).process<GuestBookRemoveMessage>(state);
router.route().set(http::ResponseStatus::_404_Not_Found, "Page not found");

auto server = asyncgi::Server{io, router};
Expand Down
50 changes: 50 additions & 0 deletions include/asyncgi/router.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <unordered_map>

namespace asyncgi {
namespace config = whaleroute::config;

constexpr auto routeParamId(std::string_view paramTypeName)
{
return whaleroute::routeParamId(paramTypeName);
}

template<>
struct config::RouteParam<routeParamId("int")> {
using type = int;
inline static std::string_view name = "int";
inline static std::string_view regex = R"(\d+)";
};

template<>
struct config::RouteParam<routeParamId("str")> {
using type = std::string;
inline static std::string_view name = "str";
inline static std::string_view regex = R"([\w\$-\.\+!*'\(\)]+)";
};

template<>
struct config::RouteParam<routeParamId("any")> {
using type = std::string;
inline static std::string_view name = "path";
inline static std::string_view regex = R"([\w\$-\.\+!*'\(\)/]+)";
};

template<typename TRouteContext>
class Router;

Expand Down Expand Up @@ -107,6 +136,27 @@ class Router : public whaleroute::RequestRouter<http::Request, Responder, detail
response.send(http::ResponseStatus::_500_Internal_Server_Error);
};

void onUnregisteredRouteParameterError(std::string_view paramName) const final
{
throw Error{sfun::join_strings(
"Regular expression for route parameter '",
paramName,
"' isn't registered. Override asyncgi::Router::routeParamRegex() method to add it.")};
}

std::optional<std::string_view> routeParamRegex(std::string_view paramName) const final
{
static const auto routeParamRegex = std::unordered_map<std::string, std::string>{
{"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_;
};
Expand Down
2 changes: 0 additions & 2 deletions include/asyncgi/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
namespace asyncgi {
using _ = whaleroute::_;

using rx = whaleroute::rx;
namespace string_literals = whaleroute::string_literals;
using TrailingSlashMode = whaleroute::TrailingSlashMode;
template<int minSize = 0>
using RouteParameters = whaleroute::RouteParameters<minSize>;
Expand Down

0 comments on commit c7bdb4d

Please sign in to comment.