nginx set remaining count for limit_req in X-RateLimit-Remaining header nginx set remaining count for limit_req in X-RateLimit-Remaining header nginx nginx

nginx set remaining count for limit_req in X-RateLimit-Remaining header


I would say that this isn't possible with the upstream version of nginx.

You can find the documentation for the limit_req directive through http://nginx.org/r/limit_req, which redirects to http://nginx.org/docs/http/ngx_http_limit_req_module.html#limit_req, which conclusively shows that the module doesn't have any known variables within it.

Looking at http://ngx.su/src/http/modules/ngx_http_limit_req_module.c confirms the conjecture.

Another option is to look at http://nginx.org/docs/varindex.html, which lists all the variables — looking for limit will only get you to $limit_rate, which is an unrelated variable.


P.S. Consider that the limit_req is done through a leaky bucket method.

Without going into further details or making stuff up (the wikipedia article is huge!), I'd guess that it may not be entirely trivial to present this information to the end user in a consistent and actionable manner.


Just like @cnst's answer, there is no an approprivate varible to save the value you want, if you really want the message, you can implement a lua function to save this message.The nginx config would like this:

http {    limit_req_zone $binary_remote_addr zone=login:10m rate=2r/s;    limit_req_status 429;    limit_conn_status 429;    server {        listen       80;        server_name  [removed];        set $x-ratelimit-ramaining 0;        set $x-ratelimit-reset 0;        access_by_lua_file your_file_name.lua;        location / {            limit_req zone=limit nodelay;            proxy_pass http://reverse-proxy-example;            add_header  X-RateLimit-Remaining $x-rate-limit-remaining;            add_header  X-RateLimit-Reset $x-ratelimit-reset;        }}

thus, each request will trigger the lua script, and you can update the variables $x-rate-limit-remaining $x-ratelimit-reset in your lua function.


Packngo from Packet has a function that might be a good fit for what you need to do.

Sample from packngo:

func (r *Response) populateRate() {    // parse the rate limit headers and populate Response.Rate    if limit := r.Header.Get(headerRateLimit); limit != "" {        r.Rate.RequestLimit, _ = strconv.Atoi(limit)    }    if remaining := r.Header.Get(headerRateRemaining); remaining != "" {        r.Rate.RequestsRemaining, _ = strconv.Atoi(remaining)    }    if reset := r.Header.Get(headerRateReset); reset != "" {        if v, _ := strconv.ParseInt(reset, 10, 64); v != 0 {            r.Rate.Reset = Timestamp{time.Unix(v, 0)}        }    }}