in lib/limit.go [196:240]
func OktaRateLimit(h http.Header, window time.Duration) map[string]interface{} {
limit := h.Get("X-Rate-Limit-Limit")
remaining := h.Get("X-Rate-Limit-Remaining")
reset := h.Get("X-Rate-Limit-Reset")
if limit == "" || remaining == "" || reset == "" {
return map[string]interface{}{
"headers": fmt.Sprintf("X-Rate-Limit-Limit=%q X-Rate-Limit-Remaining=%q X-Rate-Limit-Reset=%q",
limit, remaining, reset),
}
}
lim, err := strconv.ParseFloat(limit, 64)
if err != nil {
return map[string]interface{}{
"headers": fmt.Sprintf("X-Rate-Limit-Limit=%q X-Rate-Limit-Remaining=%q X-Rate-Limit-Reset=%q",
limit, remaining, reset),
"error": err.Error(),
}
}
rem, err := strconv.ParseFloat(remaining, 64)
if err != nil {
return map[string]interface{}{
"headers": fmt.Sprintf("X-Rate-Limit-Limit=%q X-Rate-Limit-Remaining=%q X-Rate-Limit-Reset=%q",
limit, remaining, reset),
"error": err.Error(),
}
}
rst, err := strconv.ParseInt(reset, 10, 64)
if err != nil {
return map[string]interface{}{
"headers": fmt.Sprintf("X-Rate-Limit-Limit=%q X-Rate-Limit-Remaining=%q X-Rate-Limit-Reset=%q",
limit, remaining, reset),
"error": err.Error(),
}
}
resetTime := time.Unix(rst, 0)
per := time.Until(resetTime).Seconds()
return map[string]interface{}{
"headers": fmt.Sprintf("X-Rate-Limit-Limit=%q X-Rate-Limit-Remaining=%q X-Rate-Limit-Reset=%q",
limit, remaining, reset),
"rate": rate.Limit(rem / per),
"next": rate.Limit(lim / window.Seconds()),
"burst": 1, // Be conservative here; the docs don't exactly specify burst rates.
"reset": resetTime.UTC(),
}
}