Skip to content

Commit

Permalink
-wip
Browse files Browse the repository at this point in the history
  • Loading branch information
kamchatka-volcano committed Jan 4, 2024
1 parent 5458f2f commit fd4fadf
Show file tree
Hide file tree
Showing 13 changed files with 145 additions and 99 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ jobs:
lunchtoast_exec: "lunchtoast.exe",
shell_command: -shell="msys2 -c",
tags: -skip=linux,
nginx_exec: "c:/tools/nginx-1.25.2/nginx.exe",
nginx_exec: "c:/tools/nginx-1.25.3/nginx.exe",
nginx_cfg: "nginx_windows.conf"
}
- {
Expand Down
26 changes: 13 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,31 @@ set(ASYNCGI_FCGI_RESPONDER_OBJECT_LIB ON)
SealLake_Bundle(
NAME asyncgi_fcgi_responder
GIT_REPOSITORY https://github.com/kamchatka-volcano/fcgi_responder.git
GIT_TAG v1.6.1
GIT_TAG v1.6.2
TEXT_REPLACEMENTS
"namespace fcgi" "namespace asyncgi::fcgi"
)

SealLake_Bundle(
NAME asyncgi_whaleroute
GIT_REPOSITORY https://github.com/kamchatka-volcano/whaleroute.git
GIT_TAG v2.0.1
DESTINATION include/asyncgi/detail/external
DIRECTORIES include/whaleroute
TEXT_REPLACEMENTS
NAME asyncgi_whaleroute
GIT_REPOSITORY https://github.com/kamchatka-volcano/whaleroute.git
GIT_TAG dev
DESTINATION include/asyncgi/detail/external
DIRECTORIES include/whaleroute
TEXT_REPLACEMENTS
"namespace whaleroute" "namespace asyncgi::whaleroute"
"WHALEROUTE_" "ASYNCGI_WHALEROUTE_"
)

set(ASYNCGI_HOT_TEACUP_OBJECT_LIB ON)
SealLake_Bundle(
NAME asyncgi_hot_teacup
GIT_REPOSITORY https://github.com/kamchatka-volcano/hot_teacup.git
GIT_TAG v3.1.0
WILDCARDS
NAME asyncgi_hot_teacup
GIT_REPOSITORY https://github.com/kamchatka-volcano/hot_teacup.git
GIT_TAG dev
WILDCARDS
include/hot_teacup/*.h
DESTINATION include/asyncgi/http
TEXT_REPLACEMENTS
DESTINATION include/asyncgi/http
TEXT_REPLACEMENTS
"namespace http" "namespace asyncgi::http"
"HOT_TEACUP_" "ASYNCGI_HOT_TEACUP_"
)
Expand Down
38 changes: 21 additions & 17 deletions examples/example_guestbook.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <asyncgi/asyncgi.h>
#include <mutex>
#include <optional>
#include <regex>

namespace http = asyncgi::http;
Expand All @@ -22,36 +23,38 @@ struct asyncgi::config::RouteMatcher<AccessRole, RouteContext> {
}
};

void authorizeAdmin(const asyncgi::Request& request, asyncgi::Response&, RouteContext& context)
std::optional<http::Response> authorizeAdmin(const asyncgi::Request& request, RouteContext& context)
{
if (request.cookie("admin_id") == "ADMIN_SECRET")
context.role = AccessRole::Admin;

return std::nullopt;
}

void showLoginPage(const asyncgi::Request&, asyncgi::Response& response)
http::Response showLoginPage(const asyncgi::Request&)
{
response.send(R"(
return {R"(
<head><link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css"></head>
<form method="post" enctype="multipart/form-data">
<label for="msg">Login:</label>
<input id="login" name="login" value="">
<label for="msg">Password:</label>
<input id="passwd" name="passwd" value="">
<input value="Submit" data-popup="true" type="submit">
</form>)");
</form>)"};
}

void loginAdmin(const asyncgi::Request& request, asyncgi::Response& response)
http::Response loginAdmin(const asyncgi::Request& request)
{
if (request.formField("login") == "admin" && request.formField("passwd") == "12345")
response.redirect("/", http::RedirectType::Found, {http::Cookie("admin_id", "ADMIN_SECRET")});
return {http::Redirect{"/"}, {http::Cookie("admin_id", "ADMIN_SECRET")}};
else
response.redirect("/login");
return http::Redirect{"/login"};
}

void logoutAdmin(const asyncgi::Request&, asyncgi::Response& response)
http::Response logoutAdmin(const asyncgi::Request&)
{
response.redirect("/", http::RedirectType::Found, {http::Cookie("admin_id", "")});
return {http::Redirect{"/"}, {http::Cookie("admin_id", "")}};
}

struct GuestBookMessage {
Expand Down Expand Up @@ -114,7 +117,7 @@ std::string makeLinksDiv(AccessRole role)

auto showGuestBookPage(GuestBookState& state)
{
return [&state](const asyncgi::Request& request, asyncgi::Response& response, RouteContext& context)
return [&state](const asyncgi::Request& request, RouteContext& context) -> http::Response
{
auto page = R"(<head><link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css"></head>
<div style="display:flex; flex-direction: row; justify-content: flex-end">%LINKS%</div>
Expand Down Expand Up @@ -149,13 +152,14 @@ auto showGuestBookPage(GuestBookState& state)
}
else
page = std::regex_replace(page, std::regex{"%ERROR_MSG%"}, "");
response.send(page);

return page;
};
}

auto addMessage(GuestBookState& state)
{
return [&state](const asyncgi::Request& request, asyncgi::Response& response)
return [&state](const asyncgi::Request& request) -> http::Response
{
if (std::all_of(
request.formField("msg").begin(),
Expand All @@ -164,24 +168,24 @@ auto addMessage(GuestBookState& state)
{
return std::isspace(static_cast<unsigned char>(ch));
}))
response.redirect("/?error=empty_msg");
return http::Redirect{"/?error=empty_msg"};
else if (
request.formField("msg").find("http://") != std::string_view::npos ||
request.formField("msg").find("https://") != std::string_view::npos)
response.redirect("/?error=urls_in_msg");
return http::Redirect{"/?error=urls_in_msg"};
else {
state.addMessage(std::string{request.formField("name")}, std::string{request.formField("msg")});
response.redirect("/");
return http::Redirect{"/"};
}
};
}

auto removeMessage(GuestBookState& state)
{
return [&state](int index, const asyncgi::Request&, asyncgi::Response& response)
return [&state](int index, const asyncgi::Request&) -> http::Response
{
state.removeMessage(index);
response.redirect("/");
return http::Redirect{"/"};
};
}

Expand Down
4 changes: 2 additions & 2 deletions examples/example_hello_world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ int main()
auto router = asyncgi::Router{io};
router.route("/", http::RequestMethod::Get)
.process(
[](const asyncgi::Request&, asyncgi::Response& response)
[](const asyncgi::Request&)
{
response.send("Hello world");
return http::Response{"Hello world"};
});

auto server = asyncgi::Server{io, router};
Expand Down
10 changes: 5 additions & 5 deletions examples/example_request_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

namespace http = asyncgi::http;

void guestBookPage(const asyncgi::Request& request, asyncgi::Response& response)
http::Response guestBookPage(const asyncgi::Request& request)
{
if (request.path() == "/")
response.send(R"(
return {R"(
<h1>Guest book</h1>
<p>No messages</p>
)");
else
response.send(http::ResponseStatus::_404_Not_Found);
)"};

return http::ResponseStatus::_404_Not_Found;
}

int main()
Expand Down
24 changes: 12 additions & 12 deletions examples/example_route_context.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <asyncgi/asyncgi.h>
#include <mutex>
#include <optional>

namespace http = asyncgi::http;
using namespace std::string_literals;
Expand All @@ -14,45 +15,44 @@ struct RouteContext {
};

struct AdminAuthorizer {
void operator()(const asyncgi::Request& request, asyncgi::Response&, RouteContext& context)
std::optional<http::Response> operator()(const asyncgi::Request& request, RouteContext& context)
{
if (request.cookie("admin_id") == "ADMIN_SECRET")
context.role = AccessRole::Admin;

return std::nullopt;
}
};

struct LoginPage {
void operator()(const asyncgi::Request&, asyncgi::Response& response, RouteContext& context)
http::Response operator()(const asyncgi::Request&, RouteContext& context)
{
if (context.role == AccessRole::Guest)
response.send(R"(
return {R"(
<html>
<form method="post" enctype="multipart/form-data">
<label for="msg">Login:</label>
<input id="login" name="login" value="">
<label for="msg">Password:</label>
<input id="passwd" name="passwd" value="">
<input value="Submit" data-popup="true" type="submit">
</form></html>)");
</form></html>)"};
else //We are already logged in as the administrator
response.redirect("/");
return http::Redirect{"/"};
}
};

struct LoginPageAuthorize {
void operator()(const asyncgi::Request& request, asyncgi::Response& response, RouteContext& context)
http::Response operator()(const asyncgi::Request& request, RouteContext& context)
{
if (context.role == AccessRole::Guest) {
if (request.formField("login") == "admin" && request.formField("passwd") == "12345")
response.redirect(
"/",
asyncgi::http::RedirectType::Found,
{asyncgi::http::Cookie("admin_id", "ADMIN_SECRET")});
return {http::Redirect{"/"}, {asyncgi::http::Cookie("admin_id", "ADMIN_SECRET")}};
else
response.redirect("/login");
return http::Redirect{"/login"};
}
else //We are already logged in as the administrator
response.redirect("/");
return http::Redirect{"/"};
}
};

Expand Down
28 changes: 14 additions & 14 deletions examples/example_route_matcher.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <asyncgi/asyncgi.h>
#include <mutex>
#include <optional>

namespace http = asyncgi::http;
using namespace std::string_literals;
Expand All @@ -14,38 +15,37 @@ struct RouteContext {
};

struct AdminAuthorizer {
void operator()(const asyncgi::Request& request, asyncgi::Response&, RouteContext& context)
std::optional<http::Response> operator()(const asyncgi::Request& request, RouteContext& context)
{
if (request.cookie("admin_id") == "ADMIN_SECRET")
context.role = AccessRole::Admin;

return std::nullopt;
}
};

struct LoginPage {
void operator()(const asyncgi::Request&, asyncgi::Response& response, RouteContext&)
http::Response operator()(const asyncgi::Request&)
{
response.send(R"(
return {R"(
<html>
<form method="post" enctype="multipart/form-data">
<label for="msg">Login:</label>
<input id="login" name="login" value="">
<label for="msg">Password:</label>
<input id="passwd" name="passwd" value="">
<input value="Submit" data-popup="true" type="submit">
</form></html>)");
</form></html>)"};
}
};

struct LoginPageAuthorize {
void operator()(const asyncgi::Request& request, asyncgi::Response& response, RouteContext&)
http::Response operator()(const asyncgi::Request& request)
{
if (request.formField("login") == "admin" && request.formField("passwd") == "12345")
response.redirect(
"/",
asyncgi::http::RedirectType::Found,
{asyncgi::http::Cookie("admin_id", "ADMIN_SECRET")});
else
response.redirect("/login");
return {http::Redirect{"/"}, {asyncgi::http::Cookie("admin_id", "ADMIN_SECRET")}};

return http::Redirect{"/login"};
}
};

Expand All @@ -63,12 +63,12 @@ int main()
auto router = asyncgi::Router<RouteContext>{io};
router.route(asyncgi::rx{".*"}).process<AdminAuthorizer>();
router.route("/").process(
[](const asyncgi::Request&, asyncgi::Response& response, RouteContext& context)
[](const asyncgi::Request&, RouteContext& context) -> http::Response
{
if (context.role == AccessRole::Admin)
response.send("<p>Hello admin</p>");
return {"<p>Hello admin</p>"};
else
response.send(R"(<p>Hello guest</p><p><a href="/login">login</a>)");
return {R"(<p>Hello guest</p><p><a href="/login">login</a>)"};
});

router.route("/login", http::RequestMethod::Get, AccessRole::Guest).process<LoginPage>();
Expand Down
12 changes: 6 additions & 6 deletions examples/example_route_params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class GuestBookPage {
{
}

void operator()(const asyncgi::Request&, asyncgi::Response& response)
http::Response operator()(const asyncgi::Request&)
{
auto messages = state_->messages();
auto page = "<h1>Guest book</h1>"s;
Expand All @@ -60,7 +60,7 @@ class GuestBookPage {
"<input id=\"msg\" name=\"msg\" value=\"\">"
"<input value=\"Submit\" data-popup=\"true\" type=\"submit\">"
"</form>";
response.send(page);
return page;
}

private:
Expand All @@ -74,10 +74,10 @@ class GuestBookAddMessage {
{
}

void operator()(const asyncgi::Request& request, asyncgi::Response& response)
http::Response operator()(const asyncgi::Request& request)
{
state_->addMessage(std::string{request.formField("msg")});
response.redirect("/");
return http::Redirect{"/"};
}

private:
Expand All @@ -91,10 +91,10 @@ class GuestBookRemoveMessage {
{
}

void operator()(int index, const asyncgi::Request&, asyncgi::Response& response)
http::Response operator()(int index, const asyncgi::Request&)
{
state_->removeMessage(index);
response.redirect("/");
return http::Redirect{"/"};
}

private:
Expand Down
Loading

0 comments on commit fd4fadf

Please sign in to comment.