on master help sign in
UTF8 support on non-Windows systems
d6e03b8Michael Snoyman
Network/Wai/Application/Static.hs+22−2
@@ -1,5 +1,6 @@
1{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE TemplateHaskell #-}
2{-# LANGUAGE TemplateHaskell #-}
3+{-# LANGUAGE CPP #-}
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)
57
58
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+
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
199 ()
204 ()
@@ -284,6 +289,20 @@ staticAppPieces (StaticSettings folder indices mlisting getmime) pieces _ = lift
284 [ ("Content-Type", mt)
289 [ ("Content-Type", mt)
285 ] lbs
290 ] lbs
286
291
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+
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
385
404
405+mdName' = fixPathName . mdName
386
406
387data MetaData =
407data MetaData =
388 FileMetaData
408 FileMetaData
wai-app-static.cabal+2−1
@@ -1,5 +1,5 @@
1name: wai-app-static
1name: wai-app-static
2−version: 0.0.1.3
2+version: 0.0.1.4
3license: BSD3
3license: BSD3
4license-file: LICENSE
4license-file: LICENSE
5author: Michael Snoyman <michael@snoyman.com>
5author: Michael Snoyman <michael@snoyman.com>
@@ -26,6 +26,7 @@ library
26 , time >= 1.1.4 && < 1.3
26 , time >= 1.1.4 && < 1.3
27 , old-locale >= 1.0.0.2 && < 1.1
27 , old-locale >= 1.0.0.2 && < 1.1
28 , file-embed >= 0.0.3.1 && < 0.1
28 , file-embed >= 0.0.3.1 && < 0.1
29+ , text >= 0.5 && < 1.0
29 exposed-modules: Network.Wai.Application.Static
30 exposed-modules: Network.Wai.Application.Static
30 ghc-options: -Wall
31 ghc-options: -Wall
31
32