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 +10/−0
- Network/Wai/Handler/Warp.hs +4/−4
- Network/Wai/Handler/Warp/Buffer.hs +4/−2
- Network/Wai/Handler/Warp/Conduit.hs +2/−6
- Network/Wai/Handler/Warp/Counter.hs +3/−4
- Network/Wai/Handler/Warp/Date.hs +1/−4
- Network/Wai/Handler/Warp/FdCache.hs +3/−6
- Network/Wai/Handler/Warp/File.hs +5/−6
- Network/Wai/Handler/Warp/FileInfoCache.hs +4/−4
- Network/Wai/Handler/Warp/HTTP2.hs +2/−2
- Network/Wai/Handler/Warp/HTTP2/EncodeFrame.hs +2/−3
- Network/Wai/Handler/Warp/HTTP2/File.hs +7/−9
- Network/Wai/Handler/Warp/HTTP2/HPACK.hs +8/−8
- Network/Wai/Handler/Warp/HTTP2/Manager.hs +4/−6
- Network/Wai/Handler/Warp/HTTP2/Receiver.hs +4/−7
- Network/Wai/Handler/Warp/HTTP2/Request.hs +11/−12
- Network/Wai/Handler/Warp/HTTP2/Sender.hs +13/−18
- Network/Wai/Handler/Warp/HTTP2/Types.hs +7/−11
- Network/Wai/Handler/Warp/HTTP2/Worker.hs +7/−12
- Network/Wai/Handler/Warp/HashMap.hs +3/−2
- Network/Wai/Handler/Warp/Header.hs +1/−0
- Network/Wai/Handler/Warp/IO.hs +2/−1
- Network/Wai/Handler/Warp/IORef.hs +0/−26
- Network/Wai/Handler/Warp/Imports.hs +27/−0
- Network/Wai/Handler/Warp/MultiMap.hs +24/−15
- Network/Wai/Handler/Warp/PackInt.hs +6/−6
- Network/Wai/Handler/Warp/ReadInt.hs +2/−2
- Network/Wai/Handler/Warp/Recv.hs +4/−7
- Network/Wai/Handler/Warp/Request.hs +9/−9
- Network/Wai/Handler/Warp/RequestHeader.hs +5/−6
- Network/Wai/Handler/Warp/Response.hs +10/−33
- Network/Wai/Handler/Warp/ResponseHeader.hs +3/−5
- Network/Wai/Handler/Warp/Run.hs +18/−22
- Network/Wai/Handler/Warp/SendFile.hs +4/−8
- Network/Wai/Handler/Warp/Settings.hs +7/−10
- Network/Wai/Handler/Warp/Some.hs +0/−73
- Network/Wai/Handler/Warp/Timeout.hs +2/−4
- Network/Wai/Handler/Warp/Types.hs +3/−3
- Network/Wai/Handler/Warp/Windows.hs +2/−1
- Network/Wai/Handler/Warp/WithApplication.hs +8/−4
- bench/Parser.hs +10/−10
- test/ExceptionSpec.hs +11/−11
- test/HTTP.hs +26/−28
- test/ResponseSpec.hs +8/−6
- test/RunSpec.hs +35/−28
- test/WithApplicationSpec.hs +6/−0
- warp.cabal +60/−11
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