httprate icon indicating copy to clipboard operation
httprate copied to clipboard

Allows limiter headers to be written via setting instead of sending them at all times

Open go-aegian opened this issue 3 years ago • 7 comments

The headers output by this middleware "X-RateLimit-Limit", "X-RateLimit-Remaining", "X-RateLimit-Reset", "Retry-After" should be output depending on a configuration for it.

go-aegian avatar Jun 14 '22 19:06 go-aegian

These headings are common practice. You'd rather have an option to turn them off.

micronull avatar Jan 27 '23 06:01 micronull

+1 for a configuration option to disable adding X-RateLimit-* headers and Retry-After header, as users may wish to only respond with these under certain circumstances.

mwodrich avatar Jan 28 '23 04:01 mwodrich

Sorry but I don’t understand the request of this ticket.

pkieltyka avatar Jan 28 '23 13:01 pkieltyka

These headers are very useful for coordinating rates with a cooperative client that just needs to bound resource usage over time, but in a scenario where the rate limits are set to limit the impact of malicious actors, I don't believe it is valuable or appropriate to give them any information about the state or configuration of the rate limiter.

mwodrich avatar Feb 06 '23 20:02 mwodrich

... but in a scenario where the rate limits are set to limit the impact of malicious actors, I don't believe it is valuable or appropriate to give them any information about the state or configuration of the rate limiter.

I agree with this.

benstigsen avatar Feb 10 '23 16:02 benstigsen

These headers are a de-facto standard for rate-limiting (see https://www.ietf.org/archive/id/draft-ietf-httpapi-ratelimit-headers-07.html draft). Let's keep them as is.

https://github.com/go-chi/httprate/blob/3327e65758bd2f38762b8e8760040d77ebf5f919/limiter.go#L99-L101

If you need to remove the headers for some reason, you can write a middleware that explicitly removes the response headers. Something like

func RemoveHeadersMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Unset headers set by previous middleware before handler writes to response body.
		w.Header().Del("X-RateLimit-Limit")
		w.Header().Del("X-RateLimit-Remaining")
		w.Header().Del("X-RateLimit-Reset")

		next.ServeHTTP(w, r)
	})
}

VojtechVitek avatar Feb 27 '24 10:02 VojtechVitek

I've just noticed this unlinked PR: https://github.com/go-chi/httprate/pull/16. Reopening.

VojtechVitek avatar Feb 27 '24 12:02 VojtechVitek

Implemented in https://github.com/go-chi/httprate/pull/31.

You can now omit all headers via:

httprate.Limit(
	1000,
	time.Minute,
	httprate.WithResponseHeaders(httprate.ResponseHeaders{}),
)

You can also customize or omit individual headers:

httprate.Limit(
            1000,
            time.Minute,
            httprate.WithResponseHeaders(httprate.ResponseHeaders{
                    Limit:      "", // omit
                    Remaining:  "", // omit
                    Increment:  "", // omit
                    Reset:      "X-RateLimit-Reset",
                    RetryAfter: "Retry-After",
            }),
    )

VojtechVitek avatar Jul 24 '24 13:07 VojtechVitek