-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | 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
--   <a>http://snapframework.com/</a>.
--   
--   This library contains the core definitions and types for the Snap
--   framework, including:
--   
--   <ol>
--   <li>Primitive types and functions for HTTP (requests, responses,
--   cookies, post/query parameters, etc)</li>
--   <li>Type aliases and helper functions for Iteratee I/O</li>
--   <li>A monad for programming web handlers called "Snap", which
--   allows:</li>
--   </ol>
--   
--   <ul>
--   <li>Stateful access to the HTTP request and response objects</li>
--   <li>Monadic failure (i.e. MonadPlus/Alternative instances) for
--   declining to handle requests and chaining handlers together</li>
--   <li>Early termination of the computation if you know early what you
--   want to return and want to prevent further monadic processing</li>
--   </ul>
--   
--   <i>Quick start</i>: The <a>Snap</a> monad and HTTP definitions are in
--   <a>Snap.Core</a>, some iteratee utilities are in <a>Snap.Iteratee</a>.
@package snap-core
@version 0.9.5.0

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 <a>debug</a> does nothing, but if you set <tt>DEBUG=1</tt> in
--   the environment you'll get debugging messages. We use
--   <tt>unsafePerformIO</tt> to make sure that the call to <tt>getEnv</tt>
--   is only made once.
--   
--   <i>N.B.</i> this is an internal interface, please don't write external
--   code that depends on it.
module Snap.Internal.Debug
debug :: MonadIO m => String -> m ()
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:
--   
--   <pre>
--   import           Snap.Types.Headers (Headers)
--   import qualified Snap.Types.Headers as H
--   
--   foo :: Headers
--   foo = H.empty
--   </pre>
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
--   <tt>Data.Enumerator</tt> in the <tt>enumerator</tt> 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 <a>Iteratee</a>, 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
--   <a>unsafeBufferIterateeWithBuffer</a>.
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 <a>mkIterateeBuffer</a>.
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 <a>Stream</a> is a sequence of chunks generated by an
--   <a>Enumerator</a>.
--   
--   <tt>(<a>Chunks</a> [])</tt> 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 <a>Iteratee</a> is capable of accepting more input. Note that more
--   input is not necessarily required; the <a>Iteratee</a> might be able
--   to generate a value immediately if it receives <a>EOF</a>.
Continue :: (Stream a -> Iteratee a m b) -> Step a b

-- | The <a>Iteratee</a> cannot receive any more input, and has generated a
--   result. Included in this value is left-over input, which can be passed
--   to composed <a>Iteratee</a>s.
Yield :: b -> Stream a -> Step a b

-- | The <a>Iteratee</a> 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: <tt>Iteratee</tt> will become abstract in
--   <tt>enumerator_0.5</tt>. If you depend on internal implementation
--   details, please import <tt><a>Data.Enumerator.Internal</a></tt>.
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:
--   
--   <ul>
--   <li>The input source runs out of data.</li>
--   <li>The iteratee yields a result value.</li>
--   <li>The iteratee throws an exception.</li>
--   </ul>
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 <tt>joinI</tt> and
--   <tt>joinE</tt>, or their operator aliases <tt>(=$)</tt> and
--   <tt>($=)</tt>. 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)

-- | <pre>
--   <a>returnI</a> step = <a>Iteratee</a> (return step)
--   </pre>
returnI :: Monad m => Step a m b -> Iteratee a m b

-- | <pre>
--   <a>yield</a> x extra = <a>returnI</a> (<a>Yield</a> x extra)
--   </pre>
--   
--   WARNING: due to the current encoding of iteratees in this library,
--   careless use of the <a>yield</a> 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 <a>yield</a> to “inject” elements into the stream.
yield :: Monad m => b -> Stream a -> Iteratee a m b

-- | <pre>
--   <a>continue</a> k = <a>returnI</a> (<a>Continue</a> k)
--   </pre>
continue :: Monad m => (Stream a -> Iteratee a m b) -> Iteratee a m b

-- | The moral equivalent of <a>throwIO</a> for iteratees.
throwError :: (Monad m, Exception e) => e -> Iteratee a m b

-- | Runs the iteratee, and calls an exception handler if an <a>Error</a>
--   is returned. By handling errors within the enumerator library, and
--   requiring all errors to be represented by <a>SomeException</a>,
--   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 <tt>catchError</tt> with an
--   appropriate isolation enumeratee, such as
--   <tt>Data.Enumerator.List.isolate</tt> or
--   <tt>Data.Enumerator.Binary.isolate</tt>, 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 <a>continue</a> instead
liftI :: Monad m => (Stream a -> Step a m b) -> Iteratee a m b

-- | The most primitive stream operator. <tt>iter &gt;&gt;== enum</tt>
--   returns a new iteratee which will read from <tt>enum</tt> before
--   continuing.
(>>==) :: Monad m => Iteratee a m b -> (Step a m b -> Iteratee a' m b') -> Iteratee a' m b'

-- | <pre>
--   (<a>==&lt;&lt;</a>) = flip (<a>&gt;&gt;==</a>)
--   </pre>
(==<<) :: Monad m => (Step a m b -> Iteratee a' m b') -> Iteratee a m b -> Iteratee a' m b'

-- | <pre>
--   (<a>$$</a>) = (<a>==&lt;&lt;</a>)
--   </pre>
--   
--   This is somewhat easier to read when constructing an iteratee from
--   many processing stages. You can treat it like <tt>(<a>$</a>)</tt>, 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'

-- | <pre>
--   (<a>&gt;==&gt;</a>) enum1 enum2 step = enum1 step <a>&gt;&gt;==</a> enum2
--   </pre>
--   
--   The moral equivalent of <tt>(<a>&gt;=&gt;</a>)</tt> 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'

-- | <pre>
--   (<a>&lt;==&lt;</a>) = flip (<a>&gt;==&gt;</a>)
--   </pre>
--   
--   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 <i>inner</i> in an enumeratee <i>wrapper</i>.
--   The resulting enumerator will generate <i>wrapper</i>’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):
--   
--   <pre>
--   enumFileCounts :: FilePath -&gt; Enumerator Int IO b
--   </pre>
--   
--   It could be written with either <a>joinE</a> or <tt>($=)</tt>:
--   
--   <pre>
--   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
--   </pre>
--   
--   Compatibility note: in version 0.4.15, the associativity of
--   <tt>($=)</tt> was changed from <tt>infixr 0</tt> to <tt>infixl 1</tt>.
--   
--   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 <i>inner</i> in an enumeratee <i>wrapper</i>. The
--   resulting iteratee will consume <i>wrapper</i>’s input type and yield
--   <i>inner</i>’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 <tt>Text</tt>:
--   
--   <pre>
--   consumeUTF8 :: Monad m =&gt; Iteratee ByteString m Text
--   </pre>
--   
--   It could be written with either <a>joinI</a> or <tt>(=$)</tt>:
--   
--   <pre>
--   import Data.Enumerator.Text as ET
--   
--   consumeUTF8 = joinI (decode utf8 $$ ET.consume)
--   consumeUTF8 = decode utf8 =$ ET.consume
--   </pre>
--   
--   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).
--   
--   <pre>
--   import Data.Enumerator
--   import Data.Enumerator.List as EL
--   
--   main = do
--       result &lt;- run (EL.iterate succ 'A' $$ EL.take 5)
--       case result of
--           Left exc -&gt; putStrLn ("Got an exception: " ++ show exc)
--           Right chars -&gt; putStrLn ("Got characters: " ++ show chars)
--   </pre>
run :: Monad m => Iteratee a m b -> m (Either SomeException b)

