module Network.HTTP.Lucu.Request
( Method(..)
, Request(..)
, reqHasBody
)
where
import Control.Applicative
import Control.Monad.Unicode
import Data.Ascii (Ascii)
import Data.Attoparsec.Char8
import qualified Data.ByteString.Char8 as C8
import Data.Default
import Network.HTTP.Lucu.Headers
import Network.HTTP.Lucu.HttpVersion
import Network.HTTP.Lucu.Parser.Http
import Network.URI
import Prelude.Unicode
data Method = OPTIONS
| GET
| HEAD
| POST
| PUT
| DELETE
| TRACE
| CONNECT
| ExtensionMethod !Ascii
deriving (Eq, Show)
data Request
= Request {
reqMethod ∷ !Method
, reqURI ∷ !URI
, reqVersion ∷ !HttpVersion
, reqHeaders ∷ !Headers
}
deriving (Eq, Show)
instance HasHeaders Request where
getHeaders = reqHeaders
setHeaders req hdr = req { reqHeaders = hdr }
reqHasBody ∷ Request → Bool
reqHasBody (reqMethod → m)
| m ≡ POST = True
| m ≡ PUT = True
| otherwise = False
instance Default (Parser Method) where
def = 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
]
instance Default (Parser Request) where
def = do skipMany crlf
(meth, u, ver) ← requestLine
hdrs ← def
return Request {
reqMethod = meth
, reqURI = u
, reqVersion = ver
, reqHeaders = hdrs
}
requestLine ∷ Parser (Method, URI, HttpVersion)
requestLine = do meth ← def
sp
u ← uri
sp
ver ← def
crlf
return (meth, u, ver)
uri ∷ Parser 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