Hi!

Attached is a patch to add r/h and r/d limit_req support.

There are at least two feature requests that i found asking for this:
- https://trac.nginx.org/nginx/ticket/68
- https://trac.nginx.org/nginx/ticket/1060

Ok?

Please consider applying.

thanks and cheers,
# HG changeset patch
# User Bernhard Reutner-Fischer <rep.dot....@gmail.com>
# Date 1518790589 -3600
#      Fri Feb 16 15:16:29 2018 +0100
# Node ID 4f5981016b6d3b4b9745f90ddf9521fa7a0d375f
# Parent  a49af443656f2b65ca5de9d8cad5594f44e18ff7
Limit req: r/h and r/d support

diff -r a49af443656f -r 4f5981016b6d src/http/modules/ngx_http_limit_req_module.c
--- a/src/http/modules/ngx_http_limit_req_module.c	Thu Feb 08 12:11:30 2018 +0300
+++ b/src/http/modules/ngx_http_limit_req_module.c	Fri Feb 16 15:16:29 2018 +0100
@@ -16,7 +16,7 @@
     u_short                      len;
     ngx_queue_t                  queue;
     ngx_msec_t                   last;
-    /* integer value, 1 corresponds to 0.001 r/s */
+    /* integer value, 1 corresponds to 0.00001 r/s */
     ngx_uint_t                   excess;
     ngx_uint_t                   count;
     u_char                       data[1];
@@ -33,7 +33,7 @@
 typedef struct {
     ngx_http_limit_req_shctx_t  *sh;
     ngx_slab_pool_t             *shpool;
-    /* integer value, 1 corresponds to 0.001 r/s */
+    /* integer value, 1 corresponds to 0.00001 r/s */
     ngx_uint_t                   rate;
     ngx_http_complex_value_t     key;
     ngx_http_limit_req_node_t   *node;
@@ -42,7 +42,7 @@
 
 typedef struct {
     ngx_shm_zone_t              *shm_zone;
-    /* integer value, 1 corresponds to 0.001 r/s */
+    /* integer value, 1 corresponds to 0.00001 r/s */
     ngx_uint_t                   burst;
     ngx_uint_t                   nodelay; /* unsigned  nodelay:1 */
 } ngx_http_limit_req_limit_t;
@@ -213,7 +213,7 @@
 
         ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "limit_req[%ui]: %i %ui.%03ui",
-                       n, rc, excess / 1000, excess % 1000);
+                       n, rc, excess / 100000, excess % 100000);
 
         if (rc != NGX_AGAIN) {
             break;
@@ -231,7 +231,7 @@
         if (rc == NGX_BUSY) {
             ngx_log_error(lrcf->limit_log_level, r->connection->log, 0,
                           "limiting requests, excess: %ui.%03ui by zone \"%V\"",
-                          excess / 1000, excess % 1000,
+                          excess / 100000, excess % 100000,
                           &limit->shm_zone->shm.name);
         }
 
@@ -268,7 +268,7 @@
 
     ngx_log_error(lrcf->delay_log_level, r->connection->log, 0,
                   "delaying request, excess: %ui.%03ui, by zone \"%V\"",
-                  excess / 1000, excess % 1000, &limit->shm_zone->shm.name);
+                  excess / 100000, excess % 100000, &limit->shm_zone->shm.name);
 
     if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -398,8 +398,9 @@
             ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
 
             ms = (ngx_msec_int_t) (now - lr->last);
+            ms = ngx_abs(ms);
 
-            excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
+            excess = lr->excess - ctx->rate * ms * 100 / 100000 + 100000;
 
             if (excess < 0) {
                 excess = 0;
@@ -493,7 +494,7 @@
 
     } else {
         ctx = (*limit)->shm_zone->data;
-        max_delay = excess * 1000 / ctx->rate;
+        max_delay = excess * 100000 / ctx->rate;
     }
 
     while (n--) {
@@ -508,8 +509,9 @@
 
         now = ngx_current_msec;
         ms = (ngx_msec_int_t) (now - lr->last);
+        ms = ngx_abs(ms);
 
-        excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
+        excess = lr->excess - ctx->rate * ms * 100 / 100000 + 100000;
 
         if (excess < 0) {
             excess = 0;
@@ -527,7 +529,7 @@
             continue;
         }
 
-        delay = excess * 1000 / ctx->rate;
+        delay = excess * 100000 / ctx->rate;
 
         if (delay > max_delay) {
             max_delay = delay;
@@ -535,7 +537,7 @@
             *limit = &limits[n];
         }
     }
-
+    max_delay /= 100;
     return max_delay;
 }
 
@@ -587,7 +589,7 @@
                 return;
             }
 
-            excess = lr->excess - ctx->rate * ms / 1000;
+            excess = lr->excess - ctx->rate * ms * 100 / 100000;
 
             if (excess > 0) {
                 return;
@@ -801,6 +803,14 @@
             } else if (ngx_strncmp(p, "r/m", 3) == 0) {
                 scale = 60;
                 len -= 3;
+
+            } else if (ngx_strncmp(p, "r/h", 3) == 0) {
+                scale = 60 * 60;
+                len -= 3;
+
+            } else if (ngx_strncmp(p, "r/d", 3) == 0) {
+                scale = 60 * 60 * 24;
+                len -= 3;
             }
 
             rate = ngx_atoi(value[i].data + 5, len - 5);
@@ -825,7 +835,11 @@
         return NGX_CONF_ERROR;
     }
 
-    ctx->rate = rate * 1000 / scale;
+    ctx->rate = rate * 100000 / scale;
+    if (ctx->rate < 1) {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid rate \"%ui\"", rate);
+        return NGX_CONF_ERROR;
+    }
 
     shm_zone = ngx_shared_memory_add(cf, &name, size,
                                      &ngx_http_limit_req_module);
@@ -934,7 +948,7 @@
     }
 
     limit->shm_zone = shm_zone;
-    limit->burst = burst * 1000;
+    limit->burst = burst * 100000;
     limit->nodelay = nodelay;
 
     return NGX_CONF_OK;
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Reply via email to