haskell-servant / haskell-servant/servant
Raw files served from root override other routes.
- Dominant language
- Haskell
- Stars
- 2k
- Forks
- 427
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 5
Description
I run into 405 `Only GET or HEAD is supported` errors when trying to setup a Raw file service directly on root.
I'm not sure whether this is expected from `Raw` as an escape hatch, or whether it's an issue, but it's pretty surprising.
Minimum reproduction example:
In this example, `Raw` is served directly from root.
There is a second run-of-the-mill `Post` route.
`Post` is called with an empty list as a body.
This nets a 405 `Only GET or HEAD is supported` error.
```haskell
{-# language TypeOperators, DataKinds #-}
module Lib
( api
) where
import Servant.API (Raw, Post, ReqBody, JSON, (:>), (:<|>)(..))
import Servant.Server.StaticFiles (serveDirectoryWebApp)
import Servant.Server (serve)
import Data.Proxy (Proxy(Proxy))
import Data.Aeson (Value)
type Api
= Raw -- serve files from parent directory
:<|> "reports" :> ReqBody '[JSON] Value :> Post '[JSON] ()
appServer
= serveDirectoryWebApp "../"
:<|> \body -> pure ()
api = serve (Proxy :: Proxy Api) appServer
```
Running this gives:
```
POST /reports
Request Body: []
Accept: application/json
Status: 405 Method Not Allowed 0.00001707s
```
In this second example, the raw files are behind a path parameter (`"example"`)
The `Post` method is not changed.
It is still called with an empty list as a body.
This nets a 200 ok.
```haskell
{-# language TypeOperators, DataKinds #-}
module Lib
( api
) where
import Servant.API (Raw, Post, ReqBody, JSON, (:>), (:<|>)(..))
import Servant.Server.StaticFiles (serveDirectoryWebApp)
import Servant.Server (serve)
import Data.Proxy (Proxy(Proxy))
import Data.Aeson (Value)
type Api
= "example" :> Raw -- serve files from parent directory
:<|> "reports" :> ReqBody '[JSON] Value :> Post '[JSON] ()
appServer
= serveDirectoryWebApp "../"
:<|> \body -> pure ()
api = serve (Proxy :: Proxy Api) appServer
```
Running this gives:
```
POST /reports
Request Body: []
Accept: application/json
Status: 200 OK 0.000114646s
```
Swapping the two endpoints also works.
Contributor guide
Assessment
This issue has not been assessed yet.