wai-middleware-throttle 0.2.0.1 → 0.2.0.2
raw patch · 2 files changed
+55/−9 lines, 2 filesdep +hashabledep ~networkPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependencies added: hashable
Dependency ranges changed: network
API changes (from Hackage documentation)
+ Network.Wai.Middleware.Throttle: instance Eq Address
+ Network.Wai.Middleware.Throttle: instance Hashable Address
+ Network.Wai.Middleware.Throttle: instance Ord Address
Files
Network/Wai/Middleware/Throttle.hs view
@@ -25,6 +25,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE CPP #-} module Network.Wai.Middleware.Throttle ( @@ -45,19 +46,54 @@ import Control.Concurrent.STM import Control.Concurrent.TokenBucket-import Control.Monad (liftM)+import Control.Monad (liftM,join)+import Data.Functor ((<$>))+import Data.Function (on)+import Data.Hashable (hash,hashWithSalt,Hashable) import qualified Data.IntMap as IM+import Data.List (unionBy) import GHC.Word (Word64) import qualified Network.HTTP.Types.Status as Http import Network.Socket import Network.Wai +#ifndef MIN_VERSION_network+#define MIN_VERSION_network(a,b,c) 1+#endif newtype WaiThrottle = WT (TVar ThrottleState) +newtype Address = Address SockAddr++instance Hashable Address where+ hashWithSalt s (Address (SockAddrInet _ a)) = hashWithSalt s a+ hashWithSalt s (Address (SockAddrInet6 _ _ a _)) = hashWithSalt s a+ hashWithSalt s (Address (SockAddrUnix a)) = hashWithSalt s a+#if MIN_VERSION_network(2,6,1)+ hashWithSalt s (Address (SockAddrCan a)) = hashWithSalt s a+#endif++instance Eq Address where+ Address (SockAddrInet _ a) == Address (SockAddrInet _ b) = a == b+ Address (SockAddrInet6 _ _ a _) == Address (SockAddrInet6 _ _ b _) = a == b+ Address (SockAddrUnix a) == Address (SockAddrUnix b) = a == b+#if MIN_VERSION_network(2,6,1)+ Address (SockAddrCan a) == Address (SockAddrCan b) = a == b+#endif+ _ == _ = False -- not same constructor so cant be equal++instance Ord Address where+ Address (SockAddrInet _ a) <= Address (SockAddrInet _ b) = a <= b+ Address (SockAddrInet6 _ _ a _) <= Address (SockAddrInet6 _ _ b _) = a <= b+ Address (SockAddrUnix a) <= Address (SockAddrUnix b) = a <= b+#if MIN_VERSION_network(2,6,1)+ Address (SockAddrCan a) <= Address (SockAddrCan b) = a <= b+#endif+ Address a <= Address b = a <= b -- not same constructor so use builtin ordering+ -- | A 'HashMap' mapping the remote IP address to a 'TokenBucket'-data ThrottleState = ThrottleState !(IM.IntMap TokenBucket)+data ThrottleState = ThrottleState !(IM.IntMap [(Address,TokenBucket)]) -- | Settings which control various behaviors in the middleware.@@ -142,9 +178,9 @@ where throttleReq = do - let SockAddrInet _ remoteAddr = remoteHost req+ let remoteAddr = Address . remoteHost $ req throttleState <- atomically $ readTVar tmap- (tst, success) <- throttleReq' (fromIntegral remoteAddr) throttleState+ (tst, success) <- throttleReq' remoteAddr throttleState -- write the throttle state back atomically $ writeTVar tmap (ThrottleState tst)@@ -156,7 +192,12 @@ invRate = toInvRate (fromInteger throttleRate :: Double) burst = fromInteger throttleBurst - bucket <- maybe newTokenBucket return $ IM.lookup remoteAddr m+ bucket <- maybe newTokenBucket return $ addressToBucket remoteAddr m remaining <- tokenBucketTryAlloc1 bucket burst invRate - return (IM.insert remoteAddr bucket m, remaining)+ return (insertBucket remoteAddr bucket m, remaining)++ addressToBucket remoteAddr m = join (lookup remoteAddr <$> IM.lookup (hash remoteAddr) m)+ insertBucket remoteAddr bucket m =+ let col = unionBy ((==) `on` fst)+ in IM.insertWith col (hash remoteAddr) [(remoteAddr, bucket)] m
wai-middleware-throttle.cabal view
@@ -1,6 +1,6 @@ name: wai-middleware-throttle-version: 0.2.0.1+version: 0.2.0.2 license: BSD3 license-file: LICENSE author: Christopher Reichert@@ -29,11 +29,16 @@ , wai >= 3.0 , containers , transformers- , network+ , network >= 2.1 , http-types , stm , token-bucket+ , hashable >= 1.2 + other-extensions: CPP+ OverloadedStrings+ RecordWildCards+ if impl(ghc < 7.8) build-depends: blaze-builder < 0.4@@ -59,7 +64,7 @@ test-suite hlint main-is: test/HLint.hs- ghc-options: -Wall -Werror -threaded+ ghc-options: -Wall -threaded type: exitcode-stdio-1.0 default-language: Haskell2010 build-depends: base