wai-rate-limit-postgres 0.3.0.0 → 0.4.0.0
raw patch · 5 files changed
+67/−15 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +4/−0
- README.md +18/−0
- src/Network/Wai/RateLimit/Postgres.hs +5/−4
- test/Spec.hs +39/−10
- wai-rate-limit-postgres.cabal +1/−1
CHANGELOG.md view
@@ -3,6 +3,10 @@ `wai-rate-limit-postgres` uses [PVP Versioning][1]. The changelog is available [on GitHub][2]. +## 0.4.0.0++* Fix encoding bug by changing key type to `bytea` (#5)+ ## 0.3.0.0 * Removed unnecessary debug prints
README.md view
@@ -8,3 +8,21 @@ Depending on traffic and latency of PostgreSQL, this backend may or may not be appropriate for you. +# Testing locally with Docker++Start a PostgreSQL docker container in a terminal:+++```shell++$ docker run --name some-postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -it --rm postgres -c log_statement=all++```++Run tests in another terminal with:++```shell++$ export PG_DB_URI=postgres://postgres:postgres@localhost:5432/postgres+$ cabal test+```
src/Network/Wai/RateLimit/Postgres.hs view
@@ -46,7 +46,7 @@ " " [ "CREATE TABLE IF NOT EXISTS", tableName,- "(key VARCHAR PRIMARY KEY,",+ "(key BYTEA PRIMARY KEY,", "usage INT8 NOT NULL,", "expires_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP + '1 week'::INTERVAL)" ]@@ -64,7 +64,7 @@ do res <- try $- PG.query c getUsageQuery (PG.Only key) `catches` sqlHandlers+ PG.query c getUsageQuery (PG.Only $ PG.Binary key) `catches` sqlHandlers return $ do rows <- res case rows of@@ -85,7 +85,8 @@ pgBackendIncAndGetUsage :: Pool PG.Connection -> Text -> ByteString -> Integer -> IO (Either PGBackendError Integer) pgBackendIncAndGetUsage p tableName key usage = withResource p $ \c -> do- res <- try $ PG.query c incAndGetQuery (key, usage) `catches` sqlHandlers+ res <- try $ PG.query c incAndGetQuery (PG.Binary key, usage) `catches` sqlHandlers+ print res return $ do rows <- res case rows of@@ -109,7 +110,7 @@ pgBackendExpireIn :: Pool PG.Connection -> Text -> ByteString -> Integer -> IO (Either PGBackendError ()) pgBackendExpireIn p tableName key seconds = withResource p $ \c -> do- res <- try $ PG.execute c expireInQuery (seconds, key) `catches` sqlHandlers+ res <- try $ PG.execute c expireInQuery (seconds, PG.Binary key) `catches` sqlHandlers return $ do count <- res if count /= 1
test/Spec.hs view
@@ -1,8 +1,13 @@ module Main (main) where import Control.Concurrent-import Control.Exception-import Data.Pool+ ( ThreadId,+ forkIO,+ killThread,+ threadDelay,+ )+import Control.Exception (bracket, throwIO)+import Data.Pool (Pool, createPool) import qualified Database.PostgreSQL.Simple as PG import Database.PostgreSQL.Simple.URL (parseDatabaseUrl) import Network.HTTP.Client (Manager, defaultManagerSettings, httpLbs, newManager, parseRequest, responseStatus)@@ -10,12 +15,12 @@ import qualified Network.Wai as Wai import qualified Network.Wai.Handler.Warp as Warp import qualified Network.Wai.RateLimit as R-import Network.Wai.RateLimit.Postgres+import Network.Wai.RateLimit.Postgres (postgresBackend) import qualified Network.Wai.RateLimit.Strategy as R-import System.Environment.Blank-import System.IO.Error-import Test.Tasty-import Test.Tasty.HUnit+import System.Environment.Blank (getEnv)+import System.IO.Error (userError)+import Test.Tasty (defaultMain)+import Test.Tasty.HUnit (assertFailure, testCaseSteps) -- | Example value = "postgres://postgres:postgres@localhost:5432/postgres" testPGEnv :: String@@ -63,7 +68,6 @@ $ \step -> do step "Limit excessive requests (1)"- bracket (mkTestWaiApp 1 2 "key1" >>= launchApp) tearDownApp@@ -74,7 +78,6 @@ assertFailure "Not ratelimited!" step "Limit excessive requests (2)"- bracket (mkTestWaiApp 1 3 "key2" >>= launchApp) tearDownApp@@ -85,7 +88,6 @@ assertFailure "Unexpected result!" step "Allow non-excessive requests"- bracket (mkTestWaiApp 1 3 "key3" >>= launchApp) tearDownApp@@ -94,3 +96,30 @@ rs <- replicateM 3 $ mkReq mgr when (rs /= [200, 200, 200]) $ assertFailure "Unexpected result!"++ step "Allow excessive requests, slow down and then be allowed"+ bracket+ (mkTestWaiApp 1 1 "key4" >>= launchApp)+ tearDownApp+ $ \_ -> do+ mgr <- newManager defaultManagerSettings+ rs <- replicateM 3 $ mkReq mgr+ when (rs /= [200, 429, 429]) $+ assertFailure "Unexpected result!"+ threadDelay 1_000_000+ rs2 <- replicateM 1 $ mkReq mgr+ when (rs2 /= [200]) $+ assertFailure "Unexpected result!"++ step "Allow keys that are invalid as unicode strings"+ let invalidUtf8String = "\187" :: ByteString+ when (isRight (decodeUtf8Strict invalidUtf8String :: Either UnicodeException Text)) $+ assertFailure "`invalidUtf8String` appears to have a valid UTF8 string"+ bracket+ (mkTestWaiApp 1 3 invalidUtf8String >>= launchApp)+ tearDownApp+ $ \_ -> do+ mgr <- newManager defaultManagerSettings+ rs <- replicateM 3 $ mkReq mgr+ when (rs /= [200, 200, 200]) $+ assertFailure $ "Unexpected result: " ++ show rs
wai-rate-limit-postgres.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: wai-rate-limit-postgres-version: 0.3.0.0+version: 0.4.0.0 category: Security, Web, Network synopsis: See README for more info description: