packages feed

warp-static-0.2.0: warp.hs

{-# LANGUAGE DeriveDataTypeable, RecordWildCards #-}
import Network.Wai.Application.Static
    ( StaticSettings (..), staticApp, defaultMimeType, defaultListing
    , defaultMimeTypes, mimeTypeByExt
    , defaultFileServerSettings, fileSystemLookup
    , fileName, toFilePath
    )
import Network.Wai.Handler.Warp (run)
import System.Environment (getArgs)
import System.Console.CmdArgs
import Text.Printf (printf)
import System.Directory (canonicalizePath)
import Control.Monad (unless)
import Network.Wai.Middleware.Autohead
import Network.Wai.Middleware.Debug
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, unpack)

data Args = Args
    { docroot :: FilePath
    , index :: [FilePath]
    , port :: Int
    , noindex :: Bool
    , quiet :: Bool
    , verbose :: Bool
    , mime :: [(String, String)]
    }
    deriving (Show, Data, Typeable)

defaultArgs = Args "." ["index.html", "index.htm"] 3000 False False False []

main :: IO ()
main = do
    Args {..} <- cmdArgs defaultArgs
    let mime' = map (toFilePath *** S8.pack) mime
    let mimeMap = Map.fromList mime' `Map.union` defaultMimeTypes
    docroot' <- canonicalizePath docroot
    args <- getArgs
    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 False
               . (if verbose then debug else id)
               . autohead
    run port $ middle $ staticApp defaultFileServerSettings
        { ssFolder = fileSystemLookup $ toFilePath docroot
        , ssIndices = if noindex then [] else map pack index
        , ssListing = Just defaultListing
        , ssGetMimeType = return . mimeTypeByExt mimeMap defaultMimeType . fileName
        }