module Network.HTTP.Toolkit.Request (
RequestPath
, RequestHeader
, readRequest
, readRequestWithLimit
, parseRequestLine
, determineRequestBodyType
) where
import Control.Applicative
import Control.Monad (join)
import Control.Exception
import Data.Maybe
import Data.Traversable (sequenceA)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as B
import Network.HTTP.Types
import Network.HTTP.Toolkit.Error
import Network.HTTP.Toolkit.Connection
import Network.HTTP.Toolkit.Header
import Network.HTTP.Toolkit.Body
type RequestPath = ByteString
type RequestHeader = MessageHeader (Method, RequestPath)
readRequest :: Connection -> IO (RequestHeader, BodyReader)
readRequest = readRequestWithLimit defaultHeaderSizeLimit
readRequestWithLimit :: Limit -> Connection -> IO (RequestHeader, BodyReader)
readRequestWithLimit limit c = do
r@(MessageHeader _ headers) <- join $ sequenceA . fmap parseRequestLine_ <$> readMessageHeaderWithLimit limit c
(,) r <$> makeBodyReader c (determineRequestBodyType headers)
parseRequestLine_ :: ByteString -> IO (Method, ByteString)
parseRequestLine_ input = maybe (throwIO $ InvalidRequestLine input) return (parseRequestLine input)
parseRequestLine :: ByteString -> Maybe (Method, RequestPath)
parseRequestLine input = case B.words input of
method : path : _ -> Just (method, path)
_ -> Nothing
determineRequestBodyType :: [Header] -> BodyType
determineRequestBodyType = fromMaybe None . bodyTypeFromHeaders