Catch up with Data.Conduit.Combinators
This commit is contained in:
parent
a16e75249a
commit
103c098cf8
@ -58,7 +58,7 @@ library
|
|||||||
, binary
|
, binary
|
||||||
, http-client
|
, http-client
|
||||||
, blaze-builder
|
, blaze-builder
|
||||||
, conduit
|
, conduit >= 1.3
|
||||||
, conduit-extra
|
, conduit-extra
|
||||||
, nonce >= 1.0.2 && < 1.1
|
, nonce >= 1.0.2 && < 1.1
|
||||||
|
|
||||||
|
|||||||
@ -17,9 +17,7 @@ import Control.Monad (forever, unless, void,
|
|||||||
when)
|
when)
|
||||||
import Data.ByteString (ByteString, isInfixOf)
|
import Data.ByteString (ByteString, isInfixOf)
|
||||||
import qualified Data.ByteString.Lazy as LB
|
import qualified Data.ByteString.Lazy as LB
|
||||||
import Data.Conduit (($$), (=$))
|
import Conduit
|
||||||
import qualified Data.Conduit.Binary as CB
|
|
||||||
import qualified Data.Conduit.List as CL
|
|
||||||
import Data.Default.Class (def)
|
import Data.Default.Class (def)
|
||||||
import Data.FileEmbed (embedFile)
|
import Data.FileEmbed (embedFile)
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
@ -368,9 +366,10 @@ devel opts passThroughArgs = do
|
|||||||
-- process is piped to the actual stdout and stderr handles.
|
-- process is piped to the actual stdout and stderr handles.
|
||||||
withProcess_ procConfig $ \p -> do
|
withProcess_ procConfig $ \p -> do
|
||||||
let helper getter h =
|
let helper getter h =
|
||||||
getter p
|
runConduit
|
||||||
$$ CL.iterM (\(str :: ByteString) -> atomically (updateAppPort str buildStarted appPortVar))
|
$ getter p
|
||||||
=$ CB.sinkHandle h
|
.| iterMC (\(str :: ByteString) -> atomically (updateAppPort str buildStarted appPortVar))
|
||||||
|
.| sinkHandle h
|
||||||
race_ (helper getStdout stdout) (helper getStderr stderr)
|
race_ (helper getStdout stdout) (helper getStderr stderr)
|
||||||
|
|
||||||
-- Run the inner action with a TVar which will be set to True
|
-- Run the inner action with a TVar which will be set to True
|
||||||
|
|||||||
@ -2,20 +2,18 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
module HsFile (mkHsFile) where
|
module HsFile (mkHsFile) where
|
||||||
import Text.ProjectTemplate (createTemplate)
|
import Text.ProjectTemplate (createTemplate)
|
||||||
import Data.Conduit
|
import Conduit
|
||||||
( ($$), (=$), awaitForever)
|
|
||||||
import Data.Conduit.Filesystem (sourceDirectory)
|
|
||||||
import Control.Monad.Trans.Resource (runResourceT)
|
import Control.Monad.Trans.Resource (runResourceT)
|
||||||
import qualified Data.Conduit.List as CL
|
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import Control.Monad.IO.Class (liftIO)
|
import Control.Monad.IO.Class (liftIO)
|
||||||
import Data.String (fromString)
|
import Data.String (fromString)
|
||||||
|
|
||||||
mkHsFile :: IO ()
|
mkHsFile :: IO ()
|
||||||
mkHsFile = runResourceT $ sourceDirectory "."
|
mkHsFile = runConduitRes
|
||||||
$$ readIt
|
$ sourceDirectory "."
|
||||||
=$ createTemplate
|
.| readIt
|
||||||
=$ awaitForever (liftIO . BS.putStr)
|
.| createTemplate
|
||||||
|
.| mapM_C (liftIO . BS.putStr)
|
||||||
where
|
where
|
||||||
-- Reads a filepath from upstream and dumps a pair of (filepath, filecontents)
|
-- Reads a filepath from upstream and dumps a pair of (filepath, filecontents)
|
||||||
readIt = CL.map $ \i -> (fromString i, liftIO $ BS.readFile i)
|
readIt = mapC $ \i -> (fromString i, liftIO $ BS.readFile i)
|
||||||
|
|||||||
@ -10,9 +10,8 @@ import Yesod.Core.Handler
|
|||||||
|
|
||||||
import Yesod.Routes.Class
|
import Yesod.Routes.Class
|
||||||
|
|
||||||
import Blaze.ByteString.Builder (Builder, toByteString)
|
import Data.ByteString.Builder (Builder, toLazyByteString)
|
||||||
import Blaze.ByteString.Builder.ByteString (copyByteString)
|
import Data.Text.Encoding (encodeUtf8Builder)
|
||||||
import Blaze.ByteString.Builder.Char.Utf8 (fromText, fromChar)
|
|
||||||
import Control.Arrow ((***), second)
|
import Control.Arrow ((***), second)
|
||||||
import Control.Exception (bracket)
|
import Control.Exception (bracket)
|
||||||
#if __GLASGOW_HASKELL__ < 710
|
#if __GLASGOW_HASKELL__ < 710
|
||||||
@ -25,6 +24,7 @@ import Control.Monad.Logger (LogLevel (LevelInfo, LevelO
|
|||||||
import Control.Monad.Trans.Resource (InternalState, createInternalState, closeInternalState)
|
import Control.Monad.Trans.Resource (InternalState, createInternalState, closeInternalState)
|
||||||
import qualified Data.ByteString.Char8 as S8
|
import qualified Data.ByteString.Char8 as S8
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
|
import qualified Data.ByteString.Lazy.Char8 as BL8
|
||||||
import Data.Aeson (object, (.=))
|
import Data.Aeson (object, (.=))
|
||||||
import Data.List (foldl', nub)
|
import Data.List (foldl', nub)
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
@ -113,10 +113,10 @@ class RenderRoute site => Yesod site where
|
|||||||
-- | Override the rendering function for a particular URL and query string
|
-- | Override the rendering function for a particular URL and query string
|
||||||
-- parameters. One use case for this is to offload static hosting to a
|
-- parameters. One use case for this is to offload static hosting to a
|
||||||
-- different domain name to avoid sending cookies.
|
-- different domain name to avoid sending cookies.
|
||||||
--
|
--
|
||||||
-- For backward compatibility default implementation is in terms of
|
-- For backward compatibility default implementation is in terms of
|
||||||
-- 'urlRenderOverride', probably ineffective
|
-- 'urlRenderOverride', probably ineffective
|
||||||
--
|
--
|
||||||
-- Since 1.4.23
|
-- Since 1.4.23
|
||||||
urlParamRenderOverride :: site
|
urlParamRenderOverride :: site
|
||||||
-> Route site
|
-> Route site
|
||||||
@ -126,11 +126,11 @@ class RenderRoute site => Yesod site where
|
|||||||
where
|
where
|
||||||
addParams [] routeBldr = routeBldr
|
addParams [] routeBldr = routeBldr
|
||||||
addParams nonEmptyParams routeBldr =
|
addParams nonEmptyParams routeBldr =
|
||||||
let routeBS = toByteString routeBldr
|
let routeBS = toLazyByteString routeBldr
|
||||||
qsSeparator = fromChar $ if S8.elem '?' routeBS then '&' else '?'
|
qsSeparator = if BL8.elem '?' routeBS then "&" else "?"
|
||||||
valueToMaybe t = if t == "" then Nothing else Just t
|
valueToMaybe t = if t == "" then Nothing else Just t
|
||||||
queryText = map (id *** valueToMaybe) nonEmptyParams
|
queryText = map (id *** valueToMaybe) nonEmptyParams
|
||||||
in copyByteString routeBS `mappend` qsSeparator `mappend` renderQueryText False queryText
|
in routeBldr `mappend` qsSeparator `mappend` renderQueryText False queryText
|
||||||
|
|
||||||
-- | Determine if a request is authorized or not.
|
-- | Determine if a request is authorized or not.
|
||||||
--
|
--
|
||||||
@ -192,7 +192,7 @@ class RenderRoute site => Yesod site where
|
|||||||
-> [(T.Text, T.Text)] -- ^ query string
|
-> [(T.Text, T.Text)] -- ^ query string
|
||||||
-> Builder
|
-> Builder
|
||||||
joinPath _ ar pieces' qs' =
|
joinPath _ ar pieces' qs' =
|
||||||
fromText ar `mappend` encodePath pieces qs
|
encodeUtf8Builder ar `mappend` encodePath pieces qs
|
||||||
where
|
where
|
||||||
pieces = if null pieces' then [""] else map addDash pieces'
|
pieces = if null pieces' then [""] else map addDash pieces'
|
||||||
qs = map (TE.encodeUtf8 *** go) qs'
|
qs = map (TE.encodeUtf8 *** go) qs'
|
||||||
|
|||||||
@ -53,20 +53,21 @@ import qualified Data.ByteString as B
|
|||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import Data.Text.Lazy (Text, pack)
|
import Data.Text.Lazy (Text, pack)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Blaze.ByteString.Builder (Builder, fromByteString, fromLazyByteString)
|
import Data.Text.Encoding (encodeUtf8Builder)
|
||||||
|
import qualified Data.Text.Lazy as TL
|
||||||
|
import Data.ByteString.Builder (Builder, byteString, lazyByteString, stringUtf8)
|
||||||
#if __GLASGOW_HASKELL__ < 710
|
#if __GLASGOW_HASKELL__ < 710
|
||||||
import Data.Monoid (mempty)
|
import Data.Monoid (mempty)
|
||||||
#endif
|
#endif
|
||||||
import Text.Hamlet (Html)
|
import Text.Hamlet (Html)
|
||||||
import Text.Blaze.Html.Renderer.Utf8 (renderHtmlBuilder)
|
import Text.Blaze.Html.Renderer.Utf8 (renderHtmlBuilder)
|
||||||
import Data.Conduit (Source, Flush (Chunk), ResumableSource, mapOutput)
|
import Data.Conduit (Flush (Chunk), ResumableSource, mapOutput)
|
||||||
import Control.Monad (liftM)
|
import Control.Monad (liftM)
|
||||||
import Control.Monad.Trans.Resource (ResourceT)
|
import Control.Monad.Trans.Resource (ResourceT)
|
||||||
import Data.Conduit.Internal (ResumableSource (ResumableSource))
|
import Data.Conduit.Internal (ResumableSource (ResumableSource))
|
||||||
import qualified Data.Conduit.Internal as CI
|
import qualified Data.Conduit.Internal as CI
|
||||||
|
|
||||||
import qualified Data.Aeson as J
|
import qualified Data.Aeson as J
|
||||||
import qualified Blaze.ByteString.Builder.Char.Utf8 as Blaze
|
|
||||||
import Data.Text.Lazy.Builder (toLazyText)
|
import Data.Text.Lazy.Builder (toLazyText)
|
||||||
import Yesod.Core.Types
|
import Yesod.Core.Types
|
||||||
import Text.Lucius (Css, renderCss)
|
import Text.Lucius (Css, renderCss)
|
||||||
@ -93,15 +94,15 @@ instance ToContent Content where
|
|||||||
instance ToContent Builder where
|
instance ToContent Builder where
|
||||||
toContent = flip ContentBuilder Nothing
|
toContent = flip ContentBuilder Nothing
|
||||||
instance ToContent B.ByteString where
|
instance ToContent B.ByteString where
|
||||||
toContent bs = ContentBuilder (fromByteString bs) $ Just $ B.length bs
|
toContent bs = ContentBuilder (byteString bs) $ Just $ B.length bs
|
||||||
instance ToContent L.ByteString where
|
instance ToContent L.ByteString where
|
||||||
toContent = flip ContentBuilder Nothing . fromLazyByteString
|
toContent = flip ContentBuilder Nothing . lazyByteString
|
||||||
instance ToContent T.Text where
|
instance ToContent T.Text where
|
||||||
toContent = toContent . Blaze.fromText
|
toContent = toContent . encodeUtf8Builder
|
||||||
instance ToContent Text where
|
instance ToContent Text where
|
||||||
toContent = toContent . Blaze.fromLazyText
|
toContent = toContent . foldMap encodeUtf8Builder . TL.toChunks
|
||||||
instance ToContent String where
|
instance ToContent String where
|
||||||
toContent = toContent . Blaze.fromString
|
toContent = toContent . stringUtf8
|
||||||
instance ToContent Html where
|
instance ToContent Html where
|
||||||
toContent bs = ContentBuilder (renderHtmlBuilder bs) Nothing
|
toContent bs = ContentBuilder (renderHtmlBuilder bs) Nothing
|
||||||
instance ToContent () where
|
instance ToContent () where
|
||||||
@ -119,10 +120,10 @@ instance ToContent Javascript where
|
|||||||
instance ToFlushBuilder builder => ToContent (CI.Pipe () () builder () (ResourceT IO) ()) where
|
instance ToFlushBuilder builder => ToContent (CI.Pipe () () builder () (ResourceT IO) ()) where
|
||||||
toContent src = ContentSource $ CI.ConduitT (CI.mapOutput toFlushBuilder src >>=)
|
toContent src = ContentSource $ CI.ConduitT (CI.mapOutput toFlushBuilder src >>=)
|
||||||
|
|
||||||
instance ToFlushBuilder builder => ToContent (Source (ResourceT IO) builder) where
|
instance ToFlushBuilder builder => ToContent (CI.ConduitT () builder (ResourceT IO) ()) where
|
||||||
toContent src = ContentSource $ mapOutput toFlushBuilder src
|
toContent src = ContentSource $ mapOutput toFlushBuilder src
|
||||||
instance ToFlushBuilder builder => ToContent (ResumableSource (ResourceT IO) builder) where
|
instance ToFlushBuilder builder => ToContent (ResumableSource (ResourceT IO) builder) where
|
||||||
toContent (ResumableSource src _) = toContent src
|
toContent (ResumableSource src) = toContent src
|
||||||
|
|
||||||
-- | A class for all data which can be sent in a streaming response. Note that
|
-- | A class for all data which can be sent in a streaming response. Note that
|
||||||
-- for textual data, instances must use UTF-8 encoding.
|
-- for textual data, instances must use UTF-8 encoding.
|
||||||
@ -131,16 +132,16 @@ instance ToFlushBuilder builder => ToContent (ResumableSource (ResourceT IO) bui
|
|||||||
class ToFlushBuilder a where toFlushBuilder :: a -> Flush Builder
|
class ToFlushBuilder a where toFlushBuilder :: a -> Flush Builder
|
||||||
instance ToFlushBuilder (Flush Builder) where toFlushBuilder = id
|
instance ToFlushBuilder (Flush Builder) where toFlushBuilder = id
|
||||||
instance ToFlushBuilder Builder where toFlushBuilder = Chunk
|
instance ToFlushBuilder Builder where toFlushBuilder = Chunk
|
||||||
instance ToFlushBuilder (Flush B.ByteString) where toFlushBuilder = fmap fromByteString
|
instance ToFlushBuilder (Flush B.ByteString) where toFlushBuilder = fmap byteString
|
||||||
instance ToFlushBuilder B.ByteString where toFlushBuilder = Chunk . fromByteString
|
instance ToFlushBuilder B.ByteString where toFlushBuilder = Chunk . byteString
|
||||||
instance ToFlushBuilder (Flush L.ByteString) where toFlushBuilder = fmap fromLazyByteString
|
instance ToFlushBuilder (Flush L.ByteString) where toFlushBuilder = fmap lazyByteString
|
||||||
instance ToFlushBuilder L.ByteString where toFlushBuilder = Chunk . fromLazyByteString
|
instance ToFlushBuilder L.ByteString where toFlushBuilder = Chunk . lazyByteString
|
||||||
instance ToFlushBuilder (Flush Text) where toFlushBuilder = fmap Blaze.fromLazyText
|
instance ToFlushBuilder (Flush Text) where toFlushBuilder = fmap (foldMap encodeUtf8Builder . TL.toChunks)
|
||||||
instance ToFlushBuilder Text where toFlushBuilder = Chunk . Blaze.fromLazyText
|
instance ToFlushBuilder Text where toFlushBuilder = Chunk . foldMap encodeUtf8Builder . TL.toChunks
|
||||||
instance ToFlushBuilder (Flush T.Text) where toFlushBuilder = fmap Blaze.fromText
|
instance ToFlushBuilder (Flush T.Text) where toFlushBuilder = fmap encodeUtf8Builder
|
||||||
instance ToFlushBuilder T.Text where toFlushBuilder = Chunk . Blaze.fromText
|
instance ToFlushBuilder T.Text where toFlushBuilder = Chunk . encodeUtf8Builder
|
||||||
instance ToFlushBuilder (Flush String) where toFlushBuilder = fmap Blaze.fromString
|
instance ToFlushBuilder (Flush String) where toFlushBuilder = fmap stringUtf8
|
||||||
instance ToFlushBuilder String where toFlushBuilder = Chunk . Blaze.fromString
|
instance ToFlushBuilder String where toFlushBuilder = Chunk . stringUtf8
|
||||||
instance ToFlushBuilder (Flush Html) where toFlushBuilder = fmap renderHtmlBuilder
|
instance ToFlushBuilder (Flush Html) where toFlushBuilder = fmap renderHtmlBuilder
|
||||||
instance ToFlushBuilder Html where toFlushBuilder = Chunk . renderHtmlBuilder
|
instance ToFlushBuilder Html where toFlushBuilder = Chunk . renderHtmlBuilder
|
||||||
|
|
||||||
|
|||||||
@ -53,8 +53,9 @@ import Data.Text (Text)
|
|||||||
import Data.Monoid (mappend)
|
import Data.Monoid (mappend)
|
||||||
#endif
|
#endif
|
||||||
import qualified Data.ByteString as S
|
import qualified Data.ByteString as S
|
||||||
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import qualified Data.ByteString.Char8 as S8
|
import qualified Data.ByteString.Char8 as S8
|
||||||
import qualified Blaze.ByteString.Builder
|
import Data.ByteString.Builder (byteString, toLazyByteString)
|
||||||
import Network.HTTP.Types (status301, status307)
|
import Network.HTTP.Types (status301, status307)
|
||||||
import Yesod.Routes.Parse
|
import Yesod.Routes.Parse
|
||||||
import Yesod.Core.Types
|
import Yesod.Core.Types
|
||||||
@ -115,7 +116,7 @@ toWaiAppYre yre req =
|
|||||||
sendRedirect y segments' env sendResponse =
|
sendRedirect y segments' env sendResponse =
|
||||||
sendResponse $ W.responseLBS status
|
sendResponse $ W.responseLBS status
|
||||||
[ ("Content-Type", "text/plain")
|
[ ("Content-Type", "text/plain")
|
||||||
, ("Location", Blaze.ByteString.Builder.toByteString dest')
|
, ("Location", BL.toStrict $ toLazyByteString dest')
|
||||||
] "Redirecting"
|
] "Redirecting"
|
||||||
where
|
where
|
||||||
-- Ensure that non-GET requests get redirected correctly. See:
|
-- Ensure that non-GET requests get redirected correctly. See:
|
||||||
@ -129,7 +130,7 @@ toWaiAppYre yre req =
|
|||||||
if S.null (W.rawQueryString env)
|
if S.null (W.rawQueryString env)
|
||||||
then dest
|
then dest
|
||||||
else dest `mappend`
|
else dest `mappend`
|
||||||
Blaze.ByteString.Builder.fromByteString (W.rawQueryString env)
|
byteString (W.rawQueryString env)
|
||||||
|
|
||||||
-- | Same as 'toWaiAppPlain', but provides a default set of middlewares. This
|
-- | Same as 'toWaiAppPlain', but provides a default set of middlewares. This
|
||||||
-- set may change with future releases, but currently covers:
|
-- set may change with future releases, but currently covers:
|
||||||
|
|||||||
@ -240,13 +240,13 @@ import Web.PathPieces (PathPiece(..))
|
|||||||
import Yesod.Core.Class.Handler
|
import Yesod.Core.Class.Handler
|
||||||
import Yesod.Core.Types
|
import Yesod.Core.Types
|
||||||
import Yesod.Routes.Class (Route)
|
import Yesod.Routes.Class (Route)
|
||||||
import Blaze.ByteString.Builder (Builder)
|
import Data.ByteString.Builder (Builder)
|
||||||
import Safe (headMay)
|
import Safe (headMay)
|
||||||
import Data.CaseInsensitive (CI, original)
|
import Data.CaseInsensitive (CI, original)
|
||||||
import qualified Data.Conduit.List as CL
|
import qualified Data.Conduit.List as CL
|
||||||
import Control.Monad.Trans.Resource (MonadResource, InternalState, runResourceT, withInternalState, getInternalState, liftResourceT, resourceForkIO)
|
import Control.Monad.Trans.Resource (MonadResource, InternalState, runResourceT, withInternalState, getInternalState, liftResourceT, resourceForkIO)
|
||||||
import qualified System.PosixCompat.Files as PC
|
import qualified System.PosixCompat.Files as PC
|
||||||
import Data.Conduit (Source, transPipe, Flush (Flush), yield, Producer, Sink)
|
import Data.Conduit (ConduitT, transPipe, Flush (Flush), yield, Void)
|
||||||
import qualified Yesod.Core.TypeCache as Cache
|
import qualified Yesod.Core.TypeCache as Cache
|
||||||
import qualified Data.Word8 as W8
|
import qualified Data.Word8 as W8
|
||||||
import qualified Data.Foldable as Fold
|
import qualified Data.Foldable as Fold
|
||||||
@ -679,9 +679,10 @@ sendRawResponseNoConduit raw = withRunInIO $ \runInIO ->
|
|||||||
-- Warp).
|
-- Warp).
|
||||||
--
|
--
|
||||||
-- @since 1.2.7
|
-- @since 1.2.7
|
||||||
sendRawResponse :: (MonadHandler m, MonadUnliftIO m)
|
sendRawResponse
|
||||||
=> (Source IO S8.ByteString -> Sink S8.ByteString IO () -> m ())
|
:: (MonadHandler m, MonadUnliftIO m)
|
||||||
-> m a
|
=> (ConduitT () S8.ByteString IO () -> ConduitT S8.ByteString Void IO () -> m ())
|
||||||
|
-> m a
|
||||||
sendRawResponse raw = withRunInIO $ \runInIO ->
|
sendRawResponse raw = withRunInIO $ \runInIO ->
|
||||||
liftIO $ throwIO $ HCWai $ flip W.responseRaw fallback
|
liftIO $ throwIO $ HCWai $ flip W.responseRaw fallback
|
||||||
$ \src sink -> void $ runInIO $ raw (src' src) (CL.mapM_ sink)
|
$ \src sink -> void $ runInIO $ raw (src' src) (CL.mapM_ sink)
|
||||||
@ -1337,7 +1338,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 => Source m S.ByteString
|
rawRequestBody :: MonadHandler m => ConduitT i S.ByteString m ()
|
||||||
rawRequestBody = do
|
rawRequestBody = do
|
||||||
req <- lift waiRequest
|
req <- lift waiRequest
|
||||||
let loop = do
|
let loop = do
|
||||||
@ -1349,7 +1350,7 @@ rawRequestBody = do
|
|||||||
|
|
||||||
-- | Stream the data from the file. Since Yesod 1.2, this has been generalized
|
-- | Stream the data from the file. Since Yesod 1.2, this has been generalized
|
||||||
-- to work in any @MonadResource@.
|
-- to work in any @MonadResource@.
|
||||||
fileSource :: MonadResource m => FileInfo -> Source m S.ByteString
|
fileSource :: MonadResource m => FileInfo -> ConduitT () S.ByteString m ()
|
||||||
fileSource = transPipe liftResourceT . fileSourceRaw
|
fileSource = transPipe liftResourceT . fileSourceRaw
|
||||||
|
|
||||||
-- | Provide a pure value for the response body.
|
-- | Provide a pure value for the response body.
|
||||||
@ -1370,7 +1371,7 @@ respond ct = return . TypedContent ct . toContent
|
|||||||
--
|
--
|
||||||
-- @since 1.2.0
|
-- @since 1.2.0
|
||||||
respondSource :: ContentType
|
respondSource :: ContentType
|
||||||
-> Source (HandlerT site IO) (Flush Builder)
|
-> ConduitT () (Flush Builder) (HandlerT site IO) ()
|
||||||
-> HandlerT site IO TypedContent
|
-> HandlerT site IO TypedContent
|
||||||
respondSource ctype src = HandlerT $ \hd ->
|
respondSource ctype src = HandlerT $ \hd ->
|
||||||
-- Note that this implementation relies on the fact that the ResourceT
|
-- Note that this implementation relies on the fact that the ResourceT
|
||||||
@ -1383,44 +1384,44 @@ respondSource ctype src = HandlerT $ \hd ->
|
|||||||
-- on most datatypes, such as @ByteString@ and @Html@.
|
-- on most datatypes, such as @ByteString@ and @Html@.
|
||||||
--
|
--
|
||||||
-- @since 1.2.0
|
-- @since 1.2.0
|
||||||
sendChunk :: Monad m => ToFlushBuilder a => a -> Producer m (Flush Builder)
|
sendChunk :: Monad m => ToFlushBuilder a => a -> ConduitT i (Flush Builder) m ()
|
||||||
sendChunk = yield . toFlushBuilder
|
sendChunk = yield . toFlushBuilder
|
||||||
|
|
||||||
-- | In a streaming response, send a flush command, causing all buffered data
|
-- | In a streaming response, send a flush command, causing all buffered data
|
||||||
-- to be immediately sent to the client.
|
-- to be immediately sent to the client.
|
||||||
--
|
--
|
||||||
-- @since 1.2.0
|
-- @since 1.2.0
|
||||||
sendFlush :: Monad m => Producer m (Flush Builder)
|
sendFlush :: Monad m => ConduitT i (Flush Builder) m ()
|
||||||
sendFlush = yield Flush
|
sendFlush = yield Flush
|
||||||
|
|
||||||
-- | Type-specialized version of 'sendChunk' for strict @ByteString@s.
|
-- | Type-specialized version of 'sendChunk' for strict @ByteString@s.
|
||||||
--
|
--
|
||||||
-- @since 1.2.0
|
-- @since 1.2.0
|
||||||
sendChunkBS :: Monad m => S.ByteString -> Producer m (Flush Builder)
|
sendChunkBS :: Monad m => S.ByteString -> ConduitT i (Flush Builder) m ()
|
||||||
sendChunkBS = sendChunk
|
sendChunkBS = sendChunk
|
||||||
|
|
||||||
-- | Type-specialized version of 'sendChunk' for lazy @ByteString@s.
|
-- | Type-specialized version of 'sendChunk' for lazy @ByteString@s.
|
||||||
--
|
--
|
||||||
-- @since 1.2.0
|
-- @since 1.2.0
|
||||||
sendChunkLBS :: Monad m => L.ByteString -> Producer m (Flush Builder)
|
sendChunkLBS :: Monad m => L.ByteString -> ConduitT i (Flush Builder) m ()
|
||||||
sendChunkLBS = sendChunk
|
sendChunkLBS = sendChunk
|
||||||
|
|
||||||
-- | Type-specialized version of 'sendChunk' for strict @Text@s.
|
-- | Type-specialized version of 'sendChunk' for strict @Text@s.
|
||||||
--
|
--
|
||||||
-- @since 1.2.0
|
-- @since 1.2.0
|
||||||
sendChunkText :: Monad m => T.Text -> Producer m (Flush Builder)
|
sendChunkText :: Monad m => T.Text -> ConduitT i (Flush Builder) m ()
|
||||||
sendChunkText = sendChunk
|
sendChunkText = sendChunk
|
||||||
|
|
||||||
-- | Type-specialized version of 'sendChunk' for lazy @Text@s.
|
-- | Type-specialized version of 'sendChunk' for lazy @Text@s.
|
||||||
--
|
--
|
||||||
-- @since 1.2.0
|
-- @since 1.2.0
|
||||||
sendChunkLazyText :: Monad m => TL.Text -> Producer m (Flush Builder)
|
sendChunkLazyText :: Monad m => TL.Text -> ConduitT i (Flush Builder) m ()
|
||||||
sendChunkLazyText = sendChunk
|
sendChunkLazyText = sendChunk
|
||||||
|
|
||||||
-- | Type-specialized version of 'sendChunk' for @Html@s.
|
-- | Type-specialized version of 'sendChunk' for @Html@s.
|
||||||
--
|
--
|
||||||
-- @since 1.2.0
|
-- @since 1.2.0
|
||||||
sendChunkHtml :: Monad m => Html -> Producer m (Flush Builder)
|
sendChunkHtml :: Monad m => Html -> ConduitT i (Flush Builder) m ()
|
||||||
sendChunkHtml = sendChunk
|
sendChunkHtml = sendChunk
|
||||||
|
|
||||||
-- | Converts a child handler to a parent handler
|
-- | Converts a child handler to a parent handler
|
||||||
|
|||||||
@ -33,9 +33,7 @@ import qualified Data.Set as Set
|
|||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Data.Text.Encoding (decodeUtf8With, decodeUtf8)
|
import Data.Text.Encoding (decodeUtf8With, decodeUtf8)
|
||||||
import Data.Text.Encoding.Error (lenientDecode)
|
import Data.Text.Encoding.Error (lenientDecode)
|
||||||
import Data.Conduit
|
import Conduit
|
||||||
import Data.Conduit.List (sourceList)
|
|
||||||
import Data.Conduit.Binary (sourceFile, sinkFile)
|
|
||||||
import Data.Word (Word8, Word64)
|
import Data.Word (Word8, Word64)
|
||||||
import Control.Monad.Trans.Resource (runResourceT, ResourceT)
|
import Control.Monad.Trans.Resource (runResourceT, ResourceT)
|
||||||
import Control.Exception (throwIO)
|
import Control.Exception (throwIO)
|
||||||
@ -176,7 +174,7 @@ fromByteVector v =
|
|||||||
|
|
||||||
mkFileInfoLBS :: Text -> Text -> L.ByteString -> FileInfo
|
mkFileInfoLBS :: Text -> Text -> L.ByteString -> FileInfo
|
||||||
mkFileInfoLBS name ct lbs =
|
mkFileInfoLBS name ct lbs =
|
||||||
FileInfo name ct (sourceList $ L.toChunks lbs) (`L.writeFile` lbs)
|
FileInfo name ct (sourceLazy lbs) (`L.writeFile` lbs)
|
||||||
|
|
||||||
mkFileInfoFile :: Text -> Text -> FilePath -> FileInfo
|
mkFileInfoFile :: Text -> Text -> FilePath -> FileInfo
|
||||||
mkFileInfoFile name ct fp = FileInfo name ct (sourceFile fp) (\dst -> runResourceT $ sourceFile fp $$ sinkFile dst)
|
mkFileInfoFile name ct fp = FileInfo name ct (sourceFile fp) (\dst -> runResourceT $ sourceFile fp $$ sinkFile dst)
|
||||||
|
|||||||
@ -6,6 +6,7 @@ module Yesod.Core.Internal.Response where
|
|||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
import qualified Data.ByteString as S
|
import qualified Data.ByteString as S
|
||||||
import qualified Data.ByteString.Char8 as S8
|
import qualified Data.ByteString.Char8 as S8
|
||||||
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import Data.CaseInsensitive (CI)
|
import Data.CaseInsensitive (CI)
|
||||||
import qualified Data.CaseInsensitive as CI
|
import qualified Data.CaseInsensitive as CI
|
||||||
import Network.Wai
|
import Network.Wai
|
||||||
@ -18,8 +19,7 @@ import Yesod.Core.Types
|
|||||||
import qualified Network.HTTP.Types as H
|
import qualified Network.HTTP.Types as H
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception (SomeException, handle)
|
import Control.Exception (SomeException, handle)
|
||||||
import Blaze.ByteString.Builder (fromLazyByteString,
|
import Data.ByteString.Builder (lazyByteString, toLazyByteString)
|
||||||
toLazyByteString, toByteString)
|
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Yesod.Core.Internal.Request (tokenKey)
|
import Yesod.Core.Internal.Request (tokenKey)
|
||||||
@ -83,7 +83,7 @@ defaultStatus = H.mkStatus (-1) "INVALID DEFAULT STATUS"
|
|||||||
headerToPair :: Header
|
headerToPair :: Header
|
||||||
-> (CI ByteString, ByteString)
|
-> (CI ByteString, ByteString)
|
||||||
headerToPair (AddCookie sc) =
|
headerToPair (AddCookie sc) =
|
||||||
("Set-Cookie", toByteString $ renderSetCookie sc)
|
("Set-Cookie", BL.toStrict $ toLazyByteString $ renderSetCookie sc)
|
||||||
headerToPair (DeleteCookie key path) =
|
headerToPair (DeleteCookie key path) =
|
||||||
( "Set-Cookie"
|
( "Set-Cookie"
|
||||||
, S.concat
|
, S.concat
|
||||||
@ -100,7 +100,7 @@ evaluateContent (ContentBuilder b mlen) = handle f $ do
|
|||||||
let lbs = toLazyByteString b
|
let lbs = toLazyByteString b
|
||||||
len = L.length lbs
|
len = L.length lbs
|
||||||
mlen' = mlen `mplus` Just (fromIntegral len)
|
mlen' = mlen `mplus` Just (fromIntegral len)
|
||||||
len `seq` return (Right $ ContentBuilder (fromLazyByteString lbs) mlen')
|
len `seq` return (Right $ ContentBuilder (lazyByteString lbs) mlen')
|
||||||
where
|
where
|
||||||
f :: SomeException -> IO (Either ErrorResponse Content)
|
f :: SomeException -> IO (Either ErrorResponse Content)
|
||||||
f = return . Left . InternalError . T.pack . show
|
f = return . Left . InternalError . T.pack . show
|
||||||
|
|||||||
@ -14,7 +14,8 @@ import Data.Monoid (Monoid, mempty)
|
|||||||
import Control.Applicative ((<$>))
|
import Control.Applicative ((<$>))
|
||||||
#endif
|
#endif
|
||||||
import Yesod.Core.Internal.Response
|
import Yesod.Core.Internal.Response
|
||||||
import Blaze.ByteString.Builder (toByteString)
|
import Data.ByteString.Builder (toLazyByteString)
|
||||||
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import Control.Exception (fromException, evaluate)
|
import Control.Exception (fromException, evaluate)
|
||||||
import qualified Control.Exception as E
|
import qualified Control.Exception as E
|
||||||
import Control.Monad.IO.Class (MonadIO, liftIO)
|
import Control.Monad.IO.Class (MonadIO, liftIO)
|
||||||
@ -372,7 +373,7 @@ yesodRender :: Yesod y
|
|||||||
-> [(Text, Text)] -- ^ url query string
|
-> [(Text, Text)] -- ^ url query string
|
||||||
-> Text
|
-> Text
|
||||||
yesodRender y ar url params =
|
yesodRender y ar url params =
|
||||||
decodeUtf8With lenientDecode $ toByteString $
|
decodeUtf8With lenientDecode $ BL.toStrict $ toLazyByteString $
|
||||||
fromMaybe
|
fromMaybe
|
||||||
(joinPath y ar ps
|
(joinPath y ar ps
|
||||||
$ params ++ params')
|
$ params ++ params')
|
||||||
|
|||||||
@ -9,8 +9,7 @@
|
|||||||
{-# LANGUAGE UndecidableInstances #-}
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
module Yesod.Core.Types where
|
module Yesod.Core.Types where
|
||||||
|
|
||||||
import qualified Blaze.ByteString.Builder as BBuilder
|
import qualified Data.ByteString.Builder as BB
|
||||||
import qualified Blaze.ByteString.Builder.Char.Utf8
|
|
||||||
#if __GLASGOW_HASKELL__ < 710
|
#if __GLASGOW_HASKELL__ < 710
|
||||||
import Control.Applicative (Applicative (..))
|
import Control.Applicative (Applicative (..))
|
||||||
import Control.Applicative ((<$>))
|
import Control.Applicative ((<$>))
|
||||||
@ -25,7 +24,7 @@ import Control.Monad.Logger (LogLevel, LogSource,
|
|||||||
import Control.Monad.Trans.Resource (MonadResource (..), InternalState, runInternalState, MonadThrow (..), throwM, ResourceT)
|
import Control.Monad.Trans.Resource (MonadResource (..), InternalState, runInternalState, MonadThrow (..), throwM, ResourceT)
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import Data.Conduit (Flush, Source)
|
import Data.Conduit (Flush, ConduitT)
|
||||||
import Data.IORef (IORef, modifyIORef')
|
import Data.IORef (IORef, modifyIORef')
|
||||||
import Data.Map (Map, unionWith)
|
import Data.Map (Map, unionWith)
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
@ -59,7 +58,6 @@ import Control.Monad.Reader (MonadReader (..))
|
|||||||
import Data.Monoid ((<>))
|
import Data.Monoid ((<>))
|
||||||
import Control.DeepSeq (NFData (rnf))
|
import Control.DeepSeq (NFData (rnf))
|
||||||
import Control.DeepSeq.Generics (genericRnf)
|
import Control.DeepSeq.Generics (genericRnf)
|
||||||
import Data.Conduit.Lazy (MonadActive, monadActive)
|
|
||||||
import Yesod.Core.TypeCache (TypeMap, KeyedTypeMap)
|
import Yesod.Core.TypeCache (TypeMap, KeyedTypeMap)
|
||||||
import Control.Monad.Logger (MonadLoggerIO (..))
|
import Control.Monad.Logger (MonadLoggerIO (..))
|
||||||
import Data.Semigroup (Semigroup)
|
import Data.Semigroup (Semigroup)
|
||||||
@ -134,13 +132,13 @@ type RequestBodyContents =
|
|||||||
data FileInfo = FileInfo
|
data FileInfo = FileInfo
|
||||||
{ fileName :: !Text
|
{ fileName :: !Text
|
||||||
, fileContentType :: !Text
|
, fileContentType :: !Text
|
||||||
, fileSourceRaw :: !(Source (ResourceT IO) ByteString)
|
, fileSourceRaw :: !(ConduitT () ByteString (ResourceT IO) ())
|
||||||
, fileMove :: !(FilePath -> IO ())
|
, fileMove :: !(FilePath -> IO ())
|
||||||
}
|
}
|
||||||
|
|
||||||
data FileUpload = FileUploadMemory !(NWP.BackEnd L.ByteString)
|
data FileUpload = FileUploadMemory !(NWP.BackEnd L.ByteString)
|
||||||
| FileUploadDisk !(InternalState -> NWP.BackEnd FilePath)
|
| FileUploadDisk !(InternalState -> NWP.BackEnd FilePath)
|
||||||
| FileUploadSource !(NWP.BackEnd (Source (ResourceT IO) ByteString))
|
| FileUploadSource !(NWP.BackEnd (ConduitT () ByteString (ResourceT IO) ()))
|
||||||
|
|
||||||
-- | How to determine the root of the application for constructing URLs.
|
-- | How to determine the root of the application for constructing URLs.
|
||||||
--
|
--
|
||||||
@ -288,8 +286,8 @@ data PageContent url = PageContent
|
|||||||
, pageBody :: HtmlUrl url
|
, pageBody :: HtmlUrl url
|
||||||
}
|
}
|
||||||
|
|
||||||
data Content = ContentBuilder !BBuilder.Builder !(Maybe Int) -- ^ The content and optional content length.
|
data Content = ContentBuilder !BB.Builder !(Maybe Int) -- ^ The content and optional content length.
|
||||||
| ContentSource !(Source (ResourceT IO) (Flush BBuilder.Builder))
|
| ContentSource !(ConduitT () (Flush BB.Builder) (ResourceT IO) ())
|
||||||
| ContentFile !FilePath !(Maybe FilePart)
|
| ContentFile !FilePath !(Maybe FilePart)
|
||||||
| ContentDontEvaluate !Content
|
| ContentDontEvaluate !Content
|
||||||
|
|
||||||
@ -444,11 +442,6 @@ instance MonadIO m => MonadLogger (WidgetT site m) where
|
|||||||
instance MonadIO m => MonadLoggerIO (WidgetT site m) where
|
instance MonadIO m => MonadLoggerIO (WidgetT site m) where
|
||||||
askLoggerIO = WidgetT $ \_ hd -> return $ rheLog $ handlerEnv hd
|
askLoggerIO = WidgetT $ \_ hd -> return $ rheLog $ handlerEnv hd
|
||||||
|
|
||||||
instance MonadActive m => MonadActive (WidgetT site m) where
|
|
||||||
monadActive = lift monadActive
|
|
||||||
instance MonadActive m => MonadActive (HandlerT site m) where
|
|
||||||
monadActive = lift monadActive
|
|
||||||
|
|
||||||
instance MonadTrans (HandlerT site) where
|
instance MonadTrans (HandlerT site) where
|
||||||
lift = HandlerT . const
|
lift = HandlerT . const
|
||||||
|
|
||||||
@ -496,7 +489,7 @@ instance Monoid (UniqueList x) where
|
|||||||
instance Semigroup (UniqueList x)
|
instance Semigroup (UniqueList x)
|
||||||
|
|
||||||
instance IsString Content where
|
instance IsString Content where
|
||||||
fromString = flip ContentBuilder Nothing . Blaze.ByteString.Builder.Char.Utf8.fromString
|
fromString = flip ContentBuilder Nothing . BB.stringUtf8
|
||||||
|
|
||||||
instance RenderRoute WaiSubsite where
|
instance RenderRoute WaiSubsite where
|
||||||
data Route WaiSubsite = WaiSubsiteRoute [Text] [(Text, Text)]
|
data Route WaiSubsite = WaiSubsiteRoute [Text] [(Text, Text)]
|
||||||
|
|||||||
@ -22,7 +22,7 @@ import qualified Data.Text.Encoding as TE
|
|||||||
import Control.Arrow ((***))
|
import Control.Arrow ((***))
|
||||||
import Network.HTTP.Types (encodePath)
|
import Network.HTTP.Types (encodePath)
|
||||||
import Data.Monoid (mappend)
|
import Data.Monoid (mappend)
|
||||||
import Blaze.ByteString.Builder.Char.Utf8 (fromText)
|
import Data.Text.Encoding (encodeUtf8Builder)
|
||||||
|
|
||||||
data Subsite = Subsite
|
data Subsite = Subsite
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ instance Yesod Y where
|
|||||||
corrected = filter (not . TS.null) s
|
corrected = filter (not . TS.null) s
|
||||||
|
|
||||||
joinPath Y ar pieces' qs' =
|
joinPath Y ar pieces' qs' =
|
||||||
fromText ar `Data.Monoid.mappend` encodePath pieces qs
|
encodeUtf8Builder ar `Data.Monoid.mappend` encodePath pieces qs
|
||||||
where
|
where
|
||||||
pieces = if null pieces' then [""] else pieces'
|
pieces = if null pieces' then [""] else pieces'
|
||||||
qs = map (TE.encodeUtf8 *** go) qs'
|
qs = map (TE.encodeUtf8 *** go) qs'
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import qualified Data.ByteString.Lazy as L
|
|||||||
import qualified Data.ByteString.Char8 as S8
|
import qualified Data.ByteString.Char8 as S8
|
||||||
import Control.Exception (SomeException, try)
|
import Control.Exception (SomeException, try)
|
||||||
import Network.HTTP.Types (Status, mkStatus)
|
import Network.HTTP.Types (Status, mkStatus)
|
||||||
import Blaze.ByteString.Builder (Builder, fromByteString, toLazyByteString)
|
import Data.ByteString.Builder (Builder, toLazyByteString)
|
||||||
import Data.Monoid (mconcat)
|
import Data.Monoid (mconcat)
|
||||||
import Data.Text (Text, pack)
|
import Data.Text (Text, pack)
|
||||||
import Control.Monad (forM_)
|
import Control.Monad (forM_)
|
||||||
@ -101,7 +101,7 @@ getFileBadNameR :: Handler TypedContent
|
|||||||
getFileBadNameR = return $ TypedContent "ignored" $ ContentFile (error "filebadname") Nothing
|
getFileBadNameR = return $ TypedContent "ignored" $ ContentFile (error "filebadname") Nothing
|
||||||
|
|
||||||
goodBuilderContent :: Builder
|
goodBuilderContent :: Builder
|
||||||
goodBuilderContent = Data.Monoid.mconcat $ replicate 100 $ fromByteString "This is a test\n"
|
goodBuilderContent = Data.Monoid.mconcat $ replicate 100 $ "This is a test\n"
|
||||||
|
|
||||||
getGoodBuilderR :: Handler TypedContent
|
getGoodBuilderR :: Handler TypedContent
|
||||||
getGoodBuilderR = return $ TypedContent "text/plain" $ toContent goodBuilderContent
|
getGoodBuilderR = return $ TypedContent "text/plain" $ toContent goodBuilderContent
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import Yesod.Core
|
|||||||
import Network.Wai
|
import Network.Wai
|
||||||
import Network.Wai.Test
|
import Network.Wai.Test
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Blaze.ByteString.Builder (toByteString)
|
import Data.ByteString.Builder (toLazyByteString)
|
||||||
|
|
||||||
data Y = Y
|
data Y = Y
|
||||||
mkYesod "Y" [parseRoutes|
|
mkYesod "Y" [parseRoutes|
|
||||||
@ -86,7 +86,7 @@ case_blanks = runner $ do
|
|||||||
liftIO $ do
|
liftIO $ do
|
||||||
let go r =
|
let go r =
|
||||||
let (ps, qs) = renderRoute r
|
let (ps, qs) = renderRoute r
|
||||||
in toByteString $ joinPath Y "" ps qs
|
in toLazyByteString $ joinPath Y "" ps qs
|
||||||
(go $ TextR "-") `shouldBe` "/single/--"
|
(go $ TextR "-") `shouldBe` "/single/--"
|
||||||
(go $ TextR "") `shouldBe` "/single/-"
|
(go $ TextR "") `shouldBe` "/single/-"
|
||||||
(go $ TextsR ["", "-", "foo", "", "bar"]) `shouldBe` "/multi/-/--/foo/-/bar"
|
(go $ TextsR ["", "-", "foo", "", "bar"]) `shouldBe` "/multi/-/--/foo/-/bar"
|
||||||
|
|||||||
@ -22,7 +22,6 @@ import Control.Monad.Trans.Resource (register)
|
|||||||
import Data.IORef
|
import Data.IORef
|
||||||
import Data.Streaming.Network (bindPortTCP)
|
import Data.Streaming.Network (bindPortTCP)
|
||||||
import Network.HTTP.Types (status200)
|
import Network.HTTP.Types (status200)
|
||||||
import Blaze.ByteString.Builder (fromByteString)
|
|
||||||
|
|
||||||
mkYesod "App" [parseRoutes|
|
mkYesod "App" [parseRoutes|
|
||||||
/ HomeR GET
|
/ HomeR GET
|
||||||
@ -46,16 +45,16 @@ getHomeR = do
|
|||||||
getWaiStreamR :: Handler ()
|
getWaiStreamR :: Handler ()
|
||||||
getWaiStreamR = sendWaiResponse $ responseStream status200 [] $ \send flush -> do
|
getWaiStreamR = sendWaiResponse $ responseStream status200 [] $ \send flush -> do
|
||||||
flush
|
flush
|
||||||
send $ fromByteString "hello"
|
send "hello"
|
||||||
flush
|
flush
|
||||||
send $ fromByteString " world"
|
send " world"
|
||||||
|
|
||||||
getWaiAppStreamR :: Handler ()
|
getWaiAppStreamR :: Handler ()
|
||||||
getWaiAppStreamR = sendWaiApplication $ \_ f -> f $ responseStream status200 [] $ \send flush -> do
|
getWaiAppStreamR = sendWaiApplication $ \_ f -> f $ responseStream status200 [] $ \send flush -> do
|
||||||
flush
|
flush
|
||||||
send $ fromByteString "hello"
|
send "hello"
|
||||||
flush
|
flush
|
||||||
send $ fromByteString " world"
|
send " world"
|
||||||
|
|
||||||
getFreePort :: IO Int
|
getFreePort :: IO Int
|
||||||
getFreePort = do
|
getFreePort = do
|
||||||
|
|||||||
@ -25,12 +25,11 @@ library
|
|||||||
, time >= 1.5
|
, time >= 1.5
|
||||||
, wai >= 3.0
|
, wai >= 3.0
|
||||||
, wai-extra >= 3.0.7
|
, wai-extra >= 3.0.7
|
||||||
, bytestring >= 0.10
|
, bytestring >= 0.10.2
|
||||||
, text >= 0.7
|
, text >= 0.7
|
||||||
, template-haskell
|
, template-haskell
|
||||||
, path-pieces >= 0.1.2 && < 0.3
|
, path-pieces >= 0.1.2 && < 0.3
|
||||||
, shakespeare >= 2.0
|
, shakespeare >= 2.0
|
||||||
, blaze-builder >= 0.2.1.4 && < 0.5
|
|
||||||
, transformers >= 0.4
|
, transformers >= 0.4
|
||||||
, mtl
|
, mtl
|
||||||
, clientsession >= 0.9.1 && < 0.10
|
, clientsession >= 0.9.1 && < 0.10
|
||||||
@ -61,6 +60,7 @@ library
|
|||||||
, conduit-extra
|
, conduit-extra
|
||||||
, deepseq >= 1.3
|
, deepseq >= 1.3
|
||||||
, deepseq-generics
|
, deepseq-generics
|
||||||
|
-- FIXME remove
|
||||||
, mwc-random
|
, mwc-random
|
||||||
, primitive
|
, primitive
|
||||||
, word8
|
, word8
|
||||||
@ -187,7 +187,6 @@ test-suite tests
|
|||||||
,text
|
,text
|
||||||
,http-types
|
,http-types
|
||||||
, random
|
, random
|
||||||
, blaze-builder
|
|
||||||
,HUnit
|
,HUnit
|
||||||
,QuickCheck >= 2 && < 3
|
,QuickCheck >= 2 && < 3
|
||||||
,transformers
|
,transformers
|
||||||
|
|||||||
@ -24,9 +24,9 @@ module Yesod.EmbeddedStatic.Generators (
|
|||||||
|
|
||||||
-- * Util
|
-- * Util
|
||||||
, pathToName
|
, pathToName
|
||||||
|
|
||||||
-- * Custom Generators
|
-- * Custom Generators
|
||||||
|
|
||||||
-- $example
|
-- $example
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@ -34,7 +34,6 @@ import Control.Applicative as A ((<$>), (<*>))
|
|||||||
import Control.Exception (try, SomeException)
|
import Control.Exception (try, SomeException)
|
||||||
import Control.Monad (forM, when)
|
import Control.Monad (forM, when)
|
||||||
import Data.Char (isDigit, isLower)
|
import Data.Char (isDigit, isLower)
|
||||||
import Data.Conduit (($$))
|
|
||||||
import Data.Default (def)
|
import Data.Default (def)
|
||||||
import Data.Maybe (isNothing)
|
import Data.Maybe (isNothing)
|
||||||
import Language.Haskell.TH
|
import Language.Haskell.TH
|
||||||
@ -44,8 +43,7 @@ import System.FilePath ((</>))
|
|||||||
import Text.Jasmine (minifym)
|
import Text.Jasmine (minifym)
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import qualified Data.Conduit.List as C
|
import Conduit
|
||||||
import Data.Conduit.Binary (sourceHandle)
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified System.Process as Proc
|
import qualified System.Process as Proc
|
||||||
import System.Exit (ExitCode (ExitSuccess))
|
import System.Exit (ExitCode (ExitSuccess))
|
||||||
@ -208,13 +206,13 @@ compressTool f opts ct = do
|
|||||||
}
|
}
|
||||||
(Just hin, Just hout, _, ph) <- Proc.createProcess p
|
(Just hin, Just hout, _, ph) <- Proc.createProcess p
|
||||||
(compressed, (), code) <- runConcurrently $ (,,)
|
(compressed, (), code) <- runConcurrently $ (,,)
|
||||||
A.<$> Concurrently (sourceHandle hout $$ C.consume)
|
A.<$> Concurrently (runConduit $ sourceHandle hout .| sinkLazy)
|
||||||
A.<*> Concurrently (BL.hPut hin ct >> hClose hin)
|
A.<*> Concurrently (BL.hPut hin ct >> hClose hin)
|
||||||
A.<*> Concurrently (Proc.waitForProcess ph)
|
A.<*> Concurrently (Proc.waitForProcess ph)
|
||||||
if code == ExitSuccess
|
if code == ExitSuccess
|
||||||
then do
|
then do
|
||||||
putStrLn $ "Compressed successfully with " ++ f
|
putStrLn $ "Compressed successfully with " ++ f
|
||||||
return $ BL.fromChunks compressed
|
return compressed
|
||||||
else error $ "compressTool: compression failed with " ++ f
|
else error $ "compressTool: compression failed with " ++ f
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -94,10 +94,7 @@ import Data.List (foldl')
|
|||||||
import qualified Data.ByteString as S
|
import qualified Data.ByteString as S
|
||||||
import System.PosixCompat.Files (getFileStatus, modificationTime)
|
import System.PosixCompat.Files (getFileStatus, modificationTime)
|
||||||
import System.Posix.Types (EpochTime)
|
import System.Posix.Types (EpochTime)
|
||||||
import Data.Conduit
|
import Conduit
|
||||||
import Data.Conduit.List (sourceList, consume)
|
|
||||||
import Data.Conduit.Binary (sourceFile)
|
|
||||||
import qualified Data.Conduit.Text as CT
|
|
||||||
import Data.Functor.Identity (runIdentity)
|
import Data.Functor.Identity (runIdentity)
|
||||||
import System.FilePath ((</>), (<.>), takeDirectory)
|
import System.FilePath ((</>), (<.>), takeDirectory)
|
||||||
import qualified System.FilePath as F
|
import qualified System.FilePath as F
|
||||||
@ -425,8 +422,8 @@ base64md5File = fmap (base64 . encode) . hashFile
|
|||||||
base64md5 :: L.ByteString -> String
|
base64md5 :: L.ByteString -> String
|
||||||
base64md5 lbs =
|
base64md5 lbs =
|
||||||
base64 $ encode
|
base64 $ encode
|
||||||
$ runIdentity
|
$ runConduitPure
|
||||||
$ sourceList (L.toChunks lbs) $$ sinkHash
|
$ Conduit.sourceLazy lbs .| sinkHash
|
||||||
where
|
where
|
||||||
encode d = ByteArray.convert (d :: Digest MD5)
|
encode d = ByteArray.convert (d :: Digest MD5)
|
||||||
|
|
||||||
@ -461,8 +458,11 @@ combineStatics' :: CombineType
|
|||||||
-> [Route Static] -- ^ files to combine
|
-> [Route Static] -- ^ files to combine
|
||||||
-> Q Exp
|
-> Q Exp
|
||||||
combineStatics' combineType CombineSettings {..} routes = do
|
combineStatics' combineType CombineSettings {..} routes = do
|
||||||
texts <- qRunIO $ runResourceT $ mapM_ yield fps $$ awaitForever readUTFFile =$ consume
|
texts <- qRunIO $ runConduitRes
|
||||||
ltext <- qRunIO $ preProcess $ TL.fromChunks texts
|
$ yieldMany fps
|
||||||
|
.| awaitForever readUTFFile
|
||||||
|
.| sinkLazy
|
||||||
|
ltext <- qRunIO $ preProcess texts
|
||||||
bs <- qRunIO $ postProcess fps $ TLE.encodeUtf8 ltext
|
bs <- qRunIO $ postProcess fps $ TLE.encodeUtf8 ltext
|
||||||
let hash' = base64md5 bs
|
let hash' = base64md5 bs
|
||||||
suffix = csCombinedFolder </> hash' <.> extension
|
suffix = csCombinedFolder </> hash' <.> extension
|
||||||
@ -476,7 +476,7 @@ combineStatics' combineType CombineSettings {..} routes = do
|
|||||||
fps :: [FilePath]
|
fps :: [FilePath]
|
||||||
fps = map toFP routes
|
fps = map toFP routes
|
||||||
toFP (StaticRoute pieces _) = csStaticDir </> F.joinPath (map T.unpack pieces)
|
toFP (StaticRoute pieces _) = csStaticDir </> F.joinPath (map T.unpack pieces)
|
||||||
readUTFFile fp = sourceFile fp =$= CT.decode CT.utf8
|
readUTFFile fp = sourceFile fp .| decodeUtf8C
|
||||||
postProcess =
|
postProcess =
|
||||||
case combineType of
|
case combineType of
|
||||||
JS -> csJsPostProcess
|
JS -> csJsPostProcess
|
||||||
|
|||||||
@ -42,8 +42,7 @@ library
|
|||||||
, file-embed >= 0.0.4.1 && < 0.5
|
, file-embed >= 0.0.4.1 && < 0.5
|
||||||
, http-types >= 0.7
|
, http-types >= 0.7
|
||||||
, unix-compat >= 0.2
|
, unix-compat >= 0.2
|
||||||
, conduit >= 0.5
|
, conduit >= 1.3
|
||||||
, conduit-extra
|
|
||||||
, cryptonite-conduit >= 0.1
|
, cryptonite-conduit >= 0.1
|
||||||
, cryptonite >= 0.11
|
, cryptonite >= 0.11
|
||||||
, memory
|
, memory
|
||||||
@ -124,7 +123,6 @@ test-suite tests
|
|||||||
, unordered-containers
|
, unordered-containers
|
||||||
, async
|
, async
|
||||||
, process
|
, process
|
||||||
, conduit-extra
|
|
||||||
, exceptions
|
, exceptions
|
||||||
|
|
||||||
ghc-options: -Wall -threaded
|
ghc-options: -Wall -threaded
|
||||||
|
|||||||
@ -18,9 +18,7 @@ import qualified Data.ByteString.Lazy as L
|
|||||||
import Data.Text (Text, pack, unpack)
|
import Data.Text (Text, pack, unpack)
|
||||||
import Yesod.Core -- purposely using complete import so that Haddock will see addStaticContent
|
import Yesod.Core -- purposely using complete import so that Haddock will see addStaticContent
|
||||||
import Control.Monad (when, unless)
|
import Control.Monad (when, unless)
|
||||||
import Control.Monad.Trans.Resource (runResourceT)
|
import Conduit
|
||||||
import Data.Conduit (($$))
|
|
||||||
import Data.Conduit.Binary (sourceLbs, sinkFileCautious)
|
|
||||||
import System.Directory (doesFileExist, createDirectoryIfMissing)
|
import System.Directory (doesFileExist, createDirectoryIfMissing)
|
||||||
import Language.Haskell.TH.Syntax
|
import Language.Haskell.TH.Syntax
|
||||||
import Text.Lucius (luciusFile, luciusFileReload)
|
import Text.Lucius (luciusFile, luciusFileReload)
|
||||||
@ -46,8 +44,8 @@ addStaticContentExternal
|
|||||||
addStaticContentExternal minify hash staticDir toRoute ext' _ content = do
|
addStaticContentExternal minify hash staticDir toRoute ext' _ content = do
|
||||||
liftIO $ createDirectoryIfMissing True statictmp
|
liftIO $ createDirectoryIfMissing True statictmp
|
||||||
exists <- liftIO $ doesFileExist fn'
|
exists <- liftIO $ doesFileExist fn'
|
||||||
unless exists $
|
unless exists $ withSinkFileCautious fn' $ \sink ->
|
||||||
liftIO $ runResourceT $ sourceLbs content' $$ sinkFileCautious fn'
|
runConduit $ sourceLazy content' .| sink
|
||||||
return $ Just $ Right (toRoute ["tmp", pack fn], [])
|
return $ Just $ Right (toRoute ["tmp", pack fn], [])
|
||||||
where
|
where
|
||||||
fn, statictmp, fn' :: FilePath
|
fn, statictmp, fn' :: FilePath
|
||||||
|
|||||||
@ -38,8 +38,7 @@ library
|
|||||||
, bytestring
|
, bytestring
|
||||||
, monad-logger
|
, monad-logger
|
||||||
, fast-logger
|
, fast-logger
|
||||||
, conduit
|
, conduit >= 1.3
|
||||||
, conduit-extra >= 1.1.14
|
|
||||||
, resourcet
|
, resourcet
|
||||||
, shakespeare
|
, shakespeare
|
||||||
, streaming-commons
|
, streaming-commons
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user