@@ -1,20 +1,27 @@
11{-# LANGUAGE CPP #-}
2−-- | This module defines a sever-side handler that lets you serve static files.
2+-- | This module defines server-side handlers that lets you serve static files.
33--
4−-- - 'serveDirectory' lets you serve anything that lives under a particular
5−-- directory on your filesystem.
6−module Servant.Utils.StaticFiles (
7− serveDirectory,
8− ) where
4+-- The most common needs for a web application are covered by
5+-- 'serveDirectoryWebApp`, but the other variants allow you to use
6+-- different `StaticSettings` and 'serveDirectoryWith' even allows you
7+-- to specify arbitrary 'StaticSettings' to be used for serving static files.
8+module Servant.Utils.StaticFiles
9+ ( serveDirectoryWebApp
10+ , serveDirectoryWebAppLookup
11+ , serveDirectoryFileServer
12+ , serveDirectoryEmbedded
13+ , serveDirectoryWith
14+ ) where
915
10−import Network.Wai.Application.Static (defaultFileServerSettings,
11− staticApp)
16+import Data.ByteString (ByteString)
17+import Network.Wai.Application.Static
1218import Servant.API.Raw (Raw)
1319import Servant.Server (Server)
1420import System.FilePath (addTrailingPathSeparator)
1521#if !MIN_VERSION_wai_app_static(3,1,0)
1622import Filesystem.Path.CurrentOS (decodeString)
1723#endif
24+import WaiAppStatic.Storage.Filesystem (ETagLookup)
1825
1926-- | Serve anything under the specified directory as a 'Raw' endpoint.
2027--
@@ -22,7 +29,7 @@ import Filesystem.Path.CurrentOS (decodeString)
2229-- type MyApi = "static" :> Raw
2330--
2431-- server :: Server MyApi
25−-- server = serveDirectory "\/var\/www"
32+-- server = serveDirectoryWebApp "\/var\/www"
2633-- @
2734--
2835-- would capture any request to @\/static\/\<something>@ and look for
@@ -33,13 +40,38 @@ import Filesystem.Path.CurrentOS (decodeString)
3340--
3441-- If your goal is to serve HTML, CSS and Javascript files that use the rest of the API
3542-- as a webapp backend, you will most likely not want the static files to be hidden
36−-- behind a /\/static\// prefix. In that case, remember to put the 'serveDirectory'
43+-- behind a /\/static\// prefix. In that case, remember to put the 'serveDirectoryWebApp'
3744-- handler in the last position, because /servant/ will try to match the handlers
3845-- in order.
39−serveDirectory :: FilePath -> Server Raw
40−serveDirectory =
46+--
47+-- Corresponds to the `defaultWebAppSettings` `StaticSettings` value.
48+serveDirectoryWebApp :: FilePath -> Server Raw
49+serveDirectoryWebApp = staticApp . defaultWebAppSettings . fixPath
50+
51+-- | Same as 'serveDirectoryWebApp', but uses `defaultFileServerSettings`.
52+serveDirectoryFileServer :: FilePath -> Server Raw
53+serveDirectoryFileServer = staticApp . defaultFileServerSettings . fixPath
54+
55+-- | Same as 'serveDirectoryWebApp', but uses 'webAppSettingsWithLookup'.
56+serveDirectoryWebAppLookup :: ETagLookup -> FilePath -> Server Raw
57+serveDirectoryWebAppLookup etag =
58+ staticApp . flip webAppSettingsWithLookup etag . fixPath
59+
60+-- | Uses 'embeddedSettings'.
61+serveDirectoryEmbedded :: [(FilePath, ByteString)] -> Server Raw
62+serveDirectoryEmbedded files = staticApp (embeddedSettings files)
63+
64+-- | Alias for 'staticApp'. Lets you serve a directory
65+-- with arbitrary 'StaticSettings'. Useful when you want
66+-- particular settings not covered by the four other
67+-- variants. This is the most flexible method.
68+serveDirectoryWith :: StaticSettings -> Server Raw
69+serveDirectoryWith = staticApp
70+
71+fixPath :: FilePath -> FilePath
72+fixPath =
4173#if MIN_VERSION_wai_app_static(3,1,0)
42− staticApp . defaultFileServerSettings . addTrailingPathSeparator
74+ addTrailingPathSeparator
4375#else
44− staticApp . defaultFileServerSettings . decodeString . addTrailingPathSeparator
76+ decodeString . addTrailingPathSeparator
4577#endif