module Mongrel2.Response
( Response
, buildResponse
, mkResponse
) where
import Blaze.ByteString.Builder (Builder, toByteString, fromByteString)
import Blaze.Text.Int (integral)
import Data.ByteString (ByteString)
import Data.ByteString.Char8 ()
import Data.List (intersperse)
import Data.Monoid
import Mongrel2.Types (ClientID, UUID)
import Network.HTTP.Types (Status(..), ResponseHeaders)
import qualified Data.ByteString as S
import qualified Data.CaseInsensitive as CI
type Response = ByteString
buildSpace :: Builder
buildSpace = fromByteString " "
buildUUID :: UUID -> Builder
buildUUID = fromByteString
buildNetstring :: Builder -> Builder
buildNetstring b =
mconcat [ integral $ S.length s
, fromByteString ":"
, fromByteString s
]
where
s = toByteString b
buildClientIDList :: [ClientID] -> Builder
buildClientIDList cids =
mconcat $ intersperse buildSpace $ map integral cids
mkResponse :: UUID -> [ClientID] -> Builder -> Response
mkResponse uuid clientIDs bodyBuilder =
toByteString $ mconcat [ buildUUID uuid
, buildSpace
, buildNetstring $ buildClientIDList clientIDs
, fromByteString ", "
, bodyBuilder ]
buildResponse :: Status -> ResponseHeaders -> ByteString -> Builder
buildResponse status responseHeaders body =
mconcat [ fromByteString "HTTP/1.1 "
, integral $ statusCode status
, fromByteString " "
, fromByteString $ statusMessage status
, crlf
, mconcat $ map buildResponseHeader responseHeaders
, crlf
, fromByteString body
]
where
buildResponseHeader (name,value) =
mconcat [ fromByteString $ CI.original name
, fromByteString ": "
, fromByteString value
, crlf
]
crlf = fromByteString "\r\n"