X-Git-Url: http://git.cielonegro.org/gitweb.cgi?p=Lucu.git;a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FRequest.hs;fp=Network%2FHTTP%2FLucu%2FRequest.hs;h=8b516cca432b6cc5b67aa6298059c2e220806f91;hp=712a6107f2932f93d603e9e272013e65c2553578;hb=9bb89434103e9a22f100d6ecb7e65a5d461e0454;hpb=86d100e294fa482456980021cca10393b9830ec1 diff --git a/Network/HTTP/Lucu/Request.hs b/Network/HTTP/Lucu/Request.hs index 712a610..8b516cc 100644 --- a/Network/HTTP/Lucu/Request.hs +++ b/Network/HTTP/Lucu/Request.hs @@ -1,3 +1,7 @@ +{-# LANGUAGE + OverloadedStrings + , UnicodeSyntax + #-} {-# OPTIONS_HADDOCK prune #-} -- |Definition of things related on HTTP request. @@ -9,12 +13,16 @@ module Network.HTTP.Lucu.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 +import Control.Applicative +import Control.Monad.Unicode +import Data.Ascii (Ascii) +import Data.Attoparsec.Char8 +import qualified Data.ByteString.Char8 as C8 +import Network.HTTP.Lucu.Headers +import Network.HTTP.Lucu.HttpVersion +import Network.HTTP.Lucu.Parser.Http +import Network.URI +import Prelude.Unicode -- |This is the definition of HTTP request methods, which shouldn't -- require any description. @@ -26,28 +34,27 @@ data Method = OPTIONS | DELETE | TRACE | CONNECT - | ExtensionMethod !String + | ExtensionMethod !Ascii deriving (Eq, Show) -- |This is the definition of HTTP reqest. data Request = Request { - reqMethod :: !Method - , reqURI :: !URI - , reqVersion :: !HttpVersion - , reqHeaders :: !Headers + reqMethod ∷ !Method + , reqURI ∷ !URI + , reqVersion ∷ !HttpVersion + , reqHeaders ∷ !Headers } - deriving (Show, Eq) + deriving (Eq, Show) 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 +requestP ∷ Parser Request +requestP = do skipMany crlf + (method, uri, version) ← requestLineP + headers ← headersP return Request { reqMethod = method , reqURI = uri @@ -55,35 +62,32 @@ requestP = do _ <- many crlf , reqHeaders = headers } - -requestLineP :: Parser (Method, URI, HttpVersion) -requestLineP = do method <- methodP - _ <- sp - uri <- uriP - _ <- sp - ver <- httpVersionP - _ <- crlf +requestLineP ∷ Parser (Method, URI, HttpVersion) +requestLineP = do method ← methodP + sp + uri ← uriP + sp + ver ← httpVersionP + crlf return (method, uri, ver) +methodP ∷ Parser Method +methodP = choice + [ string "OPTIONS" ≫ return OPTIONS + , string "GET" ≫ return GET + , string "HEAD" ≫ return HEAD + , string "POST" ≫ return POST + , string "PUT" ≫ return PUT + , string "DELETE" ≫ return DELETE + , string "TRACE" ≫ return TRACE + , string "CONNECT" ≫ return CONNECT + , ExtensionMethod <$> token + ] -methodP :: Parser Method -methodP = ( let methods = [ ("OPTIONS", OPTIONS) - , ("GET" , GET ) - , ("HEAD" , HEAD ) - , ("POST" , POST ) - , ("PUT" , PUT ) - , ("DELETE" , DELETE ) - , ("TRACE" , TRACE ) - , ("CONNECT", CONNECT) - ] - in choice $ map (\ (str, mth) - -> string str >> return mth) methods ) - <|> - fmap ExtensionMethod token - - -uriP :: Parser URI -uriP = do str <- many1 $ satisfy (\ c -> not (isCtl c || c == ' ')) +uriP ∷ Parser URI +uriP = try $ + do bs ← takeWhile1 (\c → (¬) (isCtl c ∨ c ≡ '\x20')) + let str = C8.unpack bs case parseURIReference str of - Nothing -> failP - Just uri -> return uri \ No newline at end of file + Nothing -> fail ("Unparsable URI: " ⧺ str) + Just uri -> return uri