gottle

package module
v0.0.0-...-a1b2089 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 22, 2019 License: MIT Imports: 9 Imported by: 0

README

Gottle - A rate limiter for Golang which builds on Onecache

Coverage Status Build Status

$ go get -u github.com/adelowo/gottle

Docs for all available operations -> https://godoc.org/github.com/adelowo/gottle or run godoc github.com/adelowo/gottle


package main

func main() {

  func someHandler(w http.ResponseWriter, r *http.Request) {

    var throttler = NewOneCacheThrottler() //can pass in options

    //Throttle the request
    if err := throttler.Throttle(r); err != nil {
      sendFailureResponse(500, "An error occurred while trying to throttle the request")
      return
    }

    //Can also check if the current request has been rate limited
    if throttler.IsRateLimited(r) {
      //We only want to throttle requests from other account types
      //aside premium users
      if isPremiumUser(r) {
        //isPremiumUser fetches the account type from the context
        throttler.Clear(r) //Clear the rate limit
        someOperationUserWantsToCarryOut(r)
        return
      }

      sendFailureResponse(400, `
        You have been ratelimited.. Wait for some time before trying again`)
      return
    }

  }

}

This is a very simple throttler implementation (albeit it works very well). All it does is keep a record of the IP of a request and the number of times a request was received from that IP. Once the request count has passed it's limit, a lockout is obtained

There are IPProviders, which extract out the IP from a request.. There are currently two implementations you can choose from

  • RealIP - This fetches the IP from the HTTP headers (X-Forwarded-For or X-Real-IP).. This is suitable when you have a reverse proxy to your go binary.

  • RemoteIP - extremely basic and not guareented to work as expected because Go sets the RemoteAddr of a request to IP:port and you are expected to manipulate that yourself in a middleware or something of that sort.

You can also write your own IPProvider by implementing ;

IP(r *http.Request) string

You can also configure the amount of requests a client is allowed to make before a lockout is obtained.. By default, it is at 10 requests in a timeframe of 10 minutes. To override that, you simply set an option on NewOneCacheThrottler like :


interval := time.Minute
maxRequests := 60

throttler := NewOneCacheThrottler(
  ThrottleCondition(interval, maxRequests))

//Now a lockout would only be obtained after the client has made 60 requests in less than a minute

Do check the other available options in the godoc or the test suites

License

MIT

Documentation

Overview

Gottle is an HTTP ratelimiter built ontop of the onecache library.

Index

Constants

This section is empty.

Variables

View Source
var ErrClientIsRateLimited = errors.New(
	`gottle: The client is currently rate limited`)

ErrClientIsRateLimited is an error value that signifies a client has been ratelimited

Functions

func DecodeGob

func DecodeGob(buf []byte, val *throttledItem) error

func EncodeGob

func EncodeGob(val *throttledItem) ([]byte, error)

Types

type IPProvider

type IPProvider interface {
	IP(r *http.Request) string
}

IPProvider provides an interface for fetching the IP of an HTTP request

type KeyFunc

type KeyFunc func(ip string) string

KeyFunc is a function type for setting the key in the cache

type OnecacheThrottler

type OnecacheThrottler struct {
	// contains filtered or unexported fields
}

OnecacheThrottler provides an implementation of Throttler by making use of onecache's cache implementation

func NewOneCacheThrottler

func NewOneCacheThrottler(opts ...Option) *OnecacheThrottler

NewOneCacheThrottler returns an instance of OnecacheThrottler

func (*OnecacheThrottler) Attempts

func (t *OnecacheThrottler) Attempts(r *http.Request) (int, error)

Attempts returns the number of times the request have been throttled

func (*OnecacheThrottler) AttemptsLeft

func (t *OnecacheThrottler) AttemptsLeft(r *http.Request) (int, error)

AttemptsLeft gets the number of attempts left before a lockout is obtained

func (*OnecacheThrottler) Clear

func (t *OnecacheThrottler) Clear(r *http.Request) error

Clear resets the throttle on the request

func (*OnecacheThrottler) IsRateLimited

func (t *OnecacheThrottler) IsRateLimited(r *http.Request) bool

IsRateLimited checks if a client has reached his/her maximum number of tries

func (*OnecacheThrottler) Throttle

func (t *OnecacheThrottler) Throttle(r *http.Request) error

Throttle throttles an HTTP request

type Option

type Option func(*OnecacheThrottler)

Option provides configuration of the throttler from client code

func IP

func IP(ip IPProvider) Option

IP is a configuration Option that sets the provider of the HTTP request

func KeyGenerator

func KeyGenerator(gen KeyFunc) Option

KeyGenerator is a configuration Option that allows client code choose the way they'd like the ip to be used as a cache key Keep in mind that the cache store in use might still perform some operation (based on it's own keyGenerator) on the key generated

func Store

func Store(store onecache.Store) Option

Store is a configuration Option that allows client code choose one of the many adapters supported by onecache

func ThrottleCondition

func ThrottleCondition(interval time.Duration, maxRequests int) Option

ThrottleCondition provides an Option for configuring the maxRequestss and timeframe before a client can be rate limited

type RealIP

type RealIP struct{}

RealIP is an IPProvider implementation that fetches the ip of an HTTP request by inspecting the "X-Forwarded-For" or "X-Real-IP" headers This should only be used when you have a reverse proxy in place.

func NewRealIP

func NewRealIP() *RealIP

NewRealIP returns an instance of RealIP

func (*RealIP) IP

func (re *RealIP) IP(r *http.Request) string

IP returns the ip associated with the request .. Ported from pressly/chi

type RemoteIP

type RemoteIP struct{}

RemoteIP is an IPProvider that fetches the IP of the request directly from the `RemoteAddr` of the Request This is extremely unreliable. Go sets the `RemoteAddr` to "IP:port" before your app handlers are called So you must be setting it to the right value in a middleware or something Do look at the RealIP implementation or consider writing your own IPProvider

func NewRemoteIP

func NewRemoteIP() *RemoteIP

NewRemoteIP returns an instance of the RemoteIP implementation of IPProvider

func (*RemoteIP) IP

func (rip *RemoteIP) IP(r *http.Request) string

type Throttler

type Throttler interface {
	Throttle(r *http.Request) error
	Clear(r *http.Request) error
}

Throttler defines the operation needed to limit clients and check if an HTTP request is currently rate limited

type ThrottlerAttempts

type ThrottlerAttempts interface {
	Attempts(r *http.Request) (int, error)
	AttemptsLeft(r *http.Request) (int, error)
	IsRateLimited(r *http.Request) bool
}

ThrottlerAttempts provides access to stats about the current request

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL