X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FRequest.hs;h=2fcfc9123e3c8e07f343ba3d9211556d4a4c2ed7;hb=db4a546d0d462cb94639b1f273bf0b78bccc960c;hp=66511e24c1f869490469ea637e0ea763ffd1ec34;hpb=72a3e24a952616e32845eeb4fc05048e841c91a2;p=Lucu.git diff --git a/Network/HTTP/Lucu/Request.hs b/Network/HTTP/Lucu/Request.hs index 66511e2..2fcfc91 100644 --- a/Network/HTTP/Lucu/Request.hs +++ b/Network/HTTP/Lucu/Request.hs @@ -1,5 +1,6 @@ {-# LANGUAGE - OverloadedStrings + MultiParamTypeClasses + , OverloadedStrings , UnicodeSyntax , ViewPatterns #-} @@ -10,13 +11,14 @@ module Network.HTTP.Lucu.Request ( Method(..) , Request(..) , reqMustHaveBody - , requestP ) where import Control.Applicative import Control.Monad.Unicode import Data.Ascii (Ascii) import Data.Attoparsec.Char8 +import Data.Attoparsec.Parsable +import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as C8 import Network.HTTP.Lucu.Headers import Network.HTTP.Lucu.HttpVersion @@ -25,7 +27,7 @@ import Network.URI import Prelude.Unicode -- |This is the definition of HTTP request methods, which shouldn't --- require any description. +-- require any descriptions. data Method = OPTIONS | GET | HEAD @@ -37,7 +39,7 @@ data Method = OPTIONS | ExtensionMethod !Ascii deriving (Eq, Show) --- |This is the definition of HTTP reqest. +-- |This is the definition of an HTTP reqest. data Request = Request { reqMethod ∷ !Method @@ -61,42 +63,46 @@ reqMustHaveBody (reqMethod → m) | m ≡ PUT = True | otherwise = False -requestP ∷ Parser Request -requestP = do skipMany crlf - (method, uri, version) ← requestLineP - headers ← headersP - return Request { - reqMethod = method - , reqURI = uri - , reqVersion = version - , reqHeaders = headers - } +instance Parsable ByteString Request where + {-# INLINEABLE parser #-} + parser = do skipMany crlf + (meth, u, ver) ← requestLine + hdrs ← parser + return Request { + reqMethod = meth + , reqURI = u + , reqVersion = ver + , reqHeaders = hdrs + } -requestLineP ∷ Parser (Method, URI, HttpVersion) -requestLineP = do method ← methodP - sp - uri ← uriP - sp - ver ← httpVersionP - crlf - return (method, uri, ver) +requestLine ∷ Parser (Method, URI, HttpVersion) +{-# INLINEABLE requestLine #-} +requestLine = do meth ← method + sp + u ← uri + sp + ver ← parser + crlf + return (meth, u, 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 - ] +method ∷ Parser Method +{-# INLINEABLE method #-} +method = 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 + ] -uriP ∷ Parser URI -uriP = do bs ← takeWhile1 (\c → (¬) (isCtl c ∨ c ≡ '\x20')) - let str = C8.unpack bs - case parseURIReference str of - Nothing -> fail ("Unparsable URI: " ⧺ str) - Just uri -> return uri +uri ∷ Parser URI +{-# INLINEABLE uri #-} +uri = do bs ← takeWhile1 (\c → (¬) (isCtl c ∨ c ≡ '\x20')) + let str = C8.unpack bs + case parseURIReference str of + Nothing → fail ("Unparsable URI: " ⧺ str) + Just u → return u