Consider the following program:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module Repo where
import Control.Monad.Except (throwError)
import Data.List (isSuffixOf)
import Data.Proxy (Proxy(..))
import Data.Text (Text)
import GHC.Generics (Generic)
import Network.HTTP.Types.Header (hLocation)
import Network.Wai.Handler.Warp (run)
import Servant.API
import Servant.Links
import Servant.Server
data API mode = API
{ myroute :: mode :- "test" :> CaptureAll "segs" Text :> Get '[JSON] [Text]
}
deriving Generic
server :: [Text] -> Handler [Text]
server ts =
case isSuffixOf [""] ts of
False ->
throwError err303
{ errHeaders = pure
( hLocation
, mappend "/" $ toHeader $ fieldLink myroute $ ts <> [""]
)
}
True -> pure ts
main :: IO ()
main = run 8081 $ serve (Proxy @(NamedRoutes API)) $ API server
which 303 redirects test/:stuff to test/:stuff/. This works when :stuff is nonempty, eg test/abc correctly gets redirected to test/abc/ (and returns ["abc", ""]).
However, when :stuff is empty, this server loops, redirecting the page back to itself:
Request
GET /test/ HTTP/1.1
Host: localhost:8081
Pragma: no-cache
---
Response
HTTP/1.1 303 See Other
Location: /test/
Consider the following program:
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-} module Repo where import Control.Monad.Except (throwError) import Data.List (isSuffixOf) import Data.Proxy (Proxy(..)) import Data.Text (Text) import GHC.Generics (Generic) import Network.HTTP.Types.Header (hLocation) import Network.Wai.Handler.Warp (run) import Servant.API import Servant.Links import Servant.Server data API mode = API { myroute :: mode :- "test" :> CaptureAll "segs" Text :> Get '[JSON] [Text] } deriving Generic server :: [Text] -> Handler [Text] server ts = case isSuffixOf [""] ts of False -> throwError err303 { errHeaders = pure ( hLocation , mappend "/" $ toHeader $ fieldLink myroute $ ts <> [""] ) } True -> pure ts main :: IO () main = run 8081 $ serve (Proxy @(NamedRoutes API)) $ API serverwhich 303 redirects
test/:stufftotest/:stuff/. This works when:stuffis nonempty, egtest/abccorrectly gets redirected totest/abc/(and returns["abc", ""]).However, when
:stuffis empty, this server loops, redirecting the page back to itself: