snap-core-1.0.5.1: Snap: A Haskell Web Framework (core interfaces and types)

Safe Haskell | None
Language | Haskell2010

Snap.Internal.Http.Types

Description

An internal Snap module containing HTTP types.

N.B. this is an internal interface, please don't write user code that depends on it. Most of these declarations (except for the unsafe/encapsulation-breaking ones) are re-exported from Snap.Core.

Synopsis

- 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 ()
- class HasHeaders a where
  - updateHeaders :: (Headers -> Headers) -> a -> a
  - headers :: a -> Headers
- addHeader :: HasHeaders a => CI ByteString -> ByteString -> a -> a
- setHeader :: HasHeaders a => CI ByteString -> ByteString -> a -> a
- getHeader :: HasHeaders a => CI ByteString -> a -> Maybe ByteString
- listHeaders :: HasHeaders a => a -> [(CI ByteString, ByteString)]
- deleteHeader :: HasHeaders a => CI ByteString -> a -> a
- data Method
  - = GET
  - | HEAD
  - | POST
  - | PUT
  - | DELETE
  - | TRACE
  - | OPTIONS
  - | CONNECT
  - | PATCH
  - | Method ByteString
- normalizeMethod :: Method -> Method
- type HttpVersion = (Int, Int)
- data Cookie = Cookie {
  - cookieName :: !ByteString
  - cookieValue :: !ByteString
  - cookieExpires :: !(Maybe UTCTime)
  - cookieDomain :: !(Maybe ByteString)
  - cookiePath :: !(Maybe ByteString)
  - cookieSecure :: !Bool
  - cookieHttpOnly :: !Bool
  }
- type Params = Map ByteString [ByteString]
- data Request = Request {
  - rqHostName :: ByteString
  - rqClientAddr :: ByteString
  - rqClientPort :: !Int
  - rqServerAddr :: ByteString
  - rqServerPort :: !Int
  - rqLocalHostname :: ByteString
  - rqIsSecure :: !Bool
  - rqHeaders :: Headers
  - rqBody :: InputStream ByteString
  - rqContentLength :: !(Maybe Word64)
  - rqMethod :: !Method
  - rqVersion :: !HttpVersion
  - rqCookies :: [Cookie]
  - rqPathInfo :: ByteString
  - rqContextPath :: ByteString
  - rqURI :: ByteString
  - rqQueryString :: ByteString
  - rqParams :: Params
  - rqQueryParams :: Params
  - rqPostParams :: Params
  }
- type StreamProc = OutputStream Builder -> IO (OutputStream Builder)
- data ResponseBody
  - = Stream StreamProc
  - | SendFile FilePath (Maybe (Word64, Word64))
- rspBodyMap :: (StreamProc -> StreamProc) -> ResponseBody -> ResponseBody
- rspBodyToEnum :: ResponseBody -> StreamProc
- data Response = Response {
  - rspHeaders :: Headers
  - rspCookies :: Map ByteString Cookie
  - rspContentLength :: !(Maybe Word64)
  - rspBody :: ResponseBody
  - rspStatus :: !Int
  - rspStatusReason :: !ByteString
  - rspTransformingRqBody :: !Bool
  }
- rqParam :: ByteString -> Request -> Maybe [ByteString]
- rqPostParam :: ByteString -> Request -> Maybe [ByteString]
- rqQueryParam :: ByteString -> Request -> Maybe [ByteString]
- rqModifyParams :: (Params -> Params) -> Request -> Request
- rqSetParam :: ByteString -> [ByteString] -> Request -> Request
- emptyResponse :: Response
- setResponseBody :: (OutputStream Builder -> IO (OutputStream Builder)) -> Response -> Response
- setResponseStatus :: Int -> ByteString -> Response -> Response
- setResponseCode :: Int -> Response -> Response
- modifyResponseBody :: ((OutputStream Builder -> IO (OutputStream Builder)) -> OutputStream Builder -> IO (OutputStream Builder)) -> Response -> Response
- setContentType :: ByteString -> Response -> Response
- cookieToBS :: Cookie -> ByteString
- renderCookies :: Response -> Headers -> Headers
- addResponseCookie :: Cookie -> Response -> Response
- getResponseCookie :: ByteString -> Response -> Maybe Cookie
- getResponseCookies :: Response -> [Cookie]
- deleteResponseCookie :: ByteString -> Response -> Response
- modifyResponseCookie :: ByteString -> (Cookie -> Cookie) -> Response -> Response
- setContentLength :: Word64 -> Response -> Response
- clearContentLength :: Response -> Response
- formatLogTime :: CTime -> IO ByteString
- formatHttpTime :: CTime -> IO ByteString
- parseHttpTime :: ByteString -> IO CTime
- statusReasonMap :: IntMap ByteString
- rqRemoteAddr :: Request -> ByteString
- rqRemotePort :: Request -> Int

