respondSource

This commit is contained in:
Michael Snoyman 2013-03-20 13:49:43 +02:00
parent 029fc7166d
commit 8c45b2709f
4 changed files with 47 additions and 6 deletions

View File

@ -54,6 +54,8 @@ module Yesod.Core.Handler
, lookupCookies , lookupCookies
, lookupFiles , lookupFiles
-- * Special responses -- * Special responses
-- ** Streaming
, respondSource
-- ** Redirecting -- ** Redirecting
, RedirectUrl (..) , RedirectUrl (..)
, redirect , redirect
@ -139,7 +141,7 @@ import Control.Monad.Trans.Resource (MonadResource, liftResourceT)
import qualified Network.HTTP.Types as H import qualified Network.HTTP.Types as H
import qualified Network.Wai as W import qualified Network.Wai as W
import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Class (lift)
import Data.Conduit (transPipe) import Data.Conduit (transPipe, Flush)
import qualified Data.Text as T import qualified Data.Text as T
import Data.Text.Encoding (decodeUtf8With, encodeUtf8) import Data.Text.Encoding (decodeUtf8With, encodeUtf8)
@ -173,6 +175,7 @@ import Yesod.Core.Class.Handler
import Yesod.Core.Types import Yesod.Core.Types
import Yesod.Routes.Class (Route) import Yesod.Routes.Class (Route)
import Control.Failure (failure) import Control.Failure (failure)
import Blaze.ByteString.Builder (Builder)
get :: MonadHandler m => m GHState get :: MonadHandler m => m GHState
get = liftHandlerT $ HandlerT $ I.readIORef . handlerState get = liftHandlerT $ HandlerT $ I.readIORef . handlerState
@ -894,7 +897,7 @@ provideRepType ct handler =
-- | Stream in the raw request body without any parsing. -- | Stream in the raw request body without any parsing.
-- --
-- Since 1.2.0 -- Since 1.2.0
rawRequestBody :: (MonadHandler m, MonadResource m) => Source m S.ByteString rawRequestBody :: MonadHandler m => Source m S.ByteString
rawRequestBody = do rawRequestBody = do
req <- lift waiRequest req <- lift waiRequest
transPipe liftResourceT $ W.requestBody req transPipe liftResourceT $ W.requestBody req
@ -903,3 +906,16 @@ rawRequestBody = do
-- to work in any @MonadResource@. -- to work in any @MonadResource@.
fileSource :: MonadResource m => FileInfo -> Source m S.ByteString fileSource :: MonadResource m => FileInfo -> Source m S.ByteString
fileSource = transPipe liftResourceT . fileSourceRaw fileSource = transPipe liftResourceT . fileSourceRaw
-- | Use a @Source@ for the response body.
--
-- Since 1.2.0
respondSource :: ContentType
-> Source (HandlerT site IO) (Flush Builder)
-> HandlerT site IO TypedContent
respondSource ctype src = HandlerT $ \hd ->
-- Note that this implementation relies on the fact that the ResourceT
-- environment provided by the server is the same one used in HandlerT.
-- This is a safe assumption assuming the HandlerT is run correctly.
return $ TypedContent ctype $ ContentSource
$ transPipe (lift . flip unHandlerT hd) src

View File

@ -2,7 +2,6 @@
{-# LANGUAGE PatternGuards #-} {-# LANGUAGE PatternGuards #-}
module Yesod.Core.Internal.LiteApp where module Yesod.Core.Internal.LiteApp where
import Yesod.Routes.Dispatch
import Yesod.Routes.Class import Yesod.Routes.Class
import Data.Monoid import Data.Monoid
import Yesod.Core.Class.Yesod import Yesod.Core.Class.Yesod
@ -11,9 +10,6 @@ import Yesod.Core.Types
import Yesod.Core.Content import Yesod.Core.Content
import Data.Text (Text) import Data.Text (Text)
import Web.PathPieces import Web.PathPieces
import Data.Map (Map)
import qualified Data.Map as Map
import Data.ByteString (ByteString)
import Network.Wai import Network.Wai
import Yesod.Core.Handler import Yesod.Core.Handler
import Yesod.Core.Internal.Run import Yesod.Core.Internal.Run

View File

@ -14,6 +14,7 @@ import qualified YesodCoreTest.Redirect as Redirect
import qualified YesodCoreTest.JsLoader as JsLoader import qualified YesodCoreTest.JsLoader as JsLoader
import qualified YesodCoreTest.RequestBodySize as RequestBodySize import qualified YesodCoreTest.RequestBodySize as RequestBodySize
import qualified YesodCoreTest.Json as Json import qualified YesodCoreTest.Json as Json
import qualified YesodCoreTest.Streaming as Streaming
import qualified YesodCoreTest.Reps as Reps import qualified YesodCoreTest.Reps as Reps
import qualified YesodCoreTest.Auth as Auth import qualified YesodCoreTest.Auth as Auth
import qualified YesodCoreTest.LiteApp as LiteApp import qualified YesodCoreTest.LiteApp as LiteApp
@ -36,6 +37,7 @@ specs = do
JsLoader.specs JsLoader.specs
RequestBodySize.specs RequestBodySize.specs
Json.specs Json.specs
Streaming.specs
Reps.specs Reps.specs
Auth.specs Auth.specs
LiteApp.specs LiteApp.specs

View File

@ -0,0 +1,27 @@
{-# LANGUAGE OverloadedStrings #-}
module YesodCoreTest.Streaming (specs) where
import Yesod.Core
import Test.Hspec
import Network.Wai.Test
import Data.Conduit
import Blaze.ByteString.Builder (fromByteString)
app :: LiteApp
app = dispatchTo $ respondSource typeHtml $
yield $ Chunk $ fromByteString "Hello World!"
test :: String
-> (SResponse -> Session ())
-> Spec
test name f = it name $ do
wapp <- toWaiApp app
flip runSession wapp $ do
sres <- request defaultRequest
f sres
specs :: Spec
specs = describe "Streaming" $ do
test "works" $ \sres -> do
assertStatus 200 sres
assertBody "Hello World!" sres