| |||||||||||||||||||||
| |||||||||||||||||||||
| |||||||||||||||||||||
Description | |||||||||||||||||||||
This module contains the core type definitions, class instances, and functions for HTTP as well as the Snap monad, which is used for web handlers. | |||||||||||||||||||||
Synopsis | |||||||||||||||||||||
The Snap Monad | |||||||||||||||||||||
data Snap a | |||||||||||||||||||||
| |||||||||||||||||||||
runSnap :: Snap a -> (ByteString -> IO ()) -> Request -> Iteratee IO (Request, Response) | |||||||||||||||||||||
Runs a Snap monad action in the 'Iteratee IO' monad. | |||||||||||||||||||||
data NoHandlerException | |||||||||||||||||||||
| |||||||||||||||||||||
Functions for control flow and early termination | |||||||||||||||||||||
finishWith :: Response -> Snap a | |||||||||||||||||||||
Short-circuits a Snap monad action early, storing the given Response value in its state. | |||||||||||||||||||||
pass :: Snap a | |||||||||||||||||||||
Fails out of a Snap monad action. This is used to indicate that you choose not to handle the given request within the given handler. | |||||||||||||||||||||
Routing | |||||||||||||||||||||
method :: Method -> Snap a -> Snap a | |||||||||||||||||||||
Runs a Snap monad action only if the request's HTTP method matches the given method. | |||||||||||||||||||||
path | |||||||||||||||||||||
| |||||||||||||||||||||
dir | |||||||||||||||||||||
| |||||||||||||||||||||
ifTop :: Snap a -> Snap a | |||||||||||||||||||||
Runs a Snap monad action only when rqPathInfo is empty. | |||||||||||||||||||||
route :: [(ByteString, Snap a)] -> Snap a | |||||||||||||||||||||
A web handler which, given a mapping from URL entry points to web handlers, efficiently routes requests to the correct handler. The URL entry points are given as relative paths, for example: route [ ("foo/bar/quux", fooBarQuux) ] If the URI of the incoming request is /foo/bar/quux or /foo/bar/quux/...anything... then the request will be routed to "fooBarQuux", with rqContextPath set to "/foo/bar/quux/" and rqPathInfo set to "...anything...". A path component within an URL entry point beginning with a colon (":") is treated as a variable capture; the corresponding path component within the request URI will be entered into the rqParams parameters mapping with the given name. For instance, if the routes were: route [ ("foo/:bar/baz", fooBazHandler) ] Then a request for "/foo/saskatchewan/baz" would be routed to fooBazHandler with a mapping for: "bar" => "saskatchewan" in its parameters table. Longer paths are matched first, and specific routes are matched before captures. That is, if given routes: [ ("a", h1), ("a/b", h2), ("a/:x", h3) ] a request for "/a/b" will go to h2, "/a/s" for any s will go to h3, and "/a" will go to h1. The following example matches "/article" to an article index, "/login" to a login, and "/article/..." to an article renderer. route [ ("article", renderIndex) , ("article/:id", renderArticle) , ("login", method POST doLogin) ] | |||||||||||||||||||||
routeLocal :: [(ByteString, Snap a)] -> Snap a | |||||||||||||||||||||
The routeLocal function is the same as route', except it doesn't change the request's context path. This is useful if you want to route to a particular handler but you want that handler to receive the rqPathInfo as it is. | |||||||||||||||||||||
Access to state | |||||||||||||||||||||
getRequest :: Snap Request | |||||||||||||||||||||
Grabs the Request object out of the Snap monad. | |||||||||||||||||||||
getResponse :: Snap Response | |||||||||||||||||||||
Grabs the Response object out of the Snap monad. | |||||||||||||||||||||
putRequest :: Request -> Snap () | |||||||||||||||||||||
Puts a new Request object into the Snap monad. | |||||||||||||||||||||
putResponse :: Response -> Snap () | |||||||||||||||||||||
Puts a new Response object into the Snap monad. | |||||||||||||||||||||
modifyRequest :: (Request -> Request) -> Snap () | |||||||||||||||||||||
Modifies the Request object stored in a Snap monad. | |||||||||||||||||||||
modifyResponse :: (Response -> Response) -> Snap () | |||||||||||||||||||||
Modifes the Response object stored in a Snap monad. | |||||||||||||||||||||
localRequest :: (Request -> Request) -> Snap a -> Snap a | |||||||||||||||||||||
Runs a Snap action with a locally-modified Request state object. The Request object in the Snap monad state after the call to localRequest will be unchanged. | |||||||||||||||||||||
withRequest :: (Request -> Snap a) -> Snap a | |||||||||||||||||||||
Fetches the Request from state and hands it to the given action. | |||||||||||||||||||||
withResponse :: (Response -> Snap a) -> Snap a | |||||||||||||||||||||
Fetches the Response from state and hands it to the given action. | |||||||||||||||||||||
Logging | |||||||||||||||||||||
logError :: ByteString -> Snap () | |||||||||||||||||||||
Log an error message in the Snap monad | |||||||||||||||||||||
Grabbing/transforming request bodies | |||||||||||||||||||||
runRequestBody :: Iteratee IO a -> Snap a | |||||||||||||||||||||
Sends the request body through an iteratee (data consumer) and returns the result. | |||||||||||||||||||||
getRequestBody :: Snap ByteString | |||||||||||||||||||||
Returns the request body as a bytestring. | |||||||||||||||||||||
transformRequestBody | |||||||||||||||||||||
| |||||||||||||||||||||
HTTP Datatypes and Functions | |||||||||||||||||||||
HTTP-related datatypes: Request, Response, Cookie, etc. | |||||||||||||||||||||
data Request | |||||||||||||||||||||
| |||||||||||||||||||||
data Response | |||||||||||||||||||||
| |||||||||||||||||||||
type Headers = Map CIByteString [ByteString] | |||||||||||||||||||||
A type alias for a case-insensitive key-value mapping. | |||||||||||||||||||||
class HasHeaders a where | |||||||||||||||||||||
| |||||||||||||||||||||
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¶m=bar2"), looking up "param" in the mapping will give you ["bar1", "bar2"]. | |||||||||||||||||||||
data Method | |||||||||||||||||||||
| |||||||||||||||||||||
data Cookie | |||||||||||||||||||||
| |||||||||||||||||||||
type HttpVersion = (Int, Int) | |||||||||||||||||||||
Headers | |||||||||||||||||||||
addHeader :: HasHeaders a => CIByteString -> 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. | |||||||||||||||||||||
setHeader :: HasHeaders a => CIByteString -> 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. | |||||||||||||||||||||
getHeader :: HasHeaders a => CIByteString -> a -> Maybe ByteString | |||||||||||||||||||||
Gets a header value out of a HasHeaders datatype. If many headers came in with the same name, they will be catenated together. | |||||||||||||||||||||
deleteHeader :: HasHeaders a => CIByteString -> a -> a | |||||||||||||||||||||
Clears a header value from a HasHeaders datatype. | |||||||||||||||||||||
ipHeaderFilter :: Snap () | |||||||||||||||||||||
Modifies the Request in the state to set the rqRemoteAddr field to the value in the X-Forwarded-For header. If the header is not present, this action has no effect. This action should be used only when working behind a reverse http proxy that sets the X-Forwarded-For header. This is the only way to ensure the value in the X-Forwarded-For header can be trusted. This is provided as a filter so actions that require the remote address can get it in a uniform manner. It has specifically limited functionality to ensure that its transformation can be trusted, when used correctly. | |||||||||||||||||||||
ipHeaderFilter' :: CIByteString -> Snap () | |||||||||||||||||||||
Modifies the Request in the state to set the rqRemoteAddr field to the value from the header specified. If the header specified is not present, this action has no effect. This action should be used only when working behind a reverse http proxy that sets the header being looked at. This is the only way to ensure the value in the header can be trusted. This is provided as a filter so actions that require the remote address can get it in a uniform manner. It has specifically limited functionality to ensure that its transformation can be trusted, when used correctly. | |||||||||||||||||||||
Requests | |||||||||||||||||||||
rqServerName :: Request -> ByteString | |||||||||||||||||||||
The server name of the request, as it came in from the request's Host: header. | |||||||||||||||||||||
rqServerPort :: Request -> Int | |||||||||||||||||||||
Returns the port number the HTTP server is listening on. | |||||||||||||||||||||
rqRemoteAddr :: Request -> ByteString | |||||||||||||||||||||
The remote IP address. | |||||||||||||||||||||
rqRemotePort :: Request -> Int | |||||||||||||||||||||
The remote TCP port number. | |||||||||||||||||||||
rqLocalAddr :: Request -> ByteString | |||||||||||||||||||||
The local IP address for this request. | |||||||||||||||||||||
rqLocalHostname :: Request -> ByteString | |||||||||||||||||||||
Returns the HTTP server's idea of its local hostname. | |||||||||||||||||||||
rqIsSecure :: Request -> Bool | |||||||||||||||||||||
Returns True if this is an HTTPS session (currently always False). | |||||||||||||||||||||
rqContentLength :: Request -> Maybe Int | |||||||||||||||||||||
Returns the Content-Length of the HTTP request body. | |||||||||||||||||||||
rqMethod :: Request -> Method | |||||||||||||||||||||
Returns the HTTP request method. | |||||||||||||||||||||
rqVersion :: Request -> HttpVersion | |||||||||||||||||||||
Returns the HTTP version used by the client. | |||||||||||||||||||||
rqCookies :: Request -> [Cookie] | |||||||||||||||||||||
Returns a list of the cookies that came in from the HTTP request headers. | |||||||||||||||||||||
rqPathInfo :: Request -> ByteString | |||||||||||||||||||||
Handlers can (will be; --ed) be hung on a URI "entry point"; this is called the "context path". If a handler is hung on the context path "/foo/", and you request "/foo/bar", the value of rqPathInfo will be "bar". | |||||||||||||||||||||
rqContextPath :: Request -> ByteString | |||||||||||||||||||||
The "context path" of the request; catenating rqContextPath, and rqPathInfo should get you back to the original rqURI. 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. | |||||||||||||||||||||
rqURI :: Request -> ByteString | |||||||||||||||||||||
Returns the URI requested by the client. | |||||||||||||||||||||
rqQueryString :: Request -> ByteString | |||||||||||||||||||||
Returns the HTTP query string for this Request. | |||||||||||||||||||||
rqParams :: Request -> Params | |||||||||||||||||||||
Returns the Params mapping for this Request. "Parameters" are automatically decoded from the query string and POST body and entered into this mapping. | |||||||||||||||||||||
rqParam | |||||||||||||||||||||
| |||||||||||||||||||||
getParam | |||||||||||||||||||||
| |||||||||||||||||||||
rqModifyParams :: (Params -> Params) -> Request -> Request | |||||||||||||||||||||
Modifies the parameters mapping (which is a Map ByteString ByteString) in a Request using the given function. | |||||||||||||||||||||
rqSetParam | |||||||||||||||||||||
| |||||||||||||||||||||
Responses | |||||||||||||||||||||
emptyResponse :: Response | |||||||||||||||||||||
An empty Response. | |||||||||||||||||||||
setResponseCode | |||||||||||||||||||||
| |||||||||||||||||||||
setResponseStatus | |||||||||||||||||||||
| |||||||||||||||||||||
rspStatus :: Response -> Int | |||||||||||||||||||||
Returns the HTTP status code. | |||||||||||||||||||||
rspStatusReason :: Response -> ByteString | |||||||||||||||||||||
Returns the HTTP status explanation string. | |||||||||||||||||||||
setContentType :: ByteString -> Response -> Response | |||||||||||||||||||||
Sets the Content-Type in the Response headers. | |||||||||||||||||||||
addCookie | |||||||||||||||||||||
| |||||||||||||||||||||
setContentLength :: Int64 -> 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. | |||||||||||||||||||||
clearContentLength :: Response -> Response | |||||||||||||||||||||
Removes any Content-Length set in the Response. | |||||||||||||||||||||
redirect :: ByteString -> Snap () | |||||||||||||||||||||
Performs a redirect by setting the Location header to the given target URL/path and the status code to 302 in the Response object stored in a Snap monad. Note that the target URL is not validated in any way. Consider using 'redirect\'' instead, which allows you to choose the correct status code. | |||||||||||||||||||||
redirect' :: ByteString -> Int -> Snap () | |||||||||||||||||||||
Performs a redirect by setting the Location header to the given target URL/path and the status code (should be one of 301, 302, 303 or 307) in the Response object stored in a Snap monad. Note that the target URL is not validated in any way. | |||||||||||||||||||||
Response I/O | |||||||||||||||||||||
setResponseBody | |||||||||||||||||||||
| |||||||||||||||||||||
modifyResponseBody :: (forall a. Enumerator a -> Enumerator a) -> Response -> Response | |||||||||||||||||||||
Modifies a response body. | |||||||||||||||||||||
addToOutput | |||||||||||||||||||||
| |||||||||||||||||||||
writeBS :: ByteString -> Snap () | |||||||||||||||||||||
Adds the given strict ByteString to the body of the Response stored in the Snap monad state. Warning: This function is intentionally non-strict. If any pure exceptions are raised by the expression creating the ByteString, the exception won't actually be raised within the Snap handler. | |||||||||||||||||||||
writeLazyText :: Text -> Snap () | |||||||||||||||||||||
Adds the given lazy Text to the body of the Response stored in the Snap monad state. Warning: This function is intentionally non-strict. If any pure exceptions are raised by the expression creating the ByteString, the exception won't actually be raised within the Snap handler. | |||||||||||||||||||||
writeText :: Text -> Snap () | |||||||||||||||||||||
Adds the given strict Text to the body of the Response stored in the Snap monad state. Warning: This function is intentionally non-strict. If any pure exceptions are raised by the expression creating the ByteString, the exception won't actually be raised within the Snap handler. | |||||||||||||||||||||
writeLBS :: ByteString -> Snap () | |||||||||||||||||||||
Adds the given lazy ByteString to the body of the Response stored in the Snap monad state. Warning: This function is intentionally non-strict. If any pure exceptions are raised by the expression creating the ByteString, the exception won't actually be raised within the Snap handler. | |||||||||||||||||||||
sendFile :: FilePath -> Snap () | |||||||||||||||||||||
Sets the output to be the contents of the specified file. Calling sendFile will overwrite any output queued to be sent in the Response. If the response body is not modified after the call to sendFile, Snap will use the efficient sendfile() system call on platforms that support it. If the response body is modified (using modifyResponseBody), the file will be read using mmap(). | |||||||||||||||||||||
sendFilePartial :: FilePath -> (Int64, Int64) -> Snap () | |||||||||||||||||||||
Sets the output to be the contents of the specified file, within the given (start,end) range. Calling sendFilePartial will overwrite any output queued to be sent in the Response. If the response body is not modified after the call to sendFilePartial, Snap will use the efficient sendfile() system call on platforms that support it. If the response body is modified (using modifyResponseBody), the file will be read using mmap(). | |||||||||||||||||||||
Iteratee | |||||||||||||||||||||
type Enumerator a = Enumerator IO a | |||||||||||||||||||||
data SomeEnumerator | |||||||||||||||||||||
| |||||||||||||||||||||
HTTP utilities | |||||||||||||||||||||
formatHttpTime :: CTime -> IO ByteString | |||||||||||||||||||||
Converts a CTime into an HTTP timestamp. | |||||||||||||||||||||
parseHttpTime :: ByteString -> IO CTime | |||||||||||||||||||||
Converts an HTTP timestamp into a CTime. | |||||||||||||||||||||
urlEncode :: ByteString -> ByteString | |||||||||||||||||||||
URL-escapes a string (see http://tools.ietf.org/html/rfc2396.html#section-2.4) | |||||||||||||||||||||
urlDecode :: ByteString -> Maybe ByteString | |||||||||||||||||||||
Decodes an URL-escaped string (see http://tools.ietf.org/html/rfc2396.html#section-2.4) | |||||||||||||||||||||
Produced by Haddock version 2.7.2 |