Orbit Framework
An ultra-modern, asynchronous, cross-platform C++ Web Framework.
Loading...
Searching...
No Matches
HandlerWrapper.hpp
Go to the documentation of this file.
1#pragma once
5#include <orbit/http/json.hpp>
6#include <type_traits>
7#include <functional>
8#include <memory>
9#include <string>
10#include <tuple>
11
12namespace routing {
13
14// Function traits to inspect lambda signatures
15template <typename T>
16struct function_traits : public function_traits<decltype(&std::decay_t<T>::operator())> {};
17
18// Specialization for const lambdas
19template <typename ClassType, typename ReturnType, typename... Args>
20struct function_traits<ReturnType(ClassType::*)(Args...) const> {
21 using result_type = ReturnType;
22 using args_tuple = std::tuple<Args...>;
23 static constexpr size_t arg_count = sizeof...(Args);
24};
25
26// Specialization for mutable lambdas
27template <typename ClassType, typename ReturnType, typename... Args>
28struct function_traits<ReturnType(ClassType::*)(Args...)> {
29 using result_type = ReturnType;
30 using args_tuple = std::tuple<Args...>;
31 static constexpr size_t arg_count = sizeof...(Args);
32};
33
34// Specialization for free functions
35template <typename ReturnType, typename... Args>
36struct function_traits<ReturnType(*)(Args...)> {
37 using result_type = ReturnType;
38 using args_tuple = std::tuple<Args...>;
39 static constexpr size_t arg_count = sizeof...(Args);
40};
41
42// The core wrapper
43template <typename Handler>
44auto wrap_handler(Handler&& h) -> std::function<void(http::HttpRequest&, std::shared_ptr<http::ResponseWriter>)> {
45 using traits = function_traits<Handler>;
46 using Ret = typename traits::result_type;
47
48 if constexpr (std::is_same_v<Ret, void> || traits::arg_count == 2) {
49 // It's a standard handler or a Coroutine Task handling its own ResponseWriter. We just pass it through.
50 // Assumes signature: (HttpRequest&, shared_ptr<ResponseWriter>)
51 return [h = std::forward<Handler>(h)](http::HttpRequest& req, std::shared_ptr<http::ResponseWriter> writer) mutable {
52 h(req, writer);
53 };
54 } else {
55 // It returns a value! Let's auto-serialize it.
56 return [h = std::forward<Handler>(h)](http::HttpRequest& req, std::shared_ptr<http::ResponseWriter> writer) mutable {
57 try {
58 Ret result;
59 if constexpr (traits::arg_count == 0) {
60 result = h();
61 } else if constexpr (traits::arg_count == 1) {
62 result = h(req);
63 } else {
64 static_assert(traits::arg_count <= 1, "Magic handlers can only take 0 or 1 arguments (HttpRequest&)");
65 }
66
68 if constexpr (std::is_same_v<Ret, std::string>) {
69 res.status(http::HttpStatus::OK).send(result);
70 res.headers["Content-Type"] = "text/plain";
71 } else if constexpr (std::is_same_v<Ret, nlohmann::json>) {
72 res.status(http::HttpStatus::OK).send(result.dump());
73 res.headers["Content-Type"] = "application/json";
74 } else {
75 // It must be a C++ struct. nlohmann::json will serialize it!
76 nlohmann::json j = result;
78 res.headers["Content-Type"] = "application/json";
79 }
80 writer->send(std::move(res));
81 } catch (const std::exception& e) {
84 res.headers["Content-Type"] = "text/plain";
85 writer->send(std::move(res));
86 }
87 };
88 }
89}
90
91} // namespace routing
Represents an HTTP response to be sent to a client.
Definition HttpResponse.hpp:50
HttpResponse & send(const std::string &b) &
Sets the response body as plain text.
Definition HttpResponse.hpp:116
HttpResponse & status(HttpStatus code) &
Sets the HTTP status code of the response.
Definition HttpResponse.hpp:109
std::unordered_map< std::string, std::string, utils::CaseInsensitiveHash, utils::CaseInsensitiveEqual > headers
Definition HttpResponse.hpp:54
a class to store JSON values
Definition json.hpp:19401
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition json.hpp:20574
Definition HandlerWrapper.hpp:12
auto wrap_handler(Handler &&h) -> std::function< void(http::HttpRequest &, std::shared_ptr< http::ResponseWriter >)>
Definition HandlerWrapper.hpp:44
Represents an incoming HTTP request.
Definition HttpRequest.hpp:22
std::tuple< Args... > args_tuple
Definition HandlerWrapper.hpp:22
ReturnType result_type
Definition HandlerWrapper.hpp:21
ReturnType result_type
Definition HandlerWrapper.hpp:29
std::tuple< Args... > args_tuple
Definition HandlerWrapper.hpp:30
std::tuple< Args... > args_tuple
Definition HandlerWrapper.hpp:38
ReturnType result_type
Definition HandlerWrapper.hpp:37
Definition HandlerWrapper.hpp:16