duct-framework / module.web

Duct module for running web applications
21 stars 19 forks source link

:middleware doesn't effect static files. #7

Open Zaphodious opened 6 years ago

Zaphodious commented 6 years ago

Middleware added to the :duct.core/handler :middleware vector doesn't seem to have any effect on static files. This is unfortunate, as gzip (added via the ring-gzip middleware) is hugely important for compiled cljs.

Middleware correctly effects routes using :duct.router/cascading. However, "resource" compojure routes added using :duct.router/cascading don't seem to do anything, so that's little help.

The best solution I've been able to find is to explicitely declare a :duct.server.http with a handler that wraps the :duct.core/handler in whatever middleware I desire. This, I feel, is kludgy and inelegant compared to declaring a :handler :middleware.

weavejester commented 6 years ago

Static files are served with middleware, so in order for gzip middleware to work, it needs to be outside the static file middleware. In all probability, the gzip middleware you're using is just ordered wrong.

Can you provide an example of your configuration, and what it looks like when you've preped it?

Zaphodious commented 6 years ago

Gladly! here you are- https://gist.github.com/Zaphodious/67cb8ddb505cef98558a2dbae50ff0e6

Using https://github.com/bertrandk/ring-gzip

weavejester commented 6 years ago

You can see that your prepped handler looks like this (at least when nicely formatted):

 :duct.core/handler
 {:router     #ig/ref :key :duct/router
  :middleware [#ig/ref :anathema-re.middleware/gzip
               #ig/ref :duct.middleware.web/not-found
               #ig/ref :duct.middleware.web/webjars
               #ig/ref :duct.middleware.web/defaults
               #ig/ref :duct.middleware.web/log-requests
               #ig/ref :duct.middleware.web/log-errors
               #ig/ref :duct.middleware.web/stacktrace]}

The GZip middleware is appearing at the innermost layer, when we want it almost at the outermost layer. Ideally we still want errors and logging to be further out still, so if something goes wrong with the GZip middleware we'll have error messages in our logs.

 :duct.core/handler
 {:router     #ig/ref :key :duct/router
  :middleware [#ig/ref :duct.middleware.web/not-found
               #ig/ref :duct.middleware.web/webjars
               #ig/ref :duct.middleware.web/defaults
               #ig/ref :anathema-re.middleware/gzip
               #ig/ref :duct.middleware.web/log-requests
               #ig/ref :duct.middleware.web/log-errors
               #ig/ref :duct.middleware.web/stacktrace]}

To achieve this, add in the parts of the middleware that are different to your configuration. Middleware is checked to be distinct by the module, so the order should be able to be overridden:

 :duct.core/handler
 {:middleware [#ig/ref :duct.middleware.web/not-found
               #ig/ref :duct.middleware.web/webjars
               #ig/ref :duct.middleware.web/defaults
               #ig/ref :anathema-re.middleware/gzip]}

We can leave off the :router key and the final 3 middleware refs, since they're the same. This should work, but I haven't had chance to try it.

Zaphodious commented 6 years ago

This seems to have worked. I'll post another comment here if I can find any problems with it.