diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,10 @@
+## 3.3.10
+
+* Convert ResourceVanished error to ConnectionClosedByPeer exception
+  [#795](https://github.com/yesodweb/wai/pull/795)
+* Expand the documentation for `setTimeout`.
+  [#796](https://github.com/yesodweb/wai/pull/796)
+
 ## 3.3.9
 
 * Don't insert Last-Modified: if exists.
diff --git a/Network/Wai/Handler/Warp.hs b/Network/Wai/Handler/Warp.hs
--- a/Network/Wai/Handler/Warp.hs
+++ b/Network/Wai/Handler/Warp.hs
@@ -194,7 +194,13 @@
 setOnClose :: (SockAddr -> IO ()) -> Settings -> Settings
 setOnClose x y = y { settingsOnClose = x }
 
--- | Timeout value in seconds. Default value: 30
+-- | "Slow-loris" timeout lower-bound value in seconds.  Connections where
+-- network progress is made less frequently than this may be closed.  In
+-- practice many connections may be allowed to go without progress for up to
+-- twice this amount of time.  Note that this timeout is not applied to
+-- application code, only network progress.
+--
+-- Default value: 30
 --
 -- Since 2.1.0
 setTimeout :: Int -> Settings -> Settings
diff --git a/Network/Wai/Handler/Warp/HTTP2.hs b/Network/Wai/Handler/Warp/HTTP2.hs
--- a/Network/Wai/Handler/Warp/HTTP2.hs
+++ b/Network/Wai/Handler/Warp/HTTP2.hs
@@ -40,15 +40,17 @@
         req <- toWAIRequest h2req aux
         ref <- I.newIORef Nothing
         eResponseReceived <- E.try $ app req $ \rsp -> do
+            let st = responseStatus rsp
             h2rsp <- fromResponse settings ii req rsp
             pps <- fromPushPromises ii req
-            I.writeIORef ref $ Just (h2rsp, pps)
+            I.writeIORef ref $ Just (h2rsp, pps, st)
             _ <- response h2rsp pps
             return ResponseReceived
         case eResponseReceived of
           Right ResponseReceived -> do
-              Just (h2rsp, pps) <- I.readIORef ref
-              logResponse h2rsp req
+              Just (h2rsp, pps, st) <- I.readIORef ref
+              let msiz = fromIntegral <$> H2.responseBodySize h2rsp
+              logResponse req st msiz
               mapM_ (logPushPromise req) pps
           Left e@(E.SomeException _)
             -- killed by the local worker manager
@@ -58,9 +60,11 @@
             | otherwise -> do
                 S.settingsOnException settings (Just req) e
                 let ersp = S.settingsOnExceptionResponse settings e
+                    st = responseStatus ersp
                 h2rsp' <- fromResponse settings ii req ersp
+                let msiz = fromIntegral <$> H2.responseBodySize h2rsp'
                 _ <- response h2rsp' []
-                logResponse h2rsp' req
+                logResponse req st msiz
         return ()
 
     toWAIRequest h2req aux = toRequest ii settings addr hdr bdylen bdy th transport
@@ -70,11 +74,7 @@
         !bdylen = H2.requestBodySize h2req
         !th = H2.auxTimeHandle aux
 
-    logResponse h2rsp req = logger req st msiz
-      where
-        !logger = S.settingsLogger settings
-        !st = H2.responseStatus h2rsp
-        !msiz = fromIntegral <$> H2.responseBodySize h2rsp
+    logResponse = S.settingsLogger settings
 
     logPushPromise req pp = logger req path siz
       where
diff --git a/Network/Wai/Handler/Warp/Recv.hs b/Network/Wai/Handler/Warp/Recv.hs
--- a/Network/Wai/Handler/Warp/Recv.hs
+++ b/Network/Wai/Handler/Warp/Recv.hs
@@ -153,6 +153,8 @@
        else
         return bytes
 
+#ifndef mingw32_HOST_OS
 -- fixme: the type of the return value
 foreign import ccall unsafe "recv"
     c_recv :: CInt -> Ptr CChar -> CSize -> CInt -> IO CInt
+#endif
diff --git a/Network/Wai/Handler/Warp/Run.hs b/Network/Wai/Handler/Warp/Run.hs
--- a/Network/Wai/Handler/Warp/Run.hs
+++ b/Network/Wai/Handler/Warp/Run.hs
@@ -20,7 +20,7 @@
 import Data.IORef (IORef, newIORef, readIORef, writeIORef)
 import Data.Streaming.Network (bindPortTCP)
 import Foreign.C.Error (Errno(..), eCONNABORTED)
-import GHC.IO.Exception (IOException(..))
+import GHC.IO.Exception (IOException(..), IOErrorType(..))
 import qualified Network.HTTP2 as H2
 import Network.Socket (Socket, close, accept, withSocketsDo, SockAddr(SockAddrInet, SockAddrInet6), setSocketOption, SocketOption(..))
 #if MIN_VERSION_network(3,1,1)
@@ -30,6 +30,7 @@
 import Network.Wai
 import Network.Wai.Internal (ResponseReceived (ResponseReceived))
 import System.Environment (lookupEnv)
+import System.IO.Error (ioeGetErrorType)
 import qualified System.TimeManager as T
 import System.Timeout (timeout)
 
@@ -59,10 +60,14 @@
 
 -- | Creating 'Connection' for plain HTTP based on a given socket.
 socketConnection :: Settings -> Socket -> IO Connection
+#if MIN_VERSION_network(3,1,1)
 socketConnection set s = do
+#else
+socketConnection _ s = do
+#endif
     bufferPool <- newBufferPool
     writeBuf <- allocateBuffer bufferSize
-    let sendall = Sock.sendAll s
+    let sendall = sendAll' s
     isH2 <- newIORef False -- HTTP/1.x
     return Connection {
         connSendMany = Sock.sendMany s
@@ -87,6 +92,13 @@
       , connBufferSize = bufferSize
       , connHTTP2 = isH2
       }
+  where
+    sendAll' sock bs = E.handleJust
+      (\ e -> if ioeGetErrorType e == ResourceVanished
+        then Just ConnectionClosedByPeer
+        else Nothing)
+      throwIO
+      $ Sock.sendAll sock bs
 
 -- | Run an 'Application' on the given port.
 -- This calls 'runSettings' with 'defaultSettings'.
diff --git a/warp.cabal b/warp.cabal
--- a/warp.cabal
+++ b/warp.cabal
@@ -1,5 +1,5 @@
 Name:                warp
-Version:             3.3.9
+Version:             3.3.10
 Synopsis:            A fast, light-weight web server for WAI applications.
 License:             MIT
 License-file:        LICENSE