# Documentation

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 () #

class HasHeaders a where #

A typeclass for datatypes which contain HTTP headers.

Methods

updateHeaders :: (Headers -> Headers) -> a -> a #

Modify the datatype's headers.

headers :: a -> Headers #

Retrieve the headers from a datatype that has headers.

#### Instances

Instances details

HasHeaders Request # |
Instance details Defined in Snap.Internal.Http.Types Methods updateHeaders :: (Headers -> Headers) -> Request -> Request # headers :: Request -> Headers #
HasHeaders Response # |
Instance details Defined in Snap.Internal.Http.Types Methods updateHeaders :: (Headers -> Headers) -> Response -> Response # headers :: Response -> Headers #
HasHeaders Headers # |
Instance details Defined in Snap.Internal.Http.Types Methods updateHeaders :: (Headers -> Headers) -> Headers -> Headers # headers :: Headers -> Headers #

addHeader :: HasHeaders a => CI ByteString -> ByteString -> a -> a #

Adds a header key-value-pair to the `HasHeaders` datatype. If a header with the same name already exists, the new value is appended to the headers list.

Example:

    ghci> import qualified Snap.Types.Headers as H
    ghci> addHeader "Host" "localhost" H.empty
    H {unH = [("host","localhost")]}
    ghci> addHeader "Host" "127.0.0.1" it
    H {unH = [("host","localhost,127.0.0.1")]}

setHeader :: HasHeaders a => CI ByteString -> ByteString -> a -> a #

Sets a header key-value-pair in a `HasHeaders` datatype. If a header with the same name already exists, it is overwritten with the new value.

Example:

    ghci> import qualified Snap.Types.Headers as H
    ghci> setHeader "Host" "localhost" H.empty
    H {unH = [("host","localhost")]}
    ghci> setHeader "Host" "127.0.0.1" it
    H {unH = [("host","127.0.0.1")]}

getHeader :: HasHeaders a => CI ByteString -> a -> Maybe ByteString #

Gets a header value out of a `HasHeaders` datatype.

Example:

    ghci> import qualified Snap.Types.Headers as H
    ghci> getHeader "Host" $ setHeader "Host" "localhost" H.empty
    Just "localhost"

listHeaders :: HasHeaders a => a -> [(CI ByteString, ByteString)] #

Lists all the headers out of a `HasHeaders` datatype. If many headers came in with the same name, they will be catenated together.

Example:

    ghci> import qualified Snap.Types.Headers as H
    ghci> listHeaders $ setHeader "Host" "localhost" H.empty
    [("host","localhost")]

deleteHeader :: HasHeaders a => CI ByteString -> a -> a #

Clears a header value from a `HasHeaders` datatype.

Example:

    ghci> import qualified Snap.Types.Headers as H
    ghci> deleteHeader "Host" $ setHeader "Host" "localhost" H.empty
    H {unH = []}

data Method #

