Modulesnap-core-1.0.5.1Haskell2010
Snap.Internal.Http.Types
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.
- 8 types
- 1 class
- 38 values
- Packagesnap-core-1.0.5.1
- Exports47
- LanguageHaskell2010
- LicenceBSD-3-Clause
- SourceTypes.hs
A typeclass for datatypes which contain HTTP headers.
Methods
updateHeaders :: (Headers -> Headers) -> a -> aModify the datatype's headers.
headers :: a -> HeadersRetrieve the headers from a datatype that has headers.
Instances3HasHeaders
HasHeaders RequestDefined in snap-core-1.0.5.1 · Snap.Internal.Http.TypesHasHeaders ResponseDefined in snap-core-1.0.5.1 · Snap.Internal.Http.TypesHasHeaders HeadersDefined in snap-core-1.0.5.1 · Snap.Internal.Http.Types
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")]}
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")]}
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"
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")]
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 = []}
Enumerates the HTTP method values (see http://tools.ietf.org/html/rfc2068.html#section-5.1.1).
Equate the special case constructors with their corresponding
Method name variant.
Represents a (major, minor) version of the HTTP protocol.
A datatype representing an HTTP cookie.
Constructors
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"].
Contains all of the information about an incoming HTTP request.
Constructors
RequestrqHostName :: ByteStringThe 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 :: ByteStringrqClientPort :: !IntrqServerAddr :: ByteStringrqServerPort :: !IntReturns 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) 8080rqLocalHostname :: ByteStringReturns the HTTP server's idea of its local hostname, including port. This is as configured with the
Configobject 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 :: !BoolrqHeaders :: HeadersrqBody :: InputStream ByteStringActual body of the request.
rqContentLength :: !Maybe Word64rqMethod :: !MethodrqVersion :: !HttpVersionrqCookies :: [Cookie]rqPathInfo :: ByteStringHandlers 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 :: ByteStringThe "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 :: ByteStringrqQueryString :: ByteStringrqParams :: ParamsReturns the parameters mapping for this Request. "Parameters" are automatically decoded from the URI's query string and
POSTbody 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 :: ParamsThe 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 :: ParamsThe parameter mapping decoded from the POST body. Note that Snap only auto-decodes POST request bodies when the request's
Content-Typeisapplication/x-www-form-urlencoded. Formultipart/form-datause 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"])]
Instances3Show, HasHeaders, MonadState
Show RequestDefined in snap-core-1.0.5.1 · Snap.Internal.Http.TypesHasHeaders RequestDefined in snap-core-1.0.5.1 · Snap.Internal.Http.TypesMonad m => MonadState Request (RequestBuilder m)Defined in snap-core-1.0.5.1 · Snap.Internal.Test.RequestBuilder
Represents an HTTP response.
Constructors
ResponserspHeaders :: HeadersrspCookies :: Map ByteString CookierspContentLength :: !Maybe Word64We 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 :: ResponseBodyrspStatus :: !IntrspStatusReason :: !ByteStringrspTransformingRqBody :: !BoolIf true, we are transforming the request body with
transformRequestBody
Instances2Show, HasHeaders
Show ResponseDefined in snap-core-1.0.5.1 · Snap.Internal.Http.TypesHasHeaders ResponseDefined in snap-core-1.0.5.1 · Snap.Internal.Http.Types
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"]
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"]
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"]
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 :: ByteStringparameter name
-> [ByteString]parameter values
-> Requestrequest
-> 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"])]
setResponseBody :: (OutputStream Builder -> IO (OutputStream Builder))new response body
-> Responseresponse 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 :: IntHTTP response integer code
-> ByteStringHTTP response explanation
-> ResponseResponse 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
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!
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
Convert Cookie into ByteString for output.
TODO: Remove duplication. This function is copied from snap-server/Snap.Internal.Http.Server.Session.
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", ...})
Gets an HTTP Cookie with the given name from Response headers.
Example:
ghci> :set -XOverloadedStrings
ghci> getResponseCookie "cookie-name" emptyResponse
Nothing
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 :: ByteStringcookie name
-> (Cookie -> Cookie)modifier function
-> Responseresponse 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", ...})
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
Removes any Content-Length set in the Response.
Example:
ghci> clearContentLength $ setContentLength 400 emptyResponse
HTTP/1.1 200 OK
Convert a CTime into common log entry format.
Convert a CTime into an HTTP timestamp.
Example:
ghci> formatHttpTime . fromIntegral $ 10
"Thu, 01 Jan 1970 00:00:10 GMT"
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
Deprecated. (snap-core >= 1.0.0.0) please use rqClientAddr, this will be removed in 1.1.*
See rqClientAddr.
Deprecated. (snap-core >= 1.0.0.0) please use rqClientPort, this will be removed in 1.1.*
See rqClientPort.