@@ -2,6 +2,7 @@
22{-# LANGUAGE ScopedTypeVariables #-}
33{-# LANGUAGE TemplateHaskell, CPP #-}
44{-# LANGUAGE RecordWildCards #-}
5+{-# LANGUAGE PatternGuards #-}
56-- | Static file serving for WAI.
67module Network.Wai.Application.Static
78 ( -- * WAI application
@@ -74,14 +75,19 @@ serveFolder :: StaticSettings -> Pieces -> W.Request -> Folder -> IO StaticRespo
7475serveFolder ss@StaticSettings {..} pieces req folder@Folder {..} =
7576 -- first check if there is an index file in this folder
7677 case getFirst $ mconcat $ map (findIndex $ rights folderContents) ssIndices of
77− Just index -> do
78− let pieces' = setLast pieces index
79− in if ssRedirectToIndex
80− then return $ Redirect pieces' Nothing
78+ Just index ->
79+ let pieces' = setLast pieces index in
80+ case () of
81+ () | ssRedirectToIndex -> return $ Redirect pieces' Nothing
82+ | noTrailingSlash pieces, Just trailing <- toPiece "" ->
83+ return $ Redirect (pieces ++ [trailing]) Nothing
84+ | otherwise ->
8185 -- start the checking process over, with a new set
82− else checkPieces ss pieces' req
86+ checkPieces ss pieces' req
8387 Nothing ->
8488 case ssListing of
89+ Just _ | noTrailingSlash pieces, Just trailing <- toPiece "" ->
90+ return $ Redirect (pieces ++ [trailing]) Nothing
8591 Just listing -> do
8692 -- directory listings turned on, display it
8793 builder <- listing pieces folder
@@ -98,6 +104,11 @@ serveFolder ss@StaticSettings {..} pieces req folder@Folder {..} =
98104 | fromPiece t == "" = [x]
99105 setLast (a:b) x = a : setLast b x
100106
107+ noTrailingSlash :: Pieces -> Bool
108+ noTrailingSlash [] = False
109+ noTrailingSlash [x] = fromPiece x /= ""
110+ noTrailingSlash (_:xs) = noTrailingSlash xs
111+
101112 findIndex :: [File] -> Piece -> First Piece
102113 findIndex files index
103114 | index `elem` map fileName files = First $ Just index