wai-middleware-static 0.8.3 → 0.9.4
raw patch · 6 files changed
Files
- Network/Wai/Middleware/Static.hs +35/−25
- README.md +1/−1
- changelog.md +18/−0
- test/Network/Wai/Middleware/StaticSpec.hs +41/−0
- test/Spec.hs +1/−0
- wai-middleware-static.cabal +39/−19
Network/Wai/Middleware/Static.hs view
@@ -27,27 +27,22 @@ ) where import Caching.ExpiringCacheMap.HashECM (newECMIO, lookupECM, CacheSettings(..), consistentDuration)-import Control.Monad.Trans (liftIO)-import Data.List-#if !(MIN_VERSION_base(4,8,0))-import Data.Monoid (Monoid(..))-#endif+import Control.Monad+import qualified Crypto.Hash.SHA1 as SHA1+import qualified Data.ByteString.Base16 as Base16+import qualified Data.List as L #if !(MIN_VERSION_base(4,11,0)) import Data.Semigroup (Semigroup(..)) #endif import Data.Time import Data.Time.Clock.POSIX-import Network.HTTP.Types (status200, status304)-import Network.HTTP.Types.Header (RequestHeaders)+import Network.HTTP.Types import Network.Mime (MimeType, defaultMimeLookup) import Network.Wai import System.Directory (doesFileExist, getModificationTime)-#if !(MIN_VERSION_time(1,5,0))-import System.Locale-#endif-import Crypto.Hash.Algorithms-import Crypto.Hash-import Data.ByteArray.Encoding+-- import Crypto.Hash.Algorithms+-- import Crypto.Hash+-- import Data.ByteArray.Encoding import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BSC import qualified Data.ByteString.Lazy as BSL@@ -56,7 +51,7 @@ -- | Take an incoming URI and optionally modify or filter it. -- The result will be treated as a filepath.-newtype Policy = Policy { tryPolicy :: String -> Maybe String -- ^ Run a policy+newtype Policy = Policy { tryPolicy :: String -> Maybe FilePath -- ^ Run a policy } -- | Options for 'staticWithOptions' 'Middleware'.@@ -140,19 +135,19 @@ -- | Accept only URIs with given suffix hasSuffix :: String -> Policy-hasSuffix = predicate . isSuffixOf+hasSuffix = predicate . L.isSuffixOf -- | Accept only URIs with given prefix hasPrefix :: String -> Policy-hasPrefix = predicate . isPrefixOf+hasPrefix = predicate . L.isPrefixOf -- | Accept only URIs containing given string contains :: String -> Policy-contains = predicate . isInfixOf+contains = predicate . L.isInfixOf -- | Reject URIs containing \"..\" noDots :: Policy-noDots = predicate (not . isInfixOf "..")+noDots = predicate (not . L.isInfixOf "..") -- | Reject URIs that are absolute paths isNotAbsolute :: Policy@@ -234,10 +229,15 @@ -- this has no policies enabled by default and is hence insecure. Takes 'Options'. unsafeStaticPolicyWithOptions :: Options -> Policy -> Middleware unsafeStaticPolicyWithOptions options p app req callback =- maybe (app req callback)- (\fp ->- do exists <- liftIO $ doesFileExist fp- if exists+ maybe serveUpstream tryStaticFile mCandidateFile+ where+ serveUpstream :: IO ResponseReceived+ serveUpstream = app req callback++ tryStaticFile :: FilePath -> IO ResponseReceived+ tryStaticFile fp = do+ exists <- doesFileExist fp+ if exists then case cacheContainer options of CacheContainerEmpty -> sendFile fp []@@ -248,9 +248,19 @@ if checkNotModified fileMeta (readHeader "If-Modified-Since") (readHeader "If-None-Match") then sendNotModified fileMeta strategy else sendFile fp (computeHeaders fileMeta strategy)- else app req callback)+ else serveUpstream++ mCandidateFile :: Maybe FilePath+ mCandidateFile =+ guard isHeadOrGet >> (tryPolicy p $ T.unpack $ T.intercalate "/" $ pathInfo req)- where+ where+ method :: Method+ method = requestMethod req++ isHeadOrGet :: Bool+ isHeadOrGet = method == methodHead || method == methodGet+ readHeader header = lookup header $ requestHeaders req checkNotModified fm modSince etag =@@ -314,7 +324,7 @@ return $ FileMeta { fm_lastModified = BSC.pack $ formatTime defaultTimeLocale "%a, %d-%b-%Y %X %Z" mtime- , fm_etag = convertToBase Base16 (hashlazy ct :: Digest SHA1)+ , fm_etag = Base16.encode (SHA1.hashlazy ct) , fm_fileName = fp }
README.md view
@@ -1,3 +1,3 @@-# wai-middleware-static [](https://travis-ci.org/scotty-web/wai-middleware-static)+# wai-middleware-static [](https://github.com/scotty-web/wai-middleware-static/actions?query=workflow%3AHaskell-CI) WAI middleware that intercepts requests to static files and serves them if they exist.
changelog.md view
@@ -1,3 +1,21 @@+## 0.9.4 [2026.01.10]+* Allow building with `time-1.15.*` (GHC 9.14).+* Remove unused `containers`, `old-locale`, and `semigroups` dependencies.++## 0.9.3 [2024.12.28]+* Drop support for pre-8.0 versions of GHC.++## 0.9.2 [2022.03.08]+* Allow building with GHC 9.2.+* Replace the `cryptonite` and `memory` dependencies with equivalent+ functionality from `cryptohash-sha1` and `base16-bytestring`.++## 0.9.1 [2021.10.31]+* Always import `Data.List` qualified.++## 0.9.0 [2020.10.01]+* Only serve static files on `HEAD` or `GET` requests.+ ## 0.8.3 [2019.10.20] * Add `Options`, `staticWithOptions`, `staticPolicyWithOptions`, and `unsafeStaticPolicyWithOptions`. * Parameterize Middleware with options allowing custom file name to MIME type mapping.
+ test/Network/Wai/Middleware/StaticSpec.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE OverloadedStrings #-}+module Network.Wai.Middleware.StaticSpec (spec) where++import Test.Hspec hiding (shouldReturn)+import Test.Hspec.Expectations.Lifted+import Test.Hspec.Wai+import Test.Mockery.Directory++import Web.Scotty (scottyApp)+import Network.Wai.Test (SResponse(..))+import Network.HTTP.Types.Status++import Network.Wai.Middleware.Static++spec :: Spec+spec = around_ inTempDirectory $ do+ describe "static" $ with (static `fmap` scottyApp (return ())) $ do+ before_ (writeFile "foo.html" "some content") $ do+ context "on HEAD" $ do+ it "serves static file" $ do+ request "HEAD" "/foo.html" [] "" `shouldReturn` SResponse {+ simpleStatus = status200+ , simpleHeaders = [("Content-Type", "text/html")]+ , simpleBody = "some content"+ }++ context "on GET" $ do+ it "serves static file" $ do+ get "/foo.html" `shouldReturn` SResponse {+ simpleStatus = status200+ , simpleHeaders = [("Content-Type", "text/html")]+ , simpleBody = "some content"+ }++ context "otherwise" $ do+ it "serves upstream" $ do+ post "/foo.html" "" `shouldReturn` SResponse {+ simpleStatus = status404+ , simpleHeaders = [("Content-Type", "text/html")]+ , simpleBody = "<h1>404: File Not Found!</h1>"+ }
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -fforce-recomp -F -pgmF hspec-discover #-}
wai-middleware-static.cabal view
@@ -1,5 +1,5 @@ Name: wai-middleware-static-Version: 0.8.3+Version: 0.9.4 Synopsis: WAI middleware that serves requests to static files. Homepage: https://github.com/scotty-web/wai-middleware-static Bug-reports: https://github.com/scotty-web/wai-middleware-static/issues@@ -17,39 +17,59 @@ if they exist. . [WAI] <http://hackage.haskell.org/package/wai>-tested-with: GHC == 7.6.3- , GHC == 7.8.4- , GHC == 7.10.3- , GHC == 8.0.2+tested-with: GHC == 8.0.2 , GHC == 8.2.2 , GHC == 8.4.4 , GHC == 8.6.5- , GHC == 8.8.1+ , GHC == 8.8.4+ , GHC == 8.10.7+ , GHC == 9.0.2+ , GHC == 9.2.8+ , GHC == 9.4.8+ , GHC == 9.6.7+ , GHC == 9.8.4+ , GHC == 9.10.3+ , GHC == 9.12.2+ , GHC == 9.14.1 Extra-source-files: changelog.md, README.md Library Exposed-modules: Network.Wai.Middleware.Static default-language: Haskell2010 Build-depends:- base >= 4.6.0.1 && < 5,- bytestring >= 0.10.0.2 && < 0.11,- containers >= 0.5.0.0 && < 0.7,- cryptonite >= 0.10 && < 1.0,- memory >= 0.10 && < 1.0,+ base >= 4.9 && < 5,+ base16-bytestring >= 0.1 && < 1.1,+ bytestring >= 0.10.0.2 && < 0.13,+ cryptohash-sha1 >= 0.11 && < 0.12, directory >= 1.2.0.1 && < 1.4, expiring-cache-map >= 0.0.5 && < 0.1,- filepath >= 1.3.0.1 && < 1.5,+ filepath >= 1.3.0.1 && < 1.6, http-types >= 0.8.2 && < 0.13, mime-types >= 0.1.0.3 && < 0.2,- mtl >= 2.1.2 && < 2.3,- old-locale >= 1.0 && < 1.1,- semigroups >= 0.18 && < 1,- text >= 0.11.3.1 && < 1.3,- time >= 1.4 && < 1.10,+ text >= 0.11.3.1 && < 2.2,+ time >= 1.6.0.1 && < 1.16, wai >= 3.0.0 && < 3.3 - GHC-options: -Wall -fno-warn-orphans+ GHC-options: -Wall -Wno-orphans +test-suite spec+ main-is: Spec.hs+ other-modules: Network.Wai.Middleware.StaticSpec+ type: exitcode-stdio-1.0+ default-language: Haskell2010+ hs-source-dirs: test+ build-depends: base,+ hspec == 2.*,+ hspec-expectations-lifted,+ hspec-wai >= 0.6.3,+ mockery,+ scotty,+ wai-extra,+ http-types,+ wai-middleware-static+ build-tool-depends: hspec-discover:hspec-discover == 2.*+ GHC-options: -Wall+ source-repository head type: git- location: git://github.com/scotty-web/wai-middleware-static.git+ location: https://github.com/scotty-web/wai-middleware-static.git