[web-devel] Conduit/Wai proxy, HOWTO?

Jason Dusek jason.dusek at gmail.com
Wed Aug 29 15:24:37 CEST 2012

Hello All,

I seem to have something which compiles and compiling is half
the battle. Perhaps there is a better, nicer way to do it; or
maybe the code below has some mines hidden in it. Would be great
to get some insight in these matters.

Now it's time for me to go shopping.

Jason Dusek
pgp // solidsnack // C1EBC57DC55144F35460C8DF1FD4C6C1FED18A2B

import           Data.ByteString (ByteString)

import qualified Blaze.ByteString.Builder as Blaze
import           Control.Monad.Trans
import           Control.Monad.Trans.Resource
import           Data.Conduit (($=))
import qualified Data.Conduit as Conduit
import qualified Data.Conduit.List as Conduit
import           Data.Default
import qualified Network.Wai as Wai
import qualified Network.HTTP.Conduit as Conduit

wai :: String -> Wai.Application
wai s _ = do
  (_, mangari) <- allocate (Conduit.newManager def) Conduit.closeManager
  go mangari
  go :: Conduit.Manager -> Conduit.ResourceT IO Wai.Response
  go manager                    = do
    request                    <- liftIO $ Conduit.parseUrl s
    Conduit.Response s _ h src <- Conduit.http request manager
    src                        <- reSource src
    return $ Wai.ResponseSource s h (src $= b2b)

reSource :: MonadIO m => Conduit.ResumableSource m o -> m (Conduit.Source m o)
reSource resumable     = do
  (src, finalizer)    <- Conduit.unwrapResumable resumable
  return $ Conduit.addCleanup (const finalizer) src

b2b :: (Monad m) => Conduit.Conduit ByteString m (Conduit.Flush Blaze.Builder)
b2b  = Conduit.map (Conduit.Chunk . Blaze.fromByteString)

More information about the web-devel mailing list