-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Snap: A Haskell Web Framework (Core) -- -- Snap is a simple and fast web development framework and server written -- in Haskell. For more information or to download the latest version, -- you can visit the Snap project website at -- http://snapframework.com/. -- -- This library contains the core definitions and types for the Snap -- framework, including: -- --
    --
  1. Primitive types and functions for HTTP (requests, responses, -- cookies, post/query parameters, etc)
  2. --
  3. Type aliases and helper functions for Iteratee I/O
  4. --
  5. A monad for programming web handlers called "Snap", inspired by -- happstack's (http://happstack.com/index.html), which -- allows:
  6. --
-- -- -- -- Quick start: The Snap monad and HTTP definitions are in -- Snap.Core, some iteratee utilities are in Snap.Iteratee. -- -- Higher-level facilities for building web applications (like -- user/session management, component interfaces, data modeling, etc.) -- are planned but not yet implemented, so this release will mostly be of -- interest for those who: -- -- @package snap-core @version 0.7 module Snap.Util.Readable -- | Monadic analog to Read that uses ByteString instead of String. class Readable a fromBS :: (Readable a, Monad m) => ByteString -> m a instance Readable Double instance Readable Integer instance Readable Int instance Readable Text instance Readable ByteString -- | An internal Snap module for (optionally) printing debugging messages. -- Normally debug does nothing, but if you set DEBUG=1 in -- the environment you'll get debugging messages. We use -- unsafePerformIO to make sure that the call to getEnv -- is only made once. -- -- N.B. this is an internal interface, please don't write external -- code that depends on it. module Snap.Internal.Debug debug, debugErrno :: MonadIO m => String -> m () debugIgnore :: MonadIO m => String -> m () debugErrnoIgnore :: MonadIO m => String -> m () -- | An opaque data type for HTTP headers. Intended to be imported -- qualified, i.e: -- --
--   import           Snap.Types.Headers (Headers)
--   import qualified Snap.Types.Headers as H
--   
--   foo :: Headers
--   foo = H.empty
--   
module Snap.Types.Headers data Headers empty :: Headers null :: Headers -> Bool member :: CI ByteString -> Headers -> Bool lookup :: CI ByteString -> Headers -> Maybe [ByteString] lookupWithDefault :: ByteString -> CI ByteString -> Headers -> [ByteString] insert :: CI ByteString -> ByteString -> Headers -> Headers set :: CI ByteString -> ByteString -> Headers -> Headers delete :: CI ByteString -> Headers -> Headers fold :: (a -> CI ByteString -> [ByteString] -> a) -> a -> Headers -> a toList :: Headers -> [(CI ByteString, ByteString)] fromList :: [(CI ByteString, ByteString)] -> Headers instance Show Headers -- | Snap Framework type aliases and utilities for iteratees. Note that as -- a convenience, this module also exports everything from -- Data.Enumerator in the enumerator library. module Snap.Iteratee -- | Enumerates a strict bytestring. enumBS :: Monad m => ByteString -> Enumerator ByteString m a -- | Enumerates a lazy bytestring. enumLBS :: Monad m => ByteString -> Enumerator ByteString m a -- | Enumerates a Builder. enumBuilder :: Monad m => Builder -> Enumerator Builder m a enumFile :: FilePath -> Enumerator ByteString IO a enumFilePartial :: FilePath -> (Int64, Int64) -> Enumerator ByteString IO a data InvalidRangeException joinI' :: Monad m => Iteratee a m (Step a m b) -> Iteratee a m b -- | Wraps an Iteratee, counting the number of bytes consumed by it. countBytes :: Monad m => forall a. Iteratee ByteString m a -> Iteratee ByteString m (a, Int64) -- | Skip n elements of the stream, if there are that many drop' :: Monad m => Int64 -> Iteratee ByteString m () -- | Creates a buffer to be passed into -- unsafeBufferIterateeWithBuffer. mkIterateeBuffer :: IO (ForeignPtr CChar) -- | Buffers an iteratee, "unsafely". Here we use a fixed binary buffer -- which we'll re-use, meaning that if you hold on to any of the -- bytestring data passed into your iteratee (instead of, let's say, -- shoving it right out a socket) it'll get changed out from underneath -- you, breaking referential transparency. Use with caution! -- -- This version accepts a buffer created by mkIterateeBuffer. unsafeBufferIterateeWithBuffer :: ForeignPtr CChar -> Iteratee ByteString IO a -> Iteratee ByteString IO a -- | Buffers an iteratee, "unsafely". Here we use a fixed binary buffer -- which we'll re-use, meaning that if you hold on to any of the -- bytestring data passed into your iteratee (instead of, let's say, -- shoving it right out a socket) it'll get changed out from underneath -- you, breaking referential transparency. Use with caution! unsafeBufferIteratee :: Iteratee ByteString IO a -> IO (Iteratee ByteString IO a) take :: Monad m => Int -> Enumeratee ByteString ByteString m a -- | Skip n elements of the stream, if there are that many drop :: Monad m => Int -> Iteratee ByteString m () -- | Reads n bytes from a stream and applies the given iteratee to the -- stream of the read elements. Reads exactly n bytes, and if the stream -- is short propagates an error. takeExactly :: Monad m => Int64 -> Enumeratee ByteString ByteString m a takeNoMoreThan :: Monad m => Int64 -> Enumeratee ByteString ByteString m a skipToEof :: Monad m => Iteratee a m () mapEnum :: Monad m => (aOut -> aIn) -> (aIn -> aOut) -> Enumerator aIn m a -> Enumerator aOut m a mapIter :: Monad m => (aOut -> aIn) -> (aIn -> aOut) -> Iteratee aIn m a -> Iteratee aOut m a enumBuilderToByteString :: MonadIO m => Enumeratee Builder ByteString m a unsafeEnumBuilderToByteString :: MonadIO m => Enumeratee Builder ByteString m a enumByteStringToBuilder :: MonadIO m => Enumeratee ByteString Builder m a killIfTooSlow :: MonadIO m => m () -> Double -> Int -> Iteratee ByteString m a -> Iteratee ByteString m a data TooManyBytesReadException data ShortWriteException data RateTooSlowException -- | A Stream is a sequence of chunks generated by an -- Enumerator. -- -- (Chunks []) is used to indicate that a stream is still -- active, but currently has no available data. Iteratees should ignore -- empty chunks. data Stream a :: * -> * Chunks :: [a] -> Stream a EOF :: Stream a data Step a m :: (* -> *) b :: * -> (* -> *) -> * -> * -- | The Iteratee is capable of accepting more input. Note that more -- input is not necessarily required; the Iteratee might be able -- to generate a value immediately if it receives EOF. Continue :: (Stream a -> Iteratee a m b) -> Step a b -- | The Iteratee cannot receive any more input, and has generated a -- result. Included in this value is left-over input, which can be passed -- to composed Iteratees. Yield :: b -> Stream a -> Step a b -- | The Iteratee encountered an error which prevents it from -- proceeding further. Error :: SomeException -> Step a b -- | The primary data type for this library; an iteratee consumes chunks of -- input from a stream until it either yields a value or encounters an -- error. -- -- Compatibility note: Iteratee will become abstract in -- enumerator_0.5. If you depend on internal implementation -- details, please import Data.Enumerator.Internal. newtype Iteratee a m :: (* -> *) b :: * -> (* -> *) -> * -> * Iteratee :: m (Step a m b) -> Iteratee a b runIteratee :: Iteratee a b -> m (Step a m b) -- | Enumerators are sources of data, to be consumed by iteratees. -- Enumerators typically read from an external source (parser, handle, -- random generator, etc), then feed chunks into an tteratee until: -- -- type Enumerator a m :: (* -> *) b = Step a m b -> Iteratee a m b -- | An enumeratee acts as a stream adapter; place one between an -- enumerator and an iteratee, and it changes the type or contents of the -- input stream. -- -- Most users will want to combine enumerators, enumeratees, and -- iteratees using the stream combinators joinI and -- joinE, or their operator aliases (=$) and -- ($=). These combinators are used to manage how left-over -- input is passed between elements of the data processing pipeline. type Enumeratee ao ai m :: (* -> *) b = Step ai m b -> Iteratee ao m (Step ai m b) -- |
--   returnI step = Iteratee (return step)
--   
returnI :: Monad m => Step a m b -> Iteratee a m b -- |
--   yield x extra = returnI (Yield x extra)
--   
-- -- WARNING: due to the current encoding of iteratees in this library, -- careless use of the yield primitive may violate the monad laws. -- To prevent this, always make sure that an iteratee never yields extra -- data unless it has received at least one input element. -- -- More strictly, iteratees may not yield data that they did not receive -- as input. Don't use yield to “inject” elements into the stream. yield :: Monad m => b -> Stream a -> Iteratee a m b -- |
--   continue k = returnI (Continue k)
--   
continue :: Monad m => (Stream a -> Iteratee a m b) -> Iteratee a m b -- | The moral equivalent of throwIO for iteratees. throwError :: (Monad m, Exception e) => e -> Iteratee a m b -- | Runs the iteratee, and calls an exception handler if an Error -- is returned. By handling errors within the enumerator library, and -- requiring all errors to be represented by SomeException, -- libraries with varying error types can be easily composed. -- -- WARNING: Within the error handler, it is difficult or impossible to -- know how much input the original iteratee has consumed. Users are -- strongly advised to wrap all uses of catchError with an -- appropriate isolation enumeratee, such as -- Data.Enumerator.List.isolate or -- Data.Enumerator.Binary.isolate, which will handle input -- framing even in the face of unexpected errors. -- -- Since: 0.1.1 catchError :: Monad m => Iteratee a m b -> (SomeException -> Iteratee a m b) -> Iteratee a m b -- | Deprecated in 0.4.5: use Data.Enumerator.continue instead liftI :: Monad m => (Stream a -> Step a m b) -> Iteratee a m b -- | The most primitive stream operator. iter >>== enum -- returns a new iteratee which will read from enum before -- continuing. (>>==) :: Monad m => Iteratee a m b -> (Step a m b -> Iteratee a' m b') -> Iteratee a' m b' -- |
--   (==<<) = flip (>>==)
--   
(==<<) :: Monad m => (Step a m b -> Iteratee a' m b') -> Iteratee a m b -> Iteratee a' m b' -- |
--   ($$) = (==<<)
--   
-- -- This is somewhat easier to read when constructing an iteratee from -- many processing stages. You can treat it like ($), and -- read the data flow from left to right. -- -- Since: 0.1.1 ($$) :: Monad m => (Step a m b -> Iteratee a' m b') -> Iteratee a m b -> Iteratee a' m b' -- |
--   (>==>) enum1 enum2 step = enum1 step >>== enum2
--   
-- -- The moral equivalent of (>=>) for iteratees. -- -- Since: 0.1.1 (>==>) :: Monad m => Enumerator a m b -> (Step a m b -> Iteratee a' m b') -> Step a m b -> Iteratee a' m b' -- |
--   (<==<) = flip (>==>)
--   
-- -- Since: 0.1.1 (<==<) :: Monad m => (Step a m b -> Iteratee a' m b') -> Enumerator a m b -> Step a m b -> Iteratee a' m b' -- | “Wraps” an enumerator inner in an enumeratee wrapper. -- The resulting enumerator will generate wrapper’s output type. -- -- As an example, consider an enumerator that yields line character -- counts for a text file (e.g. for source code readability checking): -- --
--   enumFileCounts :: FilePath -> Enumerator Int IO b
--   
-- -- It could be written with either joinE or ($=): -- --
--   import Data.Text as T
--   import Data.Enumerator.List as EL
--   import Data.Enumerator.Text as ET
--   
--   enumFileCounts path = joinE (enumFile path) (EL.map T.length)
--   enumFileCounts path = enumFile path $= EL.map T.length
--   
-- -- Compatibility note: in version 0.4.15, the associativity of -- ($=) was changed from infixr 0 to infixl 1. -- -- Since: 0.4.9 ($=) :: Monad m => Enumerator ao m (Step ai m b) -> Enumeratee ao ai m b -> Enumerator ai m b -- | “Wraps” an iteratee inner in an enumeratee wrapper. The -- resulting iteratee will consume wrapper’s input type and yield -- inner’s output type. -- -- Note: if the inner iteratee yields leftover input when it finishes, -- that extra will be discarded. -- -- As an example, consider an iteratee that converts a stream of -- UTF8-encoded bytes into a single Text: -- --
--   consumeUTF8 :: Monad m => Iteratee ByteString m Text
--   
-- -- It could be written with either joinI or (=$): -- --
--   import Data.Enumerator.Text as ET
--   
--   consumeUTF8 = joinI (decode utf8 $$ ET.consume)
--   consumeUTF8 = decode utf8 =$ ET.consume
--   
-- -- Since: 0.4.9 (=$) :: Monad m => Enumeratee ao ai m b -> Iteratee ai m b -> Iteratee ao m b -- | Run an iteratee until it finishes, and return either the final value -- (if it succeeded) or the error (if it failed). -- --
--   import Data.Enumerator
--   import Data.Enumerator.List as EL
--   
--   main = do
--       result <- run (EL.iterate succ 'A' $$ EL.take 5)
--       case result of
--           Left exc -> putStrLn ("Got an exception: " ++ show exc)
--           Right chars -> putStrLn ("Got characters: " ++ show chars)
--   
run :: Monad m => Iteratee a m b -> m (Either SomeException b) -- | Like run, except errors are converted to exceptions and thrown. -- Primarily useful for small scripts or other simple cases. -- --
--   import Data.Enumerator
--   import Data.Enumerator.List as EL
--   
--   main = do
--       chars <- run_ (EL.iterate succ 'A' $$ EL.take 5)
--       putStrLn ("Got characters: " ++ show chars)
--   
-- -- Since: 0.4.1 run_ :: Monad m => Iteratee a m b -> m b -- |
--   consume = takeWhile (const True)
--   
-- -- Since: 0.4.5 consume :: Monad m => Iteratee a m [a] -- | Check whether a stream has reached EOF. Note that if the stream is not -- at EOF, isEOF may cause data to be read from the enumerator. isEOF :: Monad m => Iteratee a m Bool -- | Lift an Iteratee onto a monad transformer, re-wrapping its -- inner monadic values. -- -- Since: 0.1.1 liftTrans :: (Monad m, MonadTrans t, Monad (t m)) => Iteratee a m b -> Iteratee a (t m) b -- | Deprecated in 0.4.5: use Data.Enumerator.List.fold instead -- -- Since: 0.1.1 liftFoldL :: Monad m => (b -> a -> b) -> b -> Iteratee a m b -- | Deprecated in 0.4.5: use Data.Enumerator.List.fold instead -- -- Since: 0.1.1 liftFoldL' :: Monad m => (b -> a -> b) -> b -> Iteratee a m b -- | Deprecated in 0.4.5: use Data.Enumerator.List.foldM instead -- -- Since: 0.1.1 liftFoldM :: Monad m => (b -> a -> m b) -> b -> Iteratee a m b -- | Print chunks as they're received from the enumerator, optionally -- printing empty chunks. printChunks :: (MonadIO m, Show a) => Bool -> Iteratee a m () -- | Get the next element from the stream, or Nothing if the stream -- has ended. -- -- Since: 0.4.5 head :: Monad m => Iteratee a m (Maybe a) -- | Peek at the next element in the stream, or Nothing if the -- stream has ended. peek :: Monad m => Iteratee a m (Maybe a) -- | Sends EOF to its iteratee. Most clients should use run -- or run_ instead. enumEOF :: Monad m => Enumerator a m b -- | enumList n xs enumerates xs as a stream, -- passing n inputs per chunk. This is primarily useful for -- testing, debugging, and REPL exploration. -- -- Compatibility note: In version 0.5, enumList will be changed to -- the type: -- --
--   enumList :: Monad m => [a] -> Enumerator a m b
--   
enumList :: Monad m => Integer -> [a] -> Enumerator a m b -- | Compose a list of Enumerators using -- (>==>). concatEnums :: Monad m => [Enumerator a m b] -> Enumerator a m b -- |
--   checkDone = checkDoneEx (Chunks [])
--   
-- -- Use this for enumeratees which do not have an input buffer. checkDone :: Monad m => ((Stream a -> Iteratee a m b) -> Iteratee a' m (Step a m b)) -> Enumeratee a' a m b -- | map f applies f to each input element and feeds -- the resulting outputs to the inner iteratee. -- -- Since: 0.4.8 map :: Monad m => (ao -> ai) -> Enumeratee ao ai m b -- | Feeds outer input elements into the provided iteratee until it yields -- an inner input, passes that to the inner iteratee, and then loops. sequence :: Monad m => Iteratee ao m ai -> Enumeratee ao ai m b -- | “Wraps” an iteratee inner in an enumeratee wrapper. The -- resulting iteratee will consume wrapper’s input type and yield -- inner’s output type. -- -- See the documentation for (=$). -- --
--   joinI (enum $$ iter) = enum =$ iter
--   
joinI :: Monad m => Iteratee a m (Step a' m b) -> Iteratee a m b instance Typeable ShortWriteException instance Typeable RateTooSlowException instance Typeable TooManyBytesReadException instance Typeable InvalidRangeException instance Exception InvalidRangeException instance Show InvalidRangeException instance Exception TooManyBytesReadException instance Exception RateTooSlowException instance Exception ShortWriteException instance Show TooManyBytesReadException instance Show RateTooSlowException instance Show ShortWriteException instance (Functor m, MonadCatchIO m) => MonadCatchIO (Iteratee s m) -- | An internal Snap module for debugging iteratees. -- -- N.B. this is an internal interface, please don't write user -- code that depends on it. module Snap.Internal.Iteratee.Debug debugIteratee :: Iteratee ByteString IO () iterateeDebugWrapper :: (Show a, MonadIO m) => String -> Iteratee a m b -> Iteratee a m b iterateeDebugWrapperWith :: MonadIO m => (s -> String) -> String -> Iteratee s m a -> Iteratee s m a showBuilder :: Builder -> String -- | An internal Snap module containing HTTP types. -- -- N.B. this is an internal interface, please don't write user -- code that depends on it. Most of these declarations (except for the -- unsafe/encapsulation-breaking ones) are re-exported from -- Snap.Core. module Snap.Internal.Http.Types set_c_locale :: IO () c_parse_http_time :: CString -> IO CTime c_format_http_time :: CTime -> CString -> IO () c_format_log_time :: CTime -> CString -> IO () -- | A typeclass for datatypes which contain HTTP headers. class HasHeaders a updateHeaders :: HasHeaders a => (Headers -> Headers) -> a -> a headers :: HasHeaders a => a -> Headers -- | Adds a header key-value-pair to the HasHeaders datatype. If a -- header with the same name already exists, the new value is appended to -- the headers list. addHeader :: HasHeaders a => CI ByteString -> ByteString -> a -> a -- | Sets a header key-value-pair in a HasHeaders datatype. If a -- header with the same name already exists, it is overwritten with the -- new value. setHeader :: HasHeaders a => CI ByteString -> ByteString -> a -> a -- | Gets all of the values for a given header. getHeaders :: HasHeaders a => CI ByteString -> a -> Maybe [ByteString] -- | Gets a header value out of a HasHeaders datatype. If many -- headers came in with the same name, they will be catenated together. getHeader :: HasHeaders a => CI ByteString -> a -> Maybe ByteString -- | Lists all the headers out of a HasHeaders datatype. If many -- headers came in with the same name, they will be catenated together. listHeaders :: HasHeaders a => a -> [(CI ByteString, ByteString)] -- | Clears a header value from a HasHeaders datatype. deleteHeader :: HasHeaders a => CI ByteString -> a -> a -- | Enumerates the HTTP method values (see -- http://tools.ietf.org/html/rfc2068.html#section-5.1.1). data Method GET :: Method HEAD :: Method POST :: Method PUT :: Method DELETE :: Method TRACE :: Method OPTIONS :: Method CONNECT :: Method type HttpVersion = (Int, Int) -- | A datatype representing an HTTP cookie. data Cookie Cookie :: !ByteString -> !ByteString -> !Maybe UTCTime -> !Maybe ByteString -> !Maybe ByteString -> !Bool -> !Bool -> Cookie -- | The name of the cookie. cookieName :: Cookie -> !ByteString -- | The cookie's string value. cookieValue :: Cookie -> !ByteString -- | The cookie's expiration value, if it has one. cookieExpires :: Cookie -> !Maybe UTCTime -- | The cookie's "domain" value, if it has one. cookieDomain :: Cookie -> !Maybe ByteString -- | The cookie path. cookiePath :: Cookie -> !Maybe ByteString -- | Tag as secure cookie? cookieSecure :: Cookie -> !Bool -- | HttpOnly? cookieHttpOnly :: Cookie -> !Bool -- | A type alias for the HTTP parameters mapping. Each parameter key maps -- to a list of ByteString values; if a parameter is specified multiple -- times (e.g.: "GET /foo?param=bar1&param=bar2"), looking -- up "param" in the mapping will give you ["bar1", -- "bar2"]. type Params = Map ByteString [ByteString] -- | An existential wrapper for the 'Enumerator ByteString IO a' type newtype SomeEnumerator SomeEnumerator :: (forall a. Enumerator ByteString IO a) -> SomeEnumerator -- | Contains all of the information about an incoming HTTP request. data Request Request :: !ByteString -> !Int -> !ByteString -> !Int -> !ByteString -> !Int -> !ByteString -> !Bool -> Headers -> IORef SomeEnumerator -> !Maybe Int -> !Method -> !HttpVersion -> [Cookie] -> !ByteString -> !ByteString -> !ByteString -> !ByteString -> !ByteString -> Params -> Request -- | The server name of the request, as it came in from the request's -- Host: header. rqServerName :: Request -> !ByteString -- | Returns the port number the HTTP server is listening on. rqServerPort :: Request -> !Int -- | The remote IP address. rqRemoteAddr :: Request -> !ByteString -- | The remote TCP port number. rqRemotePort :: Request -> !Int -- | The local IP address for this request. rqLocalAddr :: Request -> !ByteString -- | Returns the port number the HTTP server is listening on. rqLocalPort :: Request -> !Int -- | Returns the HTTP server's idea of its local hostname. rqLocalHostname :: Request -> !ByteString -- | Returns True if this is an HTTPS session. rqIsSecure :: Request -> !Bool rqHeaders :: Request -> Headers rqBody :: Request -> IORef SomeEnumerator -- | Returns the Content-Length of the HTTP request body. rqContentLength :: Request -> !Maybe Int -- | Returns the HTTP request method. rqMethod :: Request -> !Method -- | Returns the HTTP version used by the client. rqVersion :: Request -> !HttpVersion -- | Returns a list of the cookies that came in from the HTTP request -- headers. rqCookies :: Request -> [Cookie] -- | We'll be doing web components (or "snaplets") for version 0.2. The -- "snaplet path" refers to the place on the URL where your containing -- snaplet is hung. The value of rqSnapletPath is either -- "" (at the top-level context) or is a path beginning with a -- slash, but not ending with one. -- -- An identity is that: -- --
--   rqURI r == S.concat [ rqSnapletPath r
--                       , rqContextPath r
--                       , rqPathInfo r
--                       , let q = rqQueryString r
--                         in if S.null q
--                              then ""
--                              else S.append "?" q
--                       ]
--   
-- -- note that until we introduce snaplets in v0.2, rqSnapletPath -- will be "" rqSnapletPath :: Request -> !ByteString -- | Handlers can (will be; --ed) be hung on a URI "entry -- point"; this is called the "context path". If a handler is hung on the -- context path "/foo/", and you request "/foo/bar", -- the value of rqPathInfo will be "bar". rqPathInfo :: Request -> !ByteString -- | The "context path" of the request; catenating rqContextPath, -- and rqPathInfo should get you back to the original rqURI -- (ignoring query strings). The rqContextPath always begins and -- ends with a slash ("/") character, and represents the path -- (relative to your component/snaplet) you took to get to your handler. rqContextPath :: Request -> !ByteString -- | Returns the URI requested by the client. rqURI :: Request -> !ByteString -- | Returns the HTTP query string for this Request. rqQueryString :: Request -> !ByteString -- | Returns the Params mapping for this Request. -- "Parameters" are automatically decoded from the query string and -- POST body and entered into this mapping. rqParams :: Request -> Params data ResponseBody -- | output body is a Builder enumerator Enum :: (forall a. Enumerator Builder IO a) -> ResponseBody -- | output body is sendfile(), optional second argument is a byte range to -- send SendFile :: FilePath -> (Maybe (Int64, Int64)) -> ResponseBody rspBodyMap :: (forall a. Enumerator Builder IO a -> Enumerator Builder IO a) -> ResponseBody -> ResponseBody rspBodyToEnum :: ResponseBody -> Enumerator Builder IO a -- | Represents an HTTP response. data Response Response :: Headers -> Map ByteString Cookie -> !HttpVersion -> !Maybe Int64 -> ResponseBody -> !Int -> !ByteString -> !Bool -> Response rspHeaders :: Response -> Headers rspCookies :: Response -> Map ByteString Cookie rspHttpVersion :: Response -> !HttpVersion -- | We will need to inspect the content length no matter what, and looking -- up "content-length" in the headers and parsing the number out of the -- text will be too expensive. rspContentLength :: Response -> !Maybe Int64 rspBody :: Response -> ResponseBody -- | Returns the HTTP status code. rspStatus :: Response -> !Int -- | Returns the HTTP status explanation string. rspStatusReason :: Response -> !ByteString -- | If true, we are transforming the request body with -- transformRequestBody rspTransformingRqBody :: Response -> !Bool -- | Looks up the value(s) for the given named parameter. Parameters -- initially come from the request's query string and any decoded POST -- body (if the request's Content-Type is -- application/x-www-form-urlencoded). Parameter values can be -- modified within handlers using rqModifyParams. rqParam :: ByteString -> Request -> Maybe [ByteString] -- | Modifies the parameters mapping (which is a Map ByteString -- ByteString) in a Request using the given function. rqModifyParams :: (Params -> Params) -> Request -> Request -- | Writes a key-value pair to the parameters mapping within the given -- request. rqSetParam :: ByteString -> [ByteString] -> Request -> Request -- | An empty Response. emptyResponse :: Response -- | Sets an HTTP response body to the given Enumerator value. setResponseBody :: (forall a. Enumerator Builder IO a) -> Response -> Response -- | Sets the HTTP response status. Note: normally you would use -- setResponseCode unless you needed a custom response -- explanation. setResponseStatus :: Int -> ByteString -> Response -> Response -- | Sets the HTTP response code. setResponseCode :: Int -> Response -> Response -- | Modifies a response body. modifyResponseBody :: (forall a. Enumerator Builder IO a -> Enumerator Builder IO a) -> Response -> Response -- | Sets the Content-Type in the Response headers. setContentType :: ByteString -> Response -> Response -- | Adds an HTTP Cookie to Response headers. addResponseCookie :: Cookie -> Response -> Response -- | Gets an HTTP Cookie with the given name from Response -- headers. getResponseCookie :: ByteString -> Response -> Maybe Cookie -- | Returns a list of Cookies present in Response getResponseCookies :: Response -> [Cookie] -- | Deletes an HTTP Cookie from the Response headers. Please -- note this does not necessarily erase the cookie from the client -- browser. deleteResponseCookie :: ByteString -> Response -> Response -- | Modifies an HTTP Cookie with given name in Response -- headers. Nothing will happen if a matching Cookie can not be -- found in Response. modifyResponseCookie :: ByteString -> (Cookie -> Cookie) -> Response -> Response -- | A note here: if you want to set the Content-Length for the -- response, Snap forces you to do it with this function rather than by -- setting it in the headers; the Content-Length in the headers -- will be ignored. -- -- The reason for this is that Snap needs to look up the value of -- Content-Length for each request, and looking the string value -- up in the headers and parsing the number out of the text will be too -- expensive. -- -- If you don't set a content length in your response, HTTP keep-alive -- will be disabled for HTTP/1.0 clients, forcing a Connection: -- close. For HTTP/1.1 clients, Snap will switch to the chunked -- transfer encoding if Content-Length is not specified. setContentLength :: Int64 -> Response -> Response -- | Removes any Content-Length set in the Response. clearContentLength :: Response -> Response -- | Converts a CTime into an HTTP timestamp. formatHttpTime :: CTime -> IO ByteString -- | Converts a CTime into common log entry format. formatLogTime :: CTime -> IO ByteString -- | Converts an HTTP timestamp into a CTime. parseHttpTime :: ByteString -> IO CTime fromStr :: String -> ByteString toStr :: ByteString -> String statusReasonMap :: IntMap ByteString instance Show Method instance Read Method instance Ord Method instance Eq Method instance Eq Cookie instance Show Cookie instance HasHeaders Response instance Show Response instance HasHeaders Headers instance HasHeaders Request instance Show Request module Snap.Internal.Parsing fullyParse :: ByteString -> Parser a -> Either String a parseNum :: Parser Int64 -- | Parsers for different tokens in an HTTP request. sp, letter, digit :: Parser Char untilEOL :: Parser ByteString crlf :: Parser ByteString generateFS :: (Word8 -> Bool) -> FastSet -- | Parser for zero or more spaces. spaces :: Parser [Char] pSpaces :: Parser ByteString fieldChars :: Parser ByteString fieldCharSet :: FastSet -- | Parser for request headers. pHeaders :: Parser [(ByteString, ByteString)] pWord :: Parser ByteString pQuotedString :: Parser ByteString isRFCText :: Char -> Bool matchAll :: [Char -> Bool] -> Char -> Bool pAvPairs :: Parser [(ByteString, ByteString)] pAvPair :: Parser (ByteString, ByteString) pParameter :: Parser (ByteString, ByteString) trim :: ByteString -> ByteString pValueWithParameters :: Parser (ByteString, [(CI ByteString, ByteString)]) pContentTypeWithParameters :: Parser (ByteString, [(CI ByteString, ByteString)]) pToken :: Parser ByteString isToken :: Char -> Bool tokenTable :: FastSet parseToCompletion :: Parser a -> ByteString -> Maybe a pUrlEscaped :: Parser ByteString -- | Decodes an URL-escaped string (see -- http://tools.ietf.org/html/rfc2396.html#section-2.4) urlDecode :: ByteString -> Maybe ByteString -- | URL-escapes a string (see -- http://tools.ietf.org/html/rfc2396.html#section-2.4) urlEncode :: ByteString -> ByteString -- | URL-escapes a string (see -- http://tools.ietf.org/html/rfc2396.html#section-2.4) into a -- Builder. urlEncodeBuilder :: ByteString -> Builder urlEncodeTable :: FastSet hexd :: Char -> Builder finish :: Result a -> Result a -- | Parses a string encoded in application/x-www-form-urlencoded -- format. parseUrlEncoded :: ByteString -> Map ByteString [ByteString] buildUrlEncoded :: Map ByteString [ByteString] -> Builder printUrlEncoded :: Map ByteString [ByteString] -> ByteString pCookies :: Parser [Cookie] parseCookie :: ByteString -> Maybe [Cookie] strictize :: ByteString -> ByteString -- | This module contains the core type definitions, class instances, and -- functions for HTTP as well as the Snap monad, which is used for -- web handlers. module Snap.Core data Snap a -- | Runs a Snap monad action in the 'Iteratee IO' monad. runSnap :: Snap a -> (ByteString -> IO ()) -> (Int -> IO ()) -> Request -> Iteratee ByteString IO (Request, Response) -- | Snap is the Monad that user web handlers run in. -- Snap gives you: -- --
    --
  1. stateful access to fetch or modify an HTTP Request
  2. --
  3. stateful access to fetch or modify an HTTP Response
  4. --
  5. failure / Alternative / MonadPlus semantics: a -- Snap handler can choose not to handle a given request, using -- empty or its synonym pass, and you can try alternative -- handlers with the <|> operator:
  6. --
-- --
--   a :: Snap String
--   a = pass
--   
--   b :: Snap String
--   b = return "foo"
--   
--   c :: Snap String
--   c = a <|> b             -- try running a, if it fails then try b
--   
-- --
    --
  1. convenience functions (writeBS, writeLBS, -- writeText, writeLazyText, addToOutput) for -- queueing output to be written to the Response:
  2. --
-- --
--   a :: (forall a . Enumerator a) -> Snap ()
--   a someEnumerator = do
--       writeBS "I'm a strict bytestring"
--       writeLBS "I'm a lazy bytestring"
--       writeText "I'm strict text"
--       addToOutput someEnumerator
--   
-- --
    --
  1. early termination: if you call finishWith:
  2. --
-- --
--   a :: Snap ()
--   a = do
--     modifyResponse $ setResponseStatus 500 "Internal Server Error"
--     writeBS "500 error"
--     r <- getResponse
--     finishWith r
--   
-- -- then any subsequent processing will be skipped and supplied -- Response value will be returned from runSnap as-is. -- --
    --
  1. access to the IO monad through a MonadIO -- instance:
  2. --
-- --
--   a :: Snap ()
--   a = liftIO fireTheMissiles
--   
-- --
    --
  1. the ability to set a timeout which will kill the handler thread -- after N seconds of inactivity (the default is 20 -- seconds):
  2. --
-- --
--   a :: Snap ()
--   a = setTimeout 30
--   
-- --
    --
  1. throw and catch exceptions using a MonadCatchIO -- instance:
  2. --
-- --
--   foo :: Snap ()
--   foo = bar `catch` \(e::SomeException) -> baz
--     where
--       bar = throw FooException
--   
-- --
    --
  1. log a message to the error log:
  2. --
-- --
--   foo :: Snap ()
--   foo = logError "grumble."
--   
-- -- You may notice that most of the type signatures in this module contain -- a (MonadSnap m) => ... typeclass constraint. -- MonadSnap is a typeclass which, in essence, says "you can get -- back to the Snap monad from here". Using MonadSnap you -- can extend the Snap monad with additional functionality and -- still have access to most of the Snap functions without writing -- lift everywhere. Instances are already provided for most of the -- common monad transformers (ReaderT, WriterT, -- StateT, etc.). -- -- MonadSnap is a type class, analogous to MonadIO for -- IO, that makes it easy to wrap Snap inside monad -- transformers. class (Monad m, MonadIO m, MonadCatchIO m, MonadPlus m, Functor m, Applicative m, Alternative m) => MonadSnap m liftSnap :: MonadSnap m => Snap a -> m a -- | This exception is thrown if the handler you supply to runSnap -- fails. data NoHandlerException NoHandlerException :: String -> NoHandlerException -- | This is exception is thrown if the handler chooses to escape regular -- HTTP traffic. data EscapeHttpException EscapeHttpException :: ((Int -> IO ()) -> Iteratee ByteString IO () -> Iteratee ByteString IO ()) -> EscapeHttpException -- | This function brackets a Snap action in resource acquisition and -- release. This is provided because MonadCatchIO's bracket -- function doesn't work properly in the case of a short-circuit return -- from the action being bracketed. -- -- In order to prevent confusion regarding the effects of the aquisition -- and release actions on the Snap state, this function doesn't accept -- Snap actions for the acquire or release actions. -- -- This function will run the release action in all cases where the -- acquire action succeeded. This includes the following behaviors from -- the bracketed Snap action. -- --
    --
  1. Normal completion
  2. --
  3. Short-circuit completion, either from calling fail or -- finishWith
  4. --
  5. An exception being thrown.
  6. --
bracketSnap :: IO a -> (a -> IO b) -> (a -> Snap c) -> Snap c -- | Short-circuits a Snap monad action early, storing the given -- Response value in its state. finishWith :: MonadSnap m => Response -> m a -- | Capture the flow of control in case a handler calls finishWith. -- -- WARNING: in the event of a call to transformRequestBody -- it is possible to violate HTTP protocol safety when using this -- function. If you call catchFinishWith it is suggested that you -- do not modify the body of the Response which was passed to the -- finishWith call. catchFinishWith :: Snap a -> Snap (Either Response a) -- | Fails out of a Snap monad action. This is used to indicate that -- you choose not to handle the given request within the given handler. pass :: MonadSnap m => m a -- | Terminate the HTTP session with the given exception. terminateConnection :: (Exception e, MonadCatchIO m) => e -> m a -- | Terminate the HTTP session and hand control to some external handler, -- escaping all further HTTP traffic. -- -- The external handler takes two arguments: a function to tickle the -- timeout manager, and a write end to the socket. escapeHttp :: MonadCatchIO m => ((Int -> IO ()) -> Iteratee ByteString IO () -> Iteratee ByteString IO ()) -> m () -- | Runs a Snap monad action only if the request's HTTP method -- matches the given method. method :: MonadSnap m => Method -> m a -> m a -- | Runs a Snap monad action only if the request's HTTP method -- matches one of the given methods. methods :: MonadSnap m => [Method] -> m a -> m a -- | Runs a Snap monad action only for requests where -- rqPathInfo is exactly equal to the given string. If the path -- matches, locally sets rqContextPath to the old value of -- rqPathInfo, sets rqPathInfo="", and runs the given -- handler. path :: MonadSnap m => ByteString -> m a -> m a -- | Runs a Snap monad action only when the first path component is -- successfully parsed as the argument to the supplied handler function. pathArg :: (Readable a, MonadSnap m) => (a -> m b) -> m b -- | Runs a Snap monad action only when the rqPathInfo of the -- request starts with the given path. For example, -- --
--   dir "foo" handler
--   
-- -- Will fail if rqPathInfo is not "/foo" or -- "/foo/...", and will add "foo/" to the handler's -- local rqContextPath. dir :: MonadSnap m => ByteString -> m a -> m a -- | Runs a Snap monad action only when rqPathInfo is empty. ifTop :: MonadSnap m => m a -> m a -- | A web handler which, given a mapping from URL entry points to web -- handlers, efficiently routes requests to the correct handler. -- -- The URL entry points are given as relative paths, for example: -- --
--   route [ ("foo/bar/quux", fooBarQuux) ]
--   
-- -- If the URI of the incoming request is -- --
--   /foo/bar/quux
--   
-- -- or -- --
--   /foo/bar/quux/...anything...
--   
-- -- then the request will be routed to "fooBarQuux", with -- rqContextPath set to "/foo/bar/quux/" and -- rqPathInfo set to "...anything...". -- -- A path component within an URL entry point beginning with a colon -- (":") is treated as a variable capture; the -- corresponding path component within the request URI will be entered -- into the rqParams parameters mapping with the given name. For -- instance, if the routes were: -- --
--   route [ ("foo/:bar/baz", fooBazHandler) ]
--   
-- -- Then a request for "/foo/saskatchewan/baz" would be routed to -- fooBazHandler with a mapping for: -- --
--   "bar" => "saskatchewan"
--   
-- -- in its parameters table. -- -- Longer paths are matched first, and specific routes are matched before -- captures. That is, if given routes: -- --
--   [ ("a", h1), ("a/b", h2), ("a/:x", h3) ]
--   
-- -- a request for "/a/b" will go to h2, "/a/s" -- for any s will go to h3, and "/a" will go to -- h1. -- -- The following example matches "/article" to an article index, -- "/login" to a login, and "/article/..." to an -- article renderer. -- --
--   route [ ("article",     renderIndex)
--         , ("article/:id", renderArticle)
--         , ("login",       method POST doLogin) ]
--   
-- -- URL decoding -- -- A short note about URL decoding: path matching and variable capture -- are done on decoded URLs, but the contents of -- rqContextPath and rqPathInfo will contain the original -- encoded URL, i.e. what the user entered. For example, in the following -- scenario: -- --
--   route [ ("a b c d/", foo ) ]
--   
-- -- A request for "/a+b+c+d" will be sent to foo with -- rqContextPath set to "a+b+c+d". -- -- This behaviour changed as of Snap 0.6.1; previous versions had -- unspecified (and buggy!) semantics here. route :: MonadSnap m => [(ByteString, m a)] -> m a -- | The routeLocal function is the same as route', except it -- doesn't change the request's context path. This is useful if you want -- to route to a particular handler but you want that handler to receive -- the rqPathInfo as it is. routeLocal :: MonadSnap m => [(ByteString, m a)] -> m a -- | Grabs the Request object out of the Snap monad. getRequest :: MonadSnap m => m Request -- | Grabs something out of the Request object, using the given -- projection function. See gets. getsRequest :: MonadSnap m => (Request -> a) -> m a -- | Grabs the Response object out of the Snap monad. getResponse :: MonadSnap m => m Response -- | Grabs something out of the Response object, using the given -- projection function. See gets. getsResponse :: MonadSnap m => (Response -> a) -> m a -- | Puts a new Request object into the Snap monad. putRequest :: MonadSnap m => Request -> m () -- | Puts a new Response object into the Snap monad. putResponse :: MonadSnap m => Response -> m () -- | Modifies the Request object stored in a Snap monad. modifyRequest :: MonadSnap m => (Request -> Request) -> m () -- | Modifes the Response object stored in a Snap monad. modifyResponse :: MonadSnap m => (Response -> Response) -> m () -- | Runs a Snap action with a locally-modified Request state -- object. The Request object in the Snap monad state after the -- call to localRequest will be unchanged. localRequest :: MonadSnap m => (Request -> Request) -> m a -> m a -- | Fetches the Request from state and hands it to the given -- action. withRequest :: MonadSnap m => (Request -> m a) -> m a -- | Fetches the Response from state and hands it to the given -- action. withResponse :: MonadSnap m => (Response -> m a) -> m a -- | Log an error message in the Snap monad logError :: MonadSnap m => ByteString -> m () -- | Sends the request body through an iteratee (data consumer) and returns -- the result. -- -- If the iteratee you pass in here throws an exception, Snap will -- attempt to clear the rest of the unread request body before rethrowing -- the exception. If your iteratee used terminateConnection, -- however, Snap will give up and immediately close the socket. runRequestBody :: MonadSnap m => Iteratee ByteString IO a -> m a -- | Returns the request body as a lazy bytestring. -- -- This function is deprecated as of 0.6; it places no limits on the size -- of the request being read, and as such, if used, can result in a -- denial-of-service attack on your server. Please use -- readRequestBody instead. getRequestBody :: MonadSnap m => m ByteString -- | Returns the request body as a lazy bytestring. New in 0.6. readRequestBody :: MonadSnap m => Int64 -> m ByteString -- | Normally Snap is careful to ensure that the request body is fully -- consumed after your web handler runs, but before the Response -- enumerator is streamed out the socket. If you want to transform the -- request body into some output in O(1) space, you should use this -- function. -- -- Note that upon calling this function, response processing finishes -- early as if you called finishWith. Make sure you set any -- content types, headers, cookies, etc. before you call this function. transformRequestBody :: (forall a. Enumerator Builder IO a) -> Snap () -- | Contains all of the information about an incoming HTTP request. data Request -- | Represents an HTTP response. data Response data Headers -- | A typeclass for datatypes which contain HTTP headers. class HasHeaders a updateHeaders :: HasHeaders a => (Headers -> Headers) -> a -> a headers :: HasHeaders a => a -> Headers -- | A type alias for the HTTP parameters mapping. Each parameter key maps -- to a list of ByteString values; if a parameter is specified multiple -- times (e.g.: "GET /foo?param=bar1&param=bar2"), looking -- up "param" in the mapping will give you ["bar1", -- "bar2"]. type Params = Map ByteString [ByteString] -- | Enumerates the HTTP method values (see -- http://tools.ietf.org/html/rfc2068.html#section-5.1.1). data Method GET :: Method HEAD :: Method POST :: Method PUT :: Method DELETE :: Method TRACE :: Method OPTIONS :: Method CONNECT :: Method -- | A datatype representing an HTTP cookie. data Cookie Cookie :: !ByteString -> !ByteString -> !Maybe UTCTime -> !Maybe ByteString -> !Maybe ByteString -> !Bool -> !Bool -> Cookie -- | The name of the cookie. cookieName :: Cookie -> !ByteString -- | The cookie's string value. cookieValue :: Cookie -> !ByteString -- | The cookie's expiration value, if it has one. cookieExpires :: Cookie -> !Maybe UTCTime -- | The cookie's "domain" value, if it has one. cookieDomain :: Cookie -> !Maybe ByteString -- | The cookie path. cookiePath :: Cookie -> !Maybe ByteString -- | Tag as secure cookie? cookieSecure :: Cookie -> !Bool -- | HttpOnly? cookieHttpOnly :: Cookie -> !Bool type HttpVersion = (Int, Int) -- | Adds a header key-value-pair to the HasHeaders datatype. If a -- header with the same name already exists, the new value is appended to -- the headers list. addHeader :: HasHeaders a => CI ByteString -> ByteString -> a -> a -- | Sets a header key-value-pair in a HasHeaders datatype. If a -- header with the same name already exists, it is overwritten with the -- new value. setHeader :: HasHeaders a => CI ByteString -> ByteString -> a -> a -- | Gets a header value out of a HasHeaders datatype. If many -- headers came in with the same name, they will be catenated together. getHeader :: HasHeaders a => CI ByteString -> a -> Maybe ByteString -- | Gets all of the values for a given header. getHeaders :: HasHeaders a => CI ByteString -> a -> Maybe [ByteString] -- | Lists all the headers out of a HasHeaders datatype. If many -- headers came in with the same name, they will be catenated together. listHeaders :: HasHeaders a => a -> [(CI ByteString, ByteString)] -- | Clears a header value from a HasHeaders datatype. deleteHeader :: HasHeaders a => CI ByteString -> a -> a -- | Modifies the Request in the state to set the -- rqRemoteAddr field to the value in the X-Forwarded-For header. -- If the header is not present, this action has no effect. -- -- This action should be used only when working behind a reverse http -- proxy that sets the X-Forwarded-For header. This is the only way to -- ensure the value in the X-Forwarded-For header can be trusted. -- -- This is provided as a filter so actions that require the remote -- address can get it in a uniform manner. It has specifically limited -- functionality to ensure that its transformation can be trusted, when -- used correctly. ipHeaderFilter :: MonadSnap m => m () -- | Modifies the Request in the state to set the -- rqRemoteAddr field to the value from the header specified. If -- the header specified is not present, this action has no effect. -- -- This action should be used only when working behind a reverse http -- proxy that sets the header being looked at. This is the only way to -- ensure the value in the header can be trusted. -- -- This is provided as a filter so actions that require the remote -- address can get it in a uniform manner. It has specifically limited -- functionality to ensure that its transformation can be trusted, when -- used correctly. ipHeaderFilter' :: MonadSnap m => CI ByteString -> m () -- | The server name of the request, as it came in from the request's -- Host: header. rqServerName :: Request -> ByteString -- | Returns the port number the HTTP server is listening on. rqServerPort :: Request -> Int -- | The remote IP address. rqRemoteAddr :: Request -> ByteString -- | The remote TCP port number. rqRemotePort :: Request -> Int -- | The local IP address for this request. rqLocalAddr :: Request -> ByteString -- | Returns the HTTP server's idea of its local hostname. rqLocalHostname :: Request -> ByteString -- | Returns True if this is an HTTPS session. rqIsSecure :: Request -> Bool -- | Returns the Content-Length of the HTTP request body. rqContentLength :: Request -> (Maybe Int) -- | Returns the HTTP request method. rqMethod :: Request -> Method -- | Returns the HTTP version used by the client. rqVersion :: Request -> HttpVersion -- | Returns a list of the cookies that came in from the HTTP request -- headers. rqCookies :: Request -> [Cookie] -- | Handlers can (will be; --ed) be hung on a URI "entry -- point"; this is called the "context path". If a handler is hung on the -- context path "/foo/", and you request "/foo/bar", -- the value of rqPathInfo will be "bar". rqPathInfo :: Request -> ByteString -- | The "context path" of the request; catenating rqContextPath, -- and rqPathInfo should get you back to the original rqURI -- (ignoring query strings). The rqContextPath always begins and -- ends with a slash ("/") character, and represents the path -- (relative to your component/snaplet) you took to get to your handler. rqContextPath :: Request -> ByteString -- | Returns the URI requested by the client. rqURI :: Request -> ByteString -- | Returns the HTTP query string for this Request. rqQueryString :: Request -> ByteString -- | Returns the Params mapping for this Request. -- "Parameters" are automatically decoded from the query string and -- POST body and entered into this mapping. rqParams :: Request -> Params -- | Looks up the value(s) for the given named parameter. Parameters -- initially come from the request's query string and any decoded POST -- body (if the request's Content-Type is -- application/x-www-form-urlencoded). Parameter values can be -- modified within handlers using rqModifyParams. rqParam :: ByteString -> Request -> Maybe [ByteString] -- | See rqParam. Looks up a value for the given named parameter in -- the Request. If more than one value was entered for the given -- parameter name, getParam gloms the values together with: -- --
--   intercalate " "
--   
getParam :: MonadSnap m => ByteString -> m (Maybe ByteString) -- | See rqParams. Convenience function to return Params from -- the Request inside of a MonadSnap instance. getParams :: MonadSnap m => m Params -- | Modifies the parameters mapping (which is a Map ByteString -- ByteString) in a Request using the given function. rqModifyParams :: (Params -> Params) -> Request -> Request -- | Writes a key-value pair to the parameters mapping within the given -- request. rqSetParam :: ByteString -> [ByteString] -> Request -> Request -- | An empty Response. emptyResponse :: Response -- | Sets the HTTP response code. setResponseCode :: Int -> Response -> Response -- | Sets the HTTP response status. Note: normally you would use -- setResponseCode unless you needed a custom response -- explanation. setResponseStatus :: Int -> ByteString -> Response -> Response -- | Returns the HTTP status code. rspStatus :: Response -> Int -- | Returns the HTTP status explanation string. rspStatusReason :: Response -> ByteString -- | Sets the Content-Type in the Response headers. setContentType :: ByteString -> Response -> Response -- | Adds an HTTP Cookie to Response headers. addResponseCookie :: Cookie -> Response -> Response -- | Gets an HTTP Cookie with the given name from Response -- headers. getResponseCookie :: ByteString -> Response -> Maybe Cookie -- | Returns a list of Cookies present in Response getResponseCookies :: Response -> [Cookie] -- | Deletes an HTTP Cookie from the Response headers. Please -- note this does not necessarily erase the cookie from the client -- browser. deleteResponseCookie :: ByteString -> Response -> Response -- | Modifies an HTTP Cookie with given name in Response -- headers. Nothing will happen if a matching Cookie can not be -- found in Response. modifyResponseCookie :: ByteString -> (Cookie -> Cookie) -> Response -> Response -- | Expire the given Cookie in client's browser. expireCookie :: MonadSnap m => ByteString -> Maybe ByteString -> m () -- | Gets the HTTP Cookie with the specified name. getCookie :: MonadSnap m => ByteString -> m (Maybe Cookie) -- | Gets the HTTP Cookie with the specified name and decodes it. If -- the decoding fails, the handler calls pass. readCookie :: (MonadSnap m, Readable a) => ByteString -> m a -- | A note here: if you want to set the Content-Length for the -- response, Snap forces you to do it with this function rather than by -- setting it in the headers; the Content-Length in the headers -- will be ignored. -- -- The reason for this is that Snap needs to look up the value of -- Content-Length for each request, and looking the string value -- up in the headers and parsing the number out of the text will be too -- expensive. -- -- If you don't set a content length in your response, HTTP keep-alive -- will be disabled for HTTP/1.0 clients, forcing a Connection: -- close. For HTTP/1.1 clients, Snap will switch to the chunked -- transfer encoding if Content-Length is not specified. setContentLength :: Int64 -> Response -> Response -- | Removes any Content-Length set in the Response. clearContentLength :: Response -> Response -- | Performs a redirect by setting the Location header to the -- given target URL/path and the status code to 302 in the -- Response object stored in a Snap monad. Note that the -- target URL is not validated in any way. Consider using 'redirect\'' -- instead, which allows you to choose the correct status code. redirect :: MonadSnap m => ByteString -> m a -- | Performs a redirect by setting the Location header to the -- given target URL/path and the status code (should be one of 301, 302, -- 303 or 307) in the Response object stored in a Snap -- monad. Note that the target URL is not validated in any way. redirect' :: MonadSnap m => ByteString -> Int -> m a -- | Sets an HTTP response body to the given Enumerator value. setResponseBody :: (forall a. Enumerator Builder IO a) -> Response -> Response -- | Modifies a response body. modifyResponseBody :: (forall a. Enumerator Builder IO a -> Enumerator Builder IO a) -> Response -> Response -- | Adds the output from the given enumerator to the Response -- stored in the Snap monad state. addToOutput :: MonadSnap m => (forall a. Enumerator Builder IO a) -> m () -- | Adds the given Builder to the body of the Response -- stored in the | Snap monad state. writeBuilder :: MonadSnap m => Builder -> m () -- | Adds the given strict ByteString to the body of the -- Response stored in the Snap monad state. -- -- Warning: This function is intentionally non-strict. If any pure -- exceptions are raised by the expression creating the -- ByteString, the exception won't actually be raised within the -- Snap handler. writeBS :: MonadSnap m => ByteString -> m () -- | Adds the given lazy Text to the body of the Response -- stored in the Snap monad state. -- -- Warning: This function is intentionally non-strict. If any pure -- exceptions are raised by the expression creating the -- ByteString, the exception won't actually be raised within the -- Snap handler. writeLazyText :: MonadSnap m => Text -> m () -- | Adds the given strict Text to the body of the Response -- stored in the Snap monad state. -- -- Warning: This function is intentionally non-strict. If any pure -- exceptions are raised by the expression creating the -- ByteString, the exception won't actually be raised within the -- Snap handler. writeText :: MonadSnap m => Text -> m () -- | Adds the given lazy ByteString to the body of the -- Response stored in the Snap monad state. -- -- Warning: This function is intentionally non-strict. If any pure -- exceptions are raised by the expression creating the -- ByteString, the exception won't actually be raised within the -- Snap handler. writeLBS :: MonadSnap m => ByteString -> m () -- | Sets the output to be the contents of the specified file. -- -- Calling sendFile will overwrite any output queued to be sent in -- the Response. If the response body is not modified after the -- call to sendFile, Snap will use the efficient -- sendfile() system call on platforms that support it. -- -- If the response body is modified (using modifyResponseBody), -- the file will be read using mmap(). sendFile :: MonadSnap m => FilePath -> m () -- | Sets the output to be the contents of the specified file, within the -- given (start,end) range. -- -- Calling sendFilePartial will overwrite any output queued to be -- sent in the Response. If the response body is not modified -- after the call to sendFilePartial, Snap will use the efficient -- sendfile() system call on platforms that support it. -- -- If the response body is modified (using modifyResponseBody), -- the file will be read using mmap(). sendFilePartial :: MonadSnap m => FilePath -> (Int64, Int64) -> m () -- | Causes the handler thread to be killed n seconds from now. setTimeout :: MonadSnap m => Int -> m () -- | Returns an IO action which you can use to reset the handling -- thread's timeout value. getTimeoutAction :: MonadSnap m => m (Int -> IO ()) -- | Enumerators are sources of data, to be consumed by iteratees. -- Enumerators typically read from an external source (parser, handle, -- random generator, etc), then feed chunks into an tteratee until: -- -- type Enumerator a m :: (* -> *) b = Step a m b -> Iteratee a m b -- | An existential wrapper for the 'Enumerator ByteString IO a' type newtype SomeEnumerator SomeEnumerator :: (forall a. Enumerator ByteString IO a) -> SomeEnumerator -- | Converts a CTime into an HTTP timestamp. formatHttpTime :: CTime -> IO ByteString -- | Converts an HTTP timestamp into a CTime. parseHttpTime :: ByteString -> IO CTime -- | Parses a string encoded in application/x-www-form-urlencoded -- format. parseUrlEncoded :: ByteString -> Map ByteString [ByteString] buildUrlEncoded :: Map ByteString [ByteString] -> Builder printUrlEncoded :: Map ByteString [ByteString] -> ByteString -- | URL-escapes a string (see -- http://tools.ietf.org/html/rfc2396.html#section-2.4) urlEncode :: ByteString -> ByteString -- | URL-escapes a string (see -- http://tools.ietf.org/html/rfc2396.html#section-2.4) into a -- Builder. urlEncodeBuilder :: ByteString -> Builder -- | Decodes an URL-escaped string (see -- http://tools.ietf.org/html/rfc2396.html#section-2.4) urlDecode :: ByteString -> Maybe ByteString -- | As of Snap 0.6, the Snap.Types module is deprecated: please use -- Snap.Core instead. module Snap.Types -- | The Snap.Test module contains primitives and combinators for testing -- Snap applications. module Snap.Test -- | RequestBuilder is a monad transformer that allows you to conveniently -- build a snap Request for testing. data RequestBuilder m a -- | A request body of type "multipart/form-data" consists of a -- set of named form parameters, each of which can by either a list of -- regular form values or a set of file uploads. type MultipartParams = [(ByteString, MultipartParam)] data MultipartParam -- | a form variable consisting of the given ByteString values. FormData :: [ByteString] -> MultipartParam -- | a file upload consisting of the given FileData values. Files :: [FileData] -> MultipartParam data FileData FileData :: ByteString -> ByteString -> ByteString -> FileData -- | the file's name fdFileName :: FileData -> ByteString -- | the file's content-type fdContentType :: FileData -> ByteString -- | the file contents fdContents :: FileData -> ByteString -- | The RequestType datatype enumerates the different kinds of HTTP -- requests you can generate using the testing interface. Most users will -- prefer to use the get, postUrlEncoded, -- postMultipart, put, and delete convenience -- functions. data RequestType GetRequest :: RequestType RequestWithRawBody :: Method -> ByteString -> RequestType MultipartPostRequest :: MultipartParams -> RequestType UrlEncodedPostRequest :: Params -> RequestType DeleteRequest :: RequestType -- | Runs a RequestBuilder, producing the desired Request. buildRequest :: MonadIO m => RequestBuilder m () -> m Request -- | Given a web handler in the Snap monad, and a -- RequestBuilder defining a test request, runs the handler, -- producing an HTTP Response. runHandler :: MonadIO m => RequestBuilder m () -> Snap a -> m Response -- | Builds an HTTP "GET" request with the given query parameters. get :: MonadIO m => ByteString -> Params -> RequestBuilder m () -- | Builds an HTTP "POST" request with the given form parameters, using -- the "application/x-www-form-urlencoded" MIME type. postUrlEncoded :: MonadIO m => ByteString -> Params -> RequestBuilder m () -- | Builds an HTTP "POST" request with the given form parameters, using -- the "form-data/multipart" MIME type. postMultipart :: MonadIO m => ByteString -> MultipartParams -> RequestBuilder m () -- | Builds an HTTP "PUT" request. put :: MonadIO m => ByteString -> ByteString -> ByteString -> RequestBuilder m () -- | Builds a "raw" HTTP "POST" request, with the given MIME type and body -- contents. postRaw :: MonadIO m => ByteString -> ByteString -> ByteString -> RequestBuilder m () -- | Builds an HTTP "DELETE" request with the given query parameters. delete :: MonadIO m => ByteString -> Params -> RequestBuilder m () -- | Adds the given header to the request being built. addHeader :: Monad m => CI ByteString -> ByteString -> RequestBuilder m () -- | Sets the request's content-type to the given MIME type. setContentType :: Monad m => ByteString -> RequestBuilder m () -- | Sets the given header in the request being built, overwriting any -- header with the same name already present. setHeader :: Monad m => CI ByteString -> ByteString -> RequestBuilder m () -- | Sets the test request's http version setHttpVersion :: Monad m => (Int, Int) -> RequestBuilder m () -- | Escapes the given parameter mapping and sets it as the request's query -- string. setQueryString :: Monad m => Params -> RequestBuilder m () -- | Sets the request's query string to be the raw bytestring provided, -- without any escaping or other interpretation. Most users should -- instead choose the setQueryString function, which takes a -- parameter mapping. setQueryStringRaw :: Monad m => ByteString -> RequestBuilder m () -- | Sets the request's path. The path provided must begin with a -- "/" and must not contain a query string; if you want -- to provide a query string in your test request, you must use -- setQueryString or setQueryStringRaw. Note that -- rqContextPath is never set by any RequestBuilder -- function. setRequestPath :: Monad m => ByteString -> RequestBuilder m () -- | Sets the type of the Request being built. setRequestType :: MonadIO m => RequestType -> RequestBuilder m () -- | Controls whether the test request being generated appears to be an -- https request or not. setSecure :: Monad m => Bool -> RequestBuilder m () -- | Given a Response, asserts that its HTTP status code is 200 (success). assertSuccess :: Response -> Assertion -- | Given a Response, asserts that its HTTP status code is 404 (Not -- Found). assert404 :: Response -> Assertion -- | Given a Response, asserts that its HTTP status code is between 300 and -- 399 (a redirect), and that the Location header of the Response points -- to the specified URI. assertRedirectTo :: ByteString -> Response -> Assertion -- | Given a Response, asserts that its HTTP status code is between 300 and -- 399 (a redirect). assertRedirect :: Response -> Assertion -- | Given a Response, asserts that its body matches the given regular -- expression. assertBodyContains :: ByteString -> Response -> Assertion getResponseBody :: Response -> IO ByteString -- | Dumps the given response to stdout. dumpResponse :: Response -> IO () -- | Converts the given response to a bytestring. responseToString :: Response -> IO ByteString -- | Contains web handlers to serve files from a directory. module Snap.Util.FileServe -- | Gets a path from the Request using rqPathInfo and makes -- sure it is safe to use for opening files. A path is safe if it is a -- relative path and has no .. elements to escape the intended -- directory structure. getSafePath :: MonadSnap m => m FilePath -- | A type alias for MIME type type MimeMap = Map FilePath ByteString -- | A type alias for dynamic handlers type HandlerMap m = Map FilePath (FilePath -> m ()) -- | A collection of options for serving static files out of a directory. data DirectoryConfig m DirectoryConfig :: [FilePath] -> (FilePath -> m ()) -> HandlerMap m -> MimeMap -> (FilePath -> m ()) -> DirectoryConfig m -- | Files to look for when a directory is requested (e.g., index.html) indexFiles :: DirectoryConfig m -> [FilePath] -- | Handler to generate a directory listing if there is no index. indexGenerator :: DirectoryConfig m -> FilePath -> m () -- | Map of extensions to pass to dynamic file handlers. This could be -- used, for example, to implement CGI dispatch, pretty printing of -- source code, etc. dynamicHandlers :: DirectoryConfig m -> HandlerMap m -- | MIME type map to look up content types. mimeTypes :: DirectoryConfig m -> MimeMap -- | Handler that is called before a file is served. It will only be called -- when a file is actually found, not for generated index pages. preServeHook :: DirectoryConfig m -> FilePath -> m () -- | A very simple configuration for directory serving. This configuration -- uses built-in MIME types from defaultMimeTypes, and has no -- index files, index generator, dynamic file handlers, or -- preServeHook. simpleDirectoryConfig :: MonadSnap m => DirectoryConfig m -- | A reasonable default configuration for directory serving. This -- configuration uses built-in MIME types from defaultMimeTypes, -- serves common index files index.html and index.htm, -- but does not autogenerate directory indexes, nor have any dynamic file -- handlers. The preServeHook will not do anything. defaultDirectoryConfig :: MonadSnap m => DirectoryConfig m -- | A more elaborate configuration for file serving. This configuration -- uses built-in MIME types from defaultMimeTypes, serves common -- index files index.html and index.htm, and -- autogenerates directory indexes with a Snap-like feel. It still has no -- dynamic file handlers, nor preServeHook, which should be added -- as needed. -- -- Files recognized as indexes include index.html, -- index.htm, default.html, default.htm, -- home.html fancyDirectoryConfig :: MonadSnap m => DirectoryConfig m -- | An automatic index generator, which is fairly small and does not rely -- on any external files (which may not be there depending on external -- request routing). -- -- A MimeMap is passed in to display the types of files in the -- directory listing based on their extension. Preferably, this is the -- same as the map in the DirectoryConfig -- -- The styles parameter allows you to apply styles to the directory -- listing. The listing itself consists of a table, containing a header -- row using th elements, and one row per file using td elements, so -- styles for those pieces may be attached to the appropriate tags. defaultIndexGenerator :: MonadSnap m => MimeMap -> ByteString -> FilePath -> m () -- | The default set of mime type mappings we use when serving files. Its -- value: -- --
--   Map.fromList [
--     ( ".asc"     , "text/plain"                        ),
--     ( ".asf"     , "video/x-ms-asf"                    ),
--     ( ".asx"     , "video/x-ms-asf"                    ),
--     ( ".avi"     , "video/x-msvideo"                   ),
--     ( ".bz2"     , "application/x-bzip"                ),
--     ( ".c"       , "text/plain"                        ),
--     ( ".class"   , "application/octet-stream"          ),
--     ( ".conf"    , "text/plain"                        ),
--     ( ".cpp"     , "text/plain"                        ),
--     ( ".css"     , "text/css"                          ),
--     ( ".cxx"     , "text/plain"                        ),
--     ( ".dtd"     , "text/xml"                          ),
--     ( ".dvi"     , "application/x-dvi"                 ),
--     ( ".gif"     , "image/gif"                         ),
--     ( ".gz"      , "application/x-gzip"                ),
--     ( ".hs"      , "text/plain"                        ),
--     ( ".htm"     , "text/html"                         ),
--     ( ".html"    , "text/html"                         ),
--     ( ".jar"     , "application/x-java-archive"        ),
--     ( ".jpeg"    , "image/jpeg"                        ),
--     ( ".jpg"     , "image/jpeg"                        ),
--     ( ".js"      , "text/javascript"                   ),
--     ( ".json"    , "application/json"                  ),
--     ( ".log"     , "text/plain"                        ),
--     ( ".m3u"     , "audio/x-mpegurl"                   ),
--     ( ".mov"     , "video/quicktime"                   ),
--     ( ".mp3"     , "audio/mpeg"                        ),
--     ( ".mpeg"    , "video/mpeg"                        ),
--     ( ".mpg"     , "video/mpeg"                        ),
--     ( ".ogg"     , "application/ogg"                   ),
--     ( ".pac"     , "application/x-ns-proxy-autoconfig" ),
--     ( ".pdf"     , "application/pdf"                   ),
--     ( ".png"     , "image/png"                         ),
--     ( ".ps"      , "application/postscript"            ),
--     ( ".qt"      , "video/quicktime"                   ),
--     ( ".sig"     , "application/pgp-signature"         ),
--     ( ".spl"     , "application/futuresplash"          ),
--     ( ".svg"     , "image/svg+xml"                     ),
--     ( ".swf"     , "application/x-shockwave-flash"     ),
--     ( ".tar"     , "application/x-tar"                 ),
--     ( ".tar.bz2" , "application/x-bzip-compressed-tar" ),
--     ( ".tar.gz"  , "application/x-tgz"                 ),
--     ( ".tbz"     , "application/x-bzip-compressed-tar" ),
--     ( ".text"    , "text/plain"                        ),
--     ( ".tgz"     , "application/x-tgz"                 ),
--     ( ".torrent" , "application/x-bittorrent"          ),
--     ( ".txt"     , "text/plain"                        ),
--     ( ".wav"     , "audio/x-wav"                       ),
--     ( ".wax"     , "audio/x-ms-wax"                    ),
--     ( ".wma"     , "audio/x-ms-wma"                    ),
--     ( ".wmv"     , "video/x-ms-wmv"                    ),
--     ( ".xbm"     , "image/x-xbitmap"                   ),
--     ( ".xml"     , "text/xml"                          ),
--     ( ".xpm"     , "image/x-xpixmap"                   ),
--     ( ".xwd"     , "image/x-xwindowdump"               ),
--     ( ".zip"     , "application/zip"                   ) ]
--   
defaultMimeTypes :: MimeMap fileType :: MimeMap -> FilePath -> ByteString -- | Serves static files from a directory using the default configuration -- as given in defaultDirectoryConfig. serveDirectory :: MonadSnap m => FilePath -> m () -- | Serves static files from a directory. Configuration options are passed -- in a DirectoryConfig that captures various choices about -- desired behavior. The relative path given in rqPathInfo is -- searched for a requested file, and the file is served with the -- appropriate mime type if it is found. Absolute paths and ".." -- are prohibited to prevent files from being served from outside the -- sandbox. serveDirectoryWith :: MonadSnap m => DirectoryConfig m -> FilePath -> m () -- | Serves a single file specified by a full or relative path. If the file -- does not exist, throws an exception (not that it does not pass -- to the next handler). The path restrictions on serveDirectory -- don't apply to this function since the path is not being supplied by -- the user. serveFile :: MonadSnap m => FilePath -> m () -- | Same as serveFile, with control over the MIME mapping used. serveFileAs :: MonadSnap m => ByteString -> FilePath -> m () instance Eq RangeReq instance Show RangeReq -- | This module contains primitives and helper functions for handling -- requests with Content-type: multipart/form-data, i.e. HTML -- forms and file uploads. -- -- Typically most users will want to use handleFileUploads, which -- writes uploaded files to a temporary directory before sending them on -- to a handler specified by the user. -- -- Users who wish to handle their file uploads differently can use the -- lower-level streaming Iteratee interface called -- handleMultipart. That function takes uploaded files and streams -- them to an Iteratee consumer of the user's choosing. -- -- Using these functions requires making "policy" decisions which Snap -- can't really make for users, such as "what's the largest PDF file a -- user is allowed to upload?" and "should we read form inputs into the -- parameters mapping?". Policy is specified on a "global" basis (using -- UploadPolicy), and on a per-file basis (using -- PartUploadPolicy, which allows you to reject or limit the size -- of certain uploaded Content-types). module Snap.Util.FileUploads -- | Reads uploaded files into a temporary directory and calls a user -- handler to process them. -- -- Given a temporary directory, global and file-specific upload policies, -- and a user handler, this function consumes a request body uploaded -- with Content-type: multipart/form-data. Each file is read -- into the temporary directory, and then a list of the uploaded files is -- passed to the user handler. After the user handler runs (but before -- the Response body Enumerator is streamed to the client), -- the files are deleted from disk; so if you want to retain or use the -- uploaded files in the generated response, you would need to move or -- otherwise process them. -- -- The argument passed to the user handler is a list of: -- --
--   (PartInfo, Either PolicyViolationException FilePath)
--   
-- -- The first half of this tuple is a PartInfo, which contains the -- information the client browser sent about the given upload part (like -- filename, content-type, etc). The second half of this tuple is an -- Either stipulating that either: -- --
    --
  1. the file was rejected on a policy basis because of the provided -- PartUploadPolicy handler
  2. --
  3. the file was accepted and exists at the given path.
  4. --
-- -- If the request's Content-type was not -- "multipart/formdata", this function skips processing using -- pass. -- -- If the client's upload rate passes below the configured minimum (see -- setMinimumUploadRate and setMinimumUploadSeconds), this -- function terminates the connection. This setting is there to protect -- the server against slowloris-style denial of service attacks. -- -- If the given UploadPolicy stipulates that you wish form inputs -- to be placed in the rqParams parameter map (using -- setProcessFormInputs), and a form input exceeds the maximum -- allowable size, this function will throw a -- PolicyViolationException. -- -- If an uploaded part contains MIME headers longer than a fixed internal -- threshold (currently 32KB), this function will throw a -- BadPartException. handleFileUploads :: MonadSnap m => FilePath -> UploadPolicy -> (PartInfo -> PartUploadPolicy) -> ([(PartInfo, Either PolicyViolationException FilePath)] -> m a) -> m a -- | Given an upload policy and a function to consume uploaded "parts", -- consume a request body uploaded with Content-type: -- multipart/form-data. Normally most users will want to use -- handleFileUploads (which writes uploaded files to a temporary -- directory and passes their names to a given handler) rather than this -- function; the lower-level handleMultipart function should be -- used if you want to stream uploaded files to your own iteratee -- function. -- -- If the request's Content-type was not -- "multipart/formdata", this function skips processing using -- pass. -- -- If the client's upload rate passes below the configured minimum (see -- setMinimumUploadRate and setMinimumUploadSeconds), this -- function terminates the connection. This setting is there to protect -- the server against slowloris-style denial of service attacks. -- -- If the given UploadPolicy stipulates that you wish form inputs -- to be placed in the rqParams parameter map (using -- setProcessFormInputs), and a form input exceeds the maximum -- allowable size, this function will throw a -- PolicyViolationException. -- -- If an uploaded part contains MIME headers longer than a fixed internal -- threshold (currently 32KB), this function will throw a -- BadPartException. handleMultipart :: MonadSnap m => UploadPolicy -> (PartInfo -> Iteratee ByteString IO a) -> m [a] -- | PartInfo contains information about a "part" in a request -- uploaded with Content-type: multipart/form-data. data PartInfo PartInfo :: !ByteString -> !Maybe ByteString -> !ByteString -> PartInfo partFieldName :: PartInfo -> !ByteString partFileName :: PartInfo -> !Maybe ByteString partContentType :: PartInfo -> !ByteString -- | UploadPolicy controls overall policy decisions relating to -- multipart/form-data uploads, specifically: -- -- data UploadPolicy -- | A reasonable set of defaults for upload policy. The default policy is: -- -- defaultUploadPolicy :: UploadPolicy -- | Does this upload policy stipulate that we want to treat parts without -- filenames as form input? doProcessFormInputs :: UploadPolicy -> Bool -- | Set the upload policy for treating parts without filenames as form -- input. setProcessFormInputs :: Bool -> UploadPolicy -> UploadPolicy -- | Get the maximum size of a form input which will be read into our -- rqParams map. getMaximumFormInputSize :: UploadPolicy -> Int64 -- | Set the maximum size of a form input which will be read into our -- rqParams map. setMaximumFormInputSize :: Int64 -> UploadPolicy -> UploadPolicy -- | Get the minimum rate (in bytes\second/) a client must maintain -- before we kill the connection. getMinimumUploadRate :: UploadPolicy -> Double -- | Set the minimum rate (in bytes\second/) a client must maintain -- before we kill the connection. setMinimumUploadRate :: Double -> UploadPolicy -> UploadPolicy -- | Get the amount of time which must elapse before we begin enforcing the -- upload rate minimum getMinimumUploadSeconds :: UploadPolicy -> Int -- | Set the amount of time which must elapse before we begin enforcing the -- upload rate minimum setMinimumUploadSeconds :: Int -> UploadPolicy -> UploadPolicy -- | Get the "upload timeout". Whenever input is received from the client, -- the connection timeout is set this many seconds in the future. getUploadTimeout :: UploadPolicy -> Int -- | Set the upload timeout. setUploadTimeout :: Int -> UploadPolicy -> UploadPolicy -- | Upload policy can be set on an "general" basis (using -- UploadPolicy), but handlers can also make policy decisions on -- individual files/parts uploaded. For each part uploaded, handlers can -- decide: -- -- data PartUploadPolicy -- | Disallows the file to be uploaded. disallow :: PartUploadPolicy -- | Allows the file to be uploaded, with maximum size n. allowWithMaximumSize :: Int64 -> PartUploadPolicy -- | All of the exceptions defined in this package inherit from -- FileUploadException, so if you write -- --
--   foo `catch` \(e :: FileUploadException) -> ...
--   
-- -- you can catch a BadPartException, a -- PolicyViolationException, etc. data FileUploadException fileUploadExceptionReason :: FileUploadException -> Text data BadPartException badPartExceptionReason :: BadPartException -> Text data PolicyViolationException policyViolationExceptionReason :: PolicyViolationException -> Text instance Typeable FileUploadException instance Typeable BadPartException instance Typeable PolicyViolationException instance Show PartInfo instance Show UploadPolicy instance Eq UploadPolicy instance Show PartUploadPolicy instance Eq PartUploadPolicy instance Show a => Show (Capture a) instance Show PolicyViolationException instance Exception PolicyViolationException instance Show BadPartException instance Exception BadPartException instance Exception FileUploadException instance Show FileUploadException module Snap.Util.GZip -- | Runs a Snap web handler with compression if available. -- -- If the client has indicated support for gzip or -- compress in its Accept-Encoding header, and the -- Content-Type in the response is one of the following types: -- -- -- -- Then the given handler's output stream will be compressed, -- Content-Encoding will be set in the output headers, and the -- Content-Length will be cleared if it was set. (We can't -- process the stream in O(1) space if the length is known beforehand.) -- -- The wrapped handler will be run to completion, and then the -- Response that's contained within the Snap monad state -- will be passed to finishWith to prevent further processing. withCompression :: MonadSnap m => m a -> m () -- | The same as withCompression, with control over which MIME types -- to compress. withCompression' :: MonadSnap m => Set ByteString -> m a -> m () -- | Turn off compression by setting "Content-Encoding: identity" in the -- response headers. noCompression :: MonadSnap m => m () instance Typeable BadAcceptEncodingException instance Exception BadAcceptEncodingException instance Show BadAcceptEncodingException