This is likely related to rewrite ^/([0-9]+)$ /blank.php?id=$1 last;
directive. nginx documentation states:
last
stops processing the current set of ngx_http_rewrite_module directives and starts a search for a new location matching the changed URI;
It can be that the rewrite
is processed before limit_req
in nginx, therefore nginx starts to process /blank.php
and since there is no location
block matching this request, no limit is assigned.
If this is the reason for limit not working, then getting around it is somewhat complex. location
blocks only match the URL path without the query arguments. So, you would need to have:
location /blank.php {
limit_reqzone=limit burst=3;
# PHP processing directives from "location ~ \.php$" block
}
However, this would match all requests to blank.php
. If you want to restrict matching to requests with only id
query argument, you need a more complex setup:
http {
# If there is "id" argument in query arguments and it is a number, use "limit" zone. By default, use "nolimit" zone.
map $arg_id $limit_zone {
~ ^[0-9]+$ limit;
default nolimit;
}
limit_req_zone $binary_remote_addr zone=limit:1m rate=10r/s;
limit_req_zone $binary_remote_addr zone=nolimit:1m rate=1000r/s;
server {
location /blank.php {
limit_req zone=$limit_zone burst=6;
# PHP processing directives from "location ~ \.php$" block
}
location /apply {
limit_req zone=limit burst=6;
}
}
I don't see a direct way to map request from rate limited / not rate limited directly.
Therefore we need to use map
to select a limit zone, and the "nolimit" zone just has such high limits that it is essentially a zone without limites.