Skip to content

Templatized ESP8266WebServer can't inherit StaticRequestHandler #7600

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
4 of 6 tasks
jason-but opened this issue Sep 16, 2020 · 5 comments
Closed
4 of 6 tasks

Templatized ESP8266WebServer can't inherit StaticRequestHandler #7600

jason-but opened this issue Sep 16, 2020 · 5 comments

Comments

@jason-but
Copy link

jason-but commented Sep 16, 2020

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: ESP8266
  • Core Version: All versions from 2.6.0+
  • Development Env: Arduino IDE
  • Operating System: Linux

Settings in IDE

  • Module: [Generic ESP8266 Module|Wemos D1 mini r2|Nodemcu|other]
  • Flash Mode: N/A
  • Flash Size: 4MB
  • lwip Variant: N/A
  • Reset Method: N/A
  • Flash Frequency: N/A
  • CPU Frequency: N/A
  • Upload Using: N/A
  • Upload Speed: N/A

Problem Description

Recently porting some old code I wrote that utilised version 2.5.x of the ESP8266 libraries, ESP8266WebServer and StaticRequestHandler. Upgrading to a version of 2.6 or later has ESP8266WebServer moving to a templatized implementation. The mechanism I deployed which functioned correctly to statically serve web pages on the FS with authentication no longer compiles

In my original code, I inherited StaticRequestHandler as

class AuthenticatedStaticRequestHandler : public StaticRequestHandler
{
    private:
        std::function<bool(void)> _funcAuth;

    public:
        AuthenticatedStaticRequestHandler(FS& fs, const char* path, const char* uri, const char* cache_header, std::function<bool(void)> funcAuth)
         : StaticRequestHandler(fs, path, uri, cache_header), _funcAuth(funcAuth)
        {
        }

        bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override
        {
            if (_funcAuth()) return StaticRequestHandler::handle(server, requestMethod, requestUri);
            return false;
        }
};

This allowed me to extend StaticRequestHandler to call an user-provided authentication function to do basic HTTP auth prior to allowing access to the page.

I installed the page as per:

    _cServer.addHandler(new AuthenticatedStaticRequestHandler(SPIFFS, "/web/", "/", "max-age=86400", _auth_func));

This would then successfully serve all files in the /web directory but only if _auth_func() returned true that the browser was successfully authenticated. The _auth_func() function would call _cServer.authenticate() and/or _cServer.requestAuthentication() as required

After upgrading to the templatized library, I tried to rewrite this as a templatized class

template<typename ServerType>
class AuthenticatedStaticRequestHandler : public RequestHandler<ServerType>
{
    using WebServerType = ESP8266WebServerTemplate<ServerType>;
    private:
        std::function<bool(void)> _funcAuth;

    public:
        AuthenticatedStaticRequestHandler(FS& fs, const char* path, const char* uri, const char* cache_header, std::function<bool(void)> funcAuth)
         : StaticRequestHandler<ServerType>(fs, path, uri, cache_header), _funcAuth(funcAuth)
        {
        }

        bool handle(WebServerType& server, HTTPMethod requestMethod, String requestUri) override
        {
            if (_funcAuth()) return StaticRequestHandler::handle(server, requestMethod, requestUri);
            return false;
        }
};

Debug Messages

This now fails to compile with the following error messages

error: expected template-name before '<' token
 class AuthenticatedStaticRequestHandler : public RequestHandler<ServerType>
                                                                ^
error: expected '{' before '<' token
error: expected unqualified-id before '<' token

I similarly cannot create an instance of even the basic StaticRequestHandler<> from my own code.

The templatisation has hidden the RequestHandler<> class and all inherited classes and they are no longer useable

Can this be fixed, or is there a better way to serve Static Web pages while also running HTTP basic authentication?

@d-a-v
Copy link
Collaborator

d-a-v commented Sep 16, 2020

did you try

template<typename ServerType>
class AuthenticatedStaticRequestHandler : public esp8266webserver::RequestHandler<ServerType>

@jason-but
Copy link
Author

OK

Now I feel like an idiot, 20+ years of programming and I didn't think to check the namespaces :-(

Thank you

@earlephilhower
Copy link
Collaborator

Looks like this is all taken care of, then. Closing. If it's not, then do let us know!

@d-a-v
Copy link
Collaborator

d-a-v commented Sep 17, 2020

@jason-but if you knew about #7560 or if it were merged, you would have found by yourself :)

@jason-but
Copy link
Author

Unfortunately, I don't solely work in this area/space so I don't follow changes religiously, otherwise I would have :-)

Hence why I only recently started porting the old code

To make me look even more stupid, I've been programming since 83, and C++ programming since 92, so nearly 30 years and the namespace thing didn't occur to me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants