on master help sign in
UTF8 support on non-Windows systems
commitd6e03b87fb894553804f0b784e1d8334b49e24ad authorMichael Snoyman <michael@snoyman.com> dateWed 30 Mar 2011, 10:27 (16 years ago) parentc732030
2 files changed+24−3
Network/Wai/Application/Static.hs+22−2 wai-app-static.cabal+2−1
Network/Wai/Application/Static.hs+22−2
@@ -1,5 +1,6 @@
11{-# LANGUAGE OverloadedStrings #-}
22{-# LANGUAGE TemplateHaskell #-}
3+{-# LANGUAGE CPP #-}
34-- | Static file serving for WAI.
45module Network.Wai.Application.Static
56 ( -- * Generic, non-WAI code
@@ -55,6 +56,10 @@ import System.Locale (defaultTimeLocale)
5556import Data.List (sortBy, intercalate)
5657import Data.FileEmbed (embedFile)
5758
59+import qualified Data.Text as T
60+import qualified Data.Text.Encoding as TE
61+import qualified Data.Text.Encoding.Error as TEE
62+
5863-- | A list of all possible extensions, starting from the largest.
5964takeExtensions :: FilePath -> [String]
6065takeExtensions s =
@@ -193,7 +198,7 @@ checkPieces prefix indices pieces
193198 | anyButLast null pieces =
194199 return $ Redirect $ filterButLast (not . null) pieces
195200 | otherwise = do
196− let fp = concat $ prefix : map ((:) '/') pieces
201+ let fp = concat $ prefix : map ((:) '/') (map unfixPathName pieces)
197202 let (isFile, isFolder) =
198203 case () of
199204 ()
@@ -284,6 +289,20 @@ staticAppPieces (StaticSettings folder indices mlisting getmime) pieces _ = lift
284289 [ ("Content-Type", mt)
285290 ] lbs
286291
292+fixPathName :: FilePath -> FilePath
293+#if defined(mingw32_HOST_OS)
294+fixPathName = id
295+#else
296+fixPathName = T.unpack . TE.decodeUtf8With TEE.lenientDecode . S8.pack
297+#endif
298+
299+unfixPathName :: FilePath -> FilePath
300+#if defined(mingw32_HOST_OS)
301+unfixPathName = id
302+#else
303+unfixPathName = S8.unpack . TE.encodeUtf8 . T.pack
304+#endif
305+
287306-- Code below taken from Happstack: http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/FileServe/BuildingBlocks.hs
288307defaultListing :: Listing
289308defaultListing pieces localPath = do
@@ -359,7 +378,7 @@ renderDirectoryContentsTable haskellSrc folderSrc fps =
359378 then return ()
360379 else H.img ! A.src (H.stringValue folderSrc)
361380 ! 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)
363382 H.td ! A.class_ (H.stringValue "date") $ H.string $
364383 if mdIsFile md
365384 then formatCalendarTime defaultTimeLocale "%d-%b-%Y %X" $ mdModified md
@@ -383,6 +402,7 @@ renderDirectoryContentsTable haskellSrc folderSrc fps =
383402 addCommas' (a:b:c:d:e) = a : b : c : ',' : addCommas' (d : e)
384403 addCommas' x = x
385404
405+mdName' = fixPathName . mdName
386406
387407data MetaData =
388408 FileMetaData
wai-app-static.cabal+2−1
@@ -1,5 +1,5 @@
11name: wai-app-static
2−version: 0.0.1.3
2+version: 0.0.1.4
33license: BSD3
44license-file: LICENSE
55author: Michael Snoyman <michael@snoyman.com>
@@ -26,6 +26,7 @@ library
2626 , time >= 1.1.4 && < 1.3
2727 , old-locale >= 1.0.0.2 && < 1.1
2828 , file-embed >= 0.0.3.1 && < 0.1
29+ , text >= 0.5 && < 1.0
2930 exposed-modules: Network.Wai.Application.Static
3031 ghc-options: -Wall
3132