Reputation: 136
I want to impose a request limit for uncached content on my NGINX reverse proxy. I have multiple locations defined and content can get cached or won't get cached due to other rules. So I can not set a request limit just for a location, I have to handle this differently.
According to the documentation in https://www.nginx.com/blog/rate-limiting-nginx/#Advanced-Configuration-Examples, I can use the map feature in order to impose a request limit. So I tried this and created following configuration snippet:
map $upstream_cache_status $limit {
default 1;
MISS 1;
HIT 0;
}
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;
So in order to test my map first, I have added following to my location:
add_header X-Test $limit;
And I see that it works! Every resource that is cached ($upstream_cache_status = HIT), $limit seems to be 0. Every uncached content ($upstream_cache_status = MISS), $limit is 1.
Now comes the weird behaviour. As soon as I add limit_req zone=req_zone burst=10 nodelay;
into my location, $limit seems to be stuck at 1, no matter if the $upstream_cache_status is HIT or MISS.
The location looks like this:
location ~* \.(jpg|jpeg|png|gif|webp|svg|svgz|ico|pdf|doc|docx|xls|xlsx|csv|zip|gz|woff|woff2|ttf|otf|eot)$ {
limit_req zone=req_zone burst=10 nodelay;
[...]
add_header X-Test $limit;
[...]
}
Is this a NGINX bug or am I missing something here? NGINX version is 1.20.1 on AlmaLinux 8.5.
Upvotes: 2
Views: 248
Reputation: 46
Rate limiting works first, on request phase. Caching works later, on content phase (guess).
So, when limiter works, there is no information about cache status yet.
Upvotes: 2