Enumerates the HTTP method values (see http://tools.ietf.org/html/rfc2068.html#section-5.1.1).

Constructors

GET |
HEAD |
POST |
PUT |
DELETE |
TRACE |
OPTIONS |
CONNECT |
PATCH |
Method ByteString |

#### Instances

Instances details

Read Method # |
Instance details Defined in Snap.Internal.Http.Types Methods readsPrec :: Int -> ReadS Method # readList :: ReadS [Method] # readPrec :: ReadPrec Method # readListPrec :: ReadPrec [Method] #
Show Method # |
Instance details Defined in Snap.Internal.Http.Types Methods showsPrec :: Int -> Method -> ShowS # show :: Method -> String # showList :: [Method] -> ShowS #
Eq Method # |
Instance details Defined in Snap.Internal.Http.Types Methods (==) :: Method -> Method -> Bool # (/=) :: Method -> Method -> Bool #
Ord Method # |
Instance details Defined in Snap.Internal.Http.Types Methods compare :: Method -> Method -> Ordering # (<) :: Method -> Method -> Bool # (<=) :: Method -> Method -> Bool # (>) :: Method -> Method -> Bool # (>=) :: Method -> Method -> Bool # max :: Method -> Method -> Method # min :: Method -> Method -> Method #

normalizeMethod :: Method -> Method #

Equate the special case constructors with their corresponding `Method name` variant.

type HttpVersion = (Int, Int) #

Represents a (major, minor) version of the HTTP protocol.

data Cookie #

A datatype representing an HTTP cookie.

Constructors

Cookie |

Fields

- cookieName :: !ByteString

  The name of the cookie.

- cookieValue :: !ByteString

  The cookie's string value.

- cookieExpires :: !(Maybe UTCTime)

  The cookie's expiration value, if it has one.

- cookieDomain :: !(Maybe ByteString)

  The cookie's "domain" value, if it has one.

- cookiePath :: !(Maybe ByteString)

  The cookie path.

- cookieSecure :: !Bool

  Tag as secure cookie?

- cookieHttpOnly :: !Bool

  HTTP only?

#### Instances

Instances details

Show Cookie # |
Instance details Defined in Snap.Internal.Http.Types Methods showsPrec :: Int -> Cookie -> ShowS # show :: Cookie -> String # showList :: [Cookie] -> ShowS #
Eq Cookie # |
Instance details Defined in Snap.Internal.Http.Types Methods (==) :: Cookie -> Cookie -> Bool # (/=) :: Cookie -> Cookie -> Bool #

type Params = Map ByteString [ByteString] #

A type alias for the HTTP parameters mapping. Each parameter key maps to a list of `ByteString` values; if a parameter is specified multiple times (e.g.: "`GET /foo?param=bar1&param=bar2`"), looking up "`param`" in the mapping will give you `["bar1", "bar2"]`.

data Request #

Contains all of the information about an incoming HTTP request.

Constructors

Request |

Fields

- rqHostName :: ByteString

  The server name of the request, as it came in from the request's `Host:` header.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> :{
      ghci| rq <- T.buildRequest $ do
      ghci|         T.get "/foo/bar" M.empty
      ghci|         T.setHeader "host" "example.com"
      ghci| :}
      ghci> rqHostName rq
      "example.com"

- rqClientAddr :: ByteString

  The remote IP address.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqClientAddr `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      "127.0.0.1"

- rqClientPort :: !Int

  The remote TCP port number.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqClientPort `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      "60000"

- rqServerAddr :: ByteString

  The local IP address for this request.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqServerAddr `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      "127.0.0.1"

- rqServerPort :: !Int

  Returns the port number the HTTP server is listening on. This may be useless from the perspective of external requests, e.g. if the server is running behind a proxy.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqServerPort `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      8080

- rqLocalHostname :: ByteString

  Returns the HTTP server's idea of its local hostname, including port. This is as configured with the `Config` object at startup.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqLocalHostname `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      "localhost"

- rqIsSecure :: !Bool

  Returns `True` if this is an HTTPS session.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqIsSecure `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      False

- rqHeaders :: Headers

  Contains all HTTP `Headers` associated with this request.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqHeaders `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      H {unH = [("host","localhost")]}

- rqBody :: InputStream ByteString

  Actual body of the request.

- rqContentLength :: !(Maybe Word64)

  Returns the `Content-Length` of the HTTP request body.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqContentLength `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      Nothing

- rqMethod :: !Method

  Returns the HTTP request method.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqMethod `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      GET

- rqVersion :: !HttpVersion

  Returns the HTTP version used by the client.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqVersion `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      (1,1)

- rqCookies :: [Cookie]

  Returns a list of the cookies that came in from the HTTP request headers.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqCookies `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      []

