Skip to content

Commit

Permalink
Merge pull request #186 from mathieucarbou/response-override
Browse files Browse the repository at this point in the history
Response override
  • Loading branch information
mathieucarbou authored Sep 28, 2024
2 parents 18e8b47 + 7d5827e commit 595d8f3
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 107 deletions.
4 changes: 2 additions & 2 deletions src/PsychicCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ class PsychicClient;
typedef std::function<bool(PsychicRequest* request)> PsychicRequestFilterFunction;

// middleware function definition
typedef std::function<esp_err_t(PsychicRequest* request, PsychicResponse* response)> PsychicMiddlewareCallback;
typedef std::function<esp_err_t(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareCallback next)> PsychicMiddlewareFunction;
typedef std::function<esp_err_t()> PsychicMiddlewareNext;
typedef std::function<esp_err_t(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next)> PsychicMiddlewareCallback;

// client connect callback
typedef std::function<void(PsychicClient* client)> PsychicClientCallback;
Expand Down
11 changes: 5 additions & 6 deletions src/PsychicEndpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,14 @@ esp_err_t PsychicEndpoint::requestCallback(httpd_req_t* req)

PsychicEndpoint* self = (PsychicEndpoint*)req->user_ctx;
PsychicRequest request(self->_server, req);
PsychicResponse response(&request);

esp_err_t err = self->process(&request, &response);
esp_err_t err = self->process(&request);

if (err == HTTPD_404_NOT_FOUND)
return PsychicHttpServer::requestHandler(req);

if (err == ESP_ERR_HTTPD_INVALID_REQ)
return response.error(HTTPD_500_INTERNAL_SERVER_ERROR, "No handler registered.");
return request.response()->error(HTTPD_500_INTERNAL_SERVER_ERROR, "No handler registered.");

return err;
}
Expand Down Expand Up @@ -120,7 +119,7 @@ PsychicEndpoint* PsychicEndpoint::addMiddleware(PsychicMiddleware* middleware)
return this;
}

PsychicEndpoint* PsychicEndpoint::addMiddleware(PsychicMiddlewareFunction fn)
PsychicEndpoint* PsychicEndpoint::addMiddleware(PsychicMiddlewareCallback fn)
{
_handler->addMiddleware(fn);
return this;
Expand All @@ -131,11 +130,11 @@ void PsychicEndpoint::removeMiddleware(PsychicMiddleware* middleware)
_handler->removeMiddleware(middleware);
}

esp_err_t PsychicEndpoint::process(PsychicRequest* request, PsychicResponse* response)
esp_err_t PsychicEndpoint::process(PsychicRequest* request)
{
esp_err_t ret = ESP_ERR_HTTPD_INVALID_REQ;
if (_handler != NULL)
ret = _handler->process(request, response);
ret = _handler->process(request);
ESP_LOGD(PH_TAG, "Endpoint %s processed %s: %s", _uri.c_str(), request->uri().c_str(), esp_err_to_name(ret));
return ret;
}
4 changes: 2 additions & 2 deletions src/PsychicEndpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ class PsychicEndpoint
bool matches(const char* uri);

// called to process this endpoint with its middleware chain
esp_err_t process(PsychicRequest* request, PsychicResponse* response);
esp_err_t process(PsychicRequest* request);

PsychicEndpoint* addFilter(PsychicRequestFilterFunction fn);

PsychicEndpoint* addMiddleware(PsychicMiddleware* middleware);
PsychicEndpoint* addMiddleware(PsychicMiddlewareFunction fn);
PsychicEndpoint* addMiddleware(PsychicMiddlewareCallback fn);
void removeMiddleware(PsychicMiddleware* middleware);

String uri();
Expand Down
16 changes: 9 additions & 7 deletions src/PsychicHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,27 +106,27 @@ PsychicHandler* PsychicHandler::addMiddleware(PsychicMiddleware* middleware)
if (!_chain) {
_chain = new PsychicMiddlewareChain();
}
_chain->add(middleware);
_chain->addMiddleware(middleware);
return this;
}

PsychicHandler* PsychicHandler::addMiddleware(PsychicMiddlewareFunction fn)
PsychicHandler* PsychicHandler::addMiddleware(PsychicMiddlewareCallback fn)
{
if (!_chain) {
_chain = new PsychicMiddlewareChain();
}
_chain->add(fn);
_chain->addMiddleware(fn);
return this;
}

void PsychicHandler::removeMiddleware(PsychicMiddleware* middleware)
{
if (_chain) {
_chain->remove(middleware);
_chain->removeMiddleware(middleware);
}
}

