diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,13 @@
+## 3.2.15
+
+* Address space leak from exception handlers
+  [#649](https://github.com/yesodweb/wai/issues/649)
+
+## 3.2.14
+
+* Support streaming-commons 0.2
+* Warnings cleanup
+
 ## 3.2.13
 
 * Tickling HTTP/2 timer. [624](https://github.com/yesodweb/wai/pull/624)
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
@@ -119,20 +119,20 @@
   ) where
 
 import Control.Exception (SomeException, throwIO)
-import Data.ByteString (ByteString)
-import Data.Maybe (fromMaybe)
 import Data.Streaming.Network (HostPreference)
 import qualified Data.Vault.Lazy as Vault
 import qualified Network.HTTP.Types as H
 import Network.Socket (SockAddr)
 import Network.Wai (Request, Response, vault)
+
 import Network.Wai.Handler.Warp.FileInfoCache
+import Network.Wai.Handler.Warp.HTTP2.Request (getHTTP2Data, setHTTP2Data, modifyHTTP2Data)
+import Network.Wai.Handler.Warp.HTTP2.Types
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.Request
 import Network.Wai.Handler.Warp.Response (warpVersion)
 import Network.Wai.Handler.Warp.Run
 import Network.Wai.Handler.Warp.Settings
-import Network.Wai.Handler.Warp.HTTP2.Request (getHTTP2Data, setHTTP2Data, modifyHTTP2Data)
-import Network.Wai.Handler.Warp.HTTP2.Types
 import Network.Wai.Handler.Warp.Timeout
 import Network.Wai.Handler.Warp.Types hiding (getFileInfo)
 import Network.Wai.Handler.Warp.WithApplication
diff --git a/Network/Wai/Handler/Warp/Buffer.hs b/Network/Wai/Handler/Warp/Buffer.hs
--- a/Network/Wai/Handler/Warp/Buffer.hs
+++ b/Network/Wai/Handler/Warp/Buffer.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE BangPatterns, OverloadedStrings #-}
+{-# LANGUAGE BangPatterns #-}
 
 module Network.Wai.Handler.Warp.Buffer (
     bufferSize
@@ -13,13 +13,15 @@
   ) where
 
 import qualified Data.ByteString as BS
-import Data.ByteString.Internal (ByteString(..), memcpy)
+import Data.ByteString.Internal (memcpy)
 import Data.ByteString.Unsafe (unsafeTake, unsafeDrop)
 import Data.IORef (newIORef, readIORef, writeIORef)
 import qualified Data.Streaming.ByteString.Builder.Buffer as B (Buffer (..))
 import Foreign.ForeignPtr
 import Foreign.Marshal.Alloc (mallocBytes, free, finalizerFree)
 import Foreign.Ptr (castPtr, plusPtr)
+
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.Types
 
 ----------------------------------------------------------------
diff --git a/Network/Wai/Handler/Warp/Conduit.hs b/Network/Wai/Handler/Warp/Conduit.hs
--- a/Network/Wai/Handler/Warp/Conduit.hs
+++ b/Network/Wai/Handler/Warp/Conduit.hs
@@ -3,14 +3,10 @@
 module Network.Wai.Handler.Warp.Conduit where
 
 import Control.Exception
-import Control.Monad (when, unless)
-import Data.ByteString (ByteString)
 import qualified Data.ByteString as S
 import qualified Data.IORef as I
-#if __GLASGOW_HASKELL__ < 709
-import Data.Word (Word)
-#endif
-import Data.Word (Word8)
+
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.Types
 
 ----------------------------------------------------------------
diff --git a/Network/Wai/Handler/Warp/Counter.hs b/Network/Wai/Handler/Warp/Counter.hs
--- a/Network/Wai/Handler/Warp/Counter.hs
+++ b/Network/Wai/Handler/Warp/Counter.hs
@@ -8,11 +8,10 @@
   , decrease
   ) where
 
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative ((<$>))
-#endif
 import Control.Concurrent.STM
-import Control.Monad (unless)
+
+import Network.Wai.Handler.Warp.Imports
+
 
 newtype Counter = Counter (TVar Int)
 
diff --git a/Network/Wai/Handler/Warp/Date.hs b/Network/Wai/Handler/Warp/Date.hs
--- a/Network/Wai/Handler/Warp/Date.hs
+++ b/Network/Wai/Handler/Warp/Date.hs
@@ -5,11 +5,8 @@
   , GMTDate
   ) where
 
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative
-#endif
 import Control.AutoUpdate (defaultUpdateSettings, updateAction, mkAutoUpdate)
-import Data.ByteString.Char8
+import Data.ByteString
 import Network.HTTP.Date
 
 #if WINDOWS
diff --git a/Network/Wai/Handler/Warp/FdCache.hs b/Network/Wai/Handler/Warp/FdCache.hs
--- a/Network/Wai/Handler/Warp/FdCache.hs
+++ b/Network/Wai/Handler/Warp/FdCache.hs
@@ -14,13 +14,10 @@
   ) where
 
 #ifndef WINDOWS
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative ((<$>), (<*>))
-#endif
 import Control.Exception (bracket)
-import Network.Wai.Handler.Warp.IORef
-import Network.Wai.Handler.Warp.MultiMap
 import Control.Reaper
+import Data.IORef
+import Network.Wai.Handler.Warp.MultiMap
 import System.Posix.IO (openFd, OpenFileFlags(..), defaultFileFlags, OpenMode(ReadOnly), closeFd, FdOption(CloseOnExec), setFdOption)
 #endif
 import System.Posix.Types (Fd)
@@ -46,7 +43,7 @@
 withFdCache 0        action = action getFdNothing
 withFdCache duration action = bracket (initialize duration)
                                       terminate
-                                      (\mfc -> action (getFd mfc))
+                                      (action . getFd)
 
 ----------------------------------------------------------------
 
diff --git a/Network/Wai/Handler/Warp/File.hs b/Network/Wai/Handler/Warp/File.hs
--- a/Network/Wai/Handler/Warp/File.hs
+++ b/Network/Wai/Handler/Warp/File.hs
@@ -9,20 +9,19 @@
   , H.parseByteRanges
   ) where
 
-import Control.Applicative ((<|>))
 import Data.Array ((!))
-import qualified Data.ByteString.Char8 as B (pack)
-import Data.ByteString (ByteString)
-import Data.Maybe (fromMaybe)
+import qualified Data.ByteString.Char8 as C8 (pack)
 import Network.HTTP.Date
 import qualified Network.HTTP.Types as H
 import qualified Network.HTTP.Types.Header as H
 import Network.Wai
+
 import qualified Network.Wai.Handler.Warp.FileInfoCache as I
 import Network.Wai.Handler.Warp.Header
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.PackInt
-import Numeric (showInt)
 
+
 -- $setup
 -- >>> import Test.QuickCheck
 
@@ -117,7 +116,7 @@
 contentRangeHeader :: Integer -> Integer -> Integer -> H.Header
 contentRangeHeader beg end total = (H.hContentRange, range)
   where
-    range = B.pack
+    range = C8.pack
       -- building with ShowS
       $ 'b' : 'y': 't' : 'e' : 's' : ' '
       : (if beg > end then ('*':) else
diff --git a/Network/Wai/Handler/Warp/FileInfoCache.hs b/Network/Wai/Handler/Warp/FileInfoCache.hs
--- a/Network/Wai/Handler/Warp/FileInfoCache.hs
+++ b/Network/Wai/Handler/Warp/FileInfoCache.hs
@@ -8,13 +8,13 @@
   ) where
 
 import Control.Exception as E
-import Control.Monad (void)
 import Control.Reaper
-import Data.ByteString (ByteString)
 import Network.HTTP.Date
+import System.PosixCompat.Files
+
 import Network.Wai.Handler.Warp.HashMap (HashMap)
 import qualified Network.Wai.Handler.Warp.HashMap as M
-import System.PosixCompat.Files
+import Network.Wai.Handler.Warp.Imports
 
 ----------------------------------------------------------------
 
@@ -91,7 +91,7 @@
 withFileInfoCache duration action =
     E.bracket (initialize duration)
               terminate
-              (\r -> action (getAndRegisterInfo r))
+              (action . getAndRegisterInfo)
 
 initialize :: Hash -> IO FileInfoCache
 initialize duration = mkReaper 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
@@ -5,11 +5,10 @@
 
 import Control.Concurrent (forkIO, killThread)
 import qualified Control.Exception as E
-import Control.Monad (when, unless, replicateM_)
-import Data.ByteString (ByteString)
 import Network.HTTP2
 import Network.Socket (SockAddr)
 import Network.Wai
+
 import Network.Wai.Handler.Warp.HTTP2.EncodeFrame
 import Network.Wai.Handler.Warp.HTTP2.Manager
 import Network.Wai.Handler.Warp.HTTP2.Receiver
@@ -17,6 +16,7 @@
 import Network.Wai.Handler.Warp.HTTP2.Sender
 import Network.Wai.Handler.Warp.HTTP2.Types
 import Network.Wai.Handler.Warp.HTTP2.Worker
+import Network.Wai.Handler.Warp.Imports
 import qualified Network.Wai.Handler.Warp.Settings as S (Settings)
 import Network.Wai.Handler.Warp.Types
 
