Skip to content

Commit dcdf369

Browse files
committed
allow custom OPTIONS handling via middleware flagging
1 parent 39eb780 commit dcdf369

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

lib/inc/drogon/HttpMiddleware.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,46 @@ class HttpCoroMiddleware : public DrObject<T>, public HttpMiddlewareBase
148148

149149
#endif
150150

151+
/**
152+
* @brief Simple middleware that tags OPTIONS requests
153+
* @details It adds the attribute "customCORShandling" to the request, so that
154+
* HttpServer does not handle CORS for them internally.
155+
*
156+
* This allows custom CORS handling via the path handlers.
157+
* For example to restrict the origins, headers allowed, specify a max age to
158+
* avoid OPTIONS on every request, etc.
159+
*
160+
* Just register it:
161+
* 1. globally via
162+
* app().registerMiddleware(std::make_shared<drogon::HttpOptionsMiddleware>())
163+
* 2. on every path handlers that need non-default handling, with
164+
* ADD_METHOD_TO(... , "drogon::HttpOptionsMiddleware")
165+
*/
166+
template <class Derived, bool AutoCreation = true>
167+
class HttpOptionsMiddlewareImpl
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 && req->method() == drogon::HttpMethod::Options)
177+
req->attributes()->insert("customCORShandling", true);
178+
// continue with next middleware (no post-processing here)
179+
nextCb(std::move(mcb));
180+
}
181+
};
182+
183+
class HttpOptionsMiddlewareAuto
184+
: public HttpOptionsMiddlewareImpl<HttpOptionsMiddlewareAuto, true>
185+
{
186+
};
187+
188+
class HttpOptionsMiddleware
189+
: public HttpOptionsMiddlewareImpl<HttpOptionsMiddleware, false>
190+
{
191+
};
192+
151193
} // namespace drogon

lib/src/HttpServer.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,10 @@ void HttpServer::requestPassMiddlewares(const HttpRequestImplPtr &req,
576576
template <typename Pack>
577577
void HttpServer::requestPreHandling(const HttpRequestImplPtr &req, Pack &&pack)
578578
{
579-
if (req->method() == Options)
579+
// Handle CORS preflight request, except when custom handling is desired
580+
if ((req->method() == Options) &&
581+
(!req->attributes()->find("customCORShandling") ||
582+
!req->attributes()->get<bool>("customCORShandling")))
580583
{
581584
handleHttpOptions(req,
582585
*pack.binderPtr->corsMethods_,

0 commit comments

Comments
 (0)