- rqPathInfo :: ByteString

  Handlers can be hung on a `URI` "entry point"; this is called the "context path". If a handler is hung on the context path `"/foo/"`, and you request `"/foo/bar"`, the value of `rqPathInfo` will be `"bar"`.

  The following identity holds:

      rqURI r == S.concat [ rqContextPath r
                          , rqPathInfo r
                          , let q = rqQueryString r
                            in if S.null q
                                 then ""
                                 else S.append "?" q
                          ]

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqPathInfo `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      "foo/bar"

- rqContextPath :: ByteString

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

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqContextPath `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      "/"

- rqURI :: ByteString

  Returns the `URI` requested by the client.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rqURI `fmap` T.buildRequest (T.get "/foo/bar" M.empty)
      "foo/bar"

- rqQueryString :: ByteString

  Returns the HTTP query string for this `Request`.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> rq <- T.buildRequest (T.get "/foo/bar" (M.fromList [("name", ["value"])]))
      ghci> rqQueryString rq
      "name=value"

- rqParams :: Params

  Returns the parameters mapping for this `Request`. "Parameters" are automatically decoded from the URI's query string and `POST` body and entered into this mapping. The `rqParams` value is thus a union of `rqQueryParams` and `rqPostParams`.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> :{
      ghci| rq <- T.buildRequest $ do
      ghci|         T.postUrlEncoded "/foo/bar" $ M.fromList [("baz", ["qux"])]
      ghci|         T.setQueryStringRaw "baz=quux"
      ghci| :}
      ghci> rqParams rq
      fromList [("baz",["qux","quux"])]

- rqQueryParams :: Params

  The parameter mapping decoded from the URI's query string.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> :{
      ghci| rq <- T.buildRequest $ do
      ghci|         T.postUrlEncoded "/foo/bar" $ M.fromList [("baz", ["qux"])]
      ghci|         T.setQueryStringRaw "baz=quux"
      ghci| :}
      ghci> rqQueryParams rq
      fromList [("baz",["quux"])]

- rqPostParams :: Params

  The parameter mapping decoded from the POST body. Note that Snap only auto-decodes POST request bodies when the request's `Content-Type` is `application/x-www-form-urlencoded`. For `multipart/form-data` use `handleFileUploads` to decode the POST request and fill this mapping.

  Example:

      ghci> :set -XOverloadedStrings
      ghci> import qualified Snap.Test as T
      ghci> import qualified Data.Map as M
      ghci> :{
      ghci| rq <- T.buildRequest $ do
      ghci|         T.postUrlEncoded "/foo/bar" $ M.fromList [("baz", ["qux"])]
      ghci|         T.setQueryStringRaw "baz=quux"
      ghci| :}
      ghci> rqPostParams rq
      fromList [("baz",["qux"])]

#### Instances

Instances details

Show Request # |
Instance details Defined in Snap.Internal.Http.Types Methods showsPrec :: Int -> Request -> ShowS # show :: Request -> String # showList :: [Request] -> ShowS #
HasHeaders Request # |
Instance details Defined in Snap.Internal.Http.Types Methods updateHeaders :: (Headers -> Headers) -> Request -> Request # headers :: Request -> Headers #
Monad m => MonadState Request (RequestBuilder m) # |
Instance details Defined in Snap.Internal.Test.RequestBuilder Methods get :: RequestBuilder m Request # put :: Request -> RequestBuilder m () # state :: (Request -> (a, Request)) -> RequestBuilder m a #

type StreamProc = OutputStream Builder -> IO (OutputStream Builder) #

data ResponseBody #

Constructors

Stream StreamProc | output body is a function that writes to a `Builder` stream
SendFile FilePath (Maybe (Word64, Word64)) | output body is sendfile(), optional second argument is a byte range to send

rspBodyMap :: (StreamProc -> StreamProc) -> ResponseBody -> ResponseBody #

rspBodyToEnum :: ResponseBody -> StreamProc #

data Response #

Represents an HTTP response.

Constructors

Response |

Fields

- rspHeaders :: Headers
- rspCookies :: Map ByteString Cookie
- rspContentLength :: !(Maybe Word64)

  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.

- rspBody :: ResponseBody
- rspStatus :: !Int

  Returns the HTTP status code.

  Example:

      ghci> rspStatus emptyResponse
      200

