packages feed

warp 3.2.13 → 3.2.15

raw patch · 47 files changed

+397/−455 lines, 47 filesdep +gaugedep +http-clientdep +semigroupsdep −HTTPdep −bytestring-builderdep −criteriondep ~basedep ~streaming-commons

Dependencies added: gauge, http-client, semigroups

Dependencies removed: HTTP, bytestring-builder, criterion

Dependency ranges changed: base, streaming-commons

Files

ChangeLog.md view
@@ -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)
Network/Wai/Handler/Warp.hs view
@@ -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
Network/Wai/Handler/Warp/Buffer.hs view
@@ -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  ----------------------------------------------------------------
Network/Wai/Handler/Warp/Conduit.hs view
@@ -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  ----------------------------------------------------------------
Network/Wai/Handler/Warp/Counter.hs view
@@ -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) 
Network/Wai/Handler/Warp/Date.hs view
@@ -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
Network/Wai/Handler/Warp/FdCache.hs view
@@ -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)  ---------------------------------------------------------------- 
Network/Wai/Handler/Warp/File.hs view
@@ -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
Network/Wai/Handler/Warp/FileInfoCache.hs view
@@ -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
Network/Wai/Handler/Warp/HTTP2.hs view
@@ -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 
Network/Wai/Handler/Warp/HTTP2/EncodeFrame.hs view
@@ -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  ---------------------------------------------------------------- 
Network/Wai/Handler/Warp/HTTP2/File.hs view
@@ -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
Network/Wai/Handler/Warp/HTTP2/HPACK.hs view
@@ -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
Network/Wai/Handler/Warp/HTTP2/Manager.hs view
@@ -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 
Network/Wai/Handler/Warp/HTTP2/Receiver.hs view
@@ -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
Network/Wai/Handler/Warp/HTTP2/Request.hs view
@@ -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.
Network/Wai/Handler/Warp/HTTP2/Sender.hs view
@@ -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
Network/Wai/Handler/Warp/HTTP2/Types.hs view
@@ -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)  ---------------------------------------------------------------- 
Network/Wai/Handler/Warp/HTTP2/Worker.hs view
@@ -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(..))  ---------------------------------------------------------------- 
Network/Wai/Handler/Warp/HashMap.hs view
@@ -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
Network/Wai/Handler/Warp/Header.hs view
@@ -7,6 +7,7 @@ import qualified Data.ByteString as BS import Data.CaseInsensitive (foldedCase) import Network.HTTP.Types+ import Network.Wai.Handler.Warp.Types  ----------------------------------------------------------------
Network/Wai/Handler/Warp/IO.hs view
@@ -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 ()
− Network/Wai/Handler/Warp/IORef.hs
@@ -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
+ Network/Wai/Handler/Warp/Imports.hs view
@@ -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
Network/Wai/Handler/Warp/MultiMap.hs view
@@ -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
Network/Wai/Handler/Warp/PackInt.hs view
@@ -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"
Network/Wai/Handler/Warp/ReadInt.hs view
@@ -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
Network/Wai/Handler/Warp/Recv.hs view
@@ -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)
Network/Wai/Handler/Warp/Request.hs view
@@ -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)  ---------------------------------------------------------------- 
Network/Wai/Handler/Warp/RequestHeader.hs view
@@ -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
Network/Wai/Handler/Warp/Response.hs view
@@ -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
Network/Wai/Handler/Warp/ResponseHeader.hs view
@@ -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
Network/Wai/Handler/Warp/Run.hs view
@@ -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
Network/Wai/Handler/Warp/SendFile.hs view
@@ -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  ---------------------------------------------------------------- 
Network/Wai/Handler/Warp/Settings.hs view
@@ -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
− Network/Wai/Handler/Warp/Some.hs
@@ -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-
Network/Wai/Handler/Warp/Timeout.hs view
@@ -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" 
Network/Wai/Handler/Warp/Types.hs view
@@ -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)  ---------------------------------------------------------------- 
Network/Wai/Handler/Warp/Windows.hs view
@@ -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
Network/Wai/Handler/Warp/WithApplication.hs view
@@ -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)
bench/Parser.hs view
@@ -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
test/ExceptionSpec.hs view
@@ -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
test/HTTP.hs view
@@ -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
test/ResponseSpec.hs view
@@ -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
test/RunSpec.hs view
@@ -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 =
test/WithApplicationSpec.hs view
@@ -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+-}
warp.cabal view
@@ -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