diff --git a/Network/Wai/Handler/Warp/HTTP2/EncodeFrame.hs b/Network/Wai/Handler/Warp/HTTP2/EncodeFrame.hs
--- a/Network/Wai/Handler/Warp/HTTP2/EncodeFrame.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/EncodeFrame.hs
@@ -1,9 +1,8 @@
-{-# LANGUAGE OverloadedStrings #-}
-
 module Network.Wai.Handler.Warp.HTTP2.EncodeFrame where
 
-import Data.ByteString (ByteString)
 import Network.HTTP2
+
+import Network.Wai.Handler.Warp.Imports
 
 ----------------------------------------------------------------
 
diff --git a/Network/Wai/Handler/Warp/HTTP2/File.hs b/Network/Wai/Handler/Warp/HTTP2/File.hs
--- a/Network/Wai/Handler/Warp/HTTP2/File.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/File.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE BangPatterns, RecordWildCards #-}
+{-# LANGUAGE BangPatterns #-}
 
 module Network.Wai.Handler.Warp.HTTP2.File (
     RspFileInfo(..)
@@ -9,18 +9,16 @@
   , H.parseByteRanges
   ) where
 
-import Control.Applicative ((<|>))
-import qualified Data.ByteString.Char8 as B (pack)
-import Data.ByteString (ByteString)
-import Data.Maybe (fromMaybe)
+import qualified Data.ByteString.Char8 as C8 (pack)
+import Network.HPACK
+import Network.HPACK.Token
 import Network.HTTP.Date
 import qualified Network.HTTP.Types as H
 import Network.Wai
+
 import qualified Network.Wai.Handler.Warp.FileInfoCache as I
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.PackInt
-import Numeric (showInt)
-import Network.HPACK
-import Network.HPACK.Token
 
 -- $setup
 -- >>> import Test.QuickCheck
@@ -124,7 +122,7 @@
 contentRangeHeader :: Integer -> Integer -> Integer -> TokenHeader
 contentRangeHeader beg end total = (tokenContentRange, range)
   where
-    range = B.pack
+    range = C8.pack
       -- building with ShowS
       $ 'b' : 'y': 't' : 'e' : 's' : ' '
       : (if beg > end then ('*':) else
diff --git a/Network/Wai/Handler/Warp/HTTP2/HPACK.hs b/Network/Wai/Handler/Warp/HTTP2/HPACK.hs
--- a/Network/Wai/Handler/Warp/HTTP2/HPACK.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/HPACK.hs
@@ -11,12 +11,12 @@
   ) where
 
 import qualified Control.Exception as E
-import Control.Monad (unless)
-import Data.ByteString (ByteString)
 import Network.HPACK hiding (Buffer)
 import Network.HPACK.Token
 import Network.HTTP2
+
 import Network.Wai.Handler.Warp.HTTP2.Types
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.PackInt
 import qualified Network.Wai.Handler.Warp.Settings as S
 import Network.Wai.Handler.Warp.Types
@@ -87,13 +87,13 @@
 {-# INLINE checkRequestHeader #-}
 checkRequestHeader :: ValueTable -> Bool
 checkRequestHeader reqvt
-  | just mMethod (== "CONNECT") = mPath == Nothing && mScheme == Nothing
-  | mStatus     /= Nothing      = False
-  | mMethod     == Nothing      = False
-  | mScheme     == Nothing      = False
-  | mPath       == Nothing      = False
+  | just mMethod (== "CONNECT") = isNothing mPath && isNothing mScheme
+  | isJust mStatus              = False
+  | isNothing mMethod           = False
+  | isNothing mScheme           = False
+  | isNothing mPath             = False
   | mPath       == Just ""      = False
-  | mConnection /= Nothing      = False
+  | isJust mConnection          = False
   | just mTE (/= "trailers")    = False
   | otherwise                   = True
   where
diff --git a/Network/Wai/Handler/Warp/HTTP2/Manager.hs b/Network/Wai/Handler/Warp/HTTP2/Manager.hs
--- a/Network/Wai/Handler/Warp/HTTP2/Manager.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/Manager.hs
@@ -13,16 +13,14 @@
   , deleteMyId
   ) where
 
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative
-#endif
 import Control.Concurrent
 import Control.Concurrent.STM
-import Control.Monad (void)
+import Data.Foldable
+import Data.IORef
 import Data.Set (Set)
 import qualified Data.Set as Set
-import Data.Foldable
-import Network.Wai.Handler.Warp.IORef
+
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.Settings
 import qualified Network.Wai.Handler.Warp.Timeout as T
 
diff --git a/Network/Wai/Handler/Warp/HTTP2/Receiver.hs b/Network/Wai/Handler/Warp/HTTP2/Receiver.hs
--- a/Network/Wai/Handler/Warp/HTTP2/Receiver.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/Receiver.hs
@@ -6,24 +6,21 @@
 
 module Network.Wai.Handler.Warp.HTTP2.Receiver (frameReceiver) where
 
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative
-#endif
 import Control.Concurrent
 import Control.Concurrent.STM
 import qualified Control.Exception as E
-import Control.Monad (when, unless, void)
-import Data.ByteString (ByteString)
 import qualified Data.ByteString as BS
+import Data.IORef
 import Network.HPACK
 import Network.HPACK.Token
 import Network.HTTP2
 import Network.HTTP2.Priority (toPrecedence, delete, prepare)
+
 import Network.Wai.Handler.Warp.HTTP2.EncodeFrame
 import Network.Wai.Handler.Warp.HTTP2.HPACK
 import Network.Wai.Handler.Warp.HTTP2.Request
 import Network.Wai.Handler.Warp.HTTP2.Types
-import Network.Wai.Handler.Warp.IORef
+import Network.Wai.Handler.Warp.Imports hiding (delete, insert, readInt)
 import Network.Wai.Handler.Warp.ReadInt
 import Network.Wai.Handler.Warp.Types
 
@@ -168,7 +165,7 @@
                          when (ftyp `notElem` [FrameHeaders,FramePriority]) $
                              E.throwIO $ ConnectionError ProtocolError "this frame is not allowed in an idel stream"
                          csid <- readIORef clientStreamId
-                         if streamId <= csid then do
+                         if streamId <= csid then
                              if ftyp == FramePriority then
                                  return Nothing -- will be ignored
                                else
diff --git a/Network/Wai/Handler/Warp/HTTP2/Request.hs b/Network/Wai/Handler/Warp/HTTP2/Request.hs
--- a/Network/Wai/Handler/Warp/HTTP2/Request.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/Request.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE OverloadedStrings, CPP #-}
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE BangPatterns #-}
 
 module Network.Wai.Handler.Warp.HTTP2.Request (
@@ -9,26 +9,25 @@
   , modifyHTTP2Data
   ) where
 
-import Control.Applicative ((<|>))
 import Control.Arrow (first)
-import Data.ByteString (ByteString)
-import qualified Data.ByteString.Char8 as B8
-import Data.Maybe (fromJust)
+import qualified Data.ByteString.Char8 as C8
+import Data.IORef
 import qualified Data.Vault.Lazy as Vault
 import Network.HPACK
 import Network.HPACK.Token
 import qualified Network.HTTP.Types as H
 import Network.Socket (SockAddr)
 import Network.Wai
+import Network.Wai.Internal (Request(..))
+import System.IO.Unsafe (unsafePerformIO)
+
 import Network.Wai.Handler.Warp.HTTP2.Types
 import Network.Wai.Handler.Warp.HashMap (hashByteString)
-import Network.Wai.Handler.Warp.IORef
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.Request (pauseTimeoutKey, getFileInfoKey)
 import qualified Network.Wai.Handler.Warp.Settings as S (Settings, settingsNoParsePath)
 import qualified Network.Wai.Handler.Warp.Timeout as Timeout
 import Network.Wai.Handler.Warp.Types
-import Network.Wai.Internal (Request(..))
-import System.IO.Unsafe (unsafePerformIO)
 
 type MkReq = (TokenHeaderList,ValueTable) -> (Maybe Int,IO ByteString) -> IO (Request,InternalInfo)
 
@@ -76,7 +75,7 @@
     !mUserAgent = getHeaderValue tokenUserAgent reqvt
     -- CONNECT request will have ":path" omitted, use ":authority" as unparsed
     -- path instead so that it will have consistent behavior compare to HTTP 1.0
-    (unparsedPath,query) = B8.break (=='?') $ fromJust (mPath <|> mAuth)
+    (unparsedPath,query) = C8.break (=='?') $ fromJust (mPath <|> mAuth)
     !path = H.extractPath unparsedPath
     !rawPath = if S.settingsNoParsePath settings then unparsedPath else path
     !h = hashByteString rawPath
@@ -91,7 +90,7 @@
 
 getHTTP2DataKey :: Vault.Key (IO (Maybe HTTP2Data))
 getHTTP2DataKey = unsafePerformIO Vault.newKey
-{-# NOINLINE getHTTP2Data #-}
+{-# NOINLINE getHTTP2DataKey #-}
 
 -- | Getting 'HTTP2Data' through vault of the request.
 --   Warp uses this to receive 'HTTP2Data' from 'Middleware'.
@@ -104,7 +103,7 @@
 
 setHTTP2DataKey :: Vault.Key (Maybe HTTP2Data -> IO ())
 setHTTP2DataKey = unsafePerformIO Vault.newKey
-{-# NOINLINE setHTTP2Data #-}
+{-# NOINLINE setHTTP2DataKey #-}
 
 -- | Setting 'HTTP2Data' through vault of the request.
 --   'Application' or 'Middleware' should use this.
@@ -117,7 +116,7 @@
 
 modifyHTTP2DataKey :: Vault.Key ((Maybe HTTP2Data -> Maybe HTTP2Data) -> IO ())
 modifyHTTP2DataKey = unsafePerformIO Vault.newKey
-{-# NOINLINE modifyHTTP2Data #-}
+{-# NOINLINE modifyHTTP2DataKey #-}
 
 -- | Modifying 'HTTP2Data' through vault of the request.
 --   'Application' or 'Middleware' should use this.
diff --git a/Network/Wai/Handler/Warp/HTTP2/Sender.hs b/Network/Wai/Handler/Warp/HTTP2/Sender.hs
--- a/Network/Wai/Handler/Warp/HTTP2/Sender.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/Sender.hs
@@ -4,32 +4,18 @@
 
 module Network.Wai.Handler.Warp.HTTP2.Sender (frameSender) where
 
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative
-#endif
 import Control.Concurrent.STM
 import qualified Control.Exception as E
-import Control.Monad (void, when)
-import Data.Bits
 import qualified Data.ByteString as BS
 import Data.ByteString.Builder (Builder)
 import qualified Data.ByteString.Builder.Extra as B
-import Data.Maybe (isNothing)
-import Data.Word (Word8, Word32)
+import Data.IORef
 import Foreign.Ptr (Ptr, plusPtr)
 import Foreign.Storable (poke)
 import Network.HPACK (setLimitForEncoding, toHeaderTable)
 import Network.HTTP2
 import Network.HTTP2.Priority (isEmptySTM, dequeueSTM, Precedence)
 import Network.Wai
-import Network.Wai.Handler.Warp.Buffer
-import Network.Wai.Handler.Warp.HTTP2.EncodeFrame
-import Network.Wai.Handler.Warp.HTTP2.HPACK
-import Network.Wai.Handler.Warp.HTTP2.Manager (Manager)
-import Network.Wai.Handler.Warp.HTTP2.Types
-import Network.Wai.Handler.Warp.IORef
-import qualified Network.Wai.Handler.Warp.Settings as S
-import Network.Wai.Handler.Warp.Types
 
 #ifdef WINDOWS
 import qualified System.IO as IO
@@ -39,11 +25,20 @@
 import qualified Network.Wai.Handler.Warp.Timeout as T
 #endif
 
+import Network.Wai.Handler.Warp.Buffer
+import Network.Wai.Handler.Warp.HTTP2.EncodeFrame
+import Network.Wai.Handler.Warp.HTTP2.HPACK
+import Network.Wai.Handler.Warp.HTTP2.Manager (Manager)
+import Network.Wai.Handler.Warp.HTTP2.Types
+import Network.Wai.Handler.Warp.Imports hiding (readInt)
+import qualified Network.Wai.Handler.Warp.Settings as S
+import Network.Wai.Handler.Warp.Types
+
 ----------------------------------------------------------------
 
 data Leftover = LZero
               | LOne B.BufferWriter
-              | LTwo BS.ByteString B.BufferWriter
+              | LTwo ByteString B.BufferWriter
 
 ----------------------------------------------------------------
 
@@ -61,7 +56,7 @@
 waitStreaming :: TBQueue a -> IO ()
 waitStreaming tbq = atomically $ do
     isEmpty <- isEmptyTBQueue tbq
-    check (isEmpty == False)
+    check (not isEmpty)
 
 data Switch = C Control
             | O (StreamId,Precedence,Output)
@@ -296,7 +291,7 @@
             sendHeadersIfNecessary $ off0 + frameHeaderLength + kvlen
         handleEndOfBody True off0 noTrailers trailers = do
             off1 <- handleTrailers noTrailers off0 trailers
-            void $ tell
+            void tell
             closed ctx strm Finished
             return off1
         handleEndOfBody False off0 _ _ = return off0
diff --git a/Network/Wai/Handler/Warp/HTTP2/Types.hs b/Network/Wai/Handler/Warp/HTTP2/Types.hs
--- a/Network/Wai/Handler/Warp/HTTP2/Types.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/Types.hs
@@ -4,27 +4,23 @@
 
 module Network.Wai.Handler.Warp.HTTP2.Types where
 
-import Data.ByteString.Builder (Builder)
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative ((<$>),(<*>))
-#endif
 import Control.Concurrent (forkIO)
 import Control.Concurrent.STM
 import Control.Exception (SomeException, bracket)
-import Control.Monad (void, forM_)
-import Data.ByteString (ByteString)
 import qualified Data.ByteString as BS
+import Data.ByteString.Builder (Builder)
+import Data.IORef
 import Data.IntMap.Strict (IntMap, IntMap)
 import qualified Data.IntMap.Strict as M
+import Network.HPACK hiding (Buffer)
 import qualified Network.HTTP.Types as H
+import Network.HTTP2
+import Network.HTTP2.Priority
 import Network.Wai (Request, FilePart)
+
 import Network.Wai.Handler.Warp.HTTP2.Manager
-import Network.Wai.Handler.Warp.IORef
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.Types
-
-import Network.HTTP2
-import Network.HTTP2.Priority
-import Network.HPACK hiding (Buffer)
 
 ----------------------------------------------------------------
 
diff --git a/Network/Wai/Handler/Warp/HTTP2/Worker.hs b/Network/Wai/Handler/Warp/HTTP2/Worker.hs
--- a/Network/Wai/Handler/Warp/HTTP2/Worker.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/Worker.hs
@@ -11,35 +11,30 @@
   , worker
   ) where
 
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative
-import Data.Monoid (mempty)
-#endif
-import Control.Applicative ((<|>))
-import Data.Maybe (fromJust)
 import Control.Concurrent.STM
 import Control.Exception (SomeException(..), AsyncException(..))
 import qualified Control.Exception as E
-import Control.Monad (when)
 import Data.ByteString.Builder (byteString)
+import Data.IORef
+import Network.HPACK
+import Network.HPACK.Token
 import qualified Network.HTTP.Types as H
 import Network.HTTP2
 import Network.HTTP2.Priority
-import Network.HPACK
-import Network.HPACK.Token
 import Network.Wai
+import Network.Wai.Internal (Response(..), ResponseReceived(..), ResponseReceived(..))
+
 import Network.Wai.Handler.Warp.FileInfoCache
 import Network.Wai.Handler.Warp.HTTP2.EncodeFrame
 import Network.Wai.Handler.Warp.HTTP2.File
 import Network.Wai.Handler.Warp.HTTP2.Manager
-import Network.Wai.Handler.Warp.HTTP2.Types
 import Network.Wai.Handler.Warp.HTTP2.Request
-import Network.Wai.Handler.Warp.IORef
+import Network.Wai.Handler.Warp.HTTP2.Types
+import Network.Wai.Handler.Warp.Imports hiding (insert)
 import qualified Network.Wai.Handler.Warp.Response as R
 import qualified Network.Wai.Handler.Warp.Settings as S
 import qualified Network.Wai.Handler.Warp.Timeout as T
 import Network.Wai.Handler.Warp.Types
-import Network.Wai.Internal (Response(..), ResponseReceived(..), ResponseReceived(..))
 
 ----------------------------------------------------------------
 
diff --git a/Network/Wai/Handler/Warp/HashMap.hs b/Network/Wai/Handler/Warp/HashMap.hs
--- a/Network/Wai/Handler/Warp/HashMap.hs
+++ b/Network/Wai/Handler/Warp/HashMap.hs
@@ -1,6 +1,5 @@
 module Network.Wai.Handler.Warp.HashMap where
 
-import Data.ByteString (ByteString)
 import Data.Hashable (hash)
 import Data.IntMap.Strict (IntMap)
 import qualified Data.IntMap.Strict as I
@@ -8,6 +7,8 @@
 import qualified Data.Map.Strict as M
 import Prelude hiding (lookup)
 
+import Network.Wai.Handler.Warp.Imports hiding (insert, lookup)
+
 type Hash = Int
 newtype HashMap k v = HashMap (IntMap (Map k v))
 
@@ -15,7 +16,7 @@
 hashByteString = hash
 
 empty :: HashMap k v
-empty = HashMap $ I.empty
+empty = HashMap I.empty
 
 null :: HashMap k v -> Bool
 null (HashMap hm) = I.null hm
diff --git a/Network/Wai/Handler/Warp/Header.hs b/Network/Wai/Handler/Warp/Header.hs
--- a/Network/Wai/Handler/Warp/Header.hs
+++ b/Network/Wai/Handler/Warp/Header.hs
@@ -7,6 +7,7 @@
 import qualified Data.ByteString as BS
 import Data.CaseInsensitive (foldedCase)
 import Network.HTTP.Types
+
 import Network.Wai.Handler.Warp.Types
 
 ----------------------------------------------------------------
diff --git a/Network/Wai/Handler/Warp/IO.hs b/Network/Wai/Handler/Warp/IO.hs
--- a/Network/Wai/Handler/Warp/IO.hs
+++ b/Network/Wai/Handler/Warp/IO.hs
@@ -3,10 +3,11 @@
 
 module Network.Wai.Handler.Warp.IO where
 
-import Data.ByteString (ByteString)
 import Data.ByteString.Builder (Builder)
 import Data.ByteString.Builder.Extra (runBuilder, Next(Done, More, Chunk))
+
 import Network.Wai.Handler.Warp.Buffer
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.Types
 
 toBufIOWith :: Buffer -> BufSize -> (ByteString -> IO ()) -> Builder -> IO ()
diff --git a/Network/Wai/Handler/Warp/IORef.hs b/Network/Wai/Handler/Warp/IORef.hs
deleted file mode 100644
--- a/Network/Wai/Handler/Warp/IORef.hs
+++ /dev/null
@@ -1,26 +0,0 @@
-{-# LANGUAGE CPP #-}
-
-#ifndef MIN_VERSION_base
-#define MIN_VERSION_base(x,y,z) 1
-#endif
-
-module Network.Wai.Handler.Warp.IORef (
-    module Data.IORef
-#if !MIN_VERSION_base(4,6,0)
-  , atomicModifyIORef'
-#endif
-  ) where
-
-import Data.IORef
-
-#if !MIN_VERSION_base(4,6,0)
--- | Strict version of 'atomicModifyIORef'.  This forces both the value stored
--- in the 'IORef' as well as the value returned.
-atomicModifyIORef' :: IORef a -> (a -> (a,b)) -> IO b
-atomicModifyIORef' ref f = do
-    c <- atomicModifyIORef ref
-            (\x -> let (a, b) = f x    -- Lazy application of "f"
-                    in (a, a `seq` b)) -- Lazy application of "seq"
-    -- The following forces "a `seq` b", so it also forces "f x".
-    c `seq` return c
-#endif
diff --git a/Network/Wai/Handler/Warp/Imports.hs b/Network/Wai/Handler/Warp/Imports.hs
new file mode 100644
--- /dev/null
+++ b/Network/Wai/Handler/Warp/Imports.hs
@@ -0,0 +1,27 @@
+module Network.Wai.Handler.Warp.Imports (
+    ByteString(..)
+  , NonEmpty(..)
+  , module Control.Applicative
+  , module Control.Monad
+  , module Data.Bits
+  , module Data.List
+  , module Data.Int
+  , module Data.Monoid
+  , module Data.Ord
+  , module Data.Word
+  , module Data.Maybe
+  , module Numeric
+  ) where
+
+import Control.Applicative
+import Control.Monad
+import Data.Bits
+import Data.ByteString.Internal (ByteString(..))
+import Data.Int
+import Data.List
+import Data.List.NonEmpty (NonEmpty(..))
+import Data.Maybe
+import Data.Monoid
+import Data.Ord
+import Data.Word
+import Numeric
diff --git a/Network/Wai/Handler/Warp/MultiMap.hs b/Network/Wai/Handler/Warp/MultiMap.hs
--- a/Network/Wai/Handler/Warp/MultiMap.hs
+++ b/Network/Wai/Handler/Warp/MultiMap.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE CPP, BangPatterns #-}
-
 module Network.Wai.Handler.Warp.MultiMap (
     MMap
   , isEmpty
@@ -13,16 +11,16 @@
   , merge
   ) where
 
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative ((<$>))
-#endif
 import Data.IntMap.Strict (IntMap)
 import qualified Data.IntMap.Strict as I
-import qualified Network.Wai.Handler.Warp.Some as S
+import qualified Data.List.NonEmpty as NE
+import Data.Semigroup
 
+import Network.Wai.Handler.Warp.Imports hiding ((<>), union, empty, insert)
+
 ----------------------------------------------------------------
 
-type MMap v = IntMap (S.Some v)
+type MMap v = IntMap (NonEmpty v)
 
 ----------------------------------------------------------------
 
@@ -38,7 +36,7 @@
 
 -- | O(1)
 singleton :: Int -> v -> MMap v
-singleton k v = I.singleton k (S.singleton v)
+singleton k v = I.singleton k (v :| [])
 
 ----------------------------------------------------------------
 
@@ -46,19 +44,19 @@
 search :: Int -> MMap v -> Maybe v
 search k m = case I.lookup k m of
     Nothing -> Nothing
-    Just s  -> Just $! S.top s
+    Just s  -> Just $! NE.head s
 
 -- | O(log n)
 searchWith :: Int -> (v -> Bool) -> MMap v -> Maybe v
 searchWith k f m = case I.lookup k m of
-    Nothing -> Nothing
-    Just s  -> S.lookupWith f s
+    Nothing  -> Nothing
+    Just nxs -> find f $ NE.toList nxs
 
 ----------------------------------------------------------------
 
 -- | O(log n)
 insert :: Int -> v -> MMap v -> MMap v
-insert k v m = I.insertWith S.union k (S.singleton v) m
+insert k v m = I.insertWith (<>) k (v :| []) m
 
 ----------------------------------------------------------------
 
@@ -66,7 +64,7 @@
 toList :: MMap v -> [v]
 toList m = concatMap f $ I.toAscList m
   where
-    f (_,s) = S.toList s
+    f (_,s) = NE.toList s
 
 ----------------------------------------------------------------
 
@@ -78,7 +76,7 @@
   where
     go []          acc = return acc
     go ((k,s):kss) acc = do
-        mt <- S.prune action s
+        mt <- prune action s
         case mt of
             Nothing -> go kss acc
             Just t  -> go kss ((k,t) : acc)
@@ -87,4 +85,15 @@
 
 -- O(n + m) where N is the size of the second argument
 merge :: MMap v -> MMap v -> MMap v
-merge m1 m2 = I.unionWith S.union m1 m2
+merge m1 m2 = I.unionWith (<>) m1 m2
+
+----------------------------------------------------------------
+
+prune :: (a -> IO Bool) -> NonEmpty a -> IO (Maybe (NonEmpty a))
+prune act nxs = NE.nonEmpty <$> go (NE.toList nxs)
+  where
+    go []     = return []
+    go (x:xs) = do
+        keep <- act x
+        rs <- go xs
+        return $ if keep then x:rs else rs
diff --git a/Network/Wai/Handler/Warp/PackInt.hs b/Network/Wai/Handler/Warp/PackInt.hs
--- a/Network/Wai/Handler/Warp/PackInt.hs
+++ b/Network/Wai/Handler/Warp/PackInt.hs
@@ -2,21 +2,21 @@
 
 module Network.Wai.Handler.Warp.PackInt where
 
-import Control.Monad (when)
-import Data.ByteString.Internal (ByteString(..), unsafeCreate)
-import Data.Word8 (Word8)
+import Data.ByteString.Internal (unsafeCreate)
 import Foreign.Ptr (Ptr, plusPtr)
 import Foreign.Storable (poke)
 import qualified Network.HTTP.Types as H
 
+import Network.Wai.Handler.Warp.Imports
+
 -- $setup
--- >>> import Data.ByteString.Char8 as B
+-- >>> import Data.ByteString.Char8 as C8
 -- >>> import Test.QuickCheck (Large(..))
 
 -- |
 --
--- prop> packIntegral (abs n) == B.pack (show (abs n))
--- prop> \(Large n) -> let n' = fromIntegral (abs n :: Int) in packIntegral n' == B.pack (show n')
+-- prop> packIntegral (abs n) == C8.pack (show (abs n))
+-- prop> \(Large n) -> let n' = fromIntegral (abs n :: Int) in packIntegral n' == C8.pack (show n')
 
 packIntegral :: Integral a => a -> ByteString
 packIntegral 0 = "0"
diff --git a/Network/Wai/Handler/Warp/ReadInt.hs b/Network/Wai/Handler/Warp/ReadInt.hs
--- a/Network/Wai/Handler/Warp/ReadInt.hs
+++ b/Network/Wai/Handler/Warp/ReadInt.hs
@@ -13,12 +13,12 @@
 -- This function lives in its own file because the MagicHash pragma interacts
 -- poorly with the CPP pragma.
 
-import Data.ByteString (ByteString)
 import qualified Data.ByteString as S
-import Data.Int (Int64)
 import GHC.Prim
 import GHC.Types
 import GHC.Word
+
+import Network.Wai.Handler.Warp.Imports hiding (readInt)
 
 {-# INLINE readInt #-}
 readInt :: Integral a => ByteString -> a
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
@@ -9,23 +9,20 @@
   , spell
   ) where
 
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative ((<$>))
-#endif
 import qualified Control.Exception as E
 import qualified Data.ByteString as BS
-import Data.ByteString.Internal (ByteString(..))
-import Data.Word (Word8)
+import Data.IORef
 import Foreign.C.Error (eAGAIN, getErrno, throwErrno)
 import Foreign.C.Types
 import Foreign.ForeignPtr (withForeignPtr)
 import Foreign.Ptr (Ptr, castPtr, plusPtr)
 import GHC.Conc (threadWaitRead)
 import Network.Socket (Socket, fdSocket)
+import System.Posix.Types (Fd(..))
+
 import Network.Wai.Handler.Warp.Buffer
-import Network.Wai.Handler.Warp.IORef
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.Types
-import System.Posix.Types (Fd(..))
 
 #ifdef mingw32_HOST_OS
 import GHC.IO.FD (FD(..), readRawBufferPtr)
diff --git a/Network/Wai/Handler/Warp/Request.hs b/Network/Wai/Handler/Warp/Request.hs
--- a/Network/Wai/Handler/Warp/Request.hs
+++ b/Network/Wai/Handler/Warp/Request.hs
@@ -15,29 +15,29 @@
 import qualified Control.Concurrent as Conc (yield)
 import Control.Exception (throwIO, Exception)
 import Data.Array ((!))
-import Data.ByteString (ByteString)
-import Data.Typeable (Typeable)
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Unsafe as SU
 import qualified Data.CaseInsensitive as CI
 import qualified Data.IORef as I
+import Data.Typeable (Typeable)
+import qualified Data.Vault.Lazy as Vault
 import qualified Network.HTTP.Types as H
 import Network.Socket (SockAddr)
 import Network.Wai
+import qualified Network.Wai.Handler.Warp.Timeout as Timeout
+import Network.Wai.Handler.Warp.Types
+import Network.Wai.Internal
+import Prelude hiding (lines)
+import System.IO.Unsafe (unsafePerformIO)
+
 import Network.Wai.Handler.Warp.Conduit
 import Network.Wai.Handler.Warp.FileInfoCache
 import Network.Wai.Handler.Warp.HashMap (hashByteString)
 import Network.Wai.Handler.Warp.Header
+import Network.Wai.Handler.Warp.Imports hiding (readInt, lines)
 import Network.Wai.Handler.Warp.ReadInt
 import Network.Wai.Handler.Warp.RequestHeader
 import Network.Wai.Handler.Warp.Settings (Settings, settingsNoParsePath)
-import qualified Network.Wai.Handler.Warp.Timeout as Timeout
-import Network.Wai.Handler.Warp.Types
-import Network.Wai.Internal
-import Prelude hiding (lines)
-import Control.Monad (when)
-import qualified Data.Vault.Lazy as Vault
-import System.IO.Unsafe (unsafePerformIO)
 
 ----------------------------------------------------------------
 
diff --git a/Network/Wai/Handler/Warp/RequestHeader.hs b/Network/Wai/Handler/Warp/RequestHeader.hs
--- a/Network/Wai/Handler/Warp/RequestHeader.hs
+++ b/Network/Wai/Handler/Warp/RequestHeader.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE BangPatterns #-}
 
 module Network.Wai.Handler.Warp.RequestHeader (
@@ -6,16 +5,16 @@
     ) where
 
 import Control.Exception (throwIO)
-import Control.Monad (when)
 import qualified Data.ByteString as S
-import qualified Data.ByteString.Char8 as B (unpack)
-import Data.ByteString.Internal (ByteString(..), memchr)
+import qualified Data.ByteString.Char8 as C8 (unpack)
+import Data.ByteString.Internal (memchr)
 import qualified Data.CaseInsensitive as CI
-import Data.Word (Word8)
 import Foreign.ForeignPtr (withForeignPtr)
 import Foreign.Ptr (Ptr, plusPtr, minusPtr, nullPtr)
 import Foreign.Storable (peek)
 import qualified Network.HTTP.Types as H
+
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.Types
 
 -- $setup
@@ -89,7 +88,7 @@
 
     return (method,path,query,hv)
   where
-    baderr = BadFirstLine $ B.unpack requestLine
+    baderr = BadFirstLine $ C8.unpack requestLine
     check :: Ptr Word8 -> Int -> Word8 -> IO ()
     check p n w = do
         w0 <- peek $ p `plusPtr` n
diff --git a/Network/Wai/Handler/Warp/Response.hs b/Network/Wai/Handler/Warp/Response.hs
--- a/Network/Wai/Handler/Warp/Response.hs
+++ b/Network/Wai/Handler/Warp/Response.hs
@@ -1,6 +1,5 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TupleSections #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE BangPatterns #-}
@@ -14,57 +13,35 @@
   , addServer -- testing
   ) where
 
-#ifndef MIN_VERSION_base
-#define MIN_VERSION_base(x,y,z) 1
-#endif
-
 import Blaze.ByteString.Builder.HTTP (chunkedTransferEncoding, chunkedTransferTerminator)
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative
-#endif
 import qualified Control.Exception as E
-import Control.Monad (unless, when)
 import Data.Array ((!))
-import Data.ByteString (ByteString)
 import qualified Data.ByteString as S
-import qualified Data.ByteString.Char8 as S8
 import Data.ByteString.Builder (byteString, Builder)
 import Data.ByteString.Builder.Extra (flush)
+import qualified Data.ByteString.Char8 as C8
 import qualified Data.CaseInsensitive as CI
 import Data.Function (on)
-import Data.List (deleteBy)
-import Data.Maybe
-#if MIN_VERSION_base(4,5,0)
-# if __GLASGOW_HASKELL__ < 709
-import Data.Monoid (mempty)
-# endif
-import Data.Monoid ((<>))
-#else
-import Data.Monoid (mappend, mempty)
-#endif
-import Data.Streaming.Blaze (newBlazeRecv, reuseBufferStrategy)
+import Data.Streaming.ByteString.Builder (newByteStringBuilderRecv, reuseBufferStrategy)
 import Data.Version (showVersion)
 import Data.Word8 (_cr, _lf)
 import qualified Network.HTTP.Types as H
 import qualified Network.HTTP.Types.Header as H
 import Network.Wai
+import Network.Wai.Internal
+import qualified Paths_warp
+
 import Network.Wai.Handler.Warp.Buffer (toBuilderBuffer)
 import qualified Network.Wai.Handler.Warp.Date as D
 import Network.Wai.Handler.Warp.File
 import Network.Wai.Handler.Warp.Header
 import Network.Wai.Handler.Warp.IO (toBufIOWith)
+import Network.Wai.Handler.Warp.Imports
 import Network.Wai.Handler.Warp.ResponseHeader
 import Network.Wai.Handler.Warp.Settings
 import qualified Network.Wai.Handler.Warp.Timeout as T
 import Network.Wai.Handler.Warp.Types
-import Network.Wai.Internal
-import qualified Paths_warp
 
-#if !MIN_VERSION_base(4,5,0)
-(<>) :: Monoid m => m -> m -> m
-(<>) = mappend
-#endif
-
 -- $setup
 -- >>> :set -XOverloadedStrings
 
@@ -194,11 +171,11 @@
 
 {-# INLINE sanitizeHeaderValue #-}
 sanitizeHeaderValue :: ByteString -> ByteString
-sanitizeHeaderValue v = case S8.lines $ S.filter (/= _cr) v of
+sanitizeHeaderValue v = case C8.lines $ S.filter (/= _cr) v of
     []     -> ""
-    x : xs -> S8.intercalate "\r\n" (x : mapMaybe addSpaceIfMissing xs)
+    x : xs -> C8.intercalate "\r\n" (x : mapMaybe addSpaceIfMissing xs)
   where
-    addSpaceIfMissing line = case S8.uncons line of
+    addSpaceIfMissing line = case C8.uncons line of
         Nothing                           -> Nothing
         Just (first, _)
           | first == ' ' || first == '\t' -> Just line
@@ -247,7 +224,7 @@
 
 sendRsp conn _ ver s hs (RspStream streamingBody needsChunked th) = do
     header <- composeHeaderBuilder ver s hs needsChunked
-    (recv, finish) <- newBlazeRecv $ reuseBufferStrategy
+    (recv, finish) <- newByteStringBuilderRecv $ reuseBufferStrategy
                     $ toBuilderBuffer (connWriteBuffer conn) (connBufferSize conn)
     let send builder = do
             popper <- recv builder
diff --git a/Network/Wai/Handler/Warp/ResponseHeader.hs b/Network/Wai/Handler/Warp/ResponseHeader.hs
--- a/Network/Wai/Handler/Warp/ResponseHeader.hs
+++ b/Network/Wai/Handler/Warp/ResponseHeader.hs
@@ -3,17 +3,15 @@
 
 module Network.Wai.Handler.Warp.ResponseHeader (composeHeader) where
 
-import Control.Monad
-import Data.ByteString (ByteString)
 import qualified Data.ByteString as S
 import Data.ByteString.Internal (create)
 import qualified Data.CaseInsensitive as CI
-import Data.List (foldl')
-import Data.Word (Word8)
 import Foreign.Ptr
 import GHC.Storable
 import qualified Network.HTTP.Types as H
+
 import Network.Wai.Handler.Warp.Buffer (copy)
+import Network.Wai.Handler.Warp.Imports
 
 ----------------------------------------------------------------
 
@@ -24,7 +22,7 @@
     void $ copyCRLF ptr2
   where
     !len = 17 + slen + foldl' fieldLength 0 responseHeaders
-    fieldLength !l !(k,v) = l + S.length (CI.original k) + S.length v + 4
+    fieldLength !l (!k,!v) = l + S.length (CI.original k) + S.length v + 4
     !slen = S.length $ H.statusMessage status
 
 httpVer11 :: ByteString
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
@@ -9,25 +9,23 @@
 
 module Network.Wai.Handler.Warp.Run where
 
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative ((<$>))
-#endif
+import "iproute" Data.IP (toHostAddress, toHostAddress6)
 import Control.Arrow (first)
 import qualified Control.Concurrent as Conc (yield)
 import Control.Exception as E
-import Control.Monad (when, unless, void)
-import Data.ByteString (ByteString)
 import qualified Data.ByteString as S
 import Data.Char (chr)
-import "iproute" Data.IP (toHostAddress, toHostAddress6)
-import Data.IORef (IORef, newIORef, readIORef, writeIORef)
+import Data.IORef (IORef, newIORef, readIORef, writeIORef, atomicModifyIORef')
 import Data.Streaming.Network (bindPortTCP)
 import Foreign.C.Error (Errno(..), eCONNABORTED)
 import GHC.IO.Exception (IOException(..))
-import Network (Socket)
-import Network.Socket (close, accept, withSocketsDo, SockAddr(SockAddrInet, SockAddrInet6), setSocketOption, SocketOption(..))
+import Network.Socket (Socket, close, accept, withSocketsDo, SockAddr(SockAddrInet, SockAddrInet6), setSocketOption, SocketOption(..))
 import qualified Network.Socket.ByteString as Sock
 import Network.Wai
+import Network.Wai.Internal (ResponseReceived (ResponseReceived))
+import System.Environment (getEnvironment)
+import System.Timeout (timeout)
+
 import Network.Wai.Handler.Warp.Buffer
 import Network.Wai.Handler.Warp.Counter
 import qualified Network.Wai.Handler.Warp.Date as D
@@ -35,7 +33,7 @@
 import qualified Network.Wai.Handler.Warp.FileInfoCache as I
 import Network.Wai.Handler.Warp.HTTP2 (http2, isHTTP2)
 import Network.Wai.Handler.Warp.Header
-import Network.Wai.Handler.Warp.IORef
+import Network.Wai.Handler.Warp.Imports hiding (readInt)
 import Network.Wai.Handler.Warp.ReadInt
 import Network.Wai.Handler.Warp.Recv
 import Network.Wai.Handler.Warp.Request
@@ -44,10 +42,8 @@
 import Network.Wai.Handler.Warp.Settings
 import qualified Network.Wai.Handler.Warp.Timeout as T
 import Network.Wai.Handler.Warp.Types
-import Network.Wai.Internal (ResponseReceived (ResponseReceived))
-import System.Environment (getEnvironment)
-import System.Timeout (timeout)
 
+
 #if WINDOWS
 import Network.Wai.Handler.Warp.Windows
 #else
@@ -72,11 +68,6 @@
       , connBufferSize = bufferSize
       }
 
-#if __GLASGOW_HASKELL__ < 702
-allowInterrupt :: IO ()
-allowInterrupt = unblock $ return ()
-#endif
-
 -- | Run an 'Application' on the given port.
 -- This calls 'runSettings' with 'defaultSettings'.
 run :: Port -> Application -> IO ()
@@ -342,9 +333,14 @@
         writeIORef istatus True
         leftoverSource src bs
         addr <- getProxyProtocolAddr src
-        http1 True addr istatus src `E.catch` \e -> do
-            sendErrorResponse addr istatus e
-            throwIO (e :: SomeException)
+        http1 True addr istatus src `E.catch` \e ->
+          case fromException e of
+            -- See comment below referencing
+            -- https://github.com/yesodweb/wai/issues/618
+            Just NoKeepAliveRequest -> return ()
+            Nothing -> do
+              sendErrorResponse addr istatus e
+              throwIO e
   where
     getProxyProtocolAddr src =
         case settingsProxyProtocol settings of
@@ -422,7 +418,7 @@
         -- request headers, no data is available, recvRequest will
         -- throw a NoKeepAliveRequest exception, which we catch here
         -- and ignore. See: https://github.com/yesodweb/wai/issues/618
-        when keepAlive $ http1 False addr istatus src `E.catch` \NoKeepAliveRequest -> return ()
+        when keepAlive $ http1 False addr istatus src
 
     processRequest istatus src req mremainingRef idxhdr nextBodyFlush ii = do
         -- Let the application run for as long as it wants
diff --git a/Network/Wai/Handler/Warp/SendFile.hs b/Network/Wai/Handler/Warp/SendFile.hs
--- a/Network/Wai/Handler/Warp/SendFile.hs
+++ b/Network/Wai/Handler/Warp/SendFile.hs
@@ -9,22 +9,14 @@
 #endif
   ) where
 
-import Control.Monad (void, when)
-import Data.ByteString (ByteString)
 import qualified Data.ByteString as BS
 import Network.Socket (Socket)
-import Network.Wai.Handler.Warp.Buffer
-import Network.Wai.Handler.Warp.Types
 
 #ifdef WINDOWS
-import Data.ByteString.Internal (ByteString(..))
 import Foreign.ForeignPtr (newForeignPtr_)
 import Foreign.Ptr (plusPtr)
 import qualified System.IO as IO
 #else
-# if __GLASGOW_HASKELL__ < 709
-import Control.Applicative ((<$>))
-# endif
 import Control.Exception
 import Foreign.C.Error (throwErrno)
 import Foreign.C.Types
@@ -33,6 +25,10 @@
 import Network.Wai.Handler.Warp.FdCache (openFile, closeFile)
 import System.Posix.Types
 #endif
+
+import Network.Wai.Handler.Warp.Buffer
+import Network.Wai.Handler.Warp.Imports
+import Network.Wai.Handler.Warp.Types
 
 ----------------------------------------------------------------
 
diff --git a/Network/Wai/Handler/Warp/Settings.hs b/Network/Wai/Handler/Warp/Settings.hs
--- a/Network/Wai/Handler/Warp/Settings.hs
+++ b/Network/Wai/Handler/Warp/Settings.hs
@@ -6,13 +6,8 @@
 
 import Control.Concurrent (forkIOWithUnmask)
 import Control.Exception
-import Control.Monad (when, void)
-import Data.ByteString (ByteString)
-import qualified Data.ByteString.Char8 as S8
 import Data.ByteString.Builder (byteString)
-#if __GLASGOW_HASKELL__ < 709
-import Data.Monoid (mappend)
-#endif
+import qualified Data.ByteString.Char8 as C8
 import Data.Streaming.Network (HostPreference)
 import qualified Data.Text as T
 import qualified Data.Text.IO as TIO
@@ -21,12 +16,14 @@
 import qualified Network.HTTP.Types as H
 import Network.Socket (SockAddr)
 import Network.Wai
-import Network.Wai.Handler.Warp.Timeout
-import Network.Wai.Handler.Warp.Types
 import qualified Paths_warp
 import System.IO (stderr)
 import System.IO.Error (ioeGetErrorType)
 
+import Network.Wai.Handler.Warp.Imports
+import Network.Wai.Handler.Warp.Timeout
+import Network.Wai.Handler.Warp.Types
+
 -- | Various Warp server settings. This is purposely kept as an abstract data
 -- type so that new settings can be added without breaking backwards
 -- compatibility. In order to create a 'Settings' value, use 'defaultSettings'
@@ -138,7 +135,7 @@
     , settingsFork = void . forkIOWithUnmask
     , settingsNoParsePath = False
     , settingsInstallShutdownHandler = const $ return ()
-    , settingsServerName = S8.pack $ "Warp/" ++ showVersion Paths_warp.version
+    , settingsServerName = C8.pack $ "Warp/" ++ showVersion Paths_warp.version
     , settingsMaximumBodyFlush = Just 8192
     , settingsProxyProtocol = ProxyProtocolNone
     , settingsSlowlorisSize = 2048
@@ -187,4 +184,4 @@
 exceptionResponseForDebug e =
     responseBuilder H.internalServerError500
                     [(H.hContentType, "text/plain; charset=utf-8")]
-                    $ byteString . S8.pack $ "Exception: " ++ show e
+                    $ byteString . C8.pack $ "Exception: " ++ show e
diff --git a/Network/Wai/Handler/Warp/Some.hs b/Network/Wai/Handler/Warp/Some.hs
deleted file mode 100644
--- a/Network/Wai/Handler/Warp/Some.hs
+++ /dev/null
@@ -1,73 +0,0 @@
-{-# LANGUAGE BangPatterns #-}
-
-module Network.Wai.Handler.Warp.Some (
-    Some
-  , singleton
-  , top
-  , lookupWith
-  , union
-  , toList
-  , prune
-  ) where
-
-----------------------------------------------------------------
-
--- | One ore more list to implement multimap.
-data Some a = One !a
-            | Tom !a !(Some a) -- Two or more
-            deriving (Eq,Show)
-
-{-# INLINE singleton #-}
-singleton :: a -> Some a
-singleton x = One x
-
-{-# INLINE top #-}
-top :: Some a -> a
-top (One x)   = x
-top (Tom x _) = x
-
-{-# INLINE lookupWith #-}
-lookupWith :: (a -> Bool) -> Some a -> Maybe a
-lookupWith f s = go s
-  where
-    go (One x)
-      | f x       = Just x
-      | otherwise = Nothing
-    go (Tom x xs)
-      | f x       = Just x
-      | otherwise = go xs
-
-{-# INLINE union #-}
-union :: Some a -> Some a -> Some a
-union s t = go s t
-  where
-    go (One x)    u = Tom x u
-    go (Tom x xs) u = go xs (Tom x u)
-
-{-# INLINE toList #-}
-toList :: Some a -> [a]
-toList s = go s []
-  where
-    go (One x)    !acc = x : acc
-    go (Tom x xs) !acc = go xs (x : acc)
-
-{-# INLINE prune #-}
-prune :: (a -> IO Bool) -> Some a -> IO (Maybe (Some a))
-prune act s = go s
-  where
-    go (One x) = do
-        keep <- act x
-        return $ if keep then
-                     Just (One x)
-                 else
-                     Nothing
-    go (Tom x xs) = do
-        keep <- act x
-        mys <- go xs
-        return $ if keep then
-                     case mys of
-                         Nothing -> Just (One x)
-                         Just ys -> Just (Tom x ys)
-                 else
-                     mys
-
diff --git a/Network/Wai/Handler/Warp/Timeout.hs b/Network/Wai/Handler/Warp/Timeout.hs
--- a/Network/Wai/Handler/Warp/Timeout.hs
+++ b/Network/Wai/Handler/Warp/Timeout.hs
@@ -27,8 +27,8 @@
 import qualified Control.Exception as E
 import Control.Reaper
 import Data.Typeable (Typeable)
-import Network.Wai.Handler.Warp.IORef (IORef)
-import qualified Network.Wai.Handler.Warp.IORef as I
+import Data.IORef (IORef)
+import qualified Data.IORef as I
 
 ----------------------------------------------------------------
 
@@ -112,10 +112,8 @@
 data TimeoutThread = TimeoutThread
     deriving Typeable
 instance E.Exception TimeoutThread where
-#if MIN_VERSION_base(4,7,0)
     toException = E.asyncExceptionToException
     fromException = E.asyncExceptionFromException
-#endif
 instance Show TimeoutThread where
     show TimeoutThread = "Thread killed by Warp's timeout reaper"
 
diff --git a/Network/Wai/Handler/Warp/Types.hs b/Network/Wai/Handler/Warp/Types.hs
--- a/Network/Wai/Handler/Warp/Types.hs
+++ b/Network/Wai/Handler/Warp/Types.hs
@@ -5,17 +5,17 @@
 module Network.Wai.Handler.Warp.Types where
 
 import Control.Exception
-import Data.ByteString (ByteString)
 import qualified Data.ByteString as S
 import Data.IORef (IORef, readIORef, writeIORef, newIORef)
 import Data.Typeable (Typeable)
-import Data.Word (Word16, Word8)
 import Foreign.Ptr (Ptr)
+import System.Posix.Types (Fd)
+
 import qualified Network.Wai.Handler.Warp.Date as D
 import qualified Network.Wai.Handler.Warp.FdCache as F
 import qualified Network.Wai.Handler.Warp.FileInfoCache as I
+import Network.Wai.Handler.Warp.Imports
 import qualified Network.Wai.Handler.Warp.Timeout as T
-import System.Posix.Types (Fd)
 
 ----------------------------------------------------------------
 
diff --git a/Network/Wai/Handler/Warp/Windows.hs b/Network/Wai/Handler/Warp/Windows.hs
--- a/Network/Wai/Handler/Warp/Windows.hs
+++ b/Network/Wai/Handler/Warp/Windows.hs
@@ -7,7 +7,8 @@
 import Control.Exception
 import Control.Concurrent.MVar
 import Control.Concurrent
-import Control.Monad
+
+import Network.Wai.Handler.Warp.Imports
 
 windowsThreadBlockHack :: IO a -> IO a
 windowsThreadBlockHack act = do
diff --git a/Network/Wai/Handler/Warp/WithApplication.hs b/Network/Wai/Handler/Warp/WithApplication.hs
--- a/Network/Wai/Handler/Warp/WithApplication.hs
+++ b/Network/Wai/Handler/Warp/WithApplication.hs
@@ -84,7 +84,7 @@
 mkWaiter :: IO (Waiter a)
 mkWaiter = do
   mvar <- newEmptyMVar
-  return $ Waiter {
+  return Waiter {
     notify = putMVar mvar,
     waitFor = readMVar mvar
   }
@@ -94,9 +94,13 @@
 -- @since 3.2.4
 openFreePort :: IO (Port, Socket)
 openFreePort = do
-  s <- socket AF_INET Stream defaultProtocol
-  localhost <- inet_addr "127.0.0.1"
-  bind s (SockAddrInet aNY_PORT localhost)
+  let hints = defaultHints {
+          addrFlags = [AI_PASSIVE]
+        , addrSocketType = Stream
+        }
+  addr:_ <- getAddrInfo (Just hints) (Just "127.0.0.1") Nothing
+  s <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
+  bind s $ addrAddress addr
   listen s 1
   port <- socketPort s
   return (fromIntegral port, s)
diff --git a/bench/Parser.hs b/bench/Parser.hs
--- a/bench/Parser.hs
+++ b/bench/Parser.hs
@@ -18,7 +18,7 @@
 import Foreign.Ptr
 import Foreign.Storable
 
-import Criterion.Main
+import Gauge
 
 -- $setup
 -- >>> :set -XOverloadedStrings
@@ -63,15 +63,15 @@
                      ,H.HttpVersion)
 parseRequestLine3 requestLine = ret
   where
-    (!method,!rest) = S.breakByte 32 requestLine -- ' '
+    (!method,!rest) = S.break (== 32) requestLine -- ' '
     (!pathQuery,!httpVer')
       | rest == "" = throw badmsg
-      | otherwise  = S.breakByte 32 (S.drop 1 rest) -- ' '
-    (!path,!query) = S.breakByte 63 pathQuery -- '?'
+      | otherwise  = S.break (== 32) (S.drop 1 rest) -- ' '
+    (!path,!query) = S.break (== 63) pathQuery -- '?'
     !httpVer = S.drop 1 httpVer'
     (!http,!ver)
       | httpVer == "" = throw badmsg
-      | otherwise     = S.breakByte 47 httpVer -- '/'
+      | otherwise     = S.break (== 47) httpVer -- '/'
     !hv | http /= "HTTP" = throw NonHttp
         | ver == "/1.1"  = H.http11
         | otherwise      = H.http10
@@ -169,13 +169,13 @@
                         ,ByteString -- Query
                         ,H.HttpVersion)
 parseRequestLine1 requestLine = do
-    let (!method,!rest) = S.breakByte 32 requestLine -- ' '
-        (!pathQuery,!httpVer') = S.breakByte 32 (S.drop 1 rest) -- ' '
+    let (!method,!rest) = S.break (== 32) requestLine -- ' '
+        (!pathQuery,!httpVer') = S.break (== 32) (S.drop 1 rest) -- ' '
         !httpVer = S.drop 1 httpVer'
     when (rest == "" || httpVer == "") $
         throwIO $ BadFirstLine $ B.unpack requestLine
-    let (!path,!query) = S.breakByte 63 pathQuery -- '?'
-        (!http,!ver)   = S.breakByte 47 httpVer -- '/'
+    let (!path,!query) = S.break (== 63) pathQuery -- '?'
+        (!http,!ver)   = S.break (== 47) httpVer -- '/'
     when (http /= "HTTP") $ throwIO NonHttp
     let !hv | ver == "/1.1" = H.http11
             | otherwise     = H.http10
@@ -205,7 +205,7 @@
                 !http' = S.concat http''
                 (!hfirst, !hsecond) = S.splitAt 5 http'
             if hfirst == "HTTP/"
-               then let (!rpath, !qstring) = S.breakByte 63 query  -- '?'
+               then let (!rpath, !qstring) = S.break (== 63) query  -- '?'
                         !hv =
                             case hsecond of
                                 "1.1" -> H.http11
diff --git a/test/ExceptionSpec.hs b/test/ExceptionSpec.hs
--- a/test/ExceptionSpec.hs
+++ b/test/ExceptionSpec.hs
@@ -7,7 +7,7 @@
 #endif
 import Control.Monad
 import Network.HTTP.Types hiding (Header)
-import Network.Wai hiding (Response)
+import Network.Wai hiding (Response, responseStatus)
 import Network.Wai.Internal (Request(..))
 import Network.Wai.Handler.Warp
 import Test.Hspec
@@ -49,18 +49,18 @@
 spec = describe "responds even if there is an exception" $ do
         {- Disabling these tests. We can consider forcing evaluation in Warp.
         it "statusError" $ do
-            sc <- rspCode <$> sendGET "http://127.0.0.1:2345/statusError"
-            sc `shouldBe` (5,0,0)
+            sc <- responseStatus <$> sendGET "http://127.0.0.1:2345/statusError"
+            sc `shouldBe` internalServerError500
         it "headersError" $ do
-            sc <- rspCode <$> sendGET "http://127.0.0.1:2345/headersError"
-            sc `shouldBe` (5,0,0)
+            sc <- responseStatus <$> sendGET "http://127.0.0.1:2345/headersError"
+            sc `shouldBe` internalServerError500
         it "headerError" $ do
-            sc <- rspCode <$> sendGET "http://127.0.0.1:2345/headerError"
-            sc `shouldBe` (5,0,0)
+            sc <- responseStatus <$> sendGET "http://127.0.0.1:2345/headerError"
+            sc `shouldBe` internalServerError500
         it "bodyError" $ do
-            sc <- rspCode <$> sendGET "http://127.0.0.1:2345/bodyError"
-            sc `shouldBe` (5,0,0)
+            sc <- responseStatus <$> sendGET "http://127.0.0.1:2345/bodyError"
+            sc `shouldBe` internalServerError500
         -}
         it "ioException" $ withTestServer $ \prt -> do
-            sc <- rspCode <$> sendGET ("http://127.0.0.1:" ++ show prt ++ "/ioException")
-            sc `shouldBe` (5,0,0)
+            sc <- responseStatus <$> sendGET ("http://127.0.0.1:" ++ show prt ++ "/ioException")
+            sc `shouldBe` internalServerError500
diff --git a/test/HTTP.hs b/test/HTTP.hs
--- a/test/HTTP.hs
+++ b/test/HTTP.hs
@@ -1,43 +1,41 @@
-{-# LANGUAGE StandaloneDeriving #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
 module HTTP (
     sendGET
   , sendGETwH
   , sendHEAD
   , sendHEADwH
-  , rspBody
-  , rspCode
-  , rspHeaders
+  , responseBody
+  , responseStatus
+  , responseHeaders
   , getHeaderValue
-  , HeaderName(..)
-  , mkHeader
+  , HeaderName
   ) where
 
-import Network.HTTP
-import Network.Stream
+import Network.HTTP.Client
+import Network.HTTP.Types
+import Data.ByteString
+import qualified Data.ByteString.Lazy as BL
 
-sendGET :: String -> IO (Response String)
+sendGET :: String -> IO (Response BL.ByteString)
 sendGET url = sendGETwH url []
 
-sendGETwH :: String -> [Header] -> IO (Response String)
-sendGETwH url hdr = unResult $ simpleHTTP $ (getRequest url) { rqHeaders = hdr }
+sendGETwH :: String -> [Header] -> IO (Response BL.ByteString)
+sendGETwH url hdr = do
+    manager <- newManager defaultManagerSettings
+    request <- parseRequest url
+    let request' = request { requestHeaders = hdr }
+    response <- httpLbs request' manager
+    return response
 
-sendHEAD :: String -> IO (Response String)
+sendHEAD :: String -> IO (Response BL.ByteString)
 sendHEAD url = sendHEADwH url []
 
-sendHEADwH :: String -> [Header] -> IO (Response String)
-sendHEADwH url hdr = unResult $ simpleHTTP $ (headRequest url) { rqHeaders = hdr }
-
-unResult :: IO (Result (Response String)) -> IO (Response String)
-unResult action = do
-    res <- action
-    case res of
-        Right rsp -> return rsp
-        Left _ -> error "Connection error"
-
-getHeaderValue :: HasHeaders a => HeaderName -> a -> Maybe String
-getHeaderValue key r = case retrieveHeaders key r of
-    []  -> Nothing
-    x:_ -> Just $ hdrValue x
+sendHEADwH :: String -> [Header] -> IO (Response BL.ByteString)
+sendHEADwH url hdr = do
+    manager <- newManager defaultManagerSettings
+    request <- parseRequest url
+    let request' = request { requestHeaders = hdr, method = methodHead }
+    response <- httpLbs request' manager
+    return response
 
-deriving instance Eq Header
+getHeaderValue :: HeaderName -> [Header] -> Maybe ByteString
+getHeaderValue = lookup
diff --git a/test/ResponseSpec.hs b/test/ResponseSpec.hs
--- a/test/ResponseSpec.hs
+++ b/test/ResponseSpec.hs
@@ -6,16 +6,16 @@
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Char8 as S8
 import Data.Maybe (mapMaybe)
-import Network (connectTo, PortID (PortNumber))
 import Network.HTTP.Types
-import Network.Wai
+import Network.Wai hiding (responseHeaders)
 import Network.Wai.Handler.Warp
 import Network.Wai.Handler.Warp.Response
 import RunSpec (withApp)
 import System.IO (hClose, hFlush)
 import Test.Hspec
 
-import HTTP
+-- import HTTP
+import RunSpec (connectTo)
 
 main :: IO ()
 main = hspec spec
@@ -25,7 +25,7 @@
           -> Maybe String -- ^ expected content-range value
           -> Spec
 testRange range out crange = it title $ withApp defaultSettings app $ \port -> do
-    handle <- connectTo "127.0.0.1" $ PortNumber $ fromIntegral port
+    handle <- connectTo "127.0.0.1" port
     S.hPutStr handle "GET / HTTP/1.0\r\n"
     S.hPutStr handle "Range: bytes="
     S.hPutStr handle range
@@ -52,7 +52,7 @@
             -> String -- ^ expected output
             -> Spec
 testPartial size offset count out = it title $ withApp defaultSettings app $ \port -> do
-    handle <- connectTo "127.0.0.1" $ PortNumber $ fromIntegral port
+    handle <- connectTo "127.0.0.1" port
     S.hPutStr handle "GET / HTTP/1.0\r\n\r\n"
     hFlush handle
     threadDelay 10000
@@ -73,13 +73,15 @@
 
 spec :: Spec
 spec = do
+{- http-client does not support this.
     describe "preventing response splitting attack" $ do
         it "sanitizes header values" $ do
             let app _ respond = respond $ responseLBS status200 [("foo", "foo\r\nbar")] "Hello"
             withApp defaultSettings app $ \port -> do
                 res <- sendGET $ "http://127.0.0.1:" ++ show port
-                getHeaderValue (HdrCustom "foo") res `shouldBe`
+                getHeaderValue "foo" (responseHeaders res) `shouldBe`
                   Just "foo   bar" -- HTTP inserts two spaces for \r\n.
+-}
 
     describe "sanitizeHeaderValue" $ do
         it "doesn't alter valid multiline header values" $ do
diff --git a/test/RunSpec.hs b/test/RunSpec.hs
--- a/test/RunSpec.hs
+++ b/test/RunSpec.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
-module RunSpec (main, spec, withApp) where
+module RunSpec (main, spec, withApp, connectTo) where
 
 import Control.Concurrent (forkIO, killThread, threadDelay)
 import Control.Concurrent.MVar (newEmptyMVar, takeMVar, putMVar)
@@ -17,13 +17,12 @@
 import qualified Data.ByteString.Lazy as L
 import qualified Data.IORef as I
 import Data.Streaming.Network (bindPortTCP, getSocketTCP, safeRecv)
-import Network (connectTo, PortID (PortNumber))
 import Network.HTTP.Types
-import Network.Socket (close)
+import Network.Socket
 import Network.Socket.ByteString (sendAll)
-import Network.Wai
+import Network.Wai hiding (responseHeaders)
 import Network.Wai.Handler.Warp
-import System.IO (hFlush, hClose)
+import System.IO (hFlush, hClose, Handle, IOMode(..))
 import System.IO.Unsafe (unsafePerformIO)
 import System.Timeout (timeout)
 import Test.Hspec
@@ -36,6 +35,14 @@
 type Counter = I.IORef (Either String Int)
 type CounterApplication = Counter -> Application
 
+connectTo :: HostName -> Int -> IO Handle
+connectTo host port = do
+    let hints = defaultHints { addrSocketType = Stream }
+    addr:_ <- getAddrInfo (Just hints) (Just host) (Just $ show port)
+    sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
+    connect sock $ addrAddress addr
+    socketToHandle sock ReadWriteMode
+
 incr :: MonadIO m => Counter -> m ()
 incr icount = liftIO $ I.atomicModifyIORef icount $ \ecount ->
     ((case ecount of
@@ -83,8 +90,8 @@
     esocket <- try $ bindPortTCP port "127.0.0.1"
     case esocket of
         Left (_ :: IOException) -> RunSpec.getPort
-        Right socket -> do
-            close socket
+        Right sock -> do
+            close sock
             return port
 
 withApp :: Settings -> Application -> (Int -> IO a) -> IO a
@@ -107,7 +114,7 @@
 runTest expected app chunks = do
     ref <- I.newIORef (Right 0)
     withApp defaultSettings (app ref) $ \port -> do
-        handle <- connectTo "127.0.0.1" $ PortNumber $ fromIntegral port
+        handle <- connectTo "127.0.0.1" port
         forM_ chunks $ \chunk -> hPutStr handle chunk >> hFlush handle
         _ <- timeout 100000 $ replicateM_ expected $ hGetSome handle 4096
         res <- I.readIORef ref
@@ -125,7 +132,7 @@
     ref <- I.newIORef Nothing
     let onExc _ = I.writeIORef ref . Just
     withApp (setOnException onExc defaultSettings) dummyApp $ \port -> do
-        handle <- connectTo "127.0.0.1" $ PortNumber $ fromIntegral port
+        handle <- connectTo "127.0.0.1" port
         hPutStr handle input
         hFlush handle
         hClose handle
@@ -200,7 +207,7 @@
                     liftIO $ I.writeIORef iheaders $ requestHeaders req
                     f $ responseLBS status200 [] ""
             withApp defaultSettings app $ \port -> do
-                handle <- connectTo "127.0.0.1" $ PortNumber $ fromIntegral port
+                handle <- connectTo "127.0.0.1" port
                 let input = S.concat
                         [ "GET / HTTP/1.1\r\nfoo:    bar\r\n baz\r\n\tbin\r\n\r\n"
                         ]
@@ -218,7 +225,7 @@
                     liftIO $ I.writeIORef iheaders $ requestHeaders req
                     f $ responseLBS status200 [] ""
             withApp defaultSettings app $ \port -> do
-                handle <- connectTo "127.0.0.1" $ PortNumber $ fromIntegral port
+                handle <- connectTo "127.0.0.1" port
                 let input = S.concat
                         [ "GET / HTTP/1.1\r\nfoo:bar\r\n\r\n"
                         ]
@@ -239,7 +246,7 @@
                     liftIO $ I.atomicModifyIORef ifront $ \front -> (front . (S.concat bss:), ())
                     f $ responseLBS status200 [] ""
             withApp defaultSettings app $ \port -> do
-                handle <- connectTo "127.0.0.1" $ PortNumber $ fromIntegral port
+                handle <- connectTo "127.0.0.1" port
                 let input = S.concat
                         [ "POST / HTTP/1.1\r\nTransfer-Encoding: Chunked\r\n\r\n"
                         , "c\r\nHello World\n\r\n3\r\nBye\r\n0\r\n\r\n"
@@ -262,7 +269,7 @@
                     I.atomicModifyIORef ifront $ \front -> (front . (S.concat bss:), ())
                     f $ responseLBS status200 [] ""
             withApp defaultSettings app $ \port -> do
-                handle <- connectTo "127.0.0.1" $ PortNumber $ fromIntegral port
+                handle <- connectTo "127.0.0.1" port
                 let input = concat $ replicate 2 $
                         ["POST / HTTP/1.1\r\nTransfer-Encoding: Chunked\r\n\r\n"] ++
                         (replicate 50 "5\r\n12345\r\n") ++
@@ -279,7 +286,7 @@
                     liftIO $ I.atomicModifyIORef ifront $ \front -> (front . (S.concat bss:), ())
                     f $ responseLBS status200 [] ""
             withApp defaultSettings app $ \port -> do
-                handle <- connectTo "127.0.0.1" $ PortNumber $ fromIntegral port
+                handle <- connectTo "127.0.0.1" port
                 let input = S.concat
                         [ "POST / HTTP/1.1\r\nTransfer-Encoding: Chunked\r\n\r\n"
                         , "c\r\nHello World\n\r\n3\r\nBye\r\n0\r\n"
@@ -310,7 +317,7 @@
                 let bs1 = S.replicate 2048 88
                     bs2 = "This is short"
                     bs = S.append bs1 bs2
-                handle <- connectTo "127.0.0.1" $ PortNumber $ fromIntegral port
+                handle <- connectTo "127.0.0.1" port
                 hPutStr handle "POST / HTTP/1.1\r\n"
                 hPutStr handle "content-length: "
                 hPutStr handle $ S8.pack $ show $ S.length bs
@@ -336,7 +343,7 @@
                         loop
                 doubleBS = S.concatMap $ \w -> S.pack [w, w]
             withApp defaultSettings app $ \port -> do
-                handle <- connectTo "127.0.0.1" $ PortNumber $ fromIntegral port
+                handle <- connectTo "127.0.0.1" port
                 hPutStr handle "POST / HTTP/1.1\r\n\r\n12345"
                 hFlush handle
                 timeout 100000 (S.hGet handle 10) >>= (`shouldBe` Just "1122334455")
@@ -351,8 +358,8 @@
                 ] ""
         withApp defaultSettings app $ \port -> do
             res <- sendGET $ "http://127.0.0.1:" ++ show port
-            getHeaderValue HdrServer res `shouldBe` Just "server"
-            getHeaderValue HdrDate res `shouldBe` Just "date"
+            getHeaderValue hServer (responseHeaders res) `shouldBe` Just "server"
+            getHeaderValue hDate (responseHeaders res) `shouldBe` Just "date"
 
     it "streaming echo #249" $ do
         let app req f = f $ responseStream status200 [] $ \write _ -> do
@@ -363,11 +370,11 @@
                         loop
             loop
         withApp defaultSettings app $ \port -> do
-            (socket, _addr) <- getSocketTCP "127.0.0.1" port
-            sendAll socket "POST / HTTP/1.1\r\ntransfer-encoding: chunked\r\n\r\n"
+            (sock, _addr) <- getSocketTCP "127.0.0.1" port
+            sendAll sock "POST / HTTP/1.1\r\ntransfer-encoding: chunked\r\n\r\n"
             threadDelay 10000
-            sendAll socket "5\r\nhello\r\n0\r\n\r\n"
-            bs <- safeRecv socket 4096
+            sendAll sock "5\r\nhello\r\n0\r\n\r\n"
+            bs <- safeRecv sock 4096
             S.takeWhile (/= 13) bs `shouldBe` "HTTP/1.1 200 OK"
 
     it "streaming response with length" $ do
@@ -375,7 +382,7 @@
                 replicateM_ 4 $ write $ byteString "Hello"
         withApp defaultSettings app $ \port -> do
             res <- sendGET $ "http://127.0.0.1:" ++ show port
-            rspBody res `shouldBe` "HelloHelloHelloHello"
+            responseBody res `shouldBe` "HelloHelloHelloHello"
 
     describe "head requests" $ do
         let fp = "test/head-response"
@@ -388,19 +395,19 @@
                     _ -> error "invalid path"
         it "builder" $ withApp defaultSettings app $ \port -> do
             res <- sendHEAD $ concat ["http://127.0.0.1:", show port, "/builder"]
-            rspBody res `shouldBe` ""
+            responseBody res `shouldBe` ""
         it "streaming" $ withApp defaultSettings app $ \port -> do
             res <- sendHEAD $ concat ["http://127.0.0.1:", show port, "/streaming"]
-            rspBody res `shouldBe` ""
+            responseBody res `shouldBe` ""
         it "file, no range" $ withApp defaultSettings app $ \port -> do
             bs <- S.readFile fp
             res <- sendHEAD $ concat ["http://127.0.0.1:", show port, "/file"]
-            getHeaderValue HdrContentLength res `shouldBe` Just (show $ S.length bs)
+            getHeaderValue hContentLength (responseHeaders res) `shouldBe` Just (S8.pack $ show $ S.length bs)
         it "file, with range" $ withApp defaultSettings app $ \port -> do
             res <- sendHEADwH
                 (concat ["http://127.0.0.1:", show port, "/file"])
-                [mkHeader HdrRange "bytes=0-1"]
-            getHeaderValue HdrContentLength res `shouldBe` Just "2"
+                [(hRange, "bytes=0-1")]
+            getHeaderValue hContentLength (responseHeaders res) `shouldBe` Just "2"
 
 consumeBody :: IO ByteString -> IO [ByteString]
 consumeBody body =
diff --git a/test/WithApplicationSpec.hs b/test/WithApplicationSpec.hs
--- a/test/WithApplicationSpec.hs
+++ b/test/WithApplicationSpec.hs
@@ -7,6 +7,7 @@
 import           Network.HTTP.Types
 import           Network.Socket
 import           Network.Wai
+import           System.Environment
 import           System.IO
 import           System.IO.Silently
 import           System.Process
@@ -16,6 +17,9 @@
 
 spec :: Spec
 spec = do
+  runIO $ do
+      unsetEnv "http_proxy"
+      unsetEnv "https_proxy"
   describe "withApplication" $ do
     it "runs a wai Application while executing the given action" $ do
       let mkApp = return $ \ _request respond -> respond $ responseLBS ok200 [] "foo"
@@ -38,8 +42,10 @@
             readProcess "curl" ["-s", "localhost:" ++ show port] "")
           `shouldThrow` (errorCall "foo")
 
+{- The future netwrok library will not export MkSocket.
   describe "withFreePort" $ do
     it "closes the socket before exiting" $ do
       MkSocket _ _ _ _ statusMVar <- withFreePort $ \ (_, sock) -> do
         return sock
       readMVar statusMVar `shouldReturn` Closed
+-}
diff --git a/warp.cabal b/warp.cabal
--- a/warp.cabal
+++ b/warp.cabal
@@ -1,5 +1,5 @@
 Name:                warp
-Version:             3.2.13
+Version:             3.2.15
 Synopsis:            A fast, light-weight web server for WAI applications.
 License:             MIT
 License-file:        LICENSE
@@ -33,13 +33,12 @@
     Default:     False
 
 Library
-  Build-Depends:     base                      >= 3        && < 5
+  Build-Depends:     base                      >= 4.8        && < 5
                    , array
                    , async
                    , auto-update               >= 0.1.3    && < 0.2
                    , blaze-builder             >= 0.4
                    , bytestring                >= 0.9.1.4
-                   , bytestring-builder
                    , case-insensitive          >= 0.2
                    , containers
                    , ghc-prim
@@ -56,6 +55,8 @@
                    , word8
                    , hashable
                    , http-date
+  if impl(ghc < 8)
+      Build-Depends: semigroups
   if flag(network-bytestring)
       Build-Depends: network                   >= 2.2.1.5  && < 2.2.3
                    , network-bytestring        >= 0.1.3    && < 0.1.4
@@ -83,7 +84,7 @@
                      Network.Wai.Handler.Warp.HTTP2.Worker
                      Network.Wai.Handler.Warp.Header
                      Network.Wai.Handler.Warp.IO
-                     Network.Wai.Handler.Warp.IORef
+                     Network.Wai.Handler.Warp.Imports
                      Network.Wai.Handler.Warp.PackInt
                      Network.Wai.Handler.Warp.ReadInt
                      Network.Wai.Handler.Warp.Recv
@@ -94,7 +95,6 @@
                      Network.Wai.Handler.Warp.Run
                      Network.Wai.Handler.Warp.SendFile
                      Network.Wai.Handler.Warp.Settings
-                     Network.Wai.Handler.Warp.Some
                      Network.Wai.Handler.Warp.Timeout
                      Network.Wai.Handler.Warp.Types
                      Network.Wai.Handler.Warp.Windows
@@ -118,7 +118,7 @@
   HS-Source-Dirs:       test
   Ghc-Options:          -threaded -Wall
   Main-Is:              doctests.hs
-  Build-Depends:        base
+  Build-Depends:        base >= 4.8 && < 5
                       , doctest >= 0.10.1
 
 Test-Suite spec
@@ -136,19 +136,56 @@
                      SendFileSpec
                      WithApplicationSpec
                      HTTP
+                     Network.Wai.Handler.Warp
+                     Network.Wai.Handler.Warp.Buffer
+                     Network.Wai.Handler.Warp.Conduit
+                     Network.Wai.Handler.Warp.Counter
+                     Network.Wai.Handler.Warp.Date
+                     Network.Wai.Handler.Warp.FdCache
+                     Network.Wai.Handler.Warp.File
+                     Network.Wai.Handler.Warp.FileInfoCache
+                     Network.Wai.Handler.Warp.HTTP2
+                     Network.Wai.Handler.Warp.HTTP2.EncodeFrame
+                     Network.Wai.Handler.Warp.HTTP2.File
+                     Network.Wai.Handler.Warp.HTTP2.HPACK
+                     Network.Wai.Handler.Warp.HTTP2.Manager
+                     Network.Wai.Handler.Warp.HTTP2.Receiver
+                     Network.Wai.Handler.Warp.HTTP2.Request
+                     Network.Wai.Handler.Warp.HTTP2.Sender
+                     Network.Wai.Handler.Warp.HTTP2.Types
+                     Network.Wai.Handler.Warp.HTTP2.Worker
+                     Network.Wai.Handler.Warp.HashMap
+                     Network.Wai.Handler.Warp.Header
+                     Network.Wai.Handler.Warp.IO
+                     Network.Wai.Handler.Warp.Imports
+                     Network.Wai.Handler.Warp.MultiMap
+                     Network.Wai.Handler.Warp.PackInt
+                     Network.Wai.Handler.Warp.ReadInt
+                     Network.Wai.Handler.Warp.Recv
+                     Network.Wai.Handler.Warp.Request
+                     Network.Wai.Handler.Warp.RequestHeader
+                     Network.Wai.Handler.Warp.Response
+                     Network.Wai.Handler.Warp.ResponseHeader
+                     Network.Wai.Handler.Warp.Run
+                     Network.Wai.Handler.Warp.SendFile
+                     Network.Wai.Handler.Warp.Settings
+                     Network.Wai.Handler.Warp.Timeout
+                     Network.Wai.Handler.Warp.Types
+                     Network.Wai.Handler.Warp.WithApplication
+                     Paths_warp
+
     Hs-Source-Dirs:  test, .
     Type:            exitcode-stdio-1.0
 
     Ghc-Options:     -Wall
-    Build-Depends:   base >= 4 && < 5
+    Build-Depends:   base >= 4.8 && < 5
                    , array
                    , auto-update
                    , blaze-builder             >= 0.4
                    , bytestring                >= 0.9.1.4
-                   , bytestring-builder
                    , case-insensitive          >= 0.2
                    , ghc-prim
-                   , HTTP
+                   , http-client
                    , http-types                >= 0.8.5
                    , iproute                   >= 1.3.1
                    , lifted-base               >= 0.1
@@ -174,6 +211,8 @@
                    , word8
                    , hashable
                    , http-date
+  if impl(ghc < 8)
+      Build-Depends: semigroups
 
   if (os(linux) || os(freebsd) || os(darwin)) && flag(allow-sendfilefd)
     Cpp-Options:   -DSENDFILEFD
@@ -184,18 +223,28 @@
 Benchmark parser
     Type:           exitcode-stdio-1.0
     Main-Is:        Parser.hs
+    other-modules:  Network.Wai.Handler.Warp.Date
+                    Network.Wai.Handler.Warp.FdCache
+                    Network.Wai.Handler.Warp.FileInfoCache
+                    Network.Wai.Handler.Warp.HashMap
+                    Network.Wai.Handler.Warp.Imports
+                    Network.Wai.Handler.Warp.MultiMap
+                    Network.Wai.Handler.Warp.Timeout
+                    Network.Wai.Handler.Warp.Types
     HS-Source-Dirs: bench .
-    Build-Depends:  base
+    Build-Depends:  base >= 4.8 && < 5
                   , auto-update
                   , bytestring
                   , containers
-                  , criterion >= 1
+                  , gauge
                   , hashable
                   , http-date
                   , http-types
                   , network
                   , network
                   , unix-compat
+  if impl(ghc < 8)
+      Build-Depends: semigroups
 
   if (os(linux) || os(freebsd) || os(darwin)) && flag(allow-sendfilefd)
     Cpp-Options:   -DSENDFILEFD
