@@ -1,5 +1,6 @@
1{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE TemplateHaskell #-}
2{-# LANGUAGE TemplateHaskell #-}
3-- | Static file serving for WAI.
4-- | Static file serving for WAI.
4module Network.Wai.Application.Static
5module Network.Wai.Application.Static
5 ( -- * Generic, non-WAI code
6 ( -- * Generic, non-WAI code
@@ -55,6 +56,10 @@ import System.Locale (defaultTimeLocale)
55import Data.List (sortBy, intercalate)
56import Data.List (sortBy, intercalate)
56import Data.FileEmbed (embedFile)
57import Data.FileEmbed (embedFile)
59+import qualified Data.Text as T
60+import qualified Data.Text.Encoding as TE
61+import qualified Data.Text.Encoding.Error as TEE
58-- | A list of all possible extensions, starting from the largest.
63-- | A list of all possible extensions, starting from the largest.
59takeExtensions :: FilePath -> [String]
64takeExtensions :: FilePath -> [String]
60takeExtensions s =
65takeExtensions s =
@@ -193,7 +198,7 @@ checkPieces prefix indices pieces
193 | anyButLast null pieces =
198 | anyButLast null pieces =
194 return $ Redirect $ filterButLast (not . null) pieces
199 return $ Redirect $ filterButLast (not . null) pieces
195 | otherwise = do
200 | otherwise = do
196− let fp = concat $ prefix : map ((:) '/') pieces
201+ let fp = concat $ prefix : map ((:) '/') (map unfixPathName pieces)
197 let (isFile, isFolder) =
202 let (isFile, isFolder) =
198 case () of
203 case () of
@@ -284,6 +289,20 @@ staticAppPieces (StaticSettings folder indices mlisting getmime) pieces _ = lift
284 [ ("Content-Type", mt)
289 [ ("Content-Type", mt)
292+fixPathName :: FilePath -> FilePath
293+#if defined(mingw32_HOST_OS)
296+fixPathName = T.unpack . TE.decodeUtf8With TEE.lenientDecode . S8.pack
299+unfixPathName :: FilePath -> FilePath
300+#if defined(mingw32_HOST_OS)
303+unfixPathName = S8.unpack . TE.encodeUtf8 . T.pack
287-- Code below taken from Happstack: http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/FileServe/BuildingBlocks.hs
306-- Code below taken from Happstack: http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/FileServe/BuildingBlocks.hs
288defaultListing :: Listing
307defaultListing :: Listing
289defaultListing pieces localPath = do
308defaultListing pieces localPath = do
@@ -359,7 +378,7 @@ renderDirectoryContentsTable haskellSrc folderSrc fps =
359 then return ()
378 then return ()
360 else H.img ! A.src (H.stringValue folderSrc)
379 else H.img ! A.src (H.stringValue folderSrc)
361 ! A.alt (H.stringValue "Folder")
380 ! A.alt (H.stringValue "Folder")
362− H.td (H.a ! A.href (H.stringValue $ mdName md ++ if mdIsFile md then "" else "/") $ H.string $ mdName md)
381+ H.td (H.a ! A.href (H.stringValue $ mdName' md ++ if mdIsFile md then "" else "/") $ H.string $ mdName' md)
363 H.td ! A.class_ (H.stringValue "date") $ H.string $
382 H.td ! A.class_ (H.stringValue "date") $ H.string $
364 if mdIsFile md
383 if mdIsFile md
365 then formatCalendarTime defaultTimeLocale "%d-%b-%Y %X" $ mdModified md
384 then formatCalendarTime defaultTimeLocale "%d-%b-%Y %X" $ mdModified md
@@ -383,6 +402,7 @@ renderDirectoryContentsTable haskellSrc folderSrc fps =
383 addCommas' (a:b:c:d:e) = a : b : c : ',' : addCommas' (d : e)
402 addCommas' (a:b:c:d:e) = a : b : c : ',' : addCommas' (d : e)
384 addCommas' x = x
403 addCommas' x = x
405+mdName' = fixPathName . mdName
387data MetaData =
407data MetaData =
388 FileMetaData
408 FileMetaData