agrafix / Spock

Another Haskell web framework for rapid development
https://www.spock.li
678 stars 56 forks source link

How can I use Spock with wai-middleware-static? #110

Closed samvher closed 7 years ago

samvher commented 7 years ago

I figured I should do something like this:

module Main where

import Network.Wai ( Middleware )
import Network.Wai.Middleware.Static ( staticPolicy, addBase )
import Web.Spock

app :: SpockCtxM ctx conn sess st ()
app = -- hooks and routes

mw :: Middleware
mw = staticPolicy $ addBase "/static"

main :: IO ()
main = do cfg <- getCfg myConnInfo
          runSpock 3000 (return mw >> spock cfg app)

In this case I have /static/test.html and try to visit localhost:3000/test.html, but I get a 404 not found. Permissions on /static/test.html are 777.

Am I overlooking something?

Anyway, thanks for all the work on Spock, so far I found it well-designed. It often does take some effort, however, to get to the point where I can see this (I think just some examples around the code and even short docstrings would help a lot already). Once I feel a bit more at home in the code I will try to make some PRs, the project I'm working on is also already open on github (samvher/translatethenews), I hope that will be a useful reference for others later on as well (but it's kind of immature still).

samvher commented 7 years ago

I realize now that the funblog project uses this. The middleware should come after the first prehook.

Like so:

app :: SpockCtxM ctx conn sess st ()
app = prehook baseHook $ do
        middleware (staticPolicy (addBase "/static"))
        get ...

I guess for some reason it compiled, but didn't work :)

samvher commented 7 years ago

Correction, it's not about being before the first prehook, it's about calling middleware.

This also works:

app :: SpockCtxM ctx conn sess st ()
app = do middleware . staticPolicy $ addBase "/static"
         get ...
agrafix commented 7 years ago

With the most recent Spock version, you should also be able to do this:

app =
    do get ("static" <//> wildcard) $ \_ -> respondMiddleware (staticPolicy (addBase "/static"))
       get ...

Depending on the middleware this might be more efficient as only requests that begin with "static" actually pass via the middleware.