diff --git a/Network/HTTP/Conduit.hs b/Network/HTTP/Conduit.hs
--- a/Network/HTTP/Conduit.hs
+++ b/Network/HTTP/Conduit.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 -- | This module contains everything you need to initiate HTTP connections.  If
 -- you want a simple interface based on URLs, you can use 'simpleHttp'. If you
 -- want raw power, 'http' is the underlying workhorse of this package. Some
@@ -189,7 +190,7 @@
 import qualified Network.HTTP.Types as W
 import Data.Default (def)
 
-import Control.Exception.Lifted (throwIO, try, IOException, handle)
+import Control.Exception.Lifted (throwIO, try, IOException, handle, fromException)
 import Control.Monad ((<=<))
 import Control.Monad.IO.Class (MonadIO (liftIO))
 import Control.Monad.Trans.Resource
@@ -297,17 +298,18 @@
     -- not on calling @getResponse@. However, some servers seem to close
     -- connections after accepting the request headers, so we need to check for
     -- exceptions in both.
-    ex <- try' $ do
+    ex <- try $ do
         requestBuilder req C.$$ builderToByteString C.=$ connSink ci
+
         getResponse connRelease timeout' req src
 
     case (ex, isManaged) of
-        -- Connection was reused, and might be been closed. Try again
-        (Left _, Reused) -> do
+        -- Connection was reused, and might have been closed. Try again
+        (Left e, Reused) | isRetryableException e -> do
             connRelease DontReuse
             http req m
-        -- Not reused, so this is a real exception
-        (Left e, Fresh) -> liftIO $ throwIO e
+        -- Not reused, or a non-retry, so this is a real exception
+        (Left e, _) -> liftIO $ throwIO e
         -- Everything went ok, so the connection is good. If any exceptions get
         -- thrown in the response body, just throw them as normal.
         (Right res, _) -> case cookieJar req' of
@@ -317,8 +319,23 @@
                 return $ res {responseCookieJar = cookie_jar}
             Nothing -> return res
   where
-    try' :: MonadBaseControl IO m => m a -> m (Either IOException a)
-    try' = try
+
+    -- Exceptions for which we should retry our request if we were reusing an
+    -- already open connection. In the case of IOExceptions, for example, we
+    -- assume that the connection was closed on the server and therefore open a
+    -- new one.
+    isRetryableException e =
+        case fromException e of
+            Just (_ :: IOException) -> True
+            _ ->
+                case fromException e of
+                    -- Note: Some servers will timeout connections by accepting
+                    -- the incoming packets for the new request, but closing
+                    -- the connection as soon as we try to read. To make sure
+                    -- we open a new connection under these circumstances, we
+                    -- check for the NoResponseDataReceived exception.
+                    Just NoResponseDataReceived -> True
+                    _ -> False
 
 -- | Download the specified 'Request', returning the results as a 'Response'.
 --
diff --git a/Network/HTTP/Conduit/Parser.hs b/Network/HTTP/Conduit/Parser.hs
--- a/Network/HTTP/Conduit/Parser.hs
+++ b/Network/HTTP/Conduit/Parser.hs
@@ -31,6 +31,13 @@
     return (status, headers)
   where
     getStatusLine = do
+        -- Ensure that there is some data coming in. If not, we want to signal
+        -- this as a connection problem and not a protocol problem.
+        mx <- CL.peek
+        case mx of
+            Nothing -> monadThrow NoResponseDataReceived
+            Just _ -> return ()
+
         status@(_, code, _) <- sinkLine >>= parseStatus
         if code == 100
             then newline ExpectedBlankAfter100Continue >> getStatusLine
diff --git a/Network/HTTP/Conduit/Request.hs b/Network/HTTP/Conduit/Request.hs
--- a/Network/HTTP/Conduit/Request.hs
+++ b/Network/HTTP/Conduit/Request.hs
@@ -32,7 +32,6 @@
 import Blaze.ByteString.Builder.Char8 (fromChar)
 
 import qualified Data.Conduit as C
-import qualified Data.Conduit.List as CL
 
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Char8 as S8
@@ -256,15 +255,15 @@
     => Request m
     -> C.Source m Builder
 requestBuilder req =
-    CL.sourceList [builder] `mappend` bodySource
+    bodySource
   where
     (contentLength, bodySource) =
         case requestBody req of
-            RequestBodyLBS lbs -> (Just $ L.length lbs, C.yield $ fromLazyByteString lbs)
-            RequestBodyBS bs -> (Just $ fromIntegral $ S.length bs, C.yield $ fromByteString bs)
-            RequestBodyBuilder i b -> (Just $ i, C.yield b)
-            RequestBodySource i source -> (Just i, source)
-            RequestBodySourceChunked source -> (Nothing, source C.$= chunkIt)
+            RequestBodyLBS lbs -> (Just $ L.length lbs, C.yield $ builder `mappend` fromLazyByteString lbs)
+            RequestBodyBS bs -> (Just $ fromIntegral $ S.length bs, C.yield $ builder `mappend` fromByteString bs)
+            RequestBodyBuilder i b -> (Just $ i, C.yield $ builder `mappend` b)
+            RequestBodySource i source -> (Just i, C.yield builder >> source)
+            RequestBodySourceChunked source -> (Nothing, C.yield builder >> (source C.$= chunkIt))
 
     hh
         | port req == 80 && not (secure req) = host req
diff --git a/Network/HTTP/Conduit/Types.hs b/Network/HTTP/Conduit/Types.hs
--- a/Network/HTTP/Conduit/Types.hs
+++ b/Network/HTTP/Conduit/Types.hs
@@ -191,6 +191,7 @@
                    | InvalidHeader S.ByteString
                    | InternalIOException IOException
                    | ProxyConnectException S.ByteString Int (Either S.ByteString HttpException) -- ^ host/port
+                   | NoResponseDataReceived
     deriving (Show, Typeable)
 instance Exception HttpException
 
diff --git a/http-conduit.cabal b/http-conduit.cabal
--- a/http-conduit.cabal
+++ b/http-conduit.cabal
@@ -1,5 +1,5 @@
 name:            http-conduit
-version:         1.9.0
+version:         1.9.1
 license:         BSD3
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>
