on warp-static/1.3.0 help sign in
144 lines 5.1 kB history raw
1{-# LANGUAGE OverloadedStrings #-}
2module WaiAppStatic.Types
3 ( -- * Pieces
4 Piece
5 , toPiece
6 , fromPiece
7 , unsafeToPiece
8 , Pieces
9 , toPieces
10 -- * Caching
11 , MaxAge (..)
12 -- * File\/folder serving
13 , FolderName
14 , Folder (..)
15 , File (..)
16 , LookupResult (..)
17 , Listing
18 -- * Settings
19 , StaticSettings (..)
20 ) where
22import Data.Text (Text)
23import qualified Network.HTTP.Types as H
24import qualified Network.Wai as W
25import Data.ByteString (ByteString)
26import System.Posix.Types (EpochTime)
27import qualified Data.Text as T
28import Blaze.ByteString.Builder (Builder)
29import Network.Mime (MimeType)
31-- | An individual component of a path, or of a filepath.
32--
33-- This is the core type used by wai-app-static for doing lookups. It provides
34-- a smart constructor to avoid the possibility of constructing unsafe path
35-- segments (though @unsafeToPiece@ can get around that as necessary).
36--
37-- Individual file lookup backends must know how to convert from a @Piece@ to
38-- their storage system.
39newtype Piece = Piece { fromPiece :: Text }
40 deriving (Show, Eq, Ord)
42-- | Smart constructor for a @Piece@. Won\'t allow unsafe components, such as
43-- pieces beginning with a period or containing a slash. This /will/, however,
44-- allow null pieces.
45toPiece :: Text -> Maybe Piece
46toPiece t
47 | T.null t = Just $ Piece t
48 | T.head t == '.' = Nothing
49 | T.any (== '/') t = Nothing
50 | otherwise = Just $ Piece t
52-- | Construct a @Piece@ without input validation.
53unsafeToPiece :: Text -> Piece
54unsafeToPiece = Piece
56-- | Call @toPiece@ on a list.
57--
58-- > toPieces = mapM toPiece
59toPieces :: [Text] -> Maybe Pieces
60toPieces = mapM toPiece
62-- | Request coming from a user. Corresponds to @pathInfo@.
63type Pieces = [Piece]
65-- | Values for the max-age component of the cache-control response header.
66data MaxAge = NoMaxAge -- ^ no cache-control set
67 | MaxAgeSeconds Int -- ^ set to the given number of seconds
68 | MaxAgeForever -- ^ essentially infinite caching; in reality, probably one year
70-- | Just the name of a folder.
71type FolderName = Piece
73-- | Represent contents of a single folder, which can be itself either a file
74-- or a folder.
75data Folder = Folder
76 { folderContents :: [Either FolderName File]
77 }
79-- | Information on an individual file.
80data File = File
81 { -- | Size of file in bytes
82 fileGetSize :: Int
83 -- | How to construct a WAI response for this file. Some files are stored
84 -- on the filesystem and can use @ResponseFile@, while others are stored
85 -- in memory and should use @ResponseBuilder@.
86 , fileToResponse :: H.Status -> H.ResponseHeaders -> W.Response
87 -- | Last component of the filename.
88 , fileName :: Piece
89 -- | Calculate a hash of the contents of this file, such as for etag.
90 , fileGetHash :: IO (Maybe ByteString)
91 -- | Last modified time, used for both display in listings and if-modified-since.
92 , fileGetModified :: Maybe EpochTime
93 }
95-- | Result of looking up a file in some storage backend.
96--
97-- The lookup is either a file or folder, or does not exist.
98data LookupResult = LRFile File
99 | LRFolder Folder
100 | LRNotFound
102-- | How to construct a directory listing page for the given request path and
103-- the resulting folder.
104type Listing = Pieces -> Folder -> IO Builder
106-- | All of the settings available to users for tweaking wai-app-static.
107--
108-- Note that you should use the settings type approach for modifying values.
109-- See <http://www.yesodweb.com/book/settings-types> for more information.
110data StaticSettings = StaticSettings
111 {
112 -- | Lookup a single file or folder. This is how you can control storage
113 -- backend (filesystem, embedded, etc) and where to lookup.
114 ssLookupFile :: Pieces -> IO LookupResult
116 -- | Determine the mime type of the given file. Note that this function
117 -- lives in @IO@ in case you want to perform more complicated mimetype
118 -- analysis, such as via the @file@ utility.
119 , ssGetMimeType :: File -> IO MimeType
121 -- | Ordered list of filenames to be used for indices. If the user
122 -- requests a folder, and a file with the given name is found in that
123 -- folder, that file is served. This supercedes any directory listing.
124 , ssIndices :: [Piece]
126 -- | How to perform a directory listing. Optional. Will be used when the
127 -- user requested a folder.
128 , ssListing :: Maybe Listing
130 -- | Value to provide for max age in the cache-control.
131 , ssMaxAge :: MaxAge
133 -- | Given a requested path and a new destination, construct a string
134 -- that will go there. Default implementation will use relative paths.
135 , ssMkRedirect :: Pieces -> ByteString -> ByteString
137 -- | If @True@, send a redirect to the user when a folder is requested
138 -- and an index page should be displayed. When @False@, display the
139 -- content immediately.
140 , ssRedirectToIndex :: Bool
142 -- | Prefer usage of etag caching to last-modified caching.
143 , ssUseHash :: Bool
144 }