Skip to content

Latest commit

 

History

History
94 lines (63 loc) · 3.56 KB

README.org

File metadata and controls

94 lines (63 loc) · 3.56 KB

https://travis-ci.com/threatgrid/ring-turnstile-middleware.png?branch=master

ring-turnstile-middleware

Ring middleware for the Turnstile rate limiting service

Changes

  • Note: Version 0.1.1 is missing commit information–it corresponds to this commit.

Basic Usage

Use wrap-rate-limit to create an instance of the middleware, wrap your handler with it:

(require '[ring.middleware.turnstile 
           :refer [wrap-rate-limit ip-limit header-limit]]
         '[ring.util.response :refer [response]])

(def app (-> your-routes
             (wrap-rate-limit {:redis-conf {}
                               :key-prefix "your-api"
                               :limit-fns [(ip-limit 200)
                                           (header-limit 300 "x-role" "ROLE")]))

;; 200 requests per hour per IP address
;; 300 requests per hour per value of the header `x-role`

Advanced usage

Custom rate limit handler

If you want to do some specific operations when a call is rate limited, you can define your own rate limit handler:

(require '[ring.middleware.turnstile :refer [wrap-rate-limit ip-limit]]
         '[ring.util.response :refer [response]])

(def app (-> your-routes
             (wrap-rate-limit {:redis-conf {}
                               :key-prefix "your-api"
                               :limit-fns [(ip-limit 200)]
                               :rate-limit-handler 
                                (fn [request next-slot-in-sec limit]
                                 {:status 429
                                  :body (format "Too many requests, try later in %d s"
                                                next-slot-in-sec)})}))

Custom limit

You can create your own limit

(require '[ring.middleware.turnstile :refer [wrap-rate-limit ip-limit]]
         '[ring.util.response :refer [response]])   

(def custom-limit
  [request]
  (when-let [role (get-in request [:jwt "role"])
             ip-limit-fn (ip-limit 100)]
    (cond-> (ip-limit-fn request)
      (= "admin" role) (assoc :nb-request-per-hour 200))))

(def app (-> your-routes
             (wrap-rate-limit {:redis-conf {}
                               :key-prefix "your-api"
                               :limits [custom-limit]))

;; 200 requests per hour per IP for amdin users
;; 100 requests per hour for the others

The limit fn must return a hash map with the following keys:

KeywordDescription
:nb-request-per-hourThe number of request per hour limit
:rate-limit-keyThe rate limit key to group requests
:name-in-headersUsed in the rate limit headers to identify a rate limit. (templates: X-RateLimit-%s-Limit, X-RateLimit-%s-Limit). Field names in HTTP headers are case-insensitive and are composed by any char except control chars or separators

or

nil if the request is not rate limited.

License

Copyright © 2018 Cisco Systems Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.