snap package:snap-core

Snap is the Monad that user web handlers run in. Snap gives you:
  1. Stateful access to fetch or modify an HTTP Request.
    printRqContextPath :: Snap () printRqContextPath =
    writeBS . rqContextPath =<< getRequest
    
  2. Stateful access to fetch or modify an HTTP Response.
    printRspStatusReason :: Snap ()
    printRspStatusReason = writeBS . rspStatusReason
    =<< getResponse 
  3. 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:
    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
    
  4. Convenience functions (writeBS, writeLBS, writeText, writeLazyText, addToOutput) for queueing output to be written to the Response, or for streaming to the response using io-streams:
    example ::
    (OutputStream Builder -> IO (OutputStream
    Builder)) -> Snap () example streamProc = do writeBS
    "I'm a strict bytestring" writeLBS "I'm a lazy bytestring"
    writeText "I'm strict text" addToOutput streamProc
    
  5. Early termination: if you call finishWith:
    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 the supplied Response value will be returned from runSnap as-is.
  6. Access to the IO monad through a MonadIO instance:
    a :: Snap () a = liftIO fireTheMissiles
    
  7. The ability to set or extend a timeout which will kill the handler thread after N seconds of inactivity (the default is 20 seconds):
    a :: Snap () a = setTimeout 30 
  8. Throw and catch exceptions using a MonadBaseControl instance:
    import Control.Exception.Lifted
    (SomeException, throwIO, catch) foo :: Snap ()
    foo = bar `catch` (e::SomeException) -> baz where bar =
    throwIO FooException 
  9. Log a message to the error log:
    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.).
Snap is the Monad that user web handlers run in. Snap gives you:
  1. Stateful access to fetch or modify an HTTP Request.
    printRqContextPath :: Snap () printRqContextPath =
    writeBS . rqContextPath =<< getRequest
    
  2. Stateful access to fetch or modify an HTTP Response.
    printRspStatusReason :: Snap ()
    printRspStatusReason = writeBS . rspStatusReason
    =<< getResponse 
  3. 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:
    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
    
  4. Convenience functions (writeBS, writeLBS, writeText, writeLazyText, addToOutput) for queueing output to be written to the Response, or for streaming to the response using io-streams:
    example ::
    (OutputStream Builder -> IO (OutputStream
    Builder)) -> Snap () example streamProc = do writeBS
    "I'm a strict bytestring" writeLBS "I'm a lazy bytestring"
    writeText "I'm strict text" addToOutput streamProc
    
  5. Early termination: if you call finishWith:
    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 the supplied Response value will be returned from runSnap as-is.
  6. Access to the IO monad through a MonadIO instance:
    a :: Snap () a = liftIO fireTheMissiles
    
  7. The ability to set or extend a timeout which will kill the handler thread after N seconds of inactivity (the default is 20 seconds):
    a :: Snap () a = setTimeout 30 
  8. Throw and catch exceptions using a MonadBaseControl instance:
    import Control.Exception.Lifted
    (SomeException, throwIO, catch) foo :: Snap ()
    foo = bar `catch` (e::SomeException) -> baz where bar =
    throwIO FooException 
  9. Log a message to the error log:
    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.).
Snap: A Haskell Web Framework (core interfaces and types) 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. A monad for programming web handlers called "Snap", which allows:
  • Stateful access to the HTTP request and response objects
  • Monadic failure (i.e. MonadPlus/Alternative instances) for declining to handle requests and chaining handlers together
  • Early termination of the computation if you know early what you want to return and want to prevent further monadic processing
Quick start: The Snap monad and HTTP definitions are in Snap.Core.
Used internally to implement escapeHttp.
MonadSnap is a type class, analogous to MonadIO for IO, that makes it easy to wrap Snap inside monad transformers.
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. Short-circuit completion, either from calling fail or finishWith
  3. An exception being thrown.
Example:
ghci> :set -XOverloadedStrings
ghci> import qualified Data.Map as M
ghci> import qualified Snap.Test as T
ghci> let br = bracketSnap (putStrLn "before") (const $ putStrLn "after")
ghci> T.runHandler (T.get "/" M.empty) (br $ const $ writeBS "OK")
before
after
HTTP/1.1 200 OK
server: Snap/test
date: Thu, 07 Aug 2014 18:41:50 GMT

OK
Lift a computation from the Snap monad.
Runs a Snap monad action. This function is mostly intended for library writers; instead of invoking runSnap directly, use httpServe or runHandler (for testing).
Evaluates a Snap monad action. Unlike runSnap, evalSnap evaluates to the value, not the Response. Like runSnap, evalSnap is intended for library writers. Note that there is no meaningful way of evaluating a Snap monad action that contains pass without alternative (i.e. failure), finishWith (i.e. early termination), or escapeHttp (i.e. escaping Snap). In all of those three cases evalSnap throws an IO exception.