esp_err_t PsychicHandler::process(PsychicRequest* request, PsychicResponse* response)
esp_err_t PsychicHandler::process(PsychicRequest* request)
{
if (!filter(request)) {
return HTTPD_404_NOT_FOUND;
Expand All @@ -138,9 +138,11 @@ esp_err_t PsychicHandler::process(PsychicRequest* request, PsychicResponse* resp
}

if (_chain) {
return _chain->run(request, response, std::bind(&PsychicHandler::handleRequest, this, std::placeholders::_1, std::placeholders::_2));
return _chain->runChain(request, [this, request]() {
return handleRequest(request, request->response());
});

} else {
return handleRequest(request, response);
return handleRequest(request, request->response());
}
}
4 changes: 2 additions & 2 deletions src/PsychicHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ class PsychicHandler
const std::list<PsychicClient*>& getClientList();

// called to process this handler with its middleware chain and filers
esp_err_t process(PsychicRequest* request, PsychicResponse* response);
esp_err_t process(PsychicRequest* request);

//bool filter(PsychicRequest* request);
PsychicHandler* addFilter(PsychicRequestFilterFunction fn);
bool filter(PsychicRequest* request);

PsychicHandler* addMiddleware(PsychicMiddleware* middleware);
PsychicHandler* addMiddleware(PsychicMiddlewareFunction fn);
PsychicHandler* addMiddleware(PsychicMiddlewareCallback fn);
void removeMiddleware(PsychicMiddleware *middleware);

// derived classes must implement these functions
Expand Down
30 changes: 15 additions & 15 deletions src/PsychicHttpServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,23 +402,23 @@ PsychicHttpServer* PsychicHttpServer::addMiddleware(PsychicMiddleware* middlewar
if (!_chain) {
_chain = new PsychicMiddlewareChain();
}
_chain->add(middleware);
_chain->addMiddleware(middleware);
return this;
}

PsychicHttpServer* PsychicHttpServer::addMiddleware(PsychicMiddlewareFunction fn)
PsychicHttpServer* PsychicHttpServer::addMiddleware(PsychicMiddlewareCallback fn)
{
if (!_chain) {
_chain = new PsychicMiddlewareChain();
}
_chain->add(fn);
_chain->addMiddleware(fn);
return this;
}

void PsychicHttpServer::removeMiddleware(PsychicMiddleware* middleware)
{
if (_chain) {
_chain->remove(middleware);
_chain->removeMiddleware(middleware);
}
}

Expand Down Expand Up @@ -446,23 +446,24 @@ esp_err_t PsychicHttpServer::requestHandler(httpd_req_t* req)
{
PsychicHttpServer* server = (PsychicHttpServer*)httpd_get_global_user_ctx(req->handle);
PsychicRequest request(server, req);
PsychicResponse response(&request);

// process any URL rewrites
server->_rewriteRequest(&request);

// run it through our global server filter list
if (!server->_filter(&request)) {
ESP_LOGD(PH_TAG, "Request %s refused by global filter", request.uri().c_str());
return response.send(400);
return request.response()->send(400);
}

// then runs the request through the filter chain
esp_err_t ret;
if (server->_chain) {
ret = server->_chain->run(&request, &response, std::bind(&PsychicHttpServer::_process, server, std::placeholders::_1, std::placeholders::_2));
ret = server->_chain->runChain(&request, [server, &request]() {
return server->_process(&request);
});
} else {
ret = server->_process(&request, &response);
ret = server->_process(&request);
}
ESP_LOGD(PH_TAG, "Request %s processed by global middleware: %s", request.uri().c_str(), esp_err_to_name(ret));

Expand All @@ -473,21 +474,21 @@ esp_err_t PsychicHttpServer::requestHandler(httpd_req_t* req)
return ret;
}

esp_err_t PsychicHttpServer::_process(PsychicRequest* request, PsychicResponse* response)
esp_err_t PsychicHttpServer::_process(PsychicRequest* request)
{
// loop through our endpoints and see if anyone wants it.
for (auto* endpoint : _endpoints) {
if (endpoint->matches(request->uri().c_str())) {
if (endpoint->_method == request->method() || endpoint->_method == HTTP_ANY) {
request->setEndpoint(endpoint);
return endpoint->process(request, response);
return endpoint->process(request);
}
}
}

// loop through our global handlers and see if anyone wants it
for (auto* handler : _handlers) {
esp_err_t ret = handler->process(request, response);
esp_err_t ret = handler->process(request);
if (ret != HTTPD_404_NOT_FOUND)
return ret;
}
Expand All @@ -499,19 +500,18 @@ esp_err_t PsychicHttpServer::notFoundHandler(httpd_req_t* req, httpd_err_code_t
{
PsychicHttpServer* server = (PsychicHttpServer*)httpd_get_global_user_ctx(req->handle);
PsychicRequest request(server, req);
PsychicResponse response(&request);

// pull up our default handler / endpoint
PsychicHandler* handler = server->defaultEndpoint->handler();
if (!handler)
return response.send(404);
return request.response()->send(404);

esp_err_t ret = handler->process(&request, &response);
esp_err_t ret = handler->process(&request);
if (ret != HTTPD_404_NOT_FOUND)
return ret;

// not sure how we got this far.
return response.send(404);
return request.response()->send(404);
}

esp_err_t PsychicHttpServer::defaultNotFoundHandler(PsychicRequest* request, PsychicResponse* response)
Expand Down
4 changes: 2 additions & 2 deletions src/PsychicHttpServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class PsychicHttpServer
httpd_uri_match_func_t _uri_match_fn = nullptr;

bool _rewriteRequest(PsychicRequest* request);
esp_err_t _process(PsychicRequest* request, PsychicResponse* response);
esp_err_t _process(PsychicRequest* request);
bool _filter(PsychicRequest* request);

public:
Expand Down Expand Up @@ -113,7 +113,7 @@ class PsychicHttpServer
PsychicHttpServer* addFilter(PsychicRequestFilterFunction fn);

PsychicHttpServer* addMiddleware(PsychicMiddleware* middleware);
PsychicHttpServer* addMiddleware(PsychicMiddlewareFunction fn);
PsychicHttpServer* addMiddleware(PsychicMiddlewareCallback fn);
void removeMiddleware(PsychicMiddleware *middleware);

static esp_err_t requestHandler(httpd_req_t* req);
Expand Down
11 changes: 2 additions & 9 deletions src/PsychicMiddleware.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
#include "PsychicMiddleware.h"
#include "PsychicMiddlewareChain.h"
#include "PsychicRequest.h"
#include "PsychicResponse.h"

PsychicMiddlewareClosure::PsychicMiddlewareClosure(PsychicMiddlewareFunction fn) : _fn(fn)
esp_err_t PsychicMiddlewareFunction::run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next)
{
assert(_fn);
return _fn(request, request->response(), next);
}
esp_err_t PsychicMiddlewareClosure::run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareCallback next)
{
return _fn(request, response, next);
}
27 changes: 15 additions & 12 deletions src/PsychicMiddleware.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,26 @@ class PsychicMiddlewareChain;

class PsychicMiddleware
{
private:
bool _managed = false;
friend PsychicMiddlewareChain;

public:
virtual ~PsychicMiddleware() {}
virtual esp_err_t run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareCallback next) = 0;
virtual esp_err_t run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next)
{
return next();
}

