getRequest for the Response monad
This commit is contained in:
parent
4a0d7baa68
commit
f4dc87bab6
2
TODO
2
TODO
@ -1,3 +1 @@
|
|||||||
Static files and directories
|
|
||||||
Better error handling for invalid arguments (currently 500 error)
|
Better error handling for invalid arguments (currently 500 error)
|
||||||
Include request getting in Response monad.
|
|
||||||
|
|||||||
@ -124,7 +124,8 @@ toHackApplication sampleRN hm env = do
|
|||||||
runResponse (errorHandler sampleRN rr)
|
runResponse (errorHandler sampleRN rr)
|
||||||
(responseWrapper sampleRN)
|
(responseWrapper sampleRN)
|
||||||
ctypes'
|
ctypes'
|
||||||
(handler rr)
|
handler
|
||||||
|
rr
|
||||||
|
|
||||||
envToRawRequest :: [(ParamName, ParamValue)] -> Hack.Env -> RawRequest
|
envToRawRequest :: [(ParamName, ParamValue)] -> Hack.Env -> RawRequest
|
||||||
envToRawRequest urlParams' env =
|
envToRawRequest urlParams' env =
|
||||||
|
|||||||
@ -23,18 +23,14 @@ module Web.Restful.Handler
|
|||||||
import Web.Restful.Request
|
import Web.Restful.Request
|
||||||
import Web.Restful.Response
|
import Web.Restful.Response
|
||||||
|
|
||||||
type Handler = RawRequest -> Response
|
type Handler = Response -- FIXME maybe move some stuff around now...
|
||||||
|
|
||||||
liftHandler :: (Request req, HasReps rep)
|
liftHandler :: (Request req, HasReps rep)
|
||||||
=> (req -> ResponseIO rep)
|
=> (req -> ResponseIO rep)
|
||||||
-> Handler
|
-> Handler
|
||||||
liftHandler f req = liftRequest req >>= wrapResponse . f
|
liftHandler f = do
|
||||||
|
req <- getRequest
|
||||||
liftRequest :: (Request req, Monad m) => RawRequest -> m req
|
wrapResponse $ f req
|
||||||
liftRequest r =
|
|
||||||
case runRequestParser parseRequest r of
|
|
||||||
Left errors -> fail $ unlines errors -- FIXME
|
|
||||||
Right req -> return req
|
|
||||||
|
|
||||||
noHandler :: Handler
|
noHandler :: Handler
|
||||||
noHandler = const notFound
|
noHandler = notFound
|
||||||
|
|||||||
@ -33,6 +33,7 @@ module Web.Restful.Response
|
|||||||
, HasRepsW (..)
|
, HasRepsW (..)
|
||||||
, byteStringResponse
|
, byteStringResponse
|
||||||
, htmlResponse
|
, htmlResponse
|
||||||
|
, getRequest
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.ByteString.Class
|
import Data.ByteString.Class
|
||||||
@ -44,7 +45,10 @@ import qualified Data.ByteString.Lazy as B
|
|||||||
import Data.Object.Instances
|
import Data.Object.Instances
|
||||||
import Data.Maybe (fromJust)
|
import Data.Maybe (fromJust)
|
||||||
|
|
||||||
|
import Web.Restful.Request
|
||||||
|
|
||||||
import Control.Monad.Trans
|
import Control.Monad.Trans
|
||||||
|
import Control.Monad (liftM)
|
||||||
|
|
||||||
import qualified Hack
|
import qualified Hack
|
||||||
|
|
||||||
@ -79,7 +83,8 @@ getHeaders :: ErrorResult -> [Header]
|
|||||||
getHeaders (Redirect s) = [Header "Location" s]
|
getHeaders (Redirect s) = [Header "Location" s]
|
||||||
getHeaders _ = []
|
getHeaders _ = []
|
||||||
|
|
||||||
newtype ResponseT m a = ResponseT (m (Either ErrorResult a, [Header]))
|
newtype ResponseT m a =
|
||||||
|
ResponseT (RawRequest -> m (Either ErrorResult a, [Header]))
|
||||||
type ResponseIO = ResponseT IO
|
type ResponseIO = ResponseT IO
|
||||||
type Response = ResponseIO HasRepsW
|
type Response = ResponseIO HasRepsW
|
||||||
|
|
||||||
@ -87,9 +92,10 @@ runResponse :: (ErrorResult -> HasRepsW)
|
|||||||
-> (ContentType -> B.ByteString -> IO B.ByteString)
|
-> (ContentType -> B.ByteString -> IO B.ByteString)
|
||||||
-> [ContentType]
|
-> [ContentType]
|
||||||
-> Response
|
-> Response
|
||||||
|
-> RawRequest
|
||||||
-> IO Hack.Response
|
-> IO Hack.Response
|
||||||
runResponse eh wrapper ctypesAll (ResponseT inside) = do
|
runResponse eh wrapper ctypesAll (ResponseT inside) rr = do
|
||||||
(x, headers') <- inside
|
(x, headers') <- inside rr
|
||||||
let extraHeaders =
|
let extraHeaders =
|
||||||
case x of
|
case x of
|
||||||
Left r -> getHeaders r
|
Left r -> getHeaders r
|
||||||
@ -135,7 +141,7 @@ wrapResponse :: (Monad m, HasReps rep)
|
|||||||
wrapResponse = fmap HasRepsW
|
wrapResponse = fmap HasRepsW
|
||||||
|
|
||||||
instance MonadTrans ResponseT where
|
instance MonadTrans ResponseT where
|
||||||
lift ma = ResponseT $ do
|
lift ma = ResponseT $ const $ do
|
||||||
a <- ma
|
a <- ma
|
||||||
return (Right a, [])
|
return (Right a, [])
|
||||||
|
|
||||||
@ -143,24 +149,24 @@ instance MonadIO ResponseIO where
|
|||||||
liftIO = lift
|
liftIO = lift
|
||||||
|
|
||||||
redirect :: Monad m => String -> ResponseT m a
|
redirect :: Monad m => String -> ResponseT m a
|
||||||
redirect s = ResponseT (return (Left $ Redirect s, []))
|
redirect s = ResponseT (const $ return (Left $ Redirect s, []))
|
||||||
|
|
||||||
notFound :: Monad m => ResponseT m a
|
notFound :: Monad m => ResponseT m a
|
||||||
notFound = ResponseT (return (Left NotFound, []))
|
notFound = ResponseT (const $ return (Left NotFound, []))
|
||||||
|
|
||||||
instance Monad m => Functor (ResponseT m) where
|
instance Monad m => Functor (ResponseT m) where
|
||||||
fmap f x = x >>= return . f
|
fmap = liftM
|
||||||
|
|
||||||
instance Monad m => Monad (ResponseT m) where
|
instance Monad m => Monad (ResponseT m) where
|
||||||
return = lift . return
|
return = lift . return
|
||||||
fail s = ResponseT (return (Left $ InternalError s, []))
|
fail s = ResponseT (const $ return (Left $ InternalError s, []))
|
||||||
(ResponseT mx) >>= f = ResponseT $ do
|
(ResponseT mx) >>= f = ResponseT $ \rr -> do
|
||||||
(x, hs1) <- mx
|
(x, hs1) <- mx rr
|
||||||
case x of
|
case x of
|
||||||
Left x' -> return (Left x', hs1)
|
Left x' -> return (Left x', hs1)
|
||||||
Right a -> do
|
Right a -> do
|
||||||
let (ResponseT b') = f a
|
let (ResponseT b') = f a
|
||||||
(b, hs2) <- b'
|
(b, hs2) <- b' rr
|
||||||
return (b, hs1 ++ hs2)
|
return (b, hs1 ++ hs2)
|
||||||
|
|
||||||
-- | Headers to be added to a 'Result'.
|
-- | Headers to be added to a 'Result'.
|
||||||
@ -179,7 +185,7 @@ header :: Monad m => String -> String -> ResponseT m ()
|
|||||||
header a b = addHeader $ Header a b
|
header a b = addHeader $ Header a b
|
||||||
|
|
||||||
addHeader :: Monad m => Header -> ResponseT m ()
|
addHeader :: Monad m => Header -> ResponseT m ()
|
||||||
addHeader h = ResponseT (return (Right (), [h]))
|
addHeader h = ResponseT (const $ return (Right (), [h]))
|
||||||
|
|
||||||
instance HasReps () where
|
instance HasReps () where
|
||||||
reps _ = [("text/plain", toLazyByteString "")]
|
reps _ = [("text/plain", toLazyByteString "")]
|
||||||
@ -214,3 +220,13 @@ instance HasReps [(ContentType, B.ByteString)] where
|
|||||||
-- FIXME put in a separate module (maybe Web.Encodings)
|
-- FIXME put in a separate module (maybe Web.Encodings)
|
||||||
formatW3 :: UTCTime -> String
|
formatW3 :: UTCTime -> String
|
||||||
formatW3 = formatTime defaultTimeLocale "%FT%X-08:00"
|
formatW3 = formatTime defaultTimeLocale "%FT%X-08:00"
|
||||||
|
|
||||||
|
getRequest :: (Monad m, Request r) => ResponseT m r
|
||||||
|
getRequest = ResponseT $ \rr -> return (helper rr, []) where
|
||||||
|
helper :: Request r
|
||||||
|
=> RawRequest
|
||||||
|
-> Either ErrorResult r
|
||||||
|
helper rr =
|
||||||
|
case runRequestParser parseRequest rr of
|
||||||
|
Left errors -> Left $ InternalError $ unlines errors -- FIXME better error output
|
||||||
|
Right r -> Right r
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user