-- | Like <a>run</a>, except errors are converted to exceptions and thrown.
--   Primarily useful for small scripts or other simple cases.
--   
--   <pre>
--   import Data.Enumerator
--   import Data.Enumerator.List as EL
--   
--   main = do
--       chars &lt;- run_ (EL.iterate succ 'A' $$ EL.take 5)
--       putStrLn ("Got characters: " ++ show chars)
--   </pre>
--   
--   Since: 0.4.1
run_ :: Monad m => Iteratee a m b -> m b

-- | <pre>
--   <a>consume</a> = <a>takeWhile</a> (const True)
--   </pre>
--   
--   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, <tt>isEOF</tt> may cause data to be read from the enumerator.
isEOF :: Monad m => Iteratee a m Bool

-- | Lift an <a>Iteratee</a> 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 <a>fold</a> instead
--   
--   Since: 0.1.1
liftFoldL :: Monad m => (b -> a -> b) -> b -> Iteratee a m b

-- | Deprecated in 0.4.5: use <a>fold</a> instead
--   
--   Since: 0.1.1
liftFoldL' :: Monad m => (b -> a -> b) -> b -> Iteratee a m b

-- | Deprecated in 0.4.5: use <a>foldM</a> 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 <a>Nothing</a> 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 <a>Nothing</a> if the
--   stream has ended.
peek :: Monad m => Iteratee a m (Maybe a)

-- | Sends <a>EOF</a> to its iteratee. Most clients should use <tt>run</tt>
--   or <tt>run_</tt> instead.
enumEOF :: Monad m => Enumerator a m b

-- | <tt><a>enumList</a> n xs</tt> enumerates <i>xs</i> as a stream,
--   passing <i>n</i> inputs per chunk. This is primarily useful for
--   testing, debugging, and REPL exploration.
--   
--   Compatibility note: In version 0.5, <a>enumList</a> will be changed to
--   the type:
--   
--   <pre>
--   enumList :: Monad m =&gt; [a] -&gt; Enumerator a m b
--   </pre>
enumList :: Monad m => Integer -> [a] -> Enumerator a m b

-- | Compose a list of <a>Enumerator</a>s using
--   <tt>(<a>&gt;==&gt;</a>).</tt>
concatEnums :: Monad m => [Enumerator a m b] -> Enumerator a m b

-- | <pre>
--   <a>checkDone</a> = <a>checkDoneEx</a> (<a>Chunks</a> [])
--   </pre>
--   
--   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

-- | <tt><a>map</a> f</tt> applies <i>f</i> 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 <i>inner</i> in an enumeratee <i>wrapper</i>. The
--   resulting iteratee will consume <i>wrapper</i>’s input type and yield
--   <i>inner</i>’s output type.
--   
--   See the documentation for (<a>=$</a>).
--   
--   <pre>
--   joinI (enum $$ iter) = enum =$ iter
--   </pre>
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.
--   
--   <i>N.B.</i> 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.
--   
--   <i>N.B.</i> 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
--   <a>Snap.Core</a>.
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 <a>HasHeaders</a> 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 <a>HasHeaders</a> 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 <a>HasHeaders</a> 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 <a>HasHeaders</a> 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 <a>HasHeaders</a> datatype.
deleteHeader :: HasHeaders a => CI ByteString -> a -> a

-- | Enumerates the HTTP method values (see
--   <a>http://tools.ietf.org/html/rfc2068.html#section-5.1.1</a>).
data Method
GET :: Method
HEAD :: Method
POST :: Method
PUT :: Method
DELETE :: Method
TRACE :: Method
OPTIONS :: Method
CONNECT :: Method
PATCH :: Method
Method :: ByteString -> 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.: "<tt>GET /foo?param=bar1&amp;param=bar2</tt>"), looking
--   up "<tt>param</tt>" in the mapping will give you <tt>["bar1",
--   "bar2"]</tt>.
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 -> Params -> Params -> Params -> Request

-- | The server name of the request, as it came in from the request's
--   <tt>Host:</tt> 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 <tt>True</tt> if this is an <tt>HTTPS</tt> session.
rqIsSecure :: Request -> Bool
rqHeaders :: Request -> Headers
rqBody :: Request -> !(IORef SomeEnumerator)

-- | Returns the <tt>Content-Length</tt> 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 be hung on a <tt>URI</tt> "entry point"; this is called
--   the "context path". If a handler is hung on the context path
--   <tt>"/foo/"</tt>, and you request <tt>"/foo/bar"</tt>, the value of
--   <a>rqPathInfo</a> will be <tt>"bar"</tt>.
--   
--   The following identity holds:
--   
--   <pre>
--   rqURI r == S.concat [ rqContextPath r
--                       , rqPathInfo r
--                       , let q = rqQueryString r
--                         in if S.null q
--                              then ""
--                              else S.append "?" q
--                       ]
--   </pre>
rqPathInfo :: Request -> !ByteString

-- | The "context path" of the request; catenating <a>rqContextPath</a>,
--   and <a>rqPathInfo</a> should get you back to the original <a>rqURI</a>
--   (ignoring query strings). The <a>rqContextPath</a> always begins and
--   ends with a slash (<tt>"/"</tt>) character, and represents the path
--   (relative to your component/snaplet) you took to get to your handler.
rqContextPath :: Request -> !ByteString

-- | Returns the <tt>URI</tt> requested by the client.
rqURI :: Request -> !ByteString

-- | Returns the HTTP query string for this <a>Request</a>.
rqQueryString :: Request -> !ByteString

-- | Returns the parameters mapping for this <a>Request</a>. "Parameters"
--   are automatically decoded from the URI's query string and
--   <tt>POST</tt> body and entered into this mapping. The <a>rqParams</a>
--   value is thus a union of <a>rqQueryParams</a> and <a>rqPostParams</a>.
rqParams :: Request -> Params

-- | The parameter mapping decoded from the URI's query string.
rqQueryParams :: Request -> Params

-- | The parameter mapping decoded from the POST body. Note that Snap only
--   auto-decodes POST request bodies when the request's
--   <tt>Content-Type</tt> is <tt>application/x-www-form-urlencoded</tt>.
--   For <tt>multipart/form-data</tt> use <a>handleFileUploads</a> to
--   decode the POST request and fill this mapping.
rqPostParams :: Request -> Params
data ResponseBody

-- | output body is a <a>Builder</a> 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 -> !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
--   <tt>transformRequestBody</tt>
rspTransformingRqBody :: Response -> !Bool

-- | Controls whether Snap will buffer the output or not. You may wish to
--   disable buffering when using Comet-like techniques which rely on the
--   immediate sending of output data in order to maintain interactive
--   semantics.
rspOutputBuffering :: 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 <tt>Content-Type</tt> is
--   <tt>application/x-www-form-urlencoded</tt>). Parameter values can be
--   modified within handlers using <a>rqModifyParams</a>.
rqParam :: ByteString -> Request -> Maybe [ByteString]

-- | Looks up the value(s) for the given named parameter in the POST
--   parameters mapping.
rqPostParam :: ByteString -> Request -> Maybe [ByteString]

-- | Looks up the value(s) for the given named parameter in the query
--   parameters mapping.
rqQueryParam :: ByteString -> Request -> Maybe [ByteString]

-- | Modifies the parameters mapping (which is a <tt>Map ByteString
--   ByteString</tt>) in a <a>Request</a> 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 <a>Response</a>.
emptyResponse :: Response

-- | Sets an HTTP response body to the given <a>Enumerator</a> value.
setResponseBody :: (forall a. Enumerator Builder IO a) -> Response -> Response

-- | Sets the HTTP response status. Note: normally you would use
--   <a>setResponseCode</a> 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 <tt>Content-Type</tt> in the <a>Response</a> headers.
setContentType :: ByteString -> Response -> Response

-- | Adds an HTTP <a>Cookie</a> to <a>Response</a> headers.
addResponseCookie :: Cookie -> Response -> Response

-- | Gets an HTTP <a>Cookie</a> with the given name from <a>Response</a>
--   headers.
getResponseCookie :: ByteString -> Response -> Maybe Cookie

