wai-app-static 3.1.7.4 → 3.1.8
raw patch · 11 files changed
+56/−54 lines, 11 filesdep +cryptondep −cryptonitedep −networkdep ~directorydep ~old-localedep ~timePVP ok
version bump matches the API change (PVP)
Dependencies added: crypton
Dependencies removed: cryptonite, network
Dependency ranges changed: directory, old-locale, time
API changes (from Hackage documentation)
+ WaiAppStatic.Types: NoStore :: MaxAge
Files
- ChangeLog.md +10/−2
- Network/Wai/Application/Static.hs +13/−14
- WaiAppStatic/CmdLine.hs +6/−5
- WaiAppStatic/Listing.hs +4/−5
- WaiAppStatic/Storage/Embedded/Runtime.hs +5/−5
- WaiAppStatic/Storage/Filesystem.hs +2/−2
- WaiAppStatic/Types.hs +1/−0
- app/warp-static.hs +0/−1
- test/EmbeddedTestEntries.hs +1/−1
- test/WaiAppStaticTest.hs +6/−5
- wai-app-static.cabal +8/−14
ChangeLog.md view
@@ -1,5 +1,13 @@ # wai-app-static changelog +## 3.1.8++* Added `NoStore` constructor to `MaxAge` [#938](https://github.com/yesodweb/wai/pull/938)++## 3.1.7.5++* Removed dependency of `time`, `old-locale` and `network` [#902](https://github.com/yesodweb/wai/pull/902)+ ## 3.1.7.4 * Fix a bug when the cryptonite flag is disabled. [#874](https://github.com/yesodweb/wai/pull/874)@@ -10,7 +18,7 @@ ## 3.1.7.2 -* optparse-applicative 0.16.0.0 support+* `optparse-applicative-0.16.0.0` support ## 3.1.7.1 @@ -28,7 +36,7 @@ ## 3.1.6.2 -* Drop dependency on blaze-builder+* Drop dependency on `blaze-builder` ## 3.1.6.1
Network/Wai/Application/Static.hs view
@@ -36,7 +36,7 @@ import Data.ByteString.Builder (toLazyByteString) -import Data.FileEmbed (embedFile)+import Data.FileEmbed (embedFile, makeRelativeToProject) import Data.Text (Text) import qualified Data.Text as T@@ -74,7 +74,7 @@ -- | Serve an appropriate response for a folder request. serveFolder :: StaticSettings -> Pieces -> W.Request -> Folder -> IO StaticResponse-serveFolder StaticSettings {..} pieces req folder@Folder {..} =+serveFolder StaticSettings {..} pieces req folder = case ssListing of Just _ | Just path <- addTrailingSlash req, ssAddTrailingSlash -> return $ RawRedirect path@@ -205,23 +205,22 @@ cacheControl maxage = headerCacheControl . headerExpires where- ccInt =- case maxage of- NoMaxAge -> Nothing- MaxAgeSeconds i -> Just i- MaxAgeForever -> Just oneYear oneYear :: Int oneYear = 60 * 60 * 24 * 365 - headerCacheControl =- case ccInt of- Nothing -> id- Just i -> (:) ("Cache-Control", S8.append "public, max-age=" $ S8.pack $ show i)+ maxAgeValue i = S8.append "public, max-age=" $ S8.pack $ show i++ headerCacheControl = case maxage of+ NoMaxAge -> id+ MaxAgeSeconds i -> (:) ("Cache-Control", maxAgeValue i)+ MaxAgeForever -> (:) ("Cache-Control", maxAgeValue oneYear)+ NoStore -> (:) ("Cache-Control", "no-store") headerExpires = case maxage of NoMaxAge -> id MaxAgeSeconds _ -> id -- FIXME MaxAgeForever -> (:) ("Expires", "Thu, 31 Dec 2037 23:55:55 GMT")+ NoStore -> id -- | Turn a @StaticSettings@ into a WAI application. staticApp :: StaticSettings -> W.Application@@ -233,8 +232,8 @@ H.status405 [("Content-Type", "text/plain")] "Only GET or HEAD is supported"-staticAppPieces _ [".hidden", "folder.png"] _ sendResponse = sendResponse $ W.responseLBS H.status200 [("Content-Type", "image/png")] $ L.fromChunks [$(embedFile "images/folder.png")]-staticAppPieces _ [".hidden", "haskell.png"] _ sendResponse = sendResponse $ W.responseLBS H.status200 [("Content-Type", "image/png")] $ L.fromChunks [$(embedFile "images/haskell.png")]+staticAppPieces _ [".hidden", "folder.png"] _ sendResponse = sendResponse $ W.responseLBS H.status200 [("Content-Type", "image/png")] $ L.fromChunks [$(makeRelativeToProject "images/folder.png" >>= embedFile)]+staticAppPieces _ [".hidden", "haskell.png"] _ sendResponse = sendResponse $ W.responseLBS H.status200 [("Content-Type", "image/png")] $ L.fromChunks [$(makeRelativeToProject "images/haskell.png" >>= embedFile)] staticAppPieces ss rawPieces req sendResponse = liftIO $ do case toPieces rawPieces of Just pieces -> checkPieces ss pieces req >>= response@@ -280,7 +279,7 @@ , ("Location", path) ] "Redirect" - response NotFound = case (ss404Handler ss) of+ response NotFound = case ss404Handler ss of Just app -> app req sendResponse Nothing -> sendResponse $ W.responseLBS H.status404 [ ("Content-Type", "text/plain")
WaiAppStatic/CmdLine.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE DeriveDataTypeable, RecordWildCards, CPP #-}+{-# LANGUAGE CPP, RecordWildCards #-} -- | Command line version of wai-app-static, used for the warp-static server. module WaiAppStatic.CmdLine ( runCommandLine@@ -18,14 +18,15 @@ import Network.Wai.Middleware.Gzip import qualified Data.Map as Map import qualified Data.ByteString.Char8 as S8-import Control.Arrow ((***)) import Data.Text (pack) import Data.String (fromString) import Network.Mime (defaultMimeMap, mimeByExt, defaultMimeType) import WaiAppStatic.Types (ssIndices, toPiece, ssGetMimeType, fileName, fromPiece) import Data.Maybe (mapMaybe)-import Control.Arrow (second)+import Control.Arrow (second, (***))+#if __GLASGOW_HASKELL__ < 804 import Data.Monoid ((<>))+#endif data Args = Args { docroot :: FilePath@@ -94,14 +95,14 @@ -- Since 2.0.1 runCommandLine :: (Args -> Middleware) -> IO () runCommandLine middleware = do- args@Args {..} <- execParser $ info (helperOption <*> args) fullDesc+ clArgs@Args {..} <- execParser $ info (helperOption <*> args) fullDesc let mime' = map (pack *** S8.pack) mime let mimeMap = Map.fromList mime' `Map.union` defaultMimeMap docroot' <- canonicalizePath docroot unless quiet $ printf "Serving directory %s on port %d with %s index files.\n" docroot' port (if noindex then "no" else show index) let middle = gzip def { gzipFiles = GzipCompress } . (if verbose then logStdout else id)- . (middleware args)+ . middleware clArgs runSettings ( setPort port $ setHost (fromString host)
WaiAppStatic/Listing.hs view
@@ -50,13 +50,13 @@ ] H.body $ do let hasTrailingSlash =- case map fromPiece $ reverse $ pieces of+ case map fromPiece $ reverse pieces of "":_ -> True _ -> False H.h1 $ showFolder' hasTrailingSlash $ filter (not . T.null . fromPiece) pieces renderDirectoryContentsTable (map fromPiece pieces) haskellSrc folderSrc fps'' where- image x = T.unpack $ T.concat [(relativeDirFromPieces pieces), ".hidden/", x, ".png"]+ image x = T.unpack $ T.concat [relativeDirFromPieces pieces, ".hidden/", x, ".png"] folderSrc = image "folder" haskellSrc = image "haskell" showName "" = "root"@@ -92,7 +92,7 @@ -> [Either FolderName File] -> H.Html renderDirectoryContentsTable pathInfo' haskellSrc folderSrc fps =- H.table $ do H.thead $ do H.th ! (A.class_ "first") $ H.img ! (A.src $ H.toValue haskellSrc)+ H.table $ do H.thead $ do H.th ! A.class_ "first" $ H.img ! A.src (H.toValue haskellSrc) H.th "Name" H.th "Modified" H.th "Size"@@ -117,8 +117,7 @@ case either id fileName md of (fromPiece -> "") -> unsafeToPiece ".." x -> x- let isFile = either (const False) (const True) md- href = addCurrentDir $ fromPiece name+ let href = addCurrentDir $ fromPiece name addCurrentDir x = case reverse pathInfo' of "":_ -> x -- has a trailing slash
WaiAppStatic/Storage/Embedded/Runtime.hs view
@@ -8,7 +8,7 @@ import WaiAppStatic.Types import Data.ByteString (ByteString) import Control.Arrow ((&&&), second)-import Data.List+import Data.List (groupBy, sortBy) import Data.ByteString.Builder (byteString) import qualified Network.Wai as W import qualified Data.Map as Map@@ -16,7 +16,7 @@ import qualified Data.Text as T import Data.Ord import qualified Data.ByteString as S-#ifdef MIN_VERSION_cryptonite+#ifdef MIN_VERSION_crypton import Crypto.Hash (hash, MD5, Digest) import Data.ByteArray.Encoding #else@@ -41,7 +41,7 @@ return $ elookup pieces root where elookup :: Pieces -> Embedded -> LookupResult- elookup [] x = LRFolder $ Folder $ map toEntry $ Map.toList x+ elookup [] x = LRFolder $ Folder $ fmap toEntry $ Map.toList x elookup [p] x | T.null (fromPiece p) = elookup [] x elookup (p:ps) x = case Map.lookup p x of@@ -66,7 +66,7 @@ toEmbedded fps = go texts where- texts = map (\(x, y) -> (filter (not . T.null . fromPiece) $ toPieces' x, y)) fps+ texts = fmap (\(x, y) -> (filter (not . T.null . fromPiece) $ toPieces' x, y)) fps toPieces' "" = [] toPieces' x = -- See https://github.com/yesodweb/yesod/issues/626@@ -100,7 +100,7 @@ } runHash :: ByteString -> ByteString-#ifdef MIN_VERSION_cryptonite+#ifdef MIN_VERSION_crypton runHash = convertToBase Base64 . (hash :: S.ByteString -> Digest MD5) #else runHash = encode . hash
WaiAppStatic/Storage/Filesystem.hs view
@@ -26,7 +26,7 @@ import Network.Mime import System.PosixCompat.Files (fileSize, getFileStatus, modificationTime, isRegularFile) import Data.Maybe (catMaybes)-#ifdef MIN_VERSION_cryptonite+#ifdef MIN_VERSION_crypton import Data.ByteArray.Encoding import Crypto.Hash (hashlazy, MD5, Digest) #else@@ -128,7 +128,7 @@ hashFile :: FilePath -> IO ByteString hashFile fp = withBinaryFile fp ReadMode $ \h -> do f <- BL.hGetContents h-#ifdef MIN_VERSION_cryptonite+#ifdef MIN_VERSION_crypton let !hash = hashlazy f :: Digest MD5 return $ convertToBase Base64 hash #else
WaiAppStatic/Types.hs view
@@ -67,6 +67,7 @@ data MaxAge = NoMaxAge -- ^ no cache-control set | MaxAgeSeconds Int -- ^ set to the given number of seconds | MaxAgeForever -- ^ essentially infinite caching; in reality, probably one year+ | NoStore -- ^ set cache-control to no-store @since 3.1.8 -- | Just the name of a folder. type FolderName = Piece
app/warp-static.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE DeriveDataTypeable, RecordWildCards #-} module Main (main) where import WaiAppStatic.CmdLine (runCommandLine)
test/EmbeddedTestEntries.hs view
@@ -9,7 +9,7 @@ import qualified Data.ByteString.Lazy as BL body :: Int -> Char -> BL.ByteString-body i c = TL.encodeUtf8 $ TL.pack $ take i $ repeat c+body i c = TL.encodeUtf8 $ TL.pack $ replicate i c mkEntries :: IO [EmbeddableEntry] mkEntries = return
test/WaiAppStaticTest.hs view
@@ -20,6 +20,7 @@ import Network.Wai import Network.Wai.Test +import Control.Monad (forM_) import Control.Monad.IO.Class (liftIO) import Network.Mime @@ -48,12 +49,12 @@ describe "webApp" $ do it "403 for unsafe paths" $ webApp $- flip mapM_ ["..", "."] $ \path ->+ forM_ ["..", "."] $ \path -> assertStatus 403 =<< request (setRawPathInfo defRequest path) it "200 for hidden paths" $ webApp $- flip mapM_ [".hidden/folder.png", ".hidden/haskell.png"] $ \path ->+ forM_ [".hidden/folder.png", ".hidden/haskell.png"] $ \path -> assertStatus 200 =<< request (setRawPathInfo defRequest path) @@ -70,7 +71,7 @@ ssMkRedirect = \_ u -> S8.append "http://www.example.com" u } it "302 redirect when multiple slashes" $ absoluteApp $- flip mapM_ ["/a//b/c", "a//b/c"] $ \path -> do+ forM_ ["/a//b/c", "a//b/c"] $ \path -> do req <- request (setRawPathInfo defRequest path) assertStatus 302 req assertHeader "Location" "http://www.example.com/a/b/c" req@@ -89,7 +90,7 @@ assertNoHeader "Last-Modified" req it "200 when invalid in-none-match sent" $ webApp $- flip mapM_ ["cached", ""] $ \badETag -> do+ forM_ ["cached", ""] $ \badETag -> do req <- request statFile { requestHeaders = [("If-None-Match", badETag)] } assertStatus 200 req assertHeader "ETag" etag req@@ -115,7 +116,7 @@ assertBodyContains "<a href=\"b\">b</a>" resp it "200 when invalid if-modified-since header" $ fileServerApp $ do- flip mapM_ ["123", ""] $ \badDate -> do+ forM_ ["123", ""] $ \badDate -> do req <- request statFile { requestHeaders = [("If-Modified-Since", badDate)] }
wai-app-static.cabal view
@@ -1,5 +1,5 @@ name: wai-app-static-version: 3.1.7.4+version: 3.1.8 license: MIT license-file: LICENSE author: Michael Snoyman <michael@snoyman.com>@@ -24,8 +24,8 @@ Description: print debug info Default: False -Flag cryptonite- Description: Use the cryptonite library for MD5 computation+Flag crypton+ Description: Use the crypton library for MD5 computation Default: True library@@ -53,8 +53,8 @@ , wai-extra >= 3.0 && < 3.2 , optparse-applicative >= 0.7 , warp >= 3.0.11 && < 3.4- if flag(cryptonite)- build-depends: cryptonite >= 0.6+ if flag(crypton)+ build-depends: crypton >= 0.6 , memory >= 0.7 else build-depends: base64-bytestring >= 0.1@@ -80,29 +80,24 @@ hs-source-dirs: app Build-depends: base >= 4 && < 5 , wai-app-static- , directory >= 1.0- , containers >= 0.2- , bytestring >= 0.10.4- , text >= 0.7- , mime-types >= 0.1 && < 0.2 test-suite runtests default-language: Haskell2010 hs-source-dirs: test+ other-modules: EmbeddedTestEntries+ , WaiAppEmbeddedTest+ , WaiAppStaticTest main-is: ../tests.hs type: exitcode-stdio-1.0 build-depends: base >= 4 && < 5 , hspec >= 1.3 , unix-compat- , time- , old-locale , http-date , wai-app-static , wai-extra , wai , http-types- , network , bytestring , text , transformers@@ -111,7 +106,6 @@ , filepath , temporary , mockery- -- , containers ghc-options: -Wall source-repository head