private:
friend PsychicMiddlewareChain;
bool _freeOnRemoval = false;
};

class PsychicMiddlewareClosure : public PsychicMiddleware
class PsychicMiddlewareFunction : public PsychicMiddleware
{
protected:
PsychicMiddlewareFunction _fn;

public:
PsychicMiddlewareClosure(PsychicMiddlewareFunction fn);
esp_err_t run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareCallback next) override;
PsychicMiddlewareFunction(PsychicMiddlewareCallback fn) : _fn(fn) { assert(_fn); }
esp_err_t run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next) override;

protected:
PsychicMiddlewareCallback _fn;
};

#endif
#endif
44 changes: 20 additions & 24 deletions src/PsychicMiddlewareChain.cpp
Original file line number Diff line number Diff line change
@@ -1,51 +1,47 @@
#include "PsychicMiddlewareChain.h"

PsychicMiddlewareChain::PsychicMiddlewareChain() {}

PsychicMiddlewareChain::~PsychicMiddlewareChain()
{
for (auto middleware : _middleware) {
if (middleware->_managed)
for (auto middleware : _middleware)
if (middleware->_freeOnRemoval)
delete middleware;
}
_middleware.clear();
}

void PsychicMiddlewareChain::add(PsychicMiddleware* middleware)
void PsychicMiddlewareChain::addMiddleware(PsychicMiddleware* middleware)
{
_middleware.push_back(middleware);
}

void PsychicMiddlewareChain::add(PsychicMiddlewareFunction fn)
void PsychicMiddlewareChain::addMiddleware(PsychicMiddlewareCallback fn)
{
PsychicMiddlewareClosure* closure = new PsychicMiddlewareClosure(fn);
closure->_managed = true;
PsychicMiddlewareFunction* closure = new PsychicMiddlewareFunction(fn);
closure->_freeOnRemoval = true;
_middleware.push_back(closure);
}

void PsychicMiddlewareChain::remove(PsychicMiddleware* middleware)
void PsychicMiddlewareChain::removeMiddleware(PsychicMiddleware* middleware)
{
_middleware.remove(middleware);
if (middleware->_freeOnRemoval)
delete middleware;
}

esp_err_t PsychicMiddlewareChain::run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareCallback finalizer)
esp_err_t PsychicMiddlewareChain::runChain(PsychicRequest* request, PsychicMiddlewareNext finalizer)
{
if (_middleware.size() == 0) {
return finalizer(request, response);
}
if (_middleware.size() == 0)
return finalizer();

PsychicMiddlewareCallback next;
PsychicMiddlewareNext next;
std::list<PsychicMiddleware*>::iterator it = _middleware.begin();

next = [this, &next, &it, finalizer](PsychicRequest* request, PsychicResponse* response) {
if (it != _middleware.end()) {
PsychicMiddleware* m = *it;
it++;
return m->run(request, response, next);
} else {
return finalizer(request, response);
}
next = [this, &next, &it, request, finalizer]() {
if (it == _middleware.end())
return finalizer();
PsychicMiddleware* m = *it;
it++;
return m->run(request, request->response(), next);
};

return next(request, response);
return next();
}
Loading

0 comments on commit 595d8f3

Please sign in to comment.