-- | Returns a list of <a>Cookie</a>s present in <a>Response</a>
getResponseCookies :: Response -> [Cookie]

-- | Deletes an HTTP <a>Cookie</a> from the <a>Response</a> headers. Please
--   note this does not necessarily erase the cookie from the client
--   browser.
deleteResponseCookie :: ByteString -> Response -> Response

-- | Modifies an HTTP <a>Cookie</a> with given name in <a>Response</a>
--   headers. Nothing will happen if a matching <a>Cookie</a> can not be
--   found in <a>Response</a>.
modifyResponseCookie :: ByteString -> (Cookie -> Cookie) -> Response -> Response

-- | A note here: if you want to set the <tt>Content-Length</tt> for the
--   response, Snap forces you to do it with this function rather than by
--   setting it in the headers; the <tt>Content-Length</tt> in the headers
--   will be ignored.
--   
--   The reason for this is that Snap needs to look up the value of
--   <tt>Content-Length</tt> 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 <tt>Connection:
--   close</tt>. For HTTP/1.1 clients, Snap will switch to the chunked
--   transfer encoding if <tt>Content-Length</tt> is not specified.
setContentLength :: Int64 -> Response -> Response

-- | Removes any <tt>Content-Length</tt> set in the <a>Response</a>.
clearContentLength :: Response -> Response

-- | The buffering mode controls whether Snap will buffer the output or
--   not. You may wish to disable buffering when using Comet-like
--   techniques which rely on the immediate sending of output data in order
--   to maintain interactive semantics.
getBufferingMode :: Response -> Bool

-- | The buffering mode controls whether Snap will buffer the output or
--   not. You may wish to disable buffering when using Comet-like
--   techniques which rely on the immediate sending of output data in order
--   to maintain interactive semantics.
setBufferingMode :: Bool -> Response -> Response

-- | Converts a <a>CTime</a> into an HTTP timestamp.
formatHttpTime :: CTime -> IO ByteString

-- | Converts a <a>CTime</a> into common log entry format.
formatLogTime :: CTime -> IO ByteString

-- | Converts an HTTP timestamp into a <a>CTime</a>.
parseHttpTime :: ByteString -> IO CTime
fromStr :: String -> ByteString
toStr :: ByteString -> String
statusReasonMap :: IntMap ByteString
instance Show Method
instance Read Method
instance Ord Method
instance Eq Cookie
instance Show Cookie
instance HasHeaders Response
instance Show Response
instance HasHeaders Headers
instance HasHeaders Request
instance Show Request
instance Eq Method

module Snap.Internal.Parsing
fullyParse :: ByteString -> Parser a -> Either String a
parseNum :: Parser Int64

-- | Parsers for different tokens in an HTTP request.
sp :: Parser Char

-- | Parsers for different tokens in an HTTP request.
letter :: Parser Char

-- | Parsers for different tokens in an HTTP request.
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
type DList a = [a] -> [a]
pUrlEscaped :: Parser ByteString

