drogon
C++14/17-based HTTP application framework
Loading...
Searching...
No Matches
HttpMiddleware.h
Go to the documentation of this file.
1
14
15#pragma once
16
17#include <drogon/DrObject.h>
18#include <drogon/drogon_callbacks.h>
19#include <drogon/HttpRequest.h>
20#include <drogon/HttpResponse.h>
21#include <memory>
22
23#ifdef __cpp_impl_coroutine
25#endif
26
27namespace drogon
28{
32class DROGON_EXPORT HttpMiddlewareBase : public virtual DrObjectBase
33{
34 public:
58 virtual void invoke(const HttpRequestPtr &req,
59 MiddlewareNextCallback &&nextCb,
60 MiddlewareCallback &&mcb) = 0;
61 ~HttpMiddlewareBase() override = default;
62};
63
71template <typename T, bool AutoCreation = true>
72class HttpMiddleware : public DrObject<T>, public HttpMiddlewareBase
73{
74 public:
75 static constexpr bool isAutoCreation{AutoCreation};
76 ~HttpMiddleware() override = default;
77};
78
79namespace internal
80{
81DROGON_EXPORT void handleException(
82 const std::exception &,
83 const HttpRequestPtr &,
84 std::function<void(const HttpResponsePtr &)> &&);
85}
86
87#ifdef __cpp_impl_coroutine
88
89struct [[nodiscard]] MiddlewareNextAwaiter
90 : public CallbackAwaiter<HttpResponsePtr>
91{
92 public:
93 MiddlewareNextAwaiter(MiddlewareNextCallback &&nextCb)
94 : nextCb_(std::move(nextCb))
95 {
96 }
97
98 void await_suspend(std::coroutine_handle<> handle) noexcept
99 {
100 nextCb_([this, handle](const HttpResponsePtr &resp) {
101 setValue(resp);
102 handle.resume();
103 });
104 }
105
106 private:
107 MiddlewareNextCallback nextCb_;
108};
109
110template <typename T, bool AutoCreation = true>
111class HttpCoroMiddleware : public DrObject<T>, public HttpMiddlewareBase
112{
113 public:
114 static constexpr bool isAutoCreation{AutoCreation};
115 ~HttpCoroMiddleware() override = default;
116
117 void invoke(const HttpRequestPtr &req,
118 MiddlewareNextCallback &&nextCb,
119 MiddlewareCallback &&mcb) final
120 {
121 drogon::async_run([this,
122 req,
123 nextCb = std::move(nextCb),
124 mcb = std::move(mcb)]() mutable -> drogon::Task<> {
125 HttpResponsePtr resp;
126 try
127 {
128 resp = co_await invoke(req, {std::move(nextCb)});
129 }
130 catch (const std::exception &ex)
131 {
132 internal::handleException(ex, req, std::move(mcb));
133 co_return;
134 }
135 catch (...)
136 {
137 LOG_ERROR << "Exception not derived from std::exception";
138 co_return;
139 }
140
141 mcb(resp);
142 });
143 }
144
145 virtual Task<HttpResponsePtr> invoke(const HttpRequestPtr &req,
146 MiddlewareNextAwaiter &&next) = 0;
147};
148
149#endif
150
166template <class Derived, bool AutoCreation = true>
168 : public drogon::HttpMiddleware<Derived, AutoCreation>
169{
170 public:
171 void invoke(const HttpRequestPtr &req,
172 MiddlewareNextCallback &&nextCb,
173 MiddlewareCallback &&mcb) override
174 {
175 // Tag OPTIONS
176 if (req->method() == drogon::HttpMethod::Options)
177 req->attributes()->insert("drogon.customCORShandling", true);
178 // continue with next middleware (no post-processing here)
179 nextCb(std::move(mcb));
180 }
181};
182
184 : public HttpOptionsMiddlewareImpl<HttpOptionsMiddlewareAuto, true>
185{
186};
187
189 : public HttpOptionsMiddlewareImpl<HttpOptionsMiddleware, false>
190{
191};
192
193} // namespace drogon
The base class for all drogon reflection classes.
Definition DrObject.h:34
Definition DrObject.h:86
The abstract base class for middleware.
Definition HttpMiddleware.h:33
virtual void invoke(const HttpRequestPtr &req, MiddlewareNextCallback &&nextCb, MiddlewareCallback &&mcb)=0
The reflection base class template for middlewares.
Definition HttpMiddleware.h:73
Definition HttpMiddleware.h:185
Simple middleware that tags OPTIONS requests.
Definition HttpMiddleware.h:169
void invoke(const HttpRequestPtr &req, MiddlewareNextCallback &&nextCb, MiddlewareCallback &&mcb) override
Definition HttpMiddleware.h:171
Definition HttpMiddleware.h:190
Drogon Test is a minimal effort test framework developed because the major C++ test frameworks doesn'...
Definition Attribute.h:23
void async_run(Coro &&coro)
Runs a coroutine from a regular function.
Definition coroutine.h:749
STL namespace.