Skip to content
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

WebServer Hooks like in esp8266 #95

Open
luc-github opened this issue Aug 2, 2020 · 5 comments
Open

WebServer Hooks like in esp8266 #95

luc-github opened this issue Aug 2, 2020 · 5 comments
Labels

Comments

@luc-github
Copy link

luc-github commented Aug 2, 2020

Hello,
Recently there was a PR esp8266/Arduino#7459 in esp8266 that allows to use different protocol on same port of webserver

e.g WebDav on Webserver: https://github.com/d-a-v/ESPWebDAV/blob/v3/examples/Hooked/Hooked.ino

The esp8266 PR allows more generic approach as far I understand than the Websocket-Chat example

Could it be in plan to support such feature ?

Thank you ^_^

@luc-github luc-github changed the title WebHooks like in esp8266 WebServer Hooks like in esp8266 Aug 2, 2020
@fhessel
Copy link
Owner

fhessel commented Aug 2, 2020

Hi,

is your goal to intercept requests before they're processed, to check if a certain conditions is met, and then to either process the request as usual or to redirect it to another handler? Then middleware is what you're looking for. The basic middleware example shows only logging, but the authentication example covers more complex actions like requesting authentication or showing 401 pages if the user is not authenticated. The concept is quite similar to the middleware used in most NodeJS servers (like Express) or what you know as "Servlet Filters" in good old Java.

Or is the intention more to get in the direction of a modular webserver, so that you can create a server that handles /static by fetching static resources from your app image, /api to access your REST API, and for example /dav to have a WebDav interface to the SPIFFS? And then you would define a, let's call it, virtual server for each of those function which gets the stripped URL. So for example if you would call GET /api/gpio/23 this would be redirected to your API server instance as a GET /gpio/23 request? That isn't implemented yet, but I'd consider it a nice feature.

Or is the concept of these Hooks something completely different that I've misunderstood?

WebSockets are handled as a special case of incoming connections. Currently, for plain HTTP requests, the request handler function would be called and once it returns, that request is handled. If the request is for a websocket, an instance of the handler class will be instantiated and live as long as the websocket is used, while other requests can be processed in parallel.

@luc-github
Copy link
Author

luc-github commented Aug 2, 2020

wow so detailed thank you!

yes the intention is more to get in the direction of a modular webserver which give up if some path are defined for other function - so the handler can be specific to used protocol and take the control according the path

http://xxx.xxx.xxx.xx/dav for webdav protocol : like here
ws://xxx.xxx.xxx.xxx/ws for web socket protocol like in ESPAsyncWebserver
htttp://xxx.xxx.xxx.xxx/xxxx for any standard web query

So it seems like you did for Websocket /chat but more generic allowing any protocol actually

@fhessel
Copy link
Owner

fhessel commented Aug 2, 2020

So it seems like you did for Websocket /chat but more generic allowing any protocol actually

That's an interesting thought. I already separated resource resolving and handling of connections early on, because I already had a modular server structure in mind. But I didn't made the (mental) connection to the WebSocket implementation, but always saw that as a somewhat orthogonal concept, or a special case of the normal request handling.

Rethinking this, it might indeed be the best solution to have a kind-of generic HTTPApplication class that you can hook to every base URL yourself, and from which a WebSocketApplication or a WebDavApplication and so on can inherit. Then you could do something like this:

class WebDavApplication : httpsserver::HTTPApplication {
  // Implement a new http-based protocol from scratch ...
}

class MyWebSocket : httpsserver::WebSocketApplication {
  // Base class WebSocketApplication handles lifecycle, this class defines the application level ...
}

HTTPServer *server;
WebDavApplication *webdav;
MyWebSocket *websocket;

void setupServer() {
  // Create the server
  server = new HTTPServer();

  // Create and register a WebDav Handler
  webdav = new WebDavApplication();
  server->registerApplication("/dav", webdav);

  // Create and register WebSocket Handler
  websocket = new MyWebSocket();
  server->registerApplication("/ws", websocket);

  // Add a generic handler function
  ResourceNode *node = new ResourceNode("GET", "/", &handleRoot);
  server->registerNode(node);

  server->start()
}

And those "Applications" then have more control over connection lifecycle etc., but for the simple use case of just serving basic HTTP request, it doesn't change much (even though one could implement that as another instance of HTTPApplication under the hood, too.)

@fhessel fhessel added the feature label Aug 2, 2020
@luc-github
Copy link
Author

yes that is ^_^

@luc-github
Copy link
Author

Hi, sorry to bother, but any update on this feature ? ^_^

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

No branches or pull requests

2 participants