Cycle through ByteString.

This commit is contained in:
Julian K. Arni 2015-01-03 18:07:39 +01:00
parent 83f55259fa
commit ecb1da0e37

View file

@ -10,8 +10,10 @@ module Servant.Server.Internal where
import Control.Applicative import Control.Applicative
import Control.Monad.Trans.Either import Control.Monad.Trans.Either
import Data.Aeson import Data.Aeson
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import Data.IORef import Data.IORef
import Data.Maybe (catMaybes, fromMaybe) import Data.Maybe (catMaybes)
import Data.Monoid import Data.Monoid
import Data.Proxy import Data.Proxy
import Data.String import Data.String
@ -24,13 +26,27 @@ import Network.Wai
import Servant.API import Servant.API
import Servant.Common.Text import Servant.Common.Text
data ReqBodyState = Uncalled
| Called B.ByteString
| Done B.ByteString
toApplication :: RoutingApplication -> Application toApplication :: RoutingApplication -> Application
toApplication ra request respond = do toApplication ra request respond = do
reqBodyRef <- newIORef Nothing reqBodyRef <- newIORef Uncalled
let memoReqBody = fromMaybe <$> (do let memoReqBody = do
r <- requestBody request ior <- readIORef reqBodyRef
writeIORef reqBodyRef $ Just r case ior of
return r ) <*> readIORef reqBodyRef Uncalled -> do
r <- BL.toStrict <$> strictRequestBody request
writeIORef reqBodyRef $ Done r
return r
Called bs -> do
writeIORef reqBodyRef $ Done bs
return bs
Done bs -> do
writeIORef reqBodyRef $ Called bs
return B.empty
ra request{ requestBody = memoReqBody } (routingRespond . routeResult) ra request{ requestBody = memoReqBody } (routingRespond . routeResult)
where where
routingRespond :: Either RouteMismatch Response -> IO ResponseReceived routingRespond :: Either RouteMismatch Response -> IO ResponseReceived