module Network.HTTP.Lucu.Request ( Method(..) , Request , requestP -- Parser Request ) where import qualified Data.ByteString.Lazy.Char8 as B import Data.ByteString.Lazy.Char8 (ByteString) 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 | PUT | DELETE | TRACE | CONNECT | ExtensionMethod String deriving (Eq, Show) data Request = Request { reqMethod :: Method , reqURI :: URI , reqVersion :: HttpVersion , reqHeaders :: Headers , reqBody :: Maybe ByteString } deriving (Show) instance HasHeaders Request where getHeaders = reqHeaders setHeaders req hdr = req { reqHeaders = hdr } requestP :: Parser Request requestP = do many crlf (method, uri, version) <- requestLineP let req = Request { reqMethod = method , reqURI = uri , reqVersion = version , reqHeaders = emptyHeaders -- FIXME , reqBody = Nothing -- FIXME } return req 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 ) , ("PUT" , PUT ) , ("DELETE" , DELETE ) , ("TRACE" , TRACE ) , ("CONNECT", CONNECT) ] in foldl (<|>) (fail "") $ map (\ (str, mth) -> string str >> return mth) methods) <|> many1 token >>= return . ExtensionMethod uriP :: Parser URI uriP = do str <- many1 $ satisfy (\ c -> not (isCtl c || c == ' ')) case parseURIReference str of Nothing -> fail "" Just uri -> return uri