func limitPolicy()

in lib/limit.go [433:494]


func limitPolicy(h http.Header, prefix string, canonical, delta bool, window time.Duration, burst int) map[string]interface{} {
	get := getNonCanonical
	if canonical {
		get = http.Header.Get
	}
	limitKey := prefix + "-Limit"
	limit := get(h, limitKey)
	remainingKey := prefix + "-Remaining"
	remaining := get(h, remainingKey)
	resetKey := prefix + "-Reset"
	reset := get(h, resetKey)
	m := map[string]interface{}{
		"headers": fmt.Sprintf("%s=%q %s=%q %s=%q",
			limitKey, limit, remainingKey, remaining, resetKey, reset),
	}
	if limit == "" || remaining == "" || reset == "" {
		return m
	}
	lim, err := strconv.ParseFloat(limit, 64)
	if err != nil {
		m["error"] = err.Error()
		return m
	}
	rem, err := strconv.ParseFloat(remaining, 64)
	if err != nil {
		m["error"] = err.Error()
		return m
	}

	var (
		per       float64
		resetTime time.Time
	)
	if d, err := strconv.ParseInt(reset, 10, 64); err == nil {
		if delta {
			per = float64(d)
			resetTime = time.Now().Add(time.Duration(d) * time.Second)
		} else {
			resetTime = time.Unix(d, 0)
			per = time.Until(resetTime).Seconds()
		}
	} else if t, err := time.Parse(http.TimeFormat, reset); err == nil {
		per = time.Until(t).Seconds()
		resetTime = t
	} else if t, err := time.Parse(time.RFC1123, reset); err == nil {
		per = time.Until(t).Seconds()
		resetTime = t
	} else {
		m["error"] = fmt.Sprintf("could not parse %q as number or timestamp", reset)
		return m
	}
	per *= window.Seconds()

	m["next"] = rate.Limit(lim / window.Seconds())
	m["rate"] = rate.Limit(rem / per)
	if burst < 1 {
		burst = 1
	}
	m["burst"] = burst
	m["reset"] = resetTime.UTC()
	return m
}