Skip to content

Commit

Permalink
-wip refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
kamchatka-volcano committed Jul 14, 2024
1 parent 1749147 commit fe30c1b
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 97 deletions.
8 changes: 4 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ SealLake_Bundle(
GIT_REPOSITORY https://github.com/kamchatka-volcano/fcgi_responder.git
GIT_TAG dev
TEXT_REPLACEMENTS
"namespace fcgi" "namespace asyncgi::fcgi"
"namespace fcgi" "namespace asyncgi::detail::fcgi"
)

SealLake_Bundle(
Expand Down Expand Up @@ -73,13 +73,13 @@ set(SRC
src/connectionlistener.cpp
src/connectionlistenerfactory.cpp
src/clientconnection.cpp
src/request.cpp
src/response.cpp
src/requestproxy.cpp
src/responder.cpp
src/routeresponsecontextaccessor.cpp
src/serviceholder.cpp
src/fastcgirequest.cpp
src/fastcgiresponse.cpp
)
)

SealLake_StaticLibrary(
SOURCES ${SRC}
Expand Down
82 changes: 41 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ int main()
auto io = asyncgi::IO{};
auto router = asyncgi::Router{io};
router.route("/", http::RequestMethod::Get).process(
[](const asyncgi::Request&)
[](const asyncgi::RequestProxy&)
{
return http::Response{"Hello world"};
});
Expand All @@ -33,7 +33,7 @@ int main()
## Table of Contents
* [Usage](#usage)
* [Connection](#connection)
* [Request processor](#request-processor)
* [RequestProxy processor](#request-processor)
* [Router](#router)
* [Route parameters](#route-parameters)
* [Route context](#route-context)
Expand Down Expand Up @@ -75,13 +75,13 @@ server {

`asyncgi` supports both `UNIX domain` and `TCP` sockets for opening `FastCGI` connections.

### Request processor
### RequestProxy processor

In order to process requests, it's necessary to provide a function or function object that fulfills
the `RequestProcessor` requirement. This means that the function must be invocable with one of the following signatures:

* `http::Response (const asyncgi::Request&)`
* `void (const asyncgi::Request&, asyncgi::Responder&)`.
* `http::Response (const asyncgi::RequestProxy&)`
* `void (const asyncgi::RequestProxy&, asyncgi::Responder&)`.

<details>
<summary>Example</summary>
Expand All @@ -93,7 +93,7 @@ the `RequestProcessor` requirement. This means that the function must be invocab

namespace http = asyncgi::http;

http::Response guestBookPage(const asyncgi::Request& request)
http::Response guestBookPage(const asyncgi::RequestProxy& request)
{
if (request.path() == "/")
return {R"(
Expand Down Expand Up @@ -121,7 +121,7 @@ Here, the `guestBookPage` function serves as the request processor. Another way
reference to the `asyncgi::Responder` object, which can be used for sending responses manually:

```c++
void guestBookPage(const asyncgi::Request& request, asyncgi::Responder& responder)
void guestBookPage(const asyncgi::RequestProxy& request, asyncgi::Responder& responder)
{
if (request.path() == "/")
responder.send(R"(
Expand Down Expand Up @@ -186,7 +186,7 @@ public:
{
}
http::Response operator()(const asyncgi::Request&)
http::Response operator()(const asyncgi::RequestProxy&)
{
auto messages = state_->messages();
auto page = "<h1>Guest book</h1>"s;
Expand Down Expand Up @@ -216,7 +216,7 @@ public:
{
}
http::Response operator()(const asyncgi::Request& request)
http::Response operator()(const asyncgi::RequestProxy& request)
{
state_->addMessage(std::string{request.formField("msg")});
return http::Redirect{"/"};
Expand Down Expand Up @@ -251,11 +251,11 @@ When using `asyncgi::Router` with regular expressions, request processors must s
the `ParametrizedRequestProcessor` requirement. That means that a function object must be invocable with one of the
following signatures:

* `http::Response void(const TRouteParams&..., const asyncgi::Request&)`
* `void (const TRouteParams&..., const asyncgi::Request&, asyncgi::Responder&)`
* `http::Response void(const TRouteParams&..., const asyncgi::RequestProxy&)`
* `void (const TRouteParams&..., const asyncgi::RequestProxy&, asyncgi::Responder&)`

The `TRouteParams` represents zero or more parameters generated from the capturing groups of the regular expression. For
example, `http::Response (int age, string name, const asyncgi::Request&)` signature can be used to process
example, `http::Response (int age, string name, const asyncgi::RequestProxy&)` signature can be used to process
requests matched by `asyncgi::rx{"/person/(\\w+)/age/(\\d+)"}`.

In the following example a `ParametrizedRequestProcessor` named `GuestBookRemoveMessage` is added to remove the stored
Expand Down Expand Up @@ -313,7 +313,7 @@ public:
{
}

http::Response operator()(const asyncgi::Request&)
http::Response operator()(const asyncgi::RequestProxy&)
{
auto messages = state_->messages();
auto page = "<h1>Guest book</h1>"s;
Expand Down Expand Up @@ -343,7 +343,7 @@ public:
{
}

http::Response operator()(const asyncgi::Request& request)
http::Response operator()(const asyncgi::RequestProxy& request)
{
state_->addMessage(std::string{request.formField("msg")});
return http::Redirect{"/"};
Expand All @@ -360,7 +360,7 @@ public:
{
}

http::Response operator()(int index, const asyncgi::Request&)
http::Response operator()(int index, const asyncgi::RequestProxy&)
{
state_->removeMessage(index);
return http::Redirect{"/"};
Expand Down Expand Up @@ -457,7 +457,7 @@ public:
{
}
http::Response operator()(const asyncgi::Request&)
http::Response operator()(const asyncgi::RequestProxy&)
{
auto messages = state_->messages();
auto page = "<h1>Guest book</h1>"s;
Expand Down Expand Up @@ -487,7 +487,7 @@ public:
{
}
http::Response operator()(const asyncgi::Request& request)
http::Response operator()(const asyncgi::RequestProxy& request)
{
state_->addMessage(std::string{request.formField("msg")});
return http::Redirect{"/"};
Expand All @@ -504,7 +504,7 @@ public:
{
}
http::Response operator()(MessageNumber msgNumber, const asyncgi::Request&)
http::Response operator()(MessageNumber msgNumber, const asyncgi::RequestProxy&)
{
state_->removeMessage(msgNumber.value);
return http::Redirect{"/"};
Expand Down Expand Up @@ -569,7 +569,7 @@ struct RouteContext {
};

struct AdminAuthorizer {
std::optional<http::Response> operator()(const asyncgi::Request& request, RouteContext& context)
std::optional<http::Response> operator()(const asyncgi::RequestProxy& request, RouteContext& context)
{
if (request.cookie("admin_id") == "ADMIN_SECRET")
context.role = AccessRole::Admin;
Expand All @@ -579,7 +579,7 @@ struct AdminAuthorizer {
};

struct LoginPage {
http::Response operator()(const asyncgi::Request&, RouteContext& context)
http::Response operator()(const asyncgi::RequestProxy&, RouteContext& context)
{
if (context.role == AccessRole::Guest)
return {R"(
Expand All @@ -597,7 +597,7 @@ struct LoginPage {
};

struct LoginPageAuthorize {
http::Response operator()(const asyncgi::Request& request, RouteContext& context)
http::Response operator()(const asyncgi::RequestProxy& request, RouteContext& context)
{
if (context.role == AccessRole::Guest) {
if (request.formField("login") == "admin" && request.formField("passwd") == "12345")
Expand All @@ -616,7 +616,7 @@ int main()
auto router = asyncgi::Router<RouteContext>{io};
router.route(asyncgi::rx{".*"}).process<AdminAuthorizer>();
router.route("/").process(
[](const asyncgi::Request&, asyncgi::Responder& response, RouteContext& context)
[](const asyncgi::RequestProxy&, asyncgi::Responder& response, RouteContext& context)
{
if (context.role == AccessRole::Admin)
response.send("<p>Hello admin</p>");
Expand Down Expand Up @@ -666,7 +666,7 @@ struct RouteContext {
};
struct AdminAuthorizer {
std::optional<http::Response> operator()(const asyncgi::Request& request, RouteContext& context)
std::optional<http::Response> operator()(const asyncgi::RequestProxy& request, RouteContext& context)
{
if (request.cookie("admin_id") == "ADMIN_SECRET")
context.role = AccessRole::Admin;
Expand All @@ -676,7 +676,7 @@ struct AdminAuthorizer {
};
struct LoginPage {
http::Response operator()(const asyncgi::Request&)
http::Response operator()(const asyncgi::RequestProxy&)
{
return {R"(
<html>
Expand All @@ -691,7 +691,7 @@ struct LoginPage {
};
struct LoginPageAuthorize {
http::Response operator()(const asyncgi::Request& request)
http::Response operator()(const asyncgi::RequestProxy& request)
{
if (request.formField("login") == "admin" && request.formField("passwd") == "12345")
return {http::Redirect{"/"}, {asyncgi::http::Cookie("admin_id", "ADMIN_SECRET")}};
Expand All @@ -702,7 +702,7 @@ struct LoginPageAuthorize {
template<>
struct asyncgi::config::RouteMatcher<AccessRole, RouteContext> {
bool operator()(AccessRole value, const asyncgi::Request&, const RouteContext& context) const
bool operator()(AccessRole value, const asyncgi::RequestProxy&, const RouteContext& context) const
{
return value == context.role;
}
Expand All @@ -714,7 +714,7 @@ int main()
auto router = asyncgi::Router<RouteContext>{io};
router.route(asyncgi::rx{".*"}).process<AdminAuthorizer>();
router.route("/").process(
[](const asyncgi::Request&, RouteContext& context) -> http::Response
[](const asyncgi::RequestProxy&, RouteContext& context) -> http::Response
{
if (context.role == AccessRole::Admin)
return {"<p>Hello admin</p>"};
Expand Down Expand Up @@ -768,21 +768,21 @@ struct RouteContext {

template<>
struct asyncgi::config::RouteMatcher<AccessRole, RouteContext> {
bool operator()(AccessRole value, const asyncgi::Request&, const RouteContext& context) const
bool operator()(AccessRole value, const asyncgi::RequestProxy&, const RouteContext& context) const
{
return value == context.role;
}
};

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

return std::nullopt;
}

http::Response showLoginPage(const asyncgi::Request&)
http::Response showLoginPage(const asyncgi::RequestProxy&)
{
return {R"(
<head><link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css"></head>
Expand All @@ -795,15 +795,15 @@ http::Response showLoginPage(const asyncgi::Request&)
</form>)"};
}

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

http::Response logoutAdmin(const asyncgi::Request&)
http::Response logoutAdmin(const asyncgi::RequestProxy&)
{
return {http::Redirect{"/"}, {http::Cookie("admin_id", "")}};
}
Expand Down Expand Up @@ -868,7 +868,7 @@ std::string makeLinksDiv(AccessRole role)

auto showGuestBookPage(GuestBookState& state)
{
return [&state](const asyncgi::Request& request, RouteContext& context) -> http::Response
return [&state](const asyncgi::RequestProxy& 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 @@ -910,7 +910,7 @@ auto showGuestBookPage(GuestBookState& state)

auto addMessage(GuestBookState& state)
{
return [&state](const asyncgi::Request& request) -> http::Response
return [&state](const asyncgi::RequestProxy& request) -> http::Response
{
if (std::all_of(
request.formField("msg").begin(),
Expand All @@ -933,7 +933,7 @@ auto addMessage(GuestBookState& state)

auto removeMessage(GuestBookState& state)
{
return [&state](int index, const asyncgi::Request&) -> http::Response
return [&state](int index, const asyncgi::RequestProxy&) -> http::Response
{
state.removeMessage(index);
return http::Redirect{"/"};
Expand Down Expand Up @@ -987,7 +987,7 @@ struct Greeter{
{
}
http::Response operator()(const asyncgi::Request&)
http::Response operator()(const asyncgi::RequestProxy&)
{
return "Hello world\n(alive for " + std::to_string(*secondsCounter_) + " seconds)";
}
Expand Down Expand Up @@ -1040,7 +1040,7 @@ been sent.
using namespace asyncgi;

struct DelayedPage{
void operator()(const asyncgi::Request&, asyncgi::Responder& responder)
void operator()(const asyncgi::RequestProxy&, asyncgi::Responder& responder)
{
auto timer = asyncgi::Timer{responder};
timer.waitFuture(
Expand Down Expand Up @@ -1096,7 +1096,7 @@ int main()
auto client = asyncgi::Client{io};
client.makeRequest(
"/tmp/fcgi.sock",
http::Request{http::RequestMethod::Get, "/"},
http::RequestProxy{http::RequestMethod::Get, "/"},
[&io](const std::optional<http::ResponseView>& response)
{
if (response)
Expand Down Expand Up @@ -1124,13 +1124,13 @@ be used. It is important to avoid using this client object after the response ha
namespace http = asyncgi::http;

struct RequestPage{
void operator()(const asyncgi::Request&, asyncgi::Responder& responder)
void operator()(const asyncgi::RequestProxy&, asyncgi::Responder& responder)
{
// making request to FastCgi application listening on /tmp/fcgi.sock and showing the received response
auto client = asyncgi::Client{responder};
client.makeRequest(
"/tmp/fcgi.sock",
http::Request{http::RequestMethod::Get, "/"},
http::RequestProxy{http::RequestMethod::Get, "/"},
[responder](const std::optional<http::ResponseView>& reqResponse) mutable
{
if (reqResponse)
Expand Down Expand Up @@ -1208,7 +1208,7 @@ must be used. It is important to avoid using this dispatcher after the response
namespace http = asyncgi::http;

struct DelayedPage {
void operator()(const asyncgi::Request&, asyncgi::Responder& responder)
void operator()(const asyncgi::RequestProxy&, asyncgi::Responder& responder)
{
auto disp = asyncgi::AsioDispatcher{responder};
disp.postTask(
Expand Down
Loading

0 comments on commit fe30c1b

Please sign in to comment.