khoih-prog / EthernetWebServer

This is simple yet complete WebServer library for AVR, AVR Dx, Portenta_H7, Teensy, SAM DUE, SAMD21/SAMD51, nRF52, STM32, RP2040-based, etc. boards running Ethernet shields. The functions are similar and compatible to ESP8266/ESP32 WebServer libraries to make life much easier to port sketches from ESP8266/ESP32. Coexisting now with `ESP32 WebServer` and `ESP8266 ESP8266WebServer` libraries. Ethernet_Generic library is used as default for W5x00 with custom SPI
MIT License
178 stars 49 forks source link

Feature Request: Add a RequestHandler subclass which passes the server to the function #27

Closed EmperorArthur closed 3 years ago

EmperorArthur commented 3 years ago

Hello,

I am currently examining the feasibility of switching from our current custom (but extremely fast) Arduino web server code. In doing so, I noticed that the default on methods, and FunctionRequestHandler only call functions which have no arguments.

That is a serious issue, since it means the server code must be a global, and breaks all sorts of best practices.

My cheap and dirty work around is something like this, but due to the next bug, I can't even test it with our current code base.

typedef vl::Func<void(EthernetWebServer&)> THandlerFunctionWithServer;
class FunctionRequestHandlerWithServer: public FunctionRequestHandler {
public:
    FunctionRequestHandlerWithServer(THandlerFunctionWithServer fn,
                                     THandlerFunctionWithServer ufn, const String &uri, HTTPMethod method)
    : FunctionRequestHandler([](){}, [](){}, uri, method), _fns(fn), _ufns(ufn)
    {
    }

    bool handle(EthernetWebServer& server, HTTPMethod requestMethod, String requestUri) override
    {
        ETW_UNUSED(server);

        if (!canHandle(requestMethod, requestUri))
            return false;

        _fns(server);
        return true;
    }

    void upload(EthernetWebServer& server, String requestUri, HTTPUpload& upload) override
    {
        ETW_UNUSED(server);
        ETW_UNUSED(upload);

        if (canUpload(requestUri))
            _ufns(server);
    }

protected:
    THandlerFunctionWithServer _fns;
    THandlerFunctionWithServer _ufns;
};

void handlerFunction(EthernetWebServer& server) {
    server.send(404, "application/json", "Something";
}

Edit: With something like this, the EthernetServer().on(...) functions can be overloaded to support both versions.

khoih-prog commented 3 years ago

HI,

Thanks for the Feature Request.

To save both of us spending some time back and forth, could you please provide some MRE : How to create a Minimal, Reproducible Example to demonstrate your case. I'll certainly spend some time later to investigate and fix the library.

Regards,

EmperorArthur commented 3 years ago

Hello,

Unfortunately, this request is only truly needed when #28 is implemented. Our use case is the server/router living in "main.cpp", and each individual component (".h/.cpp" file) having their own THandlerFunction. This allows for modularity of the system, and is how almost all Model View Controller (MVC) web frameworks operate.*

As #28 is closed as WontFix, this issue is mute for our use case.

* For more information, Dask and Laravel are my recommended starting points, depending on language preference.

khoih-prog commented 3 years ago

Thanks for your interests and feedbacks anyway.

I'll spend some time to add separate cpp folder later, but have to close the issue now.