-- | Decodes an URL-escaped string (see
--   <a>http://tools.ietf.org/html/rfc2396.html#section-2.4</a>)
urlDecode :: ByteString -> Maybe ByteString

-- | URL-escapes a string (see
--   <a>http://tools.ietf.org/html/rfc2396.html#section-2.4</a>)
urlEncode :: ByteString -> ByteString

-- | URL-escapes a string (see
--   <a>http://tools.ietf.org/html/rfc2396.html#section-2.4</a>) into a
--   <a>Builder</a>.
urlEncodeBuilder :: ByteString -> Builder
urlEncodeTable :: FastSet
hexd :: Char -> Builder
finish :: Result a -> Result a

-- | Parses a string encoded in <tt>application/x-www-form-urlencoded</tt>
--   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
unsafeFromHex :: (Enum a, Num a, Bits a) => ByteString -> a
unsafeFromInt :: (Enum a, Num a, Bits a) => ByteString -> a


-- | An internal Snap module containing the exception that escapes HTTP
--   types.
--   
--   <i>N.B.</i> this is an internal interface, please don't write user
--   code that depends on it. Interfaces subject to change etc etc etc.
module Snap.Internal.Exceptions

-- | An exception hierarchy for exceptions that cannot be caught by
--   user-defined error handlers
data UncatchableException
UncatchableException :: e -> UncatchableException
uncatchableExceptionToException :: Exception e => e -> SomeException
uncatchableExceptionFromException :: Exception e => SomeException -> Maybe e
data ConnectionTerminatedException
ConnectionTerminatedException :: SomeException -> ConnectionTerminatedException

-- | This exception is thrown if the handler chooses to escape regular HTTP
--   traffic.
data EscapeHttpException
EscapeHttpException :: EscapeHttpHandler -> EscapeHttpException
type EscapeHttpHandler = ((Int -> Int) -> IO ()) -> Iteratee ByteString IO () -> Iteratee ByteString IO ()
instance Typeable UncatchableException
instance Typeable ConnectionTerminatedException
instance Typeable EscapeHttpException
instance Exception EscapeHttpException
instance Show EscapeHttpException
instance Exception ConnectionTerminatedException
instance Show ConnectionTerminatedException
instance Exception UncatchableException
instance Show UncatchableException


-- | This module contains the core type definitions, class instances, and
--   functions for HTTP as well as the <a>Snap</a> monad, which is used for
--   web handlers.
module Snap.Core
data Snap a

-- | Runs a <a>Snap</a> monad action in the 'Iteratee IO' monad.
runSnap :: Snap a -> (ByteString -> IO ()) -> ((Int -> Int) -> IO ()) -> Request -> Iteratee ByteString IO (Request, Response)

-- | <a>Snap</a> is the <a>Monad</a> that user web handlers run in.
--   <a>Snap</a> gives you:
--   
--   <ol>
--   <li>stateful access to fetch or modify an HTTP <a>Request</a></li>
--   <li>stateful access to fetch or modify an HTTP <a>Response</a></li>
--   <li>failure / <a>Alternative</a> / <a>MonadPlus</a> semantics: a
--   <a>Snap</a> handler can choose not to handle a given request, using
--   <a>empty</a> or its synonym <a>pass</a>, and you can try alternative
--   handlers with the <a>&lt;|&gt;</a> operator:</li>
--   </ol>
--   
--   <pre>
--   a :: Snap String
--   a = pass
--   
--   b :: Snap String
--   b = return "foo"
--   
--   c :: Snap String
--   c = a &lt;|&gt; b             -- try running a, if it fails then try b
--   </pre>
--   
--   <ol>
--   <li>convenience functions (<a>writeBS</a>, <a>writeLBS</a>,
--   <a>writeText</a>, <a>writeLazyText</a>, <a>addToOutput</a>) for
--   queueing output to be written to the <a>Response</a>:</li>
--   </ol>
--   
--   <pre>
--   a :: (forall a . Enumerator a) -&gt; Snap ()
--   a someEnumerator = do
--       writeBS "I'm a strict bytestring"
--       writeLBS "I'm a lazy bytestring"
--       writeText "I'm strict text"
--       addToOutput someEnumerator
--   </pre>
--   
--   <ol>
--   <li>early termination: if you call <a>finishWith</a>:</li>
--   </ol>
--   
--   <pre>
--   a :: Snap ()
--   a = do
--     modifyResponse $ setResponseStatus 500 "Internal Server Error"
--     writeBS "500 error"
--     r &lt;- getResponse
--     finishWith r
--   </pre>
--   
--   then any subsequent processing will be skipped and supplied
--   <a>Response</a> value will be returned from <a>runSnap</a> as-is.
--   
--   <ol>
--   <li>access to the <a>IO</a> monad through a <a>MonadIO</a>
--   instance:</li>
--   </ol>
--   
--   <pre>
--   a :: Snap ()
--   a = liftIO fireTheMissiles
--   </pre>
--   
--   <ol>
--   <li>the ability to set or extend a timeout which will kill the handler
--   thread after <tt>N</tt> seconds of inactivity (the default is 20
--   seconds):</li>
--   </ol>
--   
--   <pre>
--   a :: Snap ()
--   a = setTimeout 30
--   </pre>
--   
--   <ol>
--   <li>throw and catch exceptions using a <a>MonadCatchIO</a>
--   instance:</li>
--   </ol>
--   
--   <pre>
--   foo :: Snap ()
--   foo = bar `catch` \(e::SomeException) -&gt; baz
--     where
--       bar = throw FooException
--   </pre>
--   
--   <ol>
--   <li>log a message to the error log:</li>
--   </ol>
--   
--   <pre>
--   foo :: Snap ()
--   foo = logError "grumble."
--   </pre>
--   
--   You may notice that most of the type signatures in this module contain
--   a <tt>(MonadSnap m) =&gt; ...</tt> typeclass constraint.
--   <a>MonadSnap</a> is a typeclass which, in essence, says "you can get
--   back to the <a>Snap</a> monad from here". Using <a>MonadSnap</a> you
--   can extend the <a>Snap</a> monad with additional functionality and
--   still have access to most of the <a>Snap</a> functions without writing
--   <a>lift</a> everywhere. Instances are already provided for most of the
--   common monad transformers (<tt>ReaderT</tt>, <tt>WriterT</tt>,
--   <a>StateT</a>, etc.).
--   
--   <a>MonadSnap</a> is a type class, analogous to <a>MonadIO</a> for
--   <a>IO</a>, that makes it easy to wrap <a>Snap</a> 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 <a>runSnap</a>
--   fails.
data NoHandlerException
NoHandlerException :: String -> NoHandlerException

-- | This function brackets a Snap action in resource acquisition and
--   release. This is provided because MonadCatchIO's <a>bracket</a>
--   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.
--   
--   <ol>
--   <li>Normal completion</li>
--   <li>Short-circuit completion, either from calling <a>fail</a> or
--   <a>finishWith</a></li>
--   <li>An exception being thrown.</li>
--   </ol>
bracketSnap :: IO a -> (a -> IO b) -> (a -> Snap c) -> Snap c

-- | Short-circuits a <a>Snap</a> monad action early, storing the given
--   <a>Response</a> value in its state.
finishWith :: MonadSnap m => Response -> m a

-- | Capture the flow of control in case a handler calls <a>finishWith</a>.
--   
--   <i>WARNING</i>: in the event of a call to <a>transformRequestBody</a>
--   it is possible to violate HTTP protocol safety when using this
--   function. If you call <a>catchFinishWith</a> it is suggested that you
--   do not modify the body of the <a>Response</a> which was passed to the
--   <a>finishWith</a> call.
catchFinishWith :: Snap a -> Snap (Either Response a)

-- | Fails out of a <a>Snap</a> 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
type EscapeHttpHandler = ((Int -> Int) -> IO ()) -> Iteratee ByteString IO () -> Iteratee ByteString IO ()

-- | 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 modify the
--   thread's timeout, and a write end to the socket.
escapeHttp :: MonadCatchIO m => EscapeHttpHandler -> m ()

-- | Runs a <a>Snap</a> monad action only if the request's HTTP method
--   matches the given method.
method :: MonadSnap m => Method -> m a -> m a

-- | Runs a <a>Snap</a> 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 <a>Snap</a> monad action only for requests where
--   <a>rqPathInfo</a> is exactly equal to the given string. If the path
--   matches, locally sets <a>rqContextPath</a> to the old value of
--   <a>rqPathInfo</a>, sets <a>rqPathInfo</a>="", and runs the given
--   handler.
path :: MonadSnap m => ByteString -> m a -> m a

-- | Runs a <a>Snap</a> 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 <a>Snap</a> monad action only when the <a>rqPathInfo</a> of the
--   request starts with the given path. For example,
--   
--   <pre>
--   dir "foo" handler
--   </pre>
--   
--   Will fail if <a>rqPathInfo</a> is not "<tt>/foo</tt>" or
--   "<tt>/foo/...</tt>", and will add <tt>"foo/"</tt> to the handler's
--   local <a>rqContextPath</a>.
dir :: MonadSnap m => ByteString -> m a -> m a

-- | Runs a <a>Snap</a> monad action only when <a>rqPathInfo</a> 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:
--   
--   <pre>
--   route [ ("foo/bar/quux", fooBarQuux) ]
--   </pre>
--   
--   If the URI of the incoming request is
--   
--   <pre>
--   /foo/bar/quux
--   </pre>
--   
--   or
--   
--   <pre>
--   /foo/bar/quux/...anything...
--   </pre>
--   
--   then the request will be routed to "<tt>fooBarQuux</tt>", with
--   <a>rqContextPath</a> set to "<tt>/foo/bar/quux/</tt>" and
--   <a>rqPathInfo</a> set to "<tt>...anything...</tt>".
--   
--   A path component within an URL entry point beginning with a colon
--   ("<tt>:</tt>") is treated as a <i>variable capture</i>; the
--   corresponding path component within the request URI will be entered
--   into the <a>rqParams</a> parameters mapping with the given name. For
--   instance, if the routes were:
--   
--   <pre>
--   route [ ("foo/:bar/baz", fooBazHandler) ]
--   </pre>
--   
--   Then a request for "<tt>/foo/saskatchewan/baz</tt>" would be routed to
--   <tt>fooBazHandler</tt> with a mapping for:
--   
--   <pre>
--   "bar" =&gt; "saskatchewan"
--   </pre>
--   
--   in its parameters table.
--   
--   Longer paths are matched first, and specific routes are matched before
--   captures. That is, if given routes:
--   
--   <pre>
--   [ ("a", h1), ("a/b", h2), ("a/:x", h3) ]
--   </pre>
--   
--   a request for "<tt>/a/b</tt>" will go to <tt>h2</tt>, "<tt>/a/s</tt>"
--   for any <i>s</i> will go to <tt>h3</tt>, and "<tt>/a</tt>" will go to
--   <tt>h1</tt>.
--   
--   The following example matches "<tt>/article</tt>" to an article index,
--   "<tt>/login</tt>" to a login, and "<tt>/article/...</tt>" to an
--   article renderer.
--   
--   <pre>
--   route [ ("article",     renderIndex)
--         , ("article/:id", renderArticle)
--         , ("login",       method POST doLogin) ]
--   </pre>
--   
--   <i>URL decoding</i>
--   
--   A short note about URL decoding: path matching and variable capture
--   are done on <i>decoded</i> URLs, but the contents of
--   <a>rqContextPath</a> and <a>rqPathInfo</a> will contain the original
--   encoded URL, i.e. what the user entered. For example, in the following
--   scenario:
--   
--   <pre>
--   route [ ("a b c d/", foo ) ]
--   </pre>
--   
--   A request for "<tt>/a+b+c+d</tt>" will be sent to <tt>foo</tt> with
--   <a>rqContextPath</a> set to "<i>a+b+c+d</i>".
--   
--   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 <a>routeLocal</a> function is the same as <a>route'</a>, 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 <a>rqPathInfo</a> as it is.
routeLocal :: MonadSnap m => [(ByteString, m a)] -> m a

-- | Grabs the <a>Request</a> object out of the <a>Snap</a> monad.
getRequest :: MonadSnap m => m Request

-- | Grabs something out of the <a>Request</a> object, using the given
--   projection function. See <a>gets</a>.
getsRequest :: MonadSnap m => (Request -> a) -> m a

-- | Grabs the <a>Response</a> object out of the <a>Snap</a> monad.
getResponse :: MonadSnap m => m Response

-- | Grabs something out of the <a>Response</a> object, using the given
--   projection function. See <a>gets</a>.
getsResponse :: MonadSnap m => (Response -> a) -> m a

-- | Puts a new <a>Request</a> object into the <a>Snap</a> monad.
putRequest :: MonadSnap m => Request -> m ()

-- | Puts a new <a>Response</a> object into the <a>Snap</a> monad.
putResponse :: MonadSnap m => Response -> m ()

-- | Modifies the <a>Request</a> object stored in a <a>Snap</a> monad.
modifyRequest :: MonadSnap m => (Request -> Request) -> m ()

-- | Modifes the <a>Response</a> object stored in a <a>Snap</a> monad.
modifyResponse :: MonadSnap m => (Response -> Response) -> m ()

-- | Runs a <a>Snap</a> action with a locally-modified <a>Request</a> state
--   object. The <a>Request</a> 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 <a>Request</a> from state and hands it to the given
--   action.
withRequest :: MonadSnap m => (Request -> m a) -> m a

-- | Fetches the <a>Response</a> from state and hands it to the given
--   action.
withResponse :: MonadSnap m => (Response -> m a) -> m a

-- | Log an error message in the <a>Snap</a> 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 <a>terminateConnection</a>,
--   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
--   <a>readRequestBody</a> instead.

-- | <i>Deprecated: As of 0.6, please use <a>readRequestBody</a> instead
--   </i>
getRequestBody :: MonadSnap m => m ByteString

-- | Returns the request body as a lazy bytestring. <i>New in 0.6.</i>
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 <a>Response</a>
--   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 <a>finishWith</a>. 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.: "<tt>GET /foo?param=bar1&amp;param=bar2</tt>"), looking
--   up "<tt>param</tt>" in the mapping will give you <tt>["bar1",
--   "bar2"]</tt>.
type Params = Map ByteString [ByteString]

-- | Enumerates the HTTP method values (see
--   <a>http://tools.ietf.org/html/rfc2068.html#section-5.1.1</a>).
data Method
GET :: Method
HEAD :: Method
POST :: Method
PUT :: Method
DELETE :: Method
TRACE :: Method
OPTIONS :: Method
CONNECT :: Method
PATCH :: Method
Method :: ByteString -> 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 <a>HasHeaders</a> 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 <a>HasHeaders</a> 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 <a>HasHeaders</a> 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 <a>HasHeaders</a> 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 <a>HasHeaders</a> datatype.
deleteHeader :: HasHeaders a => CI ByteString -> a -> a

-- | Modifies the <a>Request</a> in the state to set the
--   <a>rqRemoteAddr</a> 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 <a>Request</a> in the state to set the
--   <a>rqRemoteAddr</a> 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
--   <tt>Host:</tt> 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 <tt>True</tt> if this is an <tt>HTTPS</tt> session.
rqIsSecure :: Request -> Bool

-- | Returns the <tt>Content-Length</tt> 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 be hung on a <tt>URI</tt> "entry point"; this is called
--   the "context path". If a handler is hung on the context path
--   <tt>"/foo/"</tt>, and you request <tt>"/foo/bar"</tt>, the value of
--   <a>rqPathInfo</a> will be <tt>"bar"</tt>.
--   
--   The following identity holds:
--   
--   <pre>
--   rqURI r == S.concat [ rqContextPath r
--                       , rqPathInfo r
--                       , let q = rqQueryString r
--                         in if S.null q
--                              then ""
--                              else S.append "?" q
--                       ]
--   </pre>
rqPathInfo :: Request -> ByteString

-- | The "context path" of the request; catenating <a>rqContextPath</a>,
--   and <a>rqPathInfo</a> should get you back to the original <a>rqURI</a>
--   (ignoring query strings). The <a>rqContextPath</a> always begins and
--   ends with a slash (<tt>"/"</tt>) character, and represents the path
--   (relative to your component/snaplet) you took to get to your handler.
rqContextPath :: Request -> ByteString

-- | Returns the <tt>URI</tt> requested by the client.
rqURI :: Request -> ByteString

-- | Returns the HTTP query string for this <a>Request</a>.
rqQueryString :: Request -> ByteString

-- | Returns the parameters mapping for this <a>Request</a>. "Parameters"
--   are automatically decoded from the URI's query string and
--   <tt>POST</tt> body and entered into this mapping. The <a>rqParams</a>
--   value is thus a union of <a>rqQueryParams</a> and <a>rqPostParams</a>.
rqParams :: Request -> Params

-- | The parameter mapping decoded from the URI's query string.
rqQueryParams :: Request -> Params

-- | The parameter mapping decoded from the POST body. Note that Snap only
--   auto-decodes POST request bodies when the request's
--   <tt>Content-Type</tt> is <tt>application/x-www-form-urlencoded</tt>.
--   For <tt>multipart/form-data</tt> use <a>handleFileUploads</a> to
--   decode the POST request and fill this mapping.
rqPostParams :: 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 <tt>Content-Type</tt> is
--   <tt>application/x-www-form-urlencoded</tt>). Parameter values can be
--   modified within handlers using <a>rqModifyParams</a>.
rqParam :: ByteString -> Request -> Maybe [ByteString]

-- | Looks up the value(s) for the given named parameter in the POST
--   parameters mapping.
rqPostParam :: ByteString -> Request -> Maybe [ByteString]

-- | Looks up the value(s) for the given named parameter in the query
--   parameters mapping.
rqQueryParam :: ByteString -> Request -> Maybe [ByteString]

-- | See <a>rqParam</a>. Looks up a value for the given named parameter in
--   the <a>Request</a>. If more than one value was entered for the given
--   parameter name, <a>getParam</a> gloms the values together with:
--   
--   <pre>
--   <a>intercalate</a> " "
--   </pre>
getParam :: MonadSnap m => ByteString -> m (Maybe ByteString)

-- | See <a>rqPostParam</a>. Looks up a value for the given named parameter
--   in the POST form parameters mapping in <a>Request</a>. If more than
--   one value was entered for the given parameter name,
--   <a>getPostParam</a> gloms the values together with:
--   
--   <pre>
--   <a>intercalate</a> " "
--   </pre>
getPostParam :: MonadSnap m => ByteString -> m (Maybe ByteString)

-- | See <a>rqQueryParam</a>. Looks up a value for the given named
--   parameter in the query string parameters mapping in <a>Request</a>. If
--   more than one value was entered for the given parameter name,
--   <a>getQueryParam</a> gloms the values together with:
--   
--   <pre>
--   <a>intercalate</a> " "
--   </pre>
getQueryParam :: MonadSnap m => ByteString -> m (Maybe ByteString)

-- | See <a>rqParams</a>. Convenience function to return <a>Params</a> from
--   the <a>Request</a> inside of a <a>MonadSnap</a> instance.
getParams :: MonadSnap m => m Params

-- | See <a>rqParams</a>. Convenience function to return <a>Params</a> from
--   the <a>Request</a> inside of a <a>MonadSnap</a> instance.
getPostParams :: MonadSnap m => m Params

-- | See <a>rqParams</a>. Convenience function to return <a>Params</a> from
--   the <a>Request</a> inside of a <a>MonadSnap</a> instance.
getQueryParams :: MonadSnap m => m Params

-- | Modifies the parameters mapping (which is a <tt>Map ByteString
--   ByteString</tt>) in a <a>Request</a> 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 <a>Response</a>.
emptyResponse :: Response

-- | Sets the HTTP response code.
setResponseCode :: Int -> Response -> Response

-- | Sets the HTTP response status. Note: normally you would use
--   <a>setResponseCode</a> 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 <tt>Content-Type</tt> in the <a>Response</a> headers.
setContentType :: ByteString -> Response -> Response

-- | Adds an HTTP <a>Cookie</a> to <a>Response</a> headers.
addResponseCookie :: Cookie -> Response -> Response

-- | Gets an HTTP <a>Cookie</a> with the given name from <a>Response</a>
--   headers.
getResponseCookie :: ByteString -> Response -> Maybe Cookie

-- | Returns a list of <a>Cookie</a>s present in <a>Response</a>
getResponseCookies :: Response -> [Cookie]

-- | Deletes an HTTP <a>Cookie</a> from the <a>Response</a> headers. Please
--   note this does not necessarily erase the cookie from the client
--   browser.
deleteResponseCookie :: ByteString -> Response -> Response

-- | Modifies an HTTP <a>Cookie</a> with given name in <a>Response</a>
--   headers. Nothing will happen if a matching <a>Cookie</a> can not be
--   found in <a>Response</a>.
modifyResponseCookie :: ByteString -> (Cookie -> Cookie) -> Response -> Response

-- | Expire the given <a>Cookie</a> in client's browser.
expireCookie :: MonadSnap m => ByteString -> Maybe ByteString -> m ()

-- | Gets the HTTP <a>Cookie</a> with the specified name.
getCookie :: MonadSnap m => ByteString -> m (Maybe Cookie)

-- | Gets the HTTP <a>Cookie</a> 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 <tt>Content-Length</tt> for the
--   response, Snap forces you to do it with this function rather than by
--   setting it in the headers; the <tt>Content-Length</tt> in the headers
--   will be ignored.
--   
--   The reason for this is that Snap needs to look up the value of
--   <tt>Content-Length</tt> 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 <tt>Connection:
--   close</tt>. For HTTP/1.1 clients, Snap will switch to the chunked
--   transfer encoding if <tt>Content-Length</tt> is not specified.
setContentLength :: Int64 -> Response -> Response

-- | Removes any <tt>Content-Length</tt> set in the <a>Response</a>.
clearContentLength :: Response -> Response

-- | Performs a redirect by setting the <tt>Location</tt> header to the
--   given target URL/path and the status code to 302 in the
--   <a>Response</a> object stored in a <a>Snap</a> 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 <tt>Location</tt> header to the
--   given target URL/path and the status code (should be one of 301, 302,
--   303 or 307) in the <a>Response</a> object stored in a <a>Snap</a>
--   monad. Note that the target URL is not validated in any way.
redirect' :: MonadSnap m => ByteString -> Int -> m a

-- | The buffering mode controls whether Snap will buffer the output or
--   not. You may wish to disable buffering when using Comet-like
--   techniques which rely on the immediate sending of output data in order
--   to maintain interactive semantics.
setBufferingMode :: Bool -> Response -> Response

-- | The buffering mode controls whether Snap will buffer the output or
--   not. You may wish to disable buffering when using Comet-like
--   techniques which rely on the immediate sending of output data in order
--   to maintain interactive semantics.
getBufferingMode :: Response -> Bool

-- | Sets an HTTP response body to the given <a>Enumerator</a> 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 <a>Response</a>
--   stored in the <a>Snap</a> monad state.
addToOutput :: MonadSnap m => (forall a. Enumerator Builder IO a) -> m ()

-- | Adds the given <a>Builder</a> to the body of the <a>Response</a>
--   stored in the | <a>Snap</a> monad state.
writeBuilder :: MonadSnap m => Builder -> m ()

-- | Adds the given strict <a>ByteString</a> to the body of the
--   <a>Response</a> stored in the <a>Snap</a> monad state.
--   
--   Warning: This function is intentionally non-strict. If any pure
--   exceptions are raised by the expression creating the
--   <a>ByteString</a>, the exception won't actually be raised within the
--   Snap handler.
writeBS :: MonadSnap m => ByteString -> m ()

-- | Adds the given lazy <a>Text</a> to the body of the <a>Response</a>
--   stored in the <a>Snap</a> monad state.
--   
--   Warning: This function is intentionally non-strict. If any pure
--   exceptions are raised by the expression creating the
--   <a>ByteString</a>, the exception won't actually be raised within the
--   Snap handler.
writeLazyText :: MonadSnap m => Text -> m ()

-- | Adds the given strict <a>Text</a> to the body of the <a>Response</a>
--   stored in the <a>Snap</a> monad state.
--   
--   Warning: This function is intentionally non-strict. If any pure
--   exceptions are raised by the expression creating the
--   <a>ByteString</a>, the exception won't actually be raised within the
--   Snap handler.
writeText :: MonadSnap m => Text -> m ()

-- | Adds the given lazy <a>ByteString</a> to the body of the
--   <a>Response</a> stored in the <a>Snap</a> monad state.
--   
--   Warning: This function is intentionally non-strict. If any pure
--   exceptions are raised by the expression creating the
--   <a>ByteString</a>, 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 <a>sendFile</a> will overwrite any output queued to be sent in
--   the <a>Response</a>. If the response body is not modified after the
--   call to <a>sendFile</a>, Snap will use the efficient
--   <tt>sendfile()</tt> system call on platforms that support it.
--   
--   If the response body is modified (using <a>modifyResponseBody</a>),
--   the file will be read using <tt>mmap()</tt>.
sendFile :: MonadSnap m => FilePath -> m ()

-- | Sets the output to be the contents of the specified file, within the
--   given (start,end) range.
--   
--   Calling <a>sendFilePartial</a> will overwrite any output queued to be
--   sent in the <a>Response</a>. If the response body is not modified
--   after the call to <a>sendFilePartial</a>, Snap will use the efficient
--   <tt>sendfile()</tt> system call on platforms that support it.
--   
--   If the response body is modified (using <a>modifyResponseBody</a>),
--   the file will be read using <tt>mmap()</tt>.
sendFilePartial :: MonadSnap m => FilePath -> (Int64, Int64) -> m ()

-- | Causes the handler thread to be killed <tt>n</tt> seconds from now.
setTimeout :: MonadSnap m => Int -> m ()

-- | Causes the handler thread to be killed at least <tt>n</tt> seconds
--   from now.
extendTimeout :: MonadSnap m => Int -> m ()

-- | Modifies the amount of time remaining before the request times out.
modifyTimeout :: MonadSnap m => (Int -> Int) -> m ()

-- | Returns an <a>IO</a> action which you can use to set the handling
--   thread's timeout value.

-- | <i>Deprecated: use getTimeoutModifier instead. Since 0.8. </i>
getTimeoutAction :: MonadSnap m => m (Int -> IO ())

-- | Returns an <a>IO</a> action which you can use to modify the timeout
--   value.
getTimeoutModifier :: MonadSnap m => m ((Int -> 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:
--   
--   <ul>
--   <li>The input source runs out of data.</li>
--   <li>The iteratee yields a result value.</li>
--   <li>The iteratee throws an exception.</li>
--   </ul>
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 <a>CTime</a> into an HTTP timestamp.
formatHttpTime :: CTime -> IO ByteString

-- | Converts an HTTP timestamp into a <a>CTime</a>.
parseHttpTime :: ByteString -> IO CTime

-- | Parses a string encoded in <tt>application/x-www-form-urlencoded</tt>
--   format.
parseUrlEncoded :: ByteString -> Map ByteString [ByteString]
buildUrlEncoded :: Map ByteString [ByteString] -> Builder
printUrlEncoded :: Map ByteString [ByteString] -> ByteString

-- | URL-escapes a string (see
--   <a>http://tools.ietf.org/html/rfc2396.html#section-2.4</a>)
urlEncode :: ByteString -> ByteString

-- | URL-escapes a string (see
--   <a>http://tools.ietf.org/html/rfc2396.html#section-2.4</a>) into a
--   <a>Builder</a>.
urlEncodeBuilder :: ByteString -> Builder

-- | Decodes an URL-escaped string (see
--   <a>http://tools.ietf.org/html/rfc2396.html#section-2.4</a>)
urlDecode :: ByteString -> Maybe ByteString


-- | As of Snap 0.6, the <a>Snap.Types</a> module is deprecated: please use
--   <a>Snap.Core</a> instead.

-- | <i>Deprecated: As of 0.6, use Snap.Core instead </i>
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 <a>Request</a> for testing.
data RequestBuilder m a

-- | A request body of type "<tt>multipart/form-data</tt>" 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 <a>ByteString</a> values.
FormData :: [ByteString] -> MultipartParam

-- | a file upload consisting of the given <a>FileData</a> 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 <a>RequestType</a> datatype enumerates the different kinds of HTTP
--   requests you can generate using the testing interface. Most users will
--   prefer to use the <a>get</a>, <a>postUrlEncoded</a>,
--   <a>postMultipart</a>, <a>put</a>, and <a>delete</a> convenience
--   functions.
data RequestType
GetRequest :: RequestType
RequestWithRawBody :: Method -> ByteString -> RequestType
MultipartPostRequest :: MultipartParams -> RequestType
UrlEncodedPostRequest :: Params -> RequestType
DeleteRequest :: RequestType

-- | Runs a <a>RequestBuilder</a>, producing the desired <a>Request</a>.
--   
--   N.B. <i>please</i> don't use the request you get here in a real Snap
--   application; things will probably break. Don't say you weren't warned
--   :-)
buildRequest :: MonadIO m => RequestBuilder m () -> m Request

-- | Given a web handler in the <a>Snap</a> monad, and a
--   <a>RequestBuilder</a> defining a test request, runs the handler,
--   producing an HTTP <a>Response</a>.
--   
--   This function will produce almost exactly the same output as running
--   the handler in a real server, except that chunked transfer encoding is
--   not applied, and the "Transfer-Encoding" header is not set (this makes
--   it easier to test response output).
runHandler :: MonadIO m => RequestBuilder m () -> Snap a -> m Response

-- | Given a web handler in some arbitrary <a>MonadSnap</a> monad, a
--   function specifying how to evaluate it within the context of the test
--   monad, and a <a>RequestBuilder</a> defining a test request, runs the
--   handler, producing an HTTP <a>Response</a>.
runHandlerM :: (MonadIO m, MonadSnap n) => (forall a. Request -> n a -> m Response) -> RequestBuilder m () -> n b -> m Response

-- | Given a web handler in the <a>Snap</a> monad, and a
--   <a>RequestBuilder</a> defining a test request, runs the handler and
--   returns the monadic value it produces.
--   
--   Throws an exception if the <a>Snap</a> handler early-terminates with
--   <a>finishWith</a> or <a>mzero</a>.
evalHandler :: MonadIO m => RequestBuilder m () -> Snap a -> m a

-- | Given a web handler in some arbitrary <a>MonadSnap</a> monad, a
--   function specifying how to evaluate it within the context of the test
--   monad, and a <a>RequestBuilder</a> defining a test request, runs the
--   handler, returning the monadic value it produces.
--   
--   Throws an exception if the <a>Snap</a> handler early-terminates with
--   <a>finishWith</a> or <a>mzero</a>.
evalHandlerM :: (MonadIO m, MonadSnap n) => (forall a. Request -> n a -> m a) -> RequestBuilder m () -> n b -> m b

-- | 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 <tt>content-type</tt> 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 <a>setQueryString</a> function, which takes a
--   parameter mapping.
setQueryStringRaw :: Monad m => ByteString -> RequestBuilder m ()

-- | Sets the request's path. The path provided must begin with a
--   "<tt>/</tt>" and must <i>not</i> contain a query string; if you want
--   to provide a query string in your test request, you must use
--   <a>setQueryString</a> or <a>setQueryStringRaw</a>. Note that
--   <a>rqContextPath</a> is never set by any <a>RequestBuilder</a>
--   function.
setRequestPath :: Monad m => ByteString -> RequestBuilder m ()

-- | Sets the type of the <a>Request</a> 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 <a>Request</a> using <a>rqPathInfo</a> and makes
--   sure it is safe to use for opening files. A path is safe if it is a
--   relative path and has no <a>..</a> elements to escape the intended
--   directory structure.
getSafePath :: MonadSnap m => m FilePath

-- | A type alias for MIME type
type MimeMap = HashMap FilePath ByteString

-- | A type alias for dynamic handlers
type HandlerMap m = HashMap 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 <a>defaultMimeTypes</a>, and has no
--   index files, index generator, dynamic file handlers, or
--   <a>preServeHook</a>.
simpleDirectoryConfig :: MonadSnap m => DirectoryConfig m

-- | A reasonable default configuration for directory serving. This
--   configuration uses built-in MIME types from <a>defaultMimeTypes</a>,
--   serves common index files <tt>index.html</tt> and <tt>index.htm</tt>,
--   but does not autogenerate directory indexes, nor have any dynamic file
--   handlers. The <a>preServeHook</a> will not do anything.
defaultDirectoryConfig :: MonadSnap m => DirectoryConfig m

-- | A more elaborate configuration for file serving. This configuration
--   uses built-in MIME types from <a>defaultMimeTypes</a>, serves common
--   index files <tt>index.html</tt> and <tt>index.htm</tt>, and
--   autogenerates directory indexes with a Snap-like feel. It still has no
--   dynamic file handlers, nor <a>preServeHook</a>, which should be added
--   as needed.
--   
--   Files recognized as indexes include <tt>index.html</tt>,
--   <tt>index.htm</tt>, <tt>default.html</tt>, <tt>default.htm</tt>,
--   <tt>home.html</tt>
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 <a>MimeMap</a> 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 <a>DirectoryConfig</a>
--   
--   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:
--   
--   <pre>
--   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"                         ),
--     ( ".ico"     , "image/x-icon"                      ),
--     ( ".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"                   ) ]
--   </pre>
defaultMimeTypes :: MimeMap
fileType :: MimeMap -> FilePath -> ByteString

-- | Serves static files from a directory using the default configuration
--   as given in <a>defaultDirectoryConfig</a>.
serveDirectory :: MonadSnap m => FilePath -> m ()

-- | Serves static files from a directory. Configuration options are passed
--   in a <a>DirectoryConfig</a> that captures various choices about
--   desired behavior. The relative path given in <a>rqPathInfo</a> is
--   searched for a requested file, and the file is served with the
--   appropriate mime type if it is found. Absolute paths and "<tt>..</tt>"
--   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 <i>not</i> pass
--   to the next handler). The path restrictions on <a>serveDirectory</a>
--   don't apply to this function since the path is not being supplied by
--   the user.
serveFile :: MonadSnap m => FilePath -> m ()

-- | Same as <a>serveFile</a>, 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 <tt>Content-type: multipart/form-data</tt>, i.e. HTML
--   forms and file uploads.
--   
--   Typically most users will want to use <a>handleFileUploads</a>, 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 <a>Iteratee</a> interface called
--   <a>handleMultipart</a>. That function takes uploaded files and streams
--   them to an <a>Iteratee</a> 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
--   <a>UploadPolicy</a>), and on a per-file basis (using
--   <a>PartUploadPolicy</a>, which allows you to reject or limit the size
--   of certain uploaded <tt>Content-type</tt>s).
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 <tt>Content-type: multipart/form-data</tt>. 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 <a>Response</a> body <a>Enumerator</a> 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:
--   
--   <pre>
--   (PartInfo, Either PolicyViolationException FilePath)
--   </pre>
--   
--   The first half of this tuple is a <a>PartInfo</a>, 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
--   <a>Either</a> stipulating that either:
--   
--   <ol>
--   <li>the file was rejected on a policy basis because of the provided
--   <a>PartUploadPolicy</a> handler</li>
--   <li>the file was accepted and exists at the given path.</li>
--   </ol>
--   
--   If the request's <tt>Content-type</tt> was not
--   "<tt>multipart/formdata</tt>", this function skips processing using
--   <a>pass</a>.
--   
--   If the client's upload rate passes below the configured minimum (see
--   <a>setMinimumUploadRate</a> and <a>setMinimumUploadSeconds</a>), this
--   function terminates the connection. This setting is there to protect
--   the server against slowloris-style denial of service attacks.
--   
--   If the given <a>UploadPolicy</a> stipulates that you wish form inputs
--   to be placed in the <a>rqParams</a> parameter map (using
--   <a>setProcessFormInputs</a>), and a form input exceeds the maximum
--   allowable size, this function will throw a
--   <a>PolicyViolationException</a>.
--   
--   If an uploaded part contains MIME headers longer than a fixed internal
--   threshold (currently 32KB), this function will throw a
--   <a>BadPartException</a>.
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 <tt>Content-type:
--   multipart/form-data</tt>. Normally most users will want to use
--   <a>handleFileUploads</a> (which writes uploaded files to a temporary
--   directory and passes their names to a given handler) rather than this
--   function; the lower-level <a>handleMultipart</a> function should be
--   used if you want to stream uploaded files to your own iteratee
--   function.
--   
--   If the request's <tt>Content-type</tt> was not
--   "<tt>multipart/formdata</tt>", this function skips processing using
--   <a>pass</a>.
--   
--   If the client's upload rate passes below the configured minimum (see
--   <a>setMinimumUploadRate</a> and <a>setMinimumUploadSeconds</a>), this
--   function terminates the connection. This setting is there to protect
--   the server against slowloris-style denial of service attacks.
--   
--   If the given <a>UploadPolicy</a> stipulates that you wish form inputs
--   to be placed in the <a>rqParams</a> parameter map (using
--   <a>setProcessFormInputs</a>), and a form input exceeds the maximum
--   allowable size, this function will throw a
--   <a>PolicyViolationException</a>.
--   
--   If an uploaded part contains MIME headers longer than a fixed internal
--   threshold (currently 32KB), this function will throw a
--   <a>BadPartException</a>.
handleMultipart :: MonadSnap m => UploadPolicy -> (PartInfo -> Iteratee ByteString IO a) -> m [a]

-- | <a>PartInfo</a> contains information about a "part" in a request
--   uploaded with <tt>Content-type: multipart/form-data</tt>.
data PartInfo
PartInfo :: !ByteString -> !(Maybe ByteString) -> !ByteString -> PartInfo
partFieldName :: PartInfo -> !ByteString
partFileName :: PartInfo -> !(Maybe ByteString)
partContentType :: PartInfo -> !ByteString

-- | <a>UploadPolicy</a> controls overall policy decisions relating to
--   <tt>multipart/form-data</tt> uploads, specifically:
--   
--   <ul>
--   <li>whether to treat parts without filenames as form input (reading
--   them into the <a>rqParams</a> map)</li>
--   <li>because form input is read into memory, the maximum size of a form
--   input read in this manner, and the maximum number of form inputs</li>
--   <li>the minimum upload rate a client must maintain before we kill the
--   connection; if very low-bitrate uploads were allowed then a Snap
--   server would be vulnerable to a trivial denial-of-service using a
--   "slowloris"-type attack</li>
--   <li>the minimum number of seconds which must elapse before we start
--   killing uploads for having too low an upload rate.</li>
--   <li>the amount of time we should wait before timing out the connection
--   whenever we receive input from the client.</li>
--   </ul>
data UploadPolicy

-- | A reasonable set of defaults for upload policy. The default policy is:
--   
--   <ul>
--   <li><i><tt>maximum form input size</tt></i> 128kB</li>
--   <li><i><tt>maximum number of form inputs</tt></i> 10</li>
--   <li><i><tt>minimum upload rate</tt></i> 1kB/s</li>
--   <li><i><tt>seconds before rate limiting kicks in</tt></i> 10</li>
--   <li><i><tt>inactivity timeout</tt></i> 20 seconds</li>
--   </ul>
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
--   <a>rqParams</a> map.
getMaximumFormInputSize :: UploadPolicy -> Int64

-- | Set the maximum size of a form input which will be read into our
--   <a>rqParams</a> map.
setMaximumFormInputSize :: Int64 -> UploadPolicy -> UploadPolicy

-- | Get the maximum size of a form input which will be read into our
--   <a>rqParams</a> map.
getMaximumNumberOfFormInputs :: UploadPolicy -> Int

-- | Set the maximum size of a form input which will be read into our
--   <a>rqParams</a> map.
setMaximumNumberOfFormInputs :: Int -> UploadPolicy -> UploadPolicy

-- | Get the minimum rate (in <i>bytes\</i>second/) a client must maintain
--   before we kill the connection.
getMinimumUploadRate :: UploadPolicy -> Double

-- | Set the minimum rate (in <i>bytes\</i>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
--   <a>UploadPolicy</a>), but handlers can also make policy decisions on
--   individual files/parts uploaded. For each part uploaded, handlers can
--   decide:
--   
--   <ul>
--   <li>whether to allow the file upload at all</li>
--   <li>the maximum size of uploaded files, if allowed</li>
--   </ul>
data PartUploadPolicy

-- | Disallows the file to be uploaded.
disallow :: PartUploadPolicy

-- | Allows the file to be uploaded, with maximum size <i>n</i>.
allowWithMaximumSize :: Int64 -> PartUploadPolicy

-- | All of the exceptions defined in this package inherit from
--   <a>FileUploadException</a>, so if you write
--   
--   <pre>
--   foo `catch` \(e :: FileUploadException) -&gt; ...
--   </pre>
--   
--   you can catch a <a>BadPartException</a>, a
--   <a>PolicyViolationException</a>, 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 <a>Snap</a> web handler with compression if available.
--   
--   If the client has indicated support for <tt>gzip</tt> or
--   <tt>deflate</tt> in its <tt>Accept-Encoding</tt> header, and the
--   <tt>Content-Type</tt> in the response is one of the following types:
--   
--   <ul>
--   <li><pre>application/x-javascript</pre></li>
--   <li><pre>application/json</pre></li>
--   <li><pre>text/css</pre></li>
--   <li><pre>text/html</pre></li>
--   <li><pre>text/javascript</pre></li>
--   <li><pre>text/plain</pre></li>
--   <li><pre>text/xml</pre></li>
--   <li><pre>application/x-font-truetype</pre></li>
--   </ul>
--   
--   Then the given handler's output stream will be compressed,
--   <tt>Content-Encoding</tt> will be set in the output headers, and the
--   <tt>Content-Length</tt> 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
--   <a>Response</a> that's contained within the <a>Snap</a> monad state
--   will be passed to <a>finishWith</a> to prevent further processing.
withCompression :: MonadSnap m => m a -> m ()

-- | The same as <a>withCompression</a>, 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


-- | This module provides facilities for patching incoming
--   <tt>Requests</tt> to correct the value of <a>rqRemoteAddr</a> if the
--   snap server is running behind a proxy.
--   
--   Example usage:
--   
--   <pre>
--    m :: Snap ()
--    m = undefined  -- code goes here
--   
--   applicationHandler :: Snap ()
--    applicationHandler = behindProxy X_Forwarded_For m
--   </pre>
module Snap.Util.Proxy

-- | What kind of proxy is this? Affects which headers <a>behindProxy</a>
--   pulls the original remote address from.
--   
--   Currently only proxy servers that send <tt>X-Forwarded-For</tt> or
--   <tt>Forwarded-For</tt> are supported.
data ProxyType

-- | no proxy, leave the request alone
NoProxy :: ProxyType

-- | Use the <tt>Forwarded-For</tt> or <tt>X-Forwarded-For</tt> header
X_Forwarded_For :: ProxyType

-- | Rewrite <a>rqRemoteAddr</a> if we're behind a proxy.
behindProxy :: MonadSnap m => ProxyType -> m a -> m a
instance Read ProxyType
instance Show ProxyType
instance Eq ProxyType
instance Ord ProxyType
