func setHit(policy *RatePolicy, ip string) (int, error) {
	conn := cache.NewConn()
	defer cache.CloseConn(conn)
	key := fmt.Sprintf("%s:%s", policy.Route, ip)
	res, err := redis.String(conn.Do("GET", key))
	if err == nil {
		return redis.Int(conn.Do("INCR", key))
	} else if res == "" && err == redis.ErrNil {
		res, err = redis.String(conn.Do("SET", key, 1, "EX", policy.Minutes*60))
		if res == "OK" {
			return 1, nil
		}
	}
	return -1, nil
}
TODO: try to use goroutines for Redis calls
Registers a new hit for the route from the IP in Redis.
Returns the current hit count or an error.
package middleware
import (
	"fmt"
	"net/http"
	"github.com/RohitAwate/OAuth2Bin/oauth2/cache"
	"github.com/gomodule/redigo/redis"
)
type RatePolicy struct {
	Route   string `json:"route"`
	Limit   int    `json:"limit"`
	Minutes int    `json:"minutes"`
}
type RateLimiter struct {
	Policies []RatePolicy
}
func (rl RateLimiter) Handle(handler http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		policy := rl.getRatePolicy(r.URL.Path)
		if policy == nil {
			handler.ServeHTTP(w, r)
			return
		}
		hits, err := setHit(policy, r.RemoteAddr)
		if err != nil {
			handler.ServeHTTP(w, r)
			return
		}
		if hits > policy.Limit {
			showError(policy, w, r)
		} else {
			handler.ServeHTTP(w, r)
		}
	}
}
func (rl RateLimiter) getRatePolicy(route string) *RatePolicy {
	for _, policy := range rl.Policies {
		if route == policy.Route {
			return &policy
		}
	}
	return nil
}