- rspStatusReason :: !ByteString

  Returns the HTTP status explanation string.

  Example:

      ghci> rspStatusReason emptyResponse
      OK

- rspTransformingRqBody :: !Bool

  If true, we are transforming the request body with `transformRequestBody`

#### Instances

Instances details

Show Response # |
Instance details Defined in Snap.Internal.Http.Types Methods showsPrec :: Int -> Response -> ShowS # show :: Response -> String # showList :: [Response] -> ShowS #
HasHeaders Response # |
Instance details Defined in Snap.Internal.Http.Types Methods updateHeaders :: (Headers -> Headers) -> Response -> Response # headers :: Response -> Headers #

rqParam #

Arguments

:: ByteString | parameter name to look up
-> Request | HTTP request
-> Maybe [ByteString] |

Looks up the value(s) for the given named parameter. Parameters initially come from the request's query string and any decoded POST body (if the request's `Content-Type` is `application/x-www-form-urlencoded`). Parameter values can be modified within handlers using "rqModifyParams".

Example:

    ghci> :set -XOverloadedStrings
    ghci> import qualified Snap.Test as T
    ghci> import qualified Data.Map as M
    ghci> :{
    ghci| rq <- T.buildRequest $ do
    ghci|         T.postUrlEncoded "/foo/bar" $ M.fromList [("baz", ["qux"])]
    ghci|         T.setQueryStringRaw "baz=quux"
    ghci| :}
    ghci> rqParam "baz" rq
    Just ["qux","quux"]

rqPostParam #

Arguments

:: ByteString | parameter name to look up
-> Request | HTTP request
-> Maybe [ByteString] |

Looks up the value(s) for the given named parameter in the POST parameters mapping.

Example:

    ghci> :set -XOverloadedStrings
    ghci> import qualified Snap.Test as T
    ghci> import qualified Data.Map as M
    ghci> :{
    ghci| rq <- T.buildRequest $ do
    ghci|         T.postUrlEncoded "/foo/bar" $ M.fromList [("baz", ["qux"])]
    ghci|         T.setQueryStringRaw "baz=quux"
    ghci| :}
    ghci> rqPostParam "baz" rq
    Just ["qux"]

rqQueryParam #

Arguments

:: ByteString | parameter name to look up
-> Request | HTTP request
-> Maybe [ByteString] |

Looks up the value(s) for the given named parameter in the query parameters mapping.

Example:

    ghci> :set -XOverloadedStrings
    ghci> import qualified Snap.Test as T
    ghci> import qualified Data.Map as M
    ghci> :{
    ghci| rq <- T.buildRequest $ do
    ghci|         T.postUrlEncoded "/foo/bar" $ M.fromList [("baz", ["qux"])]
    ghci|         T.setQueryStringRaw "baz=quux"
    ghci| :}
    ghci> rqQueryParam "baz" rq
    Just ["quux"]

rqModifyParams :: (Params -> Params) -> Request -> Request #

Modifies the parameters mapping (which is a `Map ByteString ByteString`) in a `Request` using the given function.

Example:

    ghci> :set -XOverloadedStrings
    ghci> import qualified Snap.Test as T
    ghci> import qualified Data.Map as M
    ghci> :{
    ghci| rq <- T.buildRequest $ do
    ghci|         T.postUrlEncoded "/foo/bar" $ M.fromList [("baz", ["qux"])]
    ghci|         T.setQueryStringRaw "baz=quux"
    ghci| :}
    ghci> rqParams rq
    fromList [("baz",["qux","quux"])]
    ghci> rqParams $ rqModifyParams (M.delete "baz") rq
    fromList []

rqSetParam #

Arguments

:: ByteString | parameter name
-> [ByteString] | parameter values
-> Request | request
-> Request |

Writes a key-value pair to the parameters mapping within the given request.

Example:

    ghci> :set -XOverloadedStrings
    ghci> import qualified Snap.Test as T
    ghci> import qualified Data.Map as M
    ghci> :{
    ghci| rq <- T.buildRequest $ do
    ghci|         T.postUrlEncoded "/foo/bar" $ M.fromList [("baz", ["qux"])]
    ghci|         T.setQueryStringRaw "baz=quux"
    ghci| :}
    ghci> rqParams rq
    fromList [("baz",["qux","quux"])]
    ghci> rqParams $ rqSetParam "baz" ["corge"] rq
    fromList [("baz", ["corge"])]

emptyResponse :: Response #

An empty `Response`.

Example:

    ghci> emptyResponse
    HTTP/1.1 200 OK

setResponseBody #

Arguments

:: (OutputStream Builder -> IO (OutputStream Builder)) | new response body
-> Response | response to modify
-> Response |

Sets an HTTP response body to the given stream procedure.

Example:

    ghci> :set -XOverloadedStrings
    ghci> import qualified System.IO.Streams as Streams
    ghci> import qualified Data.ByteString.Builder as Builder
    ghci> :{
    ghci| let r = setResponseBody
    ghci|         (out -> do
    ghci|             Streams.write (Just $ Builder.byteString "Hello, world!") out
    ghci|             return out)
    ghci|         emptyResponse
    ghci| :}
    ghci> r
    HTTP/1.1 200 OK

    Hello, world!

setResponseStatus #

Arguments

:: Int | HTTP response integer code
-> ByteString | HTTP response explanation
-> Response | Response to be modified
-> Response |

Sets the HTTP response status. Note: normally you would use `setResponseCode` unless you needed a custom response explanation.

Example:

    ghci> :set -XOverloadedStrings
    ghci> setResponseStatus 500 "Internal Server Error" emptyResponse
    HTTP/1.1 500 Internal Server Error

setResponseCode #

Arguments

:: Int | HTTP response integer code
-> Response | Response to be modified
-> Response |

Sets the HTTP response code.

Example:

    ghci> setResponseCode 404 emptyResponse
    HTTP/1.1 404 Not Found

modifyResponseBody :: ((OutputStream Builder -> IO (OutputStream Builder)) -> OutputStream Builder -> IO (OutputStream Builder)) -> Response -> Response #

Modifies a response body.

Example:

    ghci> :set -XOverloadedStrings
    ghci> import qualified System.IO.Streams as Streams
    ghci> import qualified Data.ByteString.Builder as Builder
    ghci> :{
    ghci| let r = setResponseBody
    ghci|         (out -> do
    ghci|             Streams.write (Just $ Builder.byteString "Hello, world!") out
    ghci|             return out)
    ghci|         emptyResponse
    ghci| :}
    ghci> r
    HTTP/1.1 200 OK

    Hello, world!
    ghci> :{
    ghci| let r' = modifyResponseBody
    ghci|          (f out -> do
    ghci|              out' <- f out
    ghci|              Streams.write (Just $ Builder.byteString "\nBye, world!") out'
    ghci|              return out') r
    ghci| :}
    ghci> r'
    HTTP/1.1 200 OK

    Hello, world!
    Bye, world!

setContentType :: ByteString -> Response -> Response #

Sets the `Content-Type` in the `Response` headers.

Example:

    ghci> :set -XOverloadedStrings
    ghci> setContentType "text/html" emptyResponse
    HTTP/1.1 200 OK
    content-type: text/html

cookieToBS :: Cookie -> ByteString #

Convert `Cookie` into `ByteString` for output.

TODO: Remove duplication. This function is copied from snap-server/Snap.Internal.Http.Server.Session.

renderCookies :: Response -> Headers -> Headers #

Render cookies from a given `Response` to `Headers`.

TODO: Remove duplication. This function is copied from snap-server/Snap.Internal.Http.Server.Session.

addResponseCookie #

Arguments

:: Cookie | cookie value
-> Response | response to modify
-> Response |

Adds an HTTP `Cookie` to `Response` headers.

Example:

    ghci> :set -XOverloadedStrings
    ghci> let cookie = Cookie "name" "value" Nothing Nothing Nothing False False
    ghci> getResponseCookie "name" $ addResponseCookie cookie emptyResponse
    Just (Cookie {cookieName = "name", cookieValue = "value", ...})

getResponseCookie #

Arguments

:: ByteString | cookie name
-> Response | response to query
-> Maybe Cookie |

Gets an HTTP `Cookie` with the given name from `Response` headers.

Example:

    ghci> :set -XOverloadedStrings
    ghci> getResponseCookie "cookie-name" emptyResponse
    Nothing

getResponseCookies #

Arguments

:: Response | response to query
-> [Cookie] |

Returns a list of `Cookie`s present in `Response`

Example:

    ghci> getResponseCookies emptyResponse
    []

deleteResponseCookie #

Arguments

:: ByteString | cookie name
-> Response | response to modify
-> Response |

Deletes an HTTP `Cookie` from the `Response` headers. Please note this does not necessarily erase the cookie from the client browser.

Example:

    ghci> :set -XOverloadedStrings
    ghci> let cookie = Cookie "name" "value" Nothing Nothing Nothing False False
    ghci> let rsp    = addResponseCookie cookie emptyResponse
    ghci> getResponseCookie "name" rsp
    Just (Cookie {cookieName = "name", cookieValue = "value", ...})
    ghci> getResponseCookie "name" $ deleteResponseCookie "name" rsp
    Nothing

modifyResponseCookie #

Arguments

:: ByteString | cookie name
-> (Cookie -> Cookie) | modifier function
-> Response | response to modify
-> Response |

Modifies an HTTP `Cookie` with given name in `Response` headers. Nothing will happen if a matching `Cookie` can not be found in `Response`.

Example:

    ghci> :set -XOverloadedStrings
    ghci> import Data.Monoid
    ghci> let cookie = Cookie "name" "value" Nothing Nothing Nothing False False
    ghci> let rsp    = addResponseCookie cookie emptyResponse
    ghci> getResponseCookie "name" rsp
    Just (Cookie {cookieName = "name", cookieValue = "value", ...})
    ghci> let f ck@(Cookie { cookieName = name }) = ck { cookieName = name <> "'"}
    ghci> let rsp' = modifyResponseCookie "name" f rsp
    ghci> getResponseCookie "name'" rsp'
    Just (Cookie {cookieName = "name'", ...})
    ghci> getResponseCookie "name" rsp'
    Just (Cookie {cookieName = "name", ...})

setContentLength :: Word64 -> Response -> Response #

A note here: if you want to set the `Content-Length` for the response, Snap forces you to do it with this function rather than by setting it in the headers; the `Content-Length` in the headers will be ignored.

The reason for this is that Snap needs to look up the value of `Content-Length` for each request, and looking the string value up in the headers and parsing the number out of the text will be too expensive.

If you don't set a content length in your response, HTTP keep-alive will be disabled for HTTP/1.0 clients, forcing a `Connection: close`. For HTTP/1.1 clients, Snap will switch to the chunked transfer encoding if `Content-Length` is not specified.

Example:

    ghci> setContentLength 400 emptyResponse
    HTTP/1.1 200 OK
    Content-Length: 400

clearContentLength :: Response -> Response #

Removes any `Content-Length` set in the `Response`.

Example:

    ghci> clearContentLength $ setContentLength 400 emptyResponse
    HTTP/1.1 200 OK

formatLogTime :: CTime -> IO ByteString #

Convert a `CTime` into common log entry format.

formatHttpTime :: CTime -> IO ByteString #

Convert a `CTime` into an HTTP timestamp.

Example:

    ghci> formatHttpTime . fromIntegral $ 10
    "Thu, 01 Jan 1970 00:00:10 GMT"

parseHttpTime :: ByteString -> IO CTime #

Converts an HTTP timestamp into a `CTime`.

If the given time string is unparseable, this function will return 0.

Example:

    ghci> :set -XOverloadedStrings
    ghci> parseHttpTime "Thu, 01 Jan 1970 00:00:10 GMT"
    10

statusReasonMap :: IntMap ByteString #

Adapted from:

https://www.iana.org/assignments/http-status-codes/http-status-codes.txt

rqRemoteAddr :: Request -> ByteString #

Deprecated: (snap-core >= 1.0.0.0) please use `rqClientAddr`, this will be removed in 1.1.*

See `rqClientAddr`.

rqRemotePort :: Request -> Int #

Deprecated: (snap-core >= 1.0.0.0) please use `rqClientPort`, this will be removed in 1.1.*

See `rqClientPort`.