Skip to content

Commit

Permalink
Added support for removing routes in WebServer library (#9832)
Browse files Browse the repository at this point in the history
* feat: added removeRoutes and removeHandler methods

* feat: added removeRoute and removeHandler methods

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
  • Loading branch information
3 people committed Jun 13, 2024
1 parent 211520b commit 849ec57
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
54 changes: 54 additions & 0 deletions libraries/WebServer/src/WebServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,38 @@ void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunctio
_addRequestHandler(new FunctionRequestHandler(fn, ufn, uri, method));
}

bool WebServer::removeRoute(const char *uri) {
return removeRoute(String(uri), HTTP_ANY);
}

bool WebServer::removeRoute(const char *uri, HTTPMethod method) {
return removeRoute(String(uri), method);
}

bool WebServer::removeRoute(const String &uri) {
return removeRoute(uri, HTTP_ANY);
}

bool WebServer::removeRoute(const String &uri, HTTPMethod method) {
// Loop through all request handlers and see if there is a match
RequestHandler *handler = _firstHandler;
while (handler) {
if (handler->canHandle(method, uri)) {
return _removeRequestHandler(handler);
}
handler = handler->next();
}
return false;
}

void WebServer::addHandler(RequestHandler *handler) {
_addRequestHandler(handler);
}

bool WebServer::removeHandler(RequestHandler *handler) {
return _removeRequestHandler(handler);
}

void WebServer::_addRequestHandler(RequestHandler *handler) {
if (!_lastHandler) {
_firstHandler = handler;
Expand All @@ -332,6 +360,32 @@ void WebServer::_addRequestHandler(RequestHandler *handler) {
}
}

bool WebServer::_removeRequestHandler(RequestHandler *handler) {
RequestHandler *current = _firstHandler;
RequestHandler *previous = nullptr;

while (current != nullptr) {
if (current == handler) {
if (previous == nullptr) {
_firstHandler = current->next();
} else {
previous->next(current->next());
}

if (current == _lastHandler) {
_lastHandler = previous;
}

// Delete 'matching' handler
delete current;
return true;
}
previous = current;
current = current->next();
}
return false;
}

void WebServer::serveStatic(const char *uri, FS &fs, const char *path, const char *cache_header) {
_addRequestHandler(new StaticRequestHandler(fs, path, uri, cache_header));
}
Expand Down
6 changes: 6 additions & 0 deletions libraries/WebServer/src/WebServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,12 @@ class WebServer {
void on(const Uri &uri, THandlerFunction fn);
void on(const Uri &uri, HTTPMethod method, THandlerFunction fn);
void on(const Uri &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn); //ufn handles file uploads
bool removeRoute(const char *uri);
bool removeRoute(const char *uri, HTTPMethod method);
bool removeRoute(const String &uri);
bool removeRoute(const String &uri, HTTPMethod method);
void addHandler(RequestHandler *handler);
bool removeHandler(RequestHandler *handler);
void serveStatic(const char *uri, fs::FS &fs, const char *path, const char *cache_header = NULL);
void onNotFound(THandlerFunction fn); //called when handler is not assigned
void onFileUpload(THandlerFunction ufn); //handle file uploads
Expand Down Expand Up @@ -230,6 +235,7 @@ class WebServer {
return _currentClient.write_P(b, l);
}
void _addRequestHandler(RequestHandler *handler);
bool _removeRequestHandler(RequestHandler *handler);
void _handleRequest();
void _finalizeResponse();
bool _parseRequest(NetworkClient &client);
Expand Down

3 comments on commit 849ec57

@everslick
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honest question:

Why do we need bool removeRoute(const char *uri); when we already have bool removeRoute(const String &uri); which also works when called like removeRoute("foobar"); ?

@me-no-dev
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should have actually been implemented through the const char * path in order to conserve memory when Strings are not used. Valid concern, but also not a big deal

@everslick
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's just one of those Arduino things, like passing heavy objects by value instead of reference, one can find without looking very hard. ;-)

anyway, thanks for answering.

Please sign in to comment.