module Network.HTTP.Lucu.Request
( Method(..)
, Request(..)
, requestP
)
where
import Network.HTTP.Lucu.Headers
import Network.HTTP.Lucu.HttpVersion
import Network.HTTP.Lucu.Parser
import Network.HTTP.Lucu.Parser.Http
import Network.URI
data Method = OPTIONS
| GET
| HEAD
| POST
| PUT
| DELETE
| TRACE
| CONNECT
| ExtensionMethod !String
deriving (Eq, Show)
data Request
= Request {
reqMethod :: !Method
, reqURI :: !URI
, reqVersion :: !HttpVersion
, reqHeaders :: !Headers
}
deriving (Show, Eq)
instance HasHeaders Request where
getHeaders = reqHeaders
setHeaders req hdr = req { reqHeaders = hdr }
requestP :: Parser Request
requestP = do many crlf
(method, uri, version) <- requestLineP
headers <- headersP
return Request {
reqMethod = method
, reqURI = uri
, reqVersion = version
, reqHeaders = headers
}
requestLineP :: Parser (Method, URI, HttpVersion)
requestLineP = do method <- methodP
sp
uri <- uriP
sp
ver <- httpVersionP
crlf
return (method, uri, ver)
methodP :: Parser Method
methodP = (let methods = [ ("OPTIONS", OPTIONS)
, ("GET" , GET )
, ("HEAD" , HEAD )
, ("POST" , POST )
, ("PUT" , PUT )
, ("DELETE" , DELETE )
, ("TRACE" , TRACE )
, ("CONNECT", CONNECT)
]
in foldl (<|>) failP $ map (\ (str, mth)
-> string str >> return mth) methods)
<|>
token >>= return . ExtensionMethod
uriP :: Parser URI
uriP = do str <- many1 $ satisfy (\ c -> not (isCtl c || c == ' '))
case parseURIReference str of
Nothing -> failP
Just uri -> return uri