packages feed

herringbone-wai (empty) → 0.1.0

raw patch · 4 files changed

+159/−0 lines, 4 filesdep +basedep +bytestringdep +herringbonesetup-changed

Dependencies added: base, bytestring, herringbone, http-types, system-fileio, system-filepath, time, wai, wai-app-static

Files

+ LICENSE view
@@ -0,0 +1,25 @@++The MIT License (MIT)++Copyright (c) 2014 Harry Garrood++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.+++          
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Web/Herringbone/Adapter/Wai.hs view
@@ -0,0 +1,104 @@+module Web.Herringbone.Adapter.Wai where++import Control.Monad+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as BL+import Data.Time+import Data.Time.Clock.POSIX+import System.Posix.Types (EpochTime)+import Data.Monoid+import Data.List+import Data.Maybe+import Network.Wai+import Network.Wai.Application.Static+import WaiAppStatic.Types+import Network.HTTP.Types+import Prelude hiding (FilePath)+import Filesystem.Path.CurrentOS (FilePath)+import qualified Filesystem.Path.CurrentOS as F+import qualified Filesystem as F++import Web.Herringbone++class ToLazyByteString a where+    toLazyByteString :: a -> BL.ByteString++instance ToLazyByteString FilePath where+    toLazyByteString = toLazyByteString . F.encode++instance ToLazyByteString B.ByteString where+    toLazyByteString = BL.fromChunks . (: [])+++-- | Convert a 'Herringbone' to a WAI 'Application'.+toApplication :: Herringbone -> Application+toApplication hb@(hbDestDir -> dest) =+    staticApp $ (defaultWebAppSettings dest) { ssLookupFile = lookupFile hb }++lookupFile :: Herringbone -> Pieces -> IO LookupResult+lookupFile hb pieces = do+    asset <- findAsset hb (toLogicalPath pieces)+    either assetErrorToLR bundledAssetToLR asset++    where+    assetErrorToLR = return . go++    go AssetNotFound           = LRNotFound+    go (AssetCompileError err) = LRFile . assetCompileError $ err+    go (AmbiguousSources xs)   = LRFile . ambiguousSources $ xs++    bundledAssetToLR asset = do+        file <- toFile (assetSourcePath asset)+                       (assetFilePath asset)+                       (last pieces)+        return . LRFile $ file++-- WaiAppStatic takes care of directory traversal attacks for us+toLogicalPath :: Pieces -> LogicalPath+toLogicalPath = unsafeMakeLogicalPath . map fromPiece++-- This is just given to wai-app-static which takes care of serving it.+toFile :: FilePath -- ^ source path+       -> FilePath -- ^ dest path+       -> Piece    -- ^ file name+       -> IO File+toFile source dest name = do+    size  <- F.getSize dest+    mtime <- F.getModified source+    let strDest = F.encodeString dest+    return File+        { fileGetSize     = fromIntegral size+        , fileToResponse  = \s h -> responseFile s h strDest Nothing+        , fileName        = name+        , fileGetHash     = return Nothing -- TODO+        , fileGetModified = Just . toEpochTime $ mtime+        }++toEpochTime :: UTCTime -> EpochTime+toEpochTime = fromIntegral . toSecs+    where+    toSecs :: UTCTime -> Int+    toSecs = floor . utcTimeToPOSIXSeconds++assetCompileError :: CompileError -> File+assetCompileError err =+    fileError (toLazyByteString err) (unsafeToPiece "compile-error.html")++ambiguousSources :: [FilePath] -> File+ambiguousSources sources =+    let body = "<h1>Ambiguous asset source</h1>" <>+                "<p>List of possible asset sources:</p>" <>+                "<ul>" <>+                BL.concat (map (\s -> "<li>" <> toLazyByteString s <> "</li>") sources) <>+                "</ul>"+    in fileError body (unsafeToPiece "error-ambiguous-source.html")++fileError :: BL.ByteString -> Piece -> File+fileError body name =+    File+        { fileGetSize     = fromIntegral $ BL.length body+        , fileToResponse  = \_ headers -> responseLBS status500 headers body+        , fileName        = name+        , fileGetHash     = return Nothing+        , fileGetModified = Nothing+        }
+ herringbone-wai.cabal view
@@ -0,0 +1,28 @@+name:                herringbone-wai+version:             0.1.0+synopsis:            Wai adapter for the Herringbone web asset preprocessor.+description:         Wai adapter for the Herringbone web asset preprocessor.+license:             MIT+license-file:        LICENSE+author:              Harry Garrood+maintainer:          harry@garrood.me+-- copyright:+category:            Web+build-type:          Simple+-- extra-source-files:+cabal-version:       >=1.10++library+  exposed-modules:     Web.Herringbone.Adapter.Wai+  build-depends:       base >=4.6 && <5,+                       herringbone,+                       wai >= 3.0,+                       wai-app-static,+                       time,+                       system-filepath,+                       system-fileio,+                       bytestring,+                       http-types+  default-extensions:  OverloadedStrings,+                       ViewPatterns+  default-language:    Haskell2010