@@ -36,6 +36,7 @@ module Network.Wai.Handler.Warp
3636 , settingsTimeout
3737 , settingsIntercept
3838 , settingsManager
39+ , settingsRechunking
3940 -- * Datatypes
4041 , Port
4142 , InvalidRequest (..)
@@ -94,7 +95,7 @@ import Blaze.ByteString.Builder.Enumerator (builderToByteString)
9495import Blaze.ByteString.Builder.HTTP
9596 (chunkedTransferEncoding, chunkedTransferTerminator)
9697import Blaze.ByteString.Builder
97− (copyByteString, Builder, toLazyByteString, toByteStringIO)
98+ (copyByteString, Builder, toLazyByteString, toByteStringIO, toByteString)
9899import Blaze.ByteString.Builder.Char8 (fromChar, fromShow)
99100import Data.Monoid (mappend, mconcat)
100101import Network.Sendfile
@@ -212,7 +213,7 @@ serveConnection settings th onException port app conn remoteHost' = do
212213 liftIO $ T.pause th
213214 res <- E.joinI $ EB.isolate len $$ app env
214215 liftIO $ T.resume th
215− keepAlive <- liftIO $ sendResponse th env conn res
216+ keepAlive <- liftIO $ sendResponse settings th env conn res
216217 if keepAlive then serveConnection' else return ()
217218 Just intercept -> do
218219 liftIO $ T.pause th
@@ -354,9 +355,8 @@ hasBody :: H.Status -> Request -> Bool
354355hasBody s req = s /= (H.Status 204 "") && s /= H.status304 &&
355356 H.statusCode s >= 200 && requestMethod req /= "HEAD"
356357
357−sendResponse :: T.Handle
358− -> Request -> Socket -> Response -> IO Bool
359−sendResponse th req socket r = sendResponse' r
358+sendResponse :: Settings -> T.Handle -> Request -> Socket -> Response -> IO Bool
359+sendResponse settings th req socket r = sendResponse' r
360360 where
361361 version = httpVersion req
362362 isPersist = checkPersist req
@@ -429,7 +429,9 @@ sendResponse th req socket r = sendResponse' r
429429 return (checkPersist req)
430430 response _ = chunk'
431431 $ E.enumList 1 [headers' needsChunked']
432− $$ E.joinI $ builderToByteString -- FIXME unsafeBuilderToByteString
432+ $$ E.joinI $ ( if settingsRechunking settings
433+ then builderToByteString -- FIXME unsafeBuilderToByteString
434+ else EL.map toByteString )
433435 $$ (iterSocket th socket >> return (isKeepAlive hs))
434436 where
435437 needsChunked' = needsChunked hs
@@ -498,6 +500,7 @@ data Settings = Settings
498500 , settingsTimeout :: Int -- ^ Timeout value in seconds. Default value: 30
499501 , settingsIntercept :: Request -> Maybe (Socket -> E.Iteratee S.ByteString IO ())
500502 , settingsManager :: Maybe Manager -- ^ Use an existing timeout manager instead of spawning a new one. If used, 'settingsTimeout' is ignored. Default is 'Nothing'
503+ , settingsRechunking :: Bool -- ^ Should warp re-chunk response builder or not.
501504 }
502505
503506-- | The default settings for the Warp server. See the individual settings for
@@ -516,6 +519,7 @@ defaultSettings = Settings
516519 , settingsTimeout = 30
517520 , settingsIntercept = const Nothing
518521 , settingsManager = Nothing
522+ , settingsRechunking = True
519523 }
520524 where
521525 go :: InvalidRequest -> IO ()