servant-rate-limit 0.1.0.0 → 0.2.0.0
raw patch · 5 files changed
+32/−21 lines, 5 filesdep +time-unitsdep +time-units-typesdep ~wai-rate-limitPVP ok
version bump matches the API change (PVP)
Dependencies added: time-units, time-units-types
Dependency ranges changed: wai-rate-limit
API changes (from Hackage documentation)
- Servant.RateLimit.Types: instance (GHC.TypeNats.KnownNat secs, GHC.TypeNats.KnownNat capacity) => Servant.RateLimit.Types.HasRateLimitStrategy (Servant.RateLimit.Types.FixedWindow secs capacity)
- Servant.RateLimit.Types: instance (GHC.TypeNats.KnownNat secs, GHC.TypeNats.KnownNat capacity) => Servant.RateLimit.Types.HasRateLimitStrategy (Servant.RateLimit.Types.SlidingWindow secs capacity)
+ Servant.RateLimit.Types: instance (Data.Time.TypeLevel.KnownDuration dur, GHC.TypeNats.KnownNat capacity, Data.Time.Units.TimeUnit (Data.Time.TypeLevel.DurationUnit dur)) => Servant.RateLimit.Types.HasRateLimitStrategy (Servant.RateLimit.Types.FixedWindow dur capacity)
+ Servant.RateLimit.Types: instance (Data.Time.TypeLevel.KnownDuration dur, GHC.TypeNats.KnownNat capacity, Data.Time.Units.TimeUnit (Data.Time.TypeLevel.DurationUnit dur)) => Servant.RateLimit.Types.HasRateLimitStrategy (Servant.RateLimit.Types.SlidingWindow dur capacity)
- Servant.RateLimit.Types: data FixedWindow (secs :: Nat) (capacity :: Nat)
+ Servant.RateLimit.Types: data FixedWindow (dur :: TimePeriod) (capacity :: Nat)
- Servant.RateLimit.Types: data SlidingWindow (secs :: Nat) (capacity :: Nat)
+ Servant.RateLimit.Types: data SlidingWindow (dur :: TimePeriod) (capacity :: Nat)
Files
- CHANGELOG.md +4/−0
- servant-rate-limit.cabal +7/−3
- src/Servant/RateLimit/Server.hs +0/−5
- src/Servant/RateLimit/Types.hs +17/−9
- test/Spec.hs +4/−4
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Changelog for `servant-rate-limit` +## 0.2++- Use `time-units-types` to allow for better type-level specifications of the time periods that should be used by the rate-limiting strategies.+ ## 0.1 - Initial release
servant-rate-limit.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: servant-rate-limit-version: 0.1.0.0+version: 0.2.0.0 synopsis: Rate limiting for Servant description: A Haskell library which implements rate limiting for Servant category: Security@@ -59,8 +59,10 @@ , bytestring , http-types <1 , servant+ , time-units >=1.0 && <2+ , time-units-types >=0.2 && <1 , wai >=3.0 && <4- , wai-rate-limit >=0.2 && <1+ , wai-rate-limit >=0.3 && <1 if flag(server) build-depends: servant-server@@ -104,9 +106,11 @@ , servant-server , tasty , tasty-hunit+ , time-units >=1.0 && <2+ , time-units-types >=0.2 && <1 , wai >=3.0 && <4 , wai-extra- , wai-rate-limit >=0.2 && <1+ , wai-rate-limit >=0.3 && <1 , wai-rate-limit-redis , warp if flag(server)
src/Servant/RateLimit/Server.hs view
@@ -17,11 +17,6 @@ import Control.Monad import Control.Monad.IO.Class -import Data.ByteString as BS-import Data.ByteString.Char8 as C8-import Data.Kind--import Network.Wai import Network.Wai.RateLimit.Backend import Network.Wai.RateLimit.Strategy
src/Servant/RateLimit/Types.hs view
@@ -8,6 +8,7 @@ {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UndecidableInstances #-} module Servant.RateLimit.Types ( -- * Servant combinator@@ -20,7 +21,10 @@ -- * Rate-limiting policies IPAddressPolicy,- HasRateLimitPolicy(..)+ HasRateLimitPolicy(..),++ -- * Re-exports+ module Data.Time.TypeLevel ) where --------------------------------------------------------------------------------@@ -30,6 +34,8 @@ import Data.ByteString.Char8 as C8 import Data.Kind import Data.Proxy+import qualified Data.Time.Units as Units+import Data.Time.TypeLevel import Network.Wai import Network.Wai.RateLimit.Backend@@ -38,11 +44,11 @@ -------------------------------------------------------------------------------- -- | A type-level description for the parameters of the `fixedWindow` strategy.-data FixedWindow (secs :: Nat) (capacity :: Nat)+data FixedWindow (dur :: TimePeriod) (capacity :: Nat) -- | A type-level description for the parameters of the `slidingWindow` -- strategy.-data SlidingWindow (secs :: Nat) (capacity :: Nat)+data SlidingWindow (dur :: TimePeriod) (capacity :: Nat) -- | A class of types which are type-level descriptions of rate-limiting -- strategies.@@ -52,23 +58,25 @@ -- the client should be identified, returns a rate-limiting `Strategy`. strategyValue :: Backend key -> (Request -> IO key) -> Strategy -instance (KnownNat secs, KnownNat capacity)- => HasRateLimitStrategy (FixedWindow secs capacity)+instance+ (KnownDuration dur, KnownNat capacity, Units.TimeUnit (DurationUnit dur))+ => HasRateLimitStrategy (FixedWindow dur capacity) where strategyValue backend getKey = fixedWindow backend- (fromInteger $ natVal (Proxy :: Proxy secs))+ (Units.convertUnit $ durationVal @dur) (fromInteger $ natVal (Proxy :: Proxy capacity)) getKey -instance (KnownNat secs, KnownNat capacity)- => HasRateLimitStrategy (SlidingWindow secs capacity)+instance+ (KnownDuration dur, KnownNat capacity, Units.TimeUnit (DurationUnit dur))+ => HasRateLimitStrategy (SlidingWindow dur capacity) where strategyValue backend getKey = slidingWindow backend- (fromInteger $ natVal (Proxy :: Proxy secs))+ (Units.convertUnit $ durationVal @dur) (fromInteger $ natVal (Proxy :: Proxy capacity)) getKey
test/Spec.hs view
@@ -5,7 +5,9 @@ -- file in the root directory of this source tree. -- -------------------------------------------------------------------------------- +import Control.Concurrent import Control.Monad+import Control.Monad.IO.Class import Database.Redis @@ -22,18 +24,16 @@ import Test.Tasty import Test.Tasty.HUnit-import Control.Monad.IO.Class-import Control.Concurrent -------------------------------------------------------------------------------- -- | The API we use for out tests, which has endpoints for the different -- rate limiting strategies as well as an unrestricted endpoint. type TestAPI- = RateLimit (FixedWindow 2 50) (IPAddressPolicy "fixed:") :>+ = RateLimit (FixedWindow ('Second 2) 50) (IPAddressPolicy "fixed:") :> "fixed-window" :> Get '[JSON] String- :<|> RateLimit (SlidingWindow 2 50) (IPAddressPolicy "sliding:") :>+ :<|> RateLimit (SlidingWindow ('Second 2) 50) (IPAddressPolicy "sliding:") :> "sliding-window" :> Get '[JSON] String :<|> "unrestricted" :>