Skip to content

Commit 15ef3f9

Browse files
committed
Allow removing std::function type middlewares.
Signed-off-by: pvogt09 <[email protected]>
1 parent 383a3e4 commit 15ef3f9

File tree

3 files changed

+86
-10
lines changed

3 files changed

+86
-10
lines changed

src/HTTPMiddlewareFunction.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace httpsserver {
1111
class HTTPRequest;
12+
using HTTPSMiddlewareFunctionType = void(HTTPRequest * req, HTTPResponse * res, std::function<void()> next);
1213
/**
1314
* \brief A middleware function that can be registered at the server.
1415
*
@@ -21,8 +22,6 @@ namespace httpsserver {
2122
* handling in case of missing authentication. Don't forget to call next in case you want to access your
2223
* resources, though.
2324
*/
24-
typedef std::function<void(HTTPRequest * req, HTTPResponse * res, std::function<void()> next)> HTTPSMiddlewareFunction;
25-
26-
bool operator==(const HTTPSMiddlewareFunction& lhs, const HTTPSMiddlewareFunction& rhs);
25+
typedef std::function<HTTPSMiddlewareFunctionType> HTTPSMiddlewareFunction;
2726
}
2827
#endif /* SRC_HTTPMIDDLEWAREFUNCTION_HPP_ */

src/ResourceResolver.cpp

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,21 @@
22

33
namespace httpsserver {
44

5+
ResourceResolver::HTTPSMiddlewareFunctionCallback::HTTPSMiddlewareFunctionCallback(const HTTPSMiddlewareFunction callback, const HTTPSMiddlewareFunction* callback_std_function, const HTTPSMiddlewareFunctionType* callback_raw_pointer) : _callback(callback), _callback_std_function(callback_std_function), _callback_raw_pointer(callback_raw_pointer) {
6+
};
7+
8+
HTTPSMiddlewareFunction ResourceResolver::HTTPSMiddlewareFunctionCallback::getCallback() {
9+
return _callback;
10+
};
11+
12+
const HTTPSMiddlewareFunction* ResourceResolver::HTTPSMiddlewareFunctionCallback::getStdFunctionPointer() {
13+
return _callback_std_function;
14+
};
15+
16+
const HTTPSMiddlewareFunctionType* ResourceResolver::HTTPSMiddlewareFunctionCallback::getRawFunctionPointer() {
17+
return _callback_raw_pointer;
18+
};
19+
520
ResourceResolver::ResourceResolver() {
621
_nodes = new std::vector<HTTPNode *>();
722
_defaultNode = NULL;
@@ -160,20 +175,68 @@ void ResourceResolver::resolveNode(const std::string &method, const std::string
160175
}
161176
}
162177

163-
void ResourceResolver::addMiddleware(const HTTPSMiddlewareFunction mwFunction) {
178+
void ResourceResolver::updateMiddlewareList() {
179+
_middleware.clear();
180+
_middleware.reserve(_middleware_callback.size());
181+
for (auto& callback : _middleware_callback) {
182+
_middleware.push_back(callback.getCallback());
183+
}
184+
}
185+
186+
void ResourceResolver::addMiddleware(const HTTPSMiddlewareFunction &mwFunction) {
187+
const HTTPSMiddlewareFunctionCallback callback{
188+
mwFunction,
189+
&mwFunction,
190+
nullptr
191+
};
164192
_middleware.push_back(mwFunction);
193+
_middleware_callback.push_back(callback);
165194
}
166195

167196
void ResourceResolver::addMiddleware(void (*mwFunction)(HTTPRequest * req, HTTPResponse * res, std::function<void()> next)) {
168-
_middleware.push_back(HTTPSMiddlewareFunction(mwFunction));
197+
auto mwFunction_callback = HTTPSMiddlewareFunction(mwFunction);
198+
const HTTPSMiddlewareFunctionCallback callback{
199+
mwFunction_callback,
200+
&mwFunction_callback,
201+
mwFunction
202+
};
203+
_middleware.push_back(mwFunction_callback);
204+
_middleware_callback.push_back(callback);
169205
}
170206

171-
void ResourceResolver::removeMiddleware(const HTTPSMiddlewareFunction mwFunction) {
172-
_middleware.erase(std::remove(_middleware.begin(), _middleware.end(), mwFunction), _middleware.end());
207+
void ResourceResolver::removeMiddleware(const HTTPSMiddlewareFunction &mwFunction) {
208+
bool found = false;
209+
for (auto it = _middleware_callback.begin(); it != _middleware_callback.end();) {
210+
auto element = *it;
211+
const auto callback = element.getStdFunctionPointer();
212+
const auto callback_supplied = &mwFunction;
213+
if (callback != nullptr && callback == callback_supplied) {
214+
it = _middleware_callback.erase(it);
215+
found = true;
216+
} else {
217+
++it;
218+
}
219+
}
220+
if (found) {
221+
updateMiddlewareList();
222+
}
173223
}
174224

175225
void ResourceResolver::removeMiddleware(void (*mwFunction)(HTTPRequest * req, HTTPResponse * res, std::function<void()> next)) {
176-
_middleware.erase(std::remove(_middleware.begin(), _middleware.end(), mwFunction), _middleware.end());
226+
bool found = false;
227+
for (auto it = _middleware_callback.begin(); it != _middleware_callback.end();) {
228+
auto element = *it;
229+
auto callback = element.getRawFunctionPointer();
230+
if (callback != nullptr && callback == mwFunction) {
231+
it = _middleware_callback.erase(it);
232+
found = true;
233+
} else {
234+
++it;
235+
}
236+
}
237+
if (found) {
238+
updateMiddlewareList();
239+
}
177240
}
178241

179242
const std::vector<HTTPSMiddlewareFunction> ResourceResolver::getMiddleware() {

src/ResourceResolver.hpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,36 @@ class ResourceResolver {
3030
void resolveNode(const std::string &method, const std::string &url, ResolvedResource &resolvedResource, HTTPNodeType nodeType);
3131

3232
/** Add a middleware function to the end of the middleware function chain. See HTTPSMiddlewareFunction.hpp for details. */
33-
void addMiddleware(const HTTPSMiddlewareFunction mwFunction);
33+
void addMiddleware(const HTTPSMiddlewareFunction &mwFunction);
3434
void addMiddleware(void (*mwFunction)(HTTPRequest *req, HTTPResponse *res, std::function<void()> next));
3535
/** Remove a specific function from the middleware function chain. */
36-
void removeMiddleware(const HTTPSMiddlewareFunction mwFunction);
36+
void removeMiddleware(const HTTPSMiddlewareFunction &mwFunction);
3737
void removeMiddleware(void (*mwFunction)(HTTPRequest * req, HTTPResponse * res, std::function<void()> next));
3838
/** Get the current middleware chain with a resource function at the end */
3939
const std::vector<HTTPSMiddlewareFunction> getMiddleware();
4040

4141
private:
42+
class HTTPSMiddlewareFunctionCallback {
43+
private:
44+
HTTPSMiddlewareFunction _callback;
45+
const HTTPSMiddlewareFunction* _callback_std_function;
46+
const HTTPSMiddlewareFunctionType* _callback_raw_pointer;
47+
public:
48+
HTTPSMiddlewareFunctionCallback(HTTPSMiddlewareFunction callback, const HTTPSMiddlewareFunction* const callback_std_function, const HTTPSMiddlewareFunctionType* callback_raw_pointer);
49+
HTTPSMiddlewareFunction getCallback();
50+
const HTTPSMiddlewareFunction* getStdFunctionPointer();
51+
const HTTPSMiddlewareFunctionType* getRawFunctionPointer();
52+
};
4253

4354
// This vector holds all nodes (with callbacks) that are registered
4455
std::vector<HTTPNode*> * _nodes;
4556
HTTPNode * _defaultNode;
4657

4758
// Middleware functions, if any are registered. Will be called in order of the vector.
4859
std::vector<HTTPSMiddlewareFunction> _middleware;
60+
std::vector<HTTPSMiddlewareFunctionCallback> _middleware_callback;
61+
62+
void updateMiddlewareList();
4963
};
5064

5165
} /* namespace httpsserver */

0 commit comments

Comments
 (0)