Example #1
0
// Returns vulcan library compatible middleware
func (r *RateLimit) NewHandler(next http.Handler) (http.Handler, error) {
	defaultRates := ratelimit.NewRateSet()
	if err := defaultRates.Add(time.Duration(r.PeriodSeconds)*time.Second, r.Requests, r.Burst); err != nil {
		return nil, err
	}
	return ratelimit.New(next, r.extract, defaultRates,
		ratelimit.ExtractRates(r.extractRates), ratelimit.Clock(r.clock))
}
Example #2
0
func makeRateExtractor(variable string) (ratelimit.RateExtractor, error) {
	if variable == "" {
		return nil, nil
	}

	if !strings.HasPrefix(variable, "request.header.") {
		return nil, fmt.Errorf("unsupported variable format: %v", variable)
	}

	header := strings.TrimPrefix(variable, "request.header.")
	if len(header) == 0 {
		return nil, fmt.Errorf("Wrong header: %s", header)
	}

	return ratelimit.RateExtractorFunc(func(r *http.Request) (*ratelimit.RateSet, error) {
		jsonString := r.Header.Get(header)
		if jsonString == "" {
			return nil, fmt.Errorf("empty rate header")
		}

		var specs []rateSpec
		if err := json.Unmarshal([]byte(jsonString), &specs); err != nil {
			return nil, err
		}

		rateSet := ratelimit.NewRateSet()
		for _, s := range specs {
			period := time.Duration(s.PeriodSeconds) * time.Second
			if s.Burst == 0 {
				s.Burst = s.Requests
			}
			if err := rateSet.Add(period, s.Requests, s.Burst); err != nil {
				return nil, err
			}
		}
		return rateSet, nil
	}), nil
}