diff --git a/Network/HTTP/Enumerator.hs b/Network/HTTP/Enumerator.hs
--- a/Network/HTTP/Enumerator.hs
+++ b/Network/HTTP/Enumerator.hs
@@ -57,6 +57,7 @@
     , httpLbs
     , httpLbsRedirect
     , http
+    , streamingHttp
     , httpRedirect
       -- * Datatypes
     , Request (..)
@@ -89,7 +90,7 @@
 import Data.Enumerator
     ( Iteratee (..), Stream (..), catchError, throwError, consume
     , yield, Step (..), Enumeratee, ($$), joinI, Enumerator, run_
-    , continue, enumList, returnI
+    , continue, returnI, (>==>)
     )
 import qualified Data.Enumerator as E
 import Network.HTTP.Enumerator.HttpParser
@@ -107,9 +108,11 @@
 import Data.ByteString.Lazy.Internal (defaultChunkSize)
 import Codec.Binary.UTF8.String (encodeString)
 import qualified Blaze.ByteString.Builder as Blaze
+import Blaze.ByteString.Builder.Enumerator (builderToByteString)
 import qualified Blaze.ByteString.Builder.Internal.Write as Blaze
 import Data.Monoid (Monoid (..))
 import qualified Network.Wai as W
+import Data.Int (Int64)
 
 -- | The OpenSSL library requires some initialization of variables to be used,
 -- and therefore you must call 'withOpenSSL' before using any of its functions.
@@ -139,11 +142,11 @@
 withSocketConn :: MonadIO m
                => String
                -> Int
-               -> Enumerator S.ByteString m ()
+               -> Enumerator Blaze.Builder m ()
                -> Enumerator S.ByteString m a
 withSocketConn host' port' req step0 = do
     sock <- liftIO $ getSocket host' port'
-    lift $ run_ $ req $$ writeToIter $ B.sendAll sock
+    lift $ run_ $ req $$ joinI $ builderToByteString $$ writeToIter $ B.sendAll sock
     a <- readToEnum (B.recv sock defaultChunkSize) step0
     liftIO $ NS.sClose sock
     return a
@@ -172,7 +175,7 @@
 withSslConn :: MonadIO m
             => String -- ^ host
             -> Int -- ^ port
-            -> Enumerator S.ByteString m () -- ^ request
+            -> Enumerator Blaze.Builder m () -- ^ request
             -> Enumerator S.ByteString m a -- ^ response
 withSslConn host' port' req step0 = do
 
@@ -238,22 +241,38 @@
      => Request
      -> (W.Status -> W.ResponseHeaders -> Iteratee S.ByteString m a)
      -> Iteratee S.ByteString m a
-http Request {..} bodyStep = do
+http req bodyStep =
+    streamingHttp req reqBody bodyStep
+  where
+    reqBody = (L.length $ requestBody req, toEnum $ requestBody req)
+    toEnum = enumSingle . Blaze.fromLazyByteString
+
+enumSingle x (Continue k) = k $ Chunks [x]
+enumSingle _ step = returnI step
+
+-- | Same as 'http', but allows you to specify a ('Int64', 'Enumerator') pair
+-- for the request body. Note: this function ignores the 'requestBody' record
+-- in the 'Request' argument.
+streamingHttp
+     :: MonadIO m
+     => Request
+     -> (Int64, Enumerator Blaze.Builder m ())
+     -> (W.Status -> W.ResponseHeaders -> Iteratee S.ByteString m a)
+     -> Iteratee S.ByteString m a
+streamingHttp Request {..} (contentLength, bodyEnum) bodyStep = do
     let h' = S8.unpack host
     let withConn = if secure then withSslConn else withSocketConn
-    withConn h' port req $$ go
+    withConn h' port requestEnum $$ go
   where
-    req = enumList 8 $ L.toChunks request
     hh
         | port == 80 && not secure = host
         | port == 443 && secure = host
         | otherwise = host `S.append` S8.pack (':' : show port)
     headers' = ("Host", hh)
-                 : ("Content-Length", S8.pack $ show
-                                              $ L.length requestBody)
+                 : ("Content-Length", S8.pack $ show contentLength)
                  : ("Accept-Encoding", "gzip")
                  : requestHeaders
-    request = Blaze.toLazyByteString $ mconcat
+    requestHeaders' = mconcat
             [ Blaze.fromByteString method
             , Blaze.fromByteString " "
             , Blaze.fromByteString $
@@ -269,9 +288,8 @@
                 , Blaze.fromByteString "\r\n"
                 ]
             , Blaze.fromByteString "\r\n"
-            , mconcat $ map Blaze.fromByteString
-                      $ L.toChunks requestBody
             ]
+    requestEnum = enumSingle requestHeaders' >==> bodyEnum
     go = do
         ((_, sc, sm), hs) <- catchParser "HTTP headers" iterHeaders
         let s = W.Status sc sm
diff --git a/Network/TLS/Client/Enumerator.hs b/Network/TLS/Client/Enumerator.hs
--- a/Network/TLS/Client/Enumerator.hs
+++ b/Network/TLS/Client/Enumerator.hs
@@ -6,9 +6,11 @@
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as L
 import qualified Data.Enumerator as E
-import Data.Enumerator (($$))
+import Data.Enumerator (($$), joinI)
 import qualified Control.Monad.IO.Class as Trans
 import Control.Monad.Trans.Class (lift)
+import Blaze.ByteString.Builder (Builder)
+import Blaze.ByteString.Builder.Enumerator (builderToByteString)
 
 import Network.TLS.Client
 import Network.TLS.SRandom
@@ -30,7 +32,7 @@
 clientEnumSimple
     :: Trans.MonadIO m
     => Handle
-    -> E.Enumerator B.ByteString m () -- ^ request
+    -> E.Enumerator Builder m () -- ^ request
     -> E.Enumerator B.ByteString m a -- ^ response
 clientEnumSimple h req step = do
     let clientstate = TLSClientParams
@@ -56,12 +58,12 @@
 
 clientEnum :: Trans.MonadIO m
            => TLSClientParams -> SRandomGen -> Handle
-           -> E.Enumerator B.ByteString m ()
+           -> E.Enumerator Builder m ()
            -> E.Enumerator B.ByteString m a
 clientEnum tcp srg h req step0 = do
     istate <- Trans.liftIO $ newIState tcp srg
     tlsHelper istate $ connect h
-    lift $ E.run_ $ req $$ iter istate
+    lift $ E.run_ $ req $$ joinI $ builderToByteString $$ iter istate
     res <- enum istate step0
     tlsHelper istate $ close h
     return res
diff --git a/http-enumerator.cabal b/http-enumerator.cabal
--- a/http-enumerator.cabal
+++ b/http-enumerator.cabal
@@ -1,5 +1,5 @@
 name:            http-enumerator
-version:         0.3.0
+version:         0.3.1
 license:         BSD3
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>
@@ -33,6 +33,7 @@
                  , blaze-builder         >= 0.2.1   && < 0.3
                  , zlib-bindings         >= 0.0.0   && < 0.1
                  , wai                   >= 0.3     && < 0.4
+                 , blaze-builder-enumerator >= 0.2  && < 0.3
     if flag(network-bytestring)
         build-depends: network               >= 2.2.1   && < 2.2.3
                      , network-bytestring    >= 0.1.3   && < 0.1.4
