lintel 0.2.0
Loading...
Searching...
No Matches
Controller.h
Go to the documentation of this file.
1#ifndef HTTP_LIBRARY_CONTROLLER_H
2#define HTTP_LIBRARY_CONTROLLER_H
3
4#include <httplib.h>
5
6#include <cstddef>
7#include <exception>
8#include <functional>
9#include <map>
10#include <memory>
11#include <optional>
12#include <type_traits>
13#include <vector>
14
23
24
25#define ADD_HANDLER_METHOD(pattern, httpType, name) \
26 void name##httpType(const httplib::Request &request, \
27 httplib::Response &response, \
28 const lintel::ContentType &contentType, \
29 const std::optional<lintel::UserToken> &user); \
30 Handler name##httpType##Function = addMethod<std::function<HandlerArgs>, httpType>( \
31 pattern, [&](const httplib::Request &request, httplib::Response &response) { \
32 std::string auth = request.get_header_value("Authorization"); \
33 std::string contentTypeString = request.get_header_value("Content-Type"); \
34 if (contentTypeString.empty()) { contentTypeString = "application/json"; } \
35 lintel::ContentType contentType(contentTypeString); \
36 std::optional<lintel::UserToken> user = std::nullopt; \
37 try { \
38 if (lintel::StringUtils::startsWith(auth, "Bearer ") && auth.size() > 7) { \
39 std::string id = auth.substr(7); \
40 lintel::UserTokenLogin userTokenLogin{ clientIpOf(request), id }; \
41 user = m_authService->onAccessOf(userTokenLogin); \
42 } \
43 name##httpType(request, response, contentType, user); \
44 } catch (const lintel::HttpBadRequestException &e) { \
45 LOG_ERROR("{}: {}", #name, e.what()); \
46 response.status = lintel::HttpStatusCodes::BadRequest; \
47 response.set_content("bad request", "text/plain"); \
48 } catch (const std::exception &e) { \
49 LOG_ERROR("{}: {}", #name, e.what()); \
50 response.status = lintel::HttpStatusCodes::InternalServerError; \
51 response.set_content("internal server error", "text/plain"); \
52 } \
53 })
54
55#define ADD_HANDLER_CONTENT_READER_METHOD(pattern, httpType, name) \
56 HandlerWithContentReader name##httpType##Function = \
57 addMethod<std::function<HandlerWithContentReaderArgs>, httpType>(pattern, \
58 [&](const httplib::Request &request, httplib::Response &response, const httplib::ContentReader &contentReader) { \
59 const std::string contentTypeString = request.get_header_value("Content-Type"); \
60 lintel::ContentType contentType(contentTypeString); \
61 try { \
62 name##httpType(request, response, contentReader, contentType); \
63 } catch (const std::exception &e) { \
64 LOG_ERROR("{}: {}", #name, e.what()); \
65 response.status = lintel::HttpStatusCodes::InternalServerError; \
66 response.set_content("internal server error", "text/plain"); \
67 } \
68 }); \
69 void name##httpType(const httplib::Request &request, \
70 httplib::Response &response, \
71 const httplib::ContentReader &contentReader, \
72 const lintel::ContentType &contentType)
73
74namespace lintel {
77{
79 static constexpr std::size_t kDefaultLimit = 100;
81 bool m_enabled = false;
83 std::optional<std::string> m_after;
85 std::size_t m_limit = kDefaultLimit;
86};
87
90{
91protected:
92 std::shared_ptr<IAuthService> m_authService;
93
101 std::string clientIpOf(const httplib::Request &request);
102
110 static PagingParams pagingParamsOf(const httplib::Request &request);
111
113
114 using HandlerArgs = void(const httplib::Request &, httplib::Response &);
115 using HandlerWithContentReaderArgs = void(const httplib::Request &,
116 httplib::Response &,
117 const httplib::ContentReader &);
118 using Handler = std::function<HandlerArgs>;
119 using HandlerWithContentReader = std::function<HandlerWithContentReaderArgs>;
120
122
123 struct Method
124 {
125 const std::string m_pattern;
126 std::shared_ptr<Handler> m_handler;
127 std::shared_ptr<HandlerWithContentReader> m_handlerWithContentReader;
128 };
129
130 std::map<HttpType, std::vector<Method>> m_methods;
131
133 template<class Type, HttpType httpType> Type addMethod(const std::string &pattern, Type handler)
134 {
135 const auto found = m_methods.find(httpType);
136 static_assert(httpType != Get || !std::is_same_v<Type, HandlerWithContentReader>,
137 "Get and HandlerWithContentReader is not supported");
138 static_assert(std::is_same_v<Type, Handler> || std::is_same_v<Type, HandlerWithContentReader>,
139 "Invalid method type! Pleas use Handler or "
140 "HandlerWithContentReader");
141 if constexpr (std::is_same_v<Type, Handler>) {
142 const Method method{ pattern, std::make_shared<Type>(handler), nullptr };
143 if (found != m_methods.end()) {
144 found->second.push_back(method);
145 } else {
146 m_methods.insert({ httpType, std::vector<Method>{ method } });
147 }
148 } else if constexpr (std::is_same_v<Type, HandlerWithContentReader>) {
149 const Method method{ pattern, nullptr, std::make_shared<Type>(handler) };
150 if (found != m_methods.end()) {
151 found->second.push_back(method);
152 } else {
153 m_methods.insert({ httpType, std::vector<Method>{ method } });
154 }
155 }
156 return handler;
157 }
158
159public:
161 explicit Controller(std::shared_ptr<IAuthService> authService)
163 {}
164
165 ~Controller() override = default;
166
169 void setTrustedProxies(std::vector<std::string> trustedProxies);
170
172 void registerMethods(std::shared_ptr<httplib::Server> &server);
173};
174
175}// namespace lintel
176#endif// HTTP_LIBRARY_CONTROLLER_H
Definition ClientIpResolver.h:17
Definition Controller.h:90
~Controller() override=default
static PagingParams pagingParamsOf(const httplib::Request &request)
Type addMethod(const std::string &pattern, Type handler)
Definition Controller.h:133
ClientIpResolver m_ipResolver
Definition Controller.h:112
std::function< HandlerWithContentReaderArgs > HandlerWithContentReader
Definition Controller.h:119
HttpType
Definition Controller.h:121
@ Get
Definition Controller.h:121
@ Post
Definition Controller.h:121
@ Put
Definition Controller.h:121
@ Delete
Definition Controller.h:121
std::function< HandlerArgs > Handler
Definition Controller.h:118
void setTrustedProxies(std::vector< std::string > trustedProxies)
void(const httplib::Request &, httplib::Response &) HandlerArgs
Definition Controller.h:114
std::shared_ptr< IAuthService > m_authService
Definition Controller.h:92
std::string clientIpOf(const httplib::Request &request)
void registerMethods(std::shared_ptr< httplib::Server > &server)
void(const httplib::Request &, httplib::Response &, const httplib::ContentReader &) HandlerWithContentReaderArgs
Definition Controller.h:117
Controller(std::shared_ptr< IAuthService > authService)
Definition Controller.h:161
std::map< HttpType, std::vector< Method > > m_methods
Definition Controller.h:130
Definition GroupProvider.h:11
Definition BaseFeature.h:6
constexpr std::string_view type_name()
Definition TypeName.h:9
Definition Controller.h:124
std::shared_ptr< HandlerWithContentReader > m_handlerWithContentReader
Definition Controller.h:127
const std::string m_pattern
Definition Controller.h:125
std::shared_ptr< Handler > m_handler
Definition Controller.h:126
Definition Controller.h:77
bool m_enabled
Definition Controller.h:81
static constexpr std::size_t kDefaultLimit
Definition Controller.h:79
std::optional< std::string > m_after
Definition Controller.h:83
std::size_t m_limit
Definition Controller.h:85