├── doc
└── logo.png
├── vcpkg.json
├── functional_tests
├── asio_dispatcher
│ └── test.toast
├── client
│ └── test.toast
├── hello_world
│ └── test.toast
├── exception_in_request_handler
│ └── test.toast
├── response_wait_future
│ └── test.toast
├── response_dispatching_asio_task
│ └── test.toast
├── request_processor
│ └── test.toast
├── client_in_processor
│ └── test.toast
├── timer
│ └── test.toast
├── route_context
│ └── test.toast
├── route_matchers
│ └── test.toast
├── router
│ └── test.toast
├── fastcgi_params
├── nginx_windows.conf
├── nginx_linux.conf
├── lunchtoast.cfg
├── route_params
│ └── test.toast
└── route_params_user_defined_types
│ └── test.toast
├── include
└── asyncgi
│ ├── asyncgi.h
│ ├── errors.h
│ ├── events.h
│ ├── detail
│ ├── asio_namespace.h
│ ├── routeresponsecontextaccessor.h
│ ├── utils.h
│ ├── lazyinitialized.h
│ ├── serviceholder.h
│ └── eventhandlerproxy.h
│ ├── asyncgi_fwd.h
│ ├── asiodispatcher.h
│ ├── types.h
│ ├── server.h
│ ├── taskcontext.h
│ ├── responder.h
│ ├── io.h
│ ├── timer.h
│ ├── client.h
│ ├── request.h
│ ├── requestprocessor.h
│ └── router.h
├── src
├── eventhandlerproxy.cpp
├── asio_error.h
├── responsesender.h
├── routeresponsecontextaccessor.cpp
├── io.cpp
├── responsesender.cpp
├── taskcontext.cpp
├── timerprovider.cpp
├── connectionfactory.h
├── asiodispatcherservice.h
├── timerprovider.h
├── serviceholder.cpp
├── ioservice.h
├── responsecontext.h
├── connectionlistener.h
├── timerservice.h
├── asiodispatcherservice.cpp
├── connectionlistenerfactory.h
├── asiodispatcher.cpp
├── connectionfactory.cpp
├── responsecontext.cpp
├── response.cpp
├── serverservice.h
├── connectionlistenerfactory.cpp
├── server.cpp
├── connectionlistener.cpp
├── timerservice.cpp
├── clientconnection.h
├── timer.cpp
├── serverservice.cpp
├── ioservice.cpp
├── connection.h
├── clientservice.h
├── client.cpp
├── clientconnection.cpp
├── connection.cpp
├── request.cpp
└── clientservice.cpp
├── external
├── seal_lake
└── asio
├── test_examples
├── CMakeLists.txt
└── test_exception_in_request_handler.cpp
├── examples
├── example_hello_world.cpp
├── example_request_processor.cpp
├── example_client.cpp
├── CMakeLists.txt
├── example_asio_dispatcher.cpp
├── example_timer.cpp
├── example_response_wait_future.cpp
├── example_client_in_processor.cpp
├── example_response_dispatching_asio_task.cpp
├── example_router.cpp
├── example_route_context.cpp
├── example_route_matcher.cpp
├── example_route_params.cpp
├── example_route_params_user_defined_types.cpp
└── example_guestbook.cpp
├── .clang-format
├── LICENSE.md
├── CMakeLists.txt
├── CMakePresets.json
├── .github
└── workflows
│ └── build_and_test.yml
└── README.md
/doc/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamchatka-volcano/asyncgi/master/doc/logo.png
--------------------------------------------------------------------------------
/vcpkg.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lunchtoast",
3 | "version-string": "0.1.0",
4 | "dependencies": [
5 | "boost-asio"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/functional_tests/asio_dispatcher/test.toast:
--------------------------------------------------------------------------------
1 | -Launch: ../../build/examples/example_asio_dispatcher
2 | -Expect output:
3 | Hello world
4 |
5 | ---
--------------------------------------------------------------------------------
/functional_tests/client/test.toast:
--------------------------------------------------------------------------------
1 | -Launch detached: ../../build/examples/example_hello_world
2 | -Wait: 1 sec
3 | -Launch: ../../build/examples/example_client
4 | -Expect output:
5 | Hello world
6 |
7 | ---
8 |
--------------------------------------------------------------------------------
/functional_tests/hello_world/test.toast:
--------------------------------------------------------------------------------
1 | -Launch detached: ../../build/examples/example_hello_world
2 | -Wait: 1 sec
3 |
4 | -Expect response from "/":
5 | Hello world
6 | ---
7 |
8 | -Expect status from "/foo": 404
--------------------------------------------------------------------------------
/functional_tests/exception_in_request_handler/test.toast:
--------------------------------------------------------------------------------
1 | -Launch detached: ../../build/test_examples/test_exception_in_request_handler
2 | -Wait: 1 sec
3 |
4 | -Expect status from "/": 500
5 | -Expect status from "/foo": 404
--------------------------------------------------------------------------------
/functional_tests/response_wait_future/test.toast:
--------------------------------------------------------------------------------
1 | -Launch detached: ../../build/examples/example_response_wait_future
2 | -Wait: 1 sec
3 |
4 | -Expect response from "/":
5 | Hello world
6 | ---
7 |
8 | -Expect status from "/foo": 404
--------------------------------------------------------------------------------
/functional_tests/response_dispatching_asio_task/test.toast:
--------------------------------------------------------------------------------
1 | -Launch detached: ../../build/examples/example_response_dispatching_asio_task
2 | -Wait: 1 sec
3 |
4 | -Expect response from "/":
5 | Hello world
6 | ---
7 |
8 | -Expect status from "/foo": 404
--------------------------------------------------------------------------------
/functional_tests/request_processor/test.toast:
--------------------------------------------------------------------------------
1 | -Launch detached: ../../build/examples/example_request_processor
2 | -Wait: 1 sec
3 |
4 | -Expect response from "/":
5 |
Guest book
6 | No messages
7 | ---
8 |
9 | -Expect status from "/foo": 404
--------------------------------------------------------------------------------
/include/asyncgi/asyncgi.h:
--------------------------------------------------------------------------------
1 | #ifndef ASYNCGI_H
2 | #define ASYNCGI_H
3 |
4 | #include "asiodispatcher.h"
5 | #include "client.h"
6 | #include "errors.h"
7 | #include "events.h"
8 | #include "io.h"
9 | #include "router.h"
10 | #include "server.h"
11 | #include "timer.h"
12 |
13 | #endif //ASYNCGI_H
--------------------------------------------------------------------------------
/include/asyncgi/errors.h:
--------------------------------------------------------------------------------
1 | #ifndef ASYNCGI_ERRORS_H
2 | #define ASYNCGI_ERRORS_H
3 | #include
4 |
5 | namespace asyncgi {
6 |
7 | class Error : public std::runtime_error {
8 | using std::runtime_error::runtime_error;
9 | };
10 |
11 | } // namespace asyncgi
12 |
13 | #endif //ASYNCGI_ERRORS_H
--------------------------------------------------------------------------------
/functional_tests/client_in_processor/test.toast:
--------------------------------------------------------------------------------
1 | -Launch detached: ../../build/examples/example_hello_world
2 | -Launch detached: ../../build/examples/example_client_in_processor
3 | -Wait: 1 sec
4 |
5 | -Expect response from "/" on port 8089:
6 | Hello world
7 | ---
8 |
9 | -Expect status from "/foo" on port 8089: 404
--------------------------------------------------------------------------------
/src/eventhandlerproxy.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | namespace asyncgi::detail {
4 |
5 | EventHandlerProxy::EventHandlerProxy() = default;
6 |
7 | void EventHandlerProxy::operator()(ErrorEvent event, std::string_view message)
8 | {
9 | errorHandler_(event, message);
10 | }
11 |
12 | } //namespace asyncgi::detail
13 |
--------------------------------------------------------------------------------
/functional_tests/timer/test.toast:
--------------------------------------------------------------------------------
1 | -Tags: linux
2 | -Launch detached: ../../build/examples/example_timer
3 | -Wait: 1100 msec
4 |
5 | -Expect response from "/":
6 | Hello world
7 | (alive for 1 seconds)
8 | ---
9 |
10 | -Wait: 1 sec
11 |
12 | -Expect response from "/":
13 | Hello world
14 | (alive for 2 seconds)
15 | ---
16 |
17 | -Expect status from "/foo": 404
--------------------------------------------------------------------------------
/include/asyncgi/events.h:
--------------------------------------------------------------------------------
1 | #ifndef ASYNCGI_EVENTS_H
2 | #define ASYNCGI_EVENTS_H
3 |
4 | namespace asyncgi {
5 |
6 | enum ErrorEvent {
7 | ConnectionError,
8 | SocketReadError,
9 | SocketWriteError,
10 | SocketCloseError,
11 | RequestProcessingError,
12 | RouteParametersError
13 | };
14 |
15 | } //namespace asyncgi
16 |
17 | #endif //ASYNCGI_EVENTS_H
18 |
--------------------------------------------------------------------------------
/src/asio_error.h:
--------------------------------------------------------------------------------
1 | #ifndef ASYNCGI_ASIO_ERROR_H
2 | #define ASYNCGI_ASIO_ERROR_H
3 |
4 | #ifdef ASYNCGI_USE_BOOST_ASIO
5 | #include
6 | namespace asyncgi {
7 | using asio_error = boost::system::error_code;
8 | }
9 | #else
10 | #include
11 | namespace asyncgi {
12 | using asio_error = std::error_code;
13 | }
14 | #endif
15 |
16 | #endif //ASYNCGI_ASIO_ERRORCODE_H
17 |
--------------------------------------------------------------------------------
/external/seal_lake:
--------------------------------------------------------------------------------
1 | include(FetchContent)
2 | set(SEAL_LAKE_VERSION v0.2.0)
3 | set(FETCHCONTENT_QUIET FALSE)
4 | FetchContent_Declare(seal_lake_${SEAL_LAKE_VERSION}
5 | SOURCE_DIR seal_lake_${SEAL_LAKE_VERSION}
6 | GIT_REPOSITORY "https://github.com/kamchatka-volcano/seal_lake.git"
7 | GIT_TAG ${SEAL_LAKE_VERSION}
8 | )
9 | FetchContent_MakeAvailable(seal_lake_${SEAL_LAKE_VERSION})
10 | include(${seal_lake_${SEAL_LAKE_VERSION}_SOURCE_DIR}/seal_lake.cmake)
--------------------------------------------------------------------------------
/include/asyncgi/detail/asio_namespace.h:
--------------------------------------------------------------------------------
1 | #ifndef ASYNCGI_ASIO_NAMESPACE_H
2 | #define ASYNCGI_ASIO_NAMESPACE_H
3 |
4 | #ifdef ASYNCGI_USE_BOOST_ASIO
5 | #define ASYNCGI_ASIO boost::asio
6 | namespace boost::asio {
7 | }
8 | namespace asyncgi {
9 | namespace asio = boost::asio;
10 | }
11 | #else
12 | #define ASYNCGI_ASIO asio
13 | namespace asio {
14 | }
15 | namespace asyncgi {
16 | namespace asio = ::asio;
17 | }
18 | #endif
19 |
20 | #endif //ASYNCGI_ASIO_NAMESPACE_H
21 |
--------------------------------------------------------------------------------
/include/asyncgi/asyncgi_fwd.h:
--------------------------------------------------------------------------------
1 | #ifndef ASYNCGI_FWD_H
2 | #define ASYNCGI_FWD_H
3 |
4 | namespace asyncgi {
5 | class IO;
6 | class Request;
7 | class Responder;
8 | class Server;
9 | class Client;
10 | class Error;
11 | class AsioDispatcher;
12 | class TaskContext;
13 | class Timer;
14 |
15 | namespace http {
16 | class Response;
17 | };
18 | namespace fastcgi {
19 | struct Request;
20 | struct Response;
21 | } //namespace fastcgi
22 |
23 | } //namespace asyncgi
24 |
25 | #endif //ASYNCGI_FWD_H
--------------------------------------------------------------------------------
/src/responsesender.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace fcgi {
5 | class Response;
6 | }
7 |
8 | namespace asyncgi::detail {
9 |
10 | class ResponseSender {
11 | public:
12 | explicit ResponseSender(fcgi::Response response);
13 | void send(std::string data);
14 | void send(std::string data, std::string errorMsg);
15 | bool isSent() const;
16 |
17 | private:
18 | fcgi::Response response_;
19 | };
20 |
21 | } // namespace asyncgi::detail
22 |
--------------------------------------------------------------------------------
/test_examples/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.18)
2 |
3 | file(GLOB SRC_FILES "*.cpp")
4 | foreach (SRC_FILE ${SRC_FILES})
5 | SealLake_StringAfterLast(${SRC_FILE} "/" EXAMPLE_NAME)
6 | SealLake_StringBeforeLast(${EXAMPLE_NAME} "." EXAMPLE_NAME)
7 |
8 | SealLake_Executable(
9 | NAME ${EXAMPLE_NAME}
10 | SOURCES ${SRC_FILE}
11 | COMPILE_FEATURES cxx_std_17
12 | PROPERTIES
13 | CXX_EXTENSIONS OFF
14 | LIBRARIES
15 | asyncgi::asyncgi Threads::Threads
16 | )
17 | endforeach ()
--------------------------------------------------------------------------------
/include/asyncgi/detail/routeresponsecontextaccessor.h:
--------------------------------------------------------------------------------
1 | #ifndef ASYNCGI_ROUTERESPONSECONTEXTACCESSOR_H
2 | #define ASYNCGI_ROUTERESPONSECONTEXTACCESSOR_H
3 |
4 | #include
5 |
6 | namespace asyncgi {
7 | class Responder;
8 |
9 | namespace whaleroute {
10 | class RequestProcessorQueue;
11 | }
12 |
13 | namespace detail {
14 |
15 | struct RouterResponseContextAccessor {
16 | static void setRequestProcessorQueue(Responder&, const std::shared_ptr&);
17 | };
18 |
19 | } //namespace detail
20 |
21 | } //namespace asyncgi
22 |
23 | #endif //ASYNCGI_ROUTERESPONSECONTEXTACCESSOR_H
24 |
--------------------------------------------------------------------------------
/src/routeresponsecontextaccessor.cpp:
--------------------------------------------------------------------------------
1 | #include "responsecontext.h"
2 | #include
3 | #include
4 | #include
5 |
6 | namespace asyncgi::detail {
7 |
8 | void RouterResponseContextAccessor::setRequestProcessorQueue(
9 | Responder& response,
10 | const std::shared_ptr& queue)
11 | {
12 | if (auto context = response.context(sfun::access_token{}).lock())
13 | context->setRequestProcessorQueue(queue);
14 | }
15 |
16 | } //namespace asyncgi::detail
--------------------------------------------------------------------------------
/src/io.cpp:
--------------------------------------------------------------------------------
1 | #include "ioservice.h"
2 | #include
3 |
4 | namespace asyncgi {
5 |
6 | IO::IO(int threadsNumber)
7 | : ioService_{std::make_unique(threadsNumber)}
8 | {
9 | }
10 |
11 | IO::~IO() = default;
12 |
13 | detail::IOService& IO::ioService(detail::IOAccessPermission)
14 | {
15 | return *ioService_;
16 | }
17 |
18 | detail::EventHandlerProxy& IO::eventHandler(detail::IOAccessPermission)
19 | {
20 | return eventHandler_;
21 | }
22 |
23 | void IO::run()
24 | {
25 | ioService_->run();
26 | }
27 |
28 | void IO::stop()
29 | {
30 | ioService_->stop();
31 | }
32 |
33 | } //namespace asyncgi
--------------------------------------------------------------------------------
/functional_tests/route_context/test.toast:
--------------------------------------------------------------------------------
1 | -Launch detached: ../../build/examples/example_route_context
2 | -Wait: 1 sec
3 |
4 | -Expect status from "/foo": 404
5 |
6 | -Expect response from "/":
7 | Hello guest
login
8 | ---
9 |
10 | -Expect status from "/login" with form param "login=admin" and form param "passwd=12345": 302
11 | -Expect cookies:
12 | # Netscape HTTP Cookie File
13 | # https://curl.se/docs/http-cookies.html
14 | # This file was generated by libcurl! Edit at your own risk.
15 |
16 | localhost FALSE / FALSE 0 admin_id ADMIN_SECRET
17 | ---
18 |
19 | -Expect response from "/":
20 |
Hello admin
21 | ---
--------------------------------------------------------------------------------
/functional_tests/route_matchers/test.toast:
--------------------------------------------------------------------------------
1 | -Launch detached: ../../build/examples/example_route_matcher
2 | -Wait: 1 sec
3 |
4 | -Expect status from "/foo": 404
5 |
6 | -Expect response from "/":
7 | Hello guest
login
8 | ---
9 |
10 | -Expect status from "/login" with form param "login=admin" and form param "passwd=12345": 302
11 | -Expect cookies:
12 | # Netscape HTTP Cookie File
13 | # https://curl.se/docs/http-cookies.html
14 | # This file was generated by libcurl! Edit at your own risk.
15 |
16 | localhost FALSE / FALSE 0 admin_id ADMIN_SECRET
17 | ---
18 |
19 | -Expect response from "/":
20 |
Hello admin
21 | ---
--------------------------------------------------------------------------------
/examples/example_hello_world.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | namespace http = asyncgi::http;
4 |
5 | int main()
6 | {
7 | auto io = asyncgi::IO{};
8 | auto router = asyncgi::Router{io};
9 | router.route("/", http::RequestMethod::Get)
10 | .process(
11 | [](const asyncgi::Request&)
12 | {
13 | return http::Response{"Hello world"};
14 | });
15 |
16 | auto server = asyncgi::Server{io, router};
17 | #ifndef _WIN32
18 | server.listen("/tmp/fcgi.sock");
19 | #else
20 | server.listen("127.0.0.1", 9088);
21 | #endif
22 | io.run();
23 | return 0;
24 | }
--------------------------------------------------------------------------------
/examples/example_request_processor.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | namespace http = asyncgi::http;
4 |
5 | http::Response guestBookPage(const asyncgi::Request& request)
6 | {
7 | if (request.path() == "/")
8 | return {R"(
9 | Guest book
10 | No messages
11 | )"};
12 |
13 | return http::ResponseStatus::_404_Not_Found;
14 | }
15 |
16 | int main()
17 | {
18 | auto io = asyncgi::IO{};
19 | auto server = asyncgi::Server{io, guestBookPage};
20 | #ifndef _WIN32
21 | server.listen("/tmp/fcgi.sock");
22 | #else
23 | server.listen("127.0.0.1", 9088);
24 | #endif
25 | io.run();
26 | return 0;
27 | }
--------------------------------------------------------------------------------
/src/responsesender.cpp:
--------------------------------------------------------------------------------
1 | #include "responsesender.h"
2 |
3 | namespace asyncgi::detail {
4 |
5 | ResponseSender::ResponseSender(fcgi::Response response)
6 | : response_{std::move(response)}
7 | {
8 | }
9 |
10 | void ResponseSender::send(std::string data)
11 | {
12 | send(data, {});
13 | }
14 |
15 | void ResponseSender::send(std::string data, std::string errorMsg)
16 | {
17 | if (!response_.isValid())
18 | return;
19 |
20 | response_.setData(std::move(data));
21 | response_.setErrorMsg(std::move(errorMsg));
22 | response_.send();
23 | }
24 |
25 | bool ResponseSender::isSent() const
26 | {
27 | return !response_.isValid();
28 | }
29 |
30 | } // namespace asyncgi::detail
--------------------------------------------------------------------------------
/src/taskcontext.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | namespace asyncgi {
5 |
6 | TaskContext::PostAction::PostAction(std::function action)
7 | : action_{std::move(action)}
8 | {
9 | }
10 |
11 | TaskContext::PostAction::~PostAction()
12 | {
13 | if (action_)
14 | action_();
15 | }
16 |
17 | TaskContext::TaskContext(asio::io_context& io, std::function postTaskAction)
18 | : io_{io}
19 | , postTaskAction_{std::make_shared(std::move(postTaskAction))}
20 | {
21 | }
22 |
23 | asio::io_context& TaskContext::io() const
24 | {
25 | return io_;
26 | }
27 |
28 | } // namespace asyncgi
29 |
--------------------------------------------------------------------------------
/src/timerprovider.cpp:
--------------------------------------------------------------------------------
1 | #include "timerprovider.h"
2 | #include "timerservice.h"
3 | #include
4 | #ifdef ASYNCGI_USE_BOOST_ASIO
5 | #include
6 | #else
7 | #include
8 | #endif
9 |
10 | namespace asyncgi::detail {
11 |
12 | TimerProvider::TimerProvider(asio::io_context& io)
13 | : io_{io}
14 | {
15 | }
16 |
17 | TimerService& TimerProvider::emplaceTimer()
18 | {
19 | return timers_.emplace_back(io_, requestProcessorQueue_);
20 | }
21 |
22 | void TimerProvider::setRequestProcessorQueue(whaleroute::RequestProcessorQueue& queue)
23 | {
24 | requestProcessorQueue_ = queue;
25 | }
26 |
27 | } // namespace asyncgi::detail
28 |
--------------------------------------------------------------------------------
/include/asyncgi/asiodispatcher.h:
--------------------------------------------------------------------------------
1 | #ifndef ASYNCGI_ASIODISPATCHER_H
2 | #define ASYNCGI_ASIODISPATCHER_H
3 |
4 | #include "taskcontext.h"
5 | #include "detail/serviceholder.h"
6 | #include
7 | #include
8 |
9 | namespace asyncgi {
10 | namespace detail {
11 | class AsioDispatcherService;
12 | }
13 |
14 | class IO;
15 | class Responder;
16 |
17 | class AsioDispatcher {
18 | public:
19 | explicit AsioDispatcher(IO&);
20 | explicit AsioDispatcher(Responder&);
21 |
22 | void postTask(std::function task);
23 |
24 | private:
25 | detail::ServiceHolder asioDispatcherService_;
26 | };
27 |
28 | } //namespace asyncgi
29 |
30 | #endif //ASYNCGI_ASIODISPATCHER_H
31 |
--------------------------------------------------------------------------------
/include/asyncgi/detail/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef ASYNCGI_UTILS_H
2 | #define ASYNCGI_UTILS_H
3 |
4 | #include
5 |
6 | namespace asyncgi::detail {
7 |
8 | template
9 | auto makeCopyableLambda(TFunc&& f)
10 | {
11 | auto funcPtr = std::make_shared>(std::forward(f));
12 | return [funcPtr](auto&&... args) -> decltype(auto)
13 | {
14 | return (*funcPtr)(decltype(args)(args)...);
15 | };
16 | }
17 |
18 | template
19 | decltype(auto) refWrapperOrRValue(T&& obj)
20 | {
21 | if constexpr (std::is_lvalue_reference_v)
22 | return std::ref(std::forward(obj));
23 | else
24 | return std::forward(obj);
25 | }
26 |
27 | } //namespace asyncgi::detail
28 |
29 | #endif //ASYNCGI_UTILS_H
30 |
--------------------------------------------------------------------------------
/examples/example_client.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using namespace asyncgi;
5 |
6 | int main()
7 | {
8 | auto io = asyncgi::IO{};
9 | auto client = asyncgi::Client{io};
10 | client.makeRequest(
11 | #ifndef _WIN32
12 | "/tmp/fcgi.sock",
13 | #else
14 | "127.0.0.1",
15 | 9088,
16 | #endif
17 | http::Request{http::RequestMethod::Get, "/"},
18 | [&io](const std::optional& response)
19 | {
20 | if (response)
21 | std::cout << response->body() << std::endl;
22 | else
23 | std::cout << "No response" << std::endl;
24 | io.stop();
25 | });
26 | io.run();
27 | return 0;
28 | }
--------------------------------------------------------------------------------
/external/asio:
--------------------------------------------------------------------------------
1 | set(THREADS_PREFER_PTHREAD_FLAG ON)
2 | find_package(Threads REQUIRED)
3 |
4 | include(FetchContent)
5 | Set(FETCHCONTENT_QUIET FALSE)
6 |
7 | if (NOT TARGET asio)
8 | FetchContent_Declare(asio
9 | GIT_REPOSITORY https://github.com/chriskohlhoff/asio.git
10 | GIT_TAG asio-1-24-0
11 | GIT_SHALLOW ON
12 | GIT_PROGRESS TRUE
13 | CONFIGURE_COMMAND ""
14 | BUILD_COMMAND ""
15 | )
16 |
17 | FetchContent_GetProperties(asio)
18 | if(NOT asio_POPULATED)
19 | FetchContent_Populate(asio)
20 | endif()
21 |
22 | add_library(asio INTERFACE)
23 | target_include_directories(asio INTERFACE ${asio_SOURCE_DIR}/asio/include)
24 | target_link_libraries(asio INTERFACE Threads::Threads)
25 | endif()
--------------------------------------------------------------------------------
/src/connectionfactory.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "ioservice.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | namespace asyncgi::detail {
10 | template
11 | class Connection;
12 |
13 | class ConnectionFactory {
14 | public:
15 | ConnectionFactory(RequestProcessor requestProcessor, IOService& ioService, EventHandlerProxy& eventHandler);
16 | template
17 | std::shared_ptr> makeConnection();
18 |
19 | private:
20 | RequestProcessor requestProcessor_;
21 | sfun::member ioService_;
22 | sfun::member eventHandler_;
23 | };
24 | } // namespace asyncgi::detail
25 |
--------------------------------------------------------------------------------
/include/asyncgi/types.h:
--------------------------------------------------------------------------------
1 | #ifndef ASYNCGI_TYPES_H
2 | #define ASYNCGI_TYPES_H
3 |
4 | #include "detail/external/whaleroute/types.h"
5 | #include "http/types.h"
6 | #include