<div dir="ltr">Hi,<div>  thank you for your patch. I will look at it. Why did not you merge him to repository?</div><div><br></div><div>Míra</div></div><br><div class="gmail_quote"><div dir="ltr">po 27. 8. 2018 v 18:00 odesílatel Ruslan Ermilov <<a href="mailto:ru@nginx.com">ru@nginx.com</a>> napsal:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Also, Maxim Dounin reminded me that I prepared the patch set<br>
to add variables support to limit_rate_after roughly a year ago,<br>
which I have successfully forgotten now.  Here it is, for your<br>
consideration, in the state it was a year ago.<br>
<br>
# HG changeset patch<br>
# Parent  e3723f2a11b7ec1c196d59c331739bc21d9d9afd<br>
Added post processing to ngx_http_set_complex_value_slot().<br>
<br>
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c<br>
--- a/src/http/ngx_http_script.c<br>
+++ b/src/http/ngx_http_script.c<br>
@@ -214,6 +214,7 @@ ngx_http_set_complex_value_slot(ngx_conf<br>
     char  *p = conf;<br>
<br>
     ngx_str_t                          *value;<br>
+    ngx_conf_post_t                    *post;<br>
     ngx_http_complex_value_t          **cv;<br>
     ngx_http_compile_complex_value_t    ccv;<br>
<br>
@@ -240,6 +241,11 @@ ngx_http_set_complex_value_slot(ngx_conf<br>
         return NGX_CONF_ERROR;<br>
     }<br>
<br>
+    if (cmd->post) {<br>
+        post = cmd->post;<br>
+        return post->post_handler(cf, post, *cv);<br>
+    }<br>
+<br>
     return NGX_CONF_OK;<br>
 }<br>
<br>
# HG changeset patch<br>
# Parent  2b522e0bcd9fd218026f923f58a1b8bfed864b2a<br>
Added size_t type support to ngx_http_set_complex_value_slot().<br>
<br>
If a complex value is expected to be size_t, and the compiled value<br>
is constant, the ngx_http_complex_value_size_p post handler will<br>
remember the constant size_t value.<br>
<br>
The value is accessed through ngx_http_complex_value_size() which<br>
either returns the remembered constant or evaluates the expression<br>
and parses it as size_t.<br>
<br>
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c<br>
--- a/src/http/ngx_http_script.c<br>
+++ b/src/http/ngx_http_script.c<br>
@@ -10,6 +10,13 @@<br>
 #include <ngx_http.h><br>
<br>
<br>
+static char *ngx_http_complex_value_set_size(ngx_conf_t *cf, void *post,<br>
+    void *data);<br>
+<br>
+ngx_conf_post_handler_pt  ngx_http_complex_value_size_p =<br>
+    ngx_http_complex_value_set_size;<br>
+<br>
+<br>
 static ngx_int_t ngx_http_script_init_arrays(ngx_http_script_compile_t *sc);<br>
 static ngx_int_t ngx_http_script_done(ngx_http_script_compile_t *sc);<br>
 static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc,<br>
@@ -105,6 +112,25 @@ ngx_http_complex_value(ngx_http_request_<br>
<br>
<br>
 ngx_int_t<br>
+ngx_http_complex_value_size(ngx_http_request_t *r,<br>
+    ngx_http_complex_value_t *val, ngx_str_t *value, size_t *size)<br>
+{<br>
+    if (val->lengths == NULL) {<br>
+        *size = val->u.size;<br>
+        return NGX_OK;<br>
+    }<br>
+<br>
+    if (ngx_http_complex_value(r, val, value) != NGX_OK) {<br>
+        return NGX_ERROR;<br>
+    }<br>
+<br>
+    *size = ngx_parse_size(value);<br>
+<br>
+    return NGX_OK;<br>
+}<br>
+<br>
+<br>
+ngx_int_t<br>
 ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)<br>
 {<br>
     ngx_str_t                  *v;<br>
@@ -250,6 +276,24 @@ ngx_http_set_complex_value_slot(ngx_conf<br>
 }<br>
<br>
<br>
+static char *<br>
+ngx_http_complex_value_set_size(ngx_conf_t *cf, void *post, void *data)<br>
+{<br>
+    ngx_http_complex_value_t  *cv = data;<br>
+<br>
+    if (cv->lengths) {<br>
+        return NGX_CONF_OK;<br>
+    }<br>
+<br>
+    cv->u.size = ngx_parse_size(&cv->value);<br>
+    if (cv->u.size == (size_t) NGX_ERROR) {<br>
+        return "invalid value";<br>
+    }<br>
+<br>
+    return NGX_CONF_OK;<br>
+}<br>
+<br>
+<br>
 ngx_int_t<br>
 ngx_http_test_predicates(ngx_http_request_t *r, ngx_array_t *predicates)<br>
 {<br>
diff --git a/src/http/ngx_http_script.h b/src/http/ngx_http_script.h<br>
--- a/src/http/ngx_http_script.h<br>
+++ b/src/http/ngx_http_script.h<br>
@@ -68,6 +68,10 @@ typedef struct {<br>
     ngx_uint_t                 *flushes;<br>
     void                       *lengths;<br>
     void                       *values;<br>
+<br>
+    union {<br>
+        size_t                  size;<br>
+    } u;<br>
 } ngx_http_complex_value_t;<br>
<br>
<br>
@@ -207,6 +211,8 @@ void ngx_http_script_flush_complex_value<br>
     ngx_http_complex_value_t *val);<br>
 ngx_int_t ngx_http_complex_value(ngx_http_request_t *r,<br>
     ngx_http_complex_value_t *val, ngx_str_t *value);<br>
+ngx_int_t ngx_http_complex_value_size(ngx_http_request_t *r,<br>
+    ngx_http_complex_value_t *val, ngx_str_t *value, size_t *size);<br>
 ngx_int_t ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv);<br>
 char *ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,<br>
     void *conf);<br>
@@ -254,4 +260,7 @@ void ngx_http_script_var_code(ngx_http_s<br>
 void ngx_http_script_nop_code(ngx_http_script_engine_t *e);<br>
<br>
<br>
+extern ngx_conf_post_handler_pt  ngx_http_complex_value_size_p;<br>
+<br>
+<br>
 #endif /* _NGX_HTTP_SCRIPT_H_INCLUDED_ */<br>
# HG changeset patch<br>
# Parent  fbf2ea9783be4eeaa938bc4173dbac1149b762dc<br>
Variables support in limit_rate and limit_rate_after (ticket #293).<br>
<br>
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c<br>
--- a/src/http/ngx_http_core_module.c<br>
+++ b/src/http/ngx_http_core_module.c<br>
@@ -474,18 +474,18 @@ static ngx_command_t  ngx_http_core_comm<br>
     { ngx_string("limit_rate"),<br>
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF<br>
                         |NGX_CONF_TAKE1,<br>
-      ngx_conf_set_size_slot,<br>
+      ngx_http_set_complex_value_slot,<br>
       NGX_HTTP_LOC_CONF_OFFSET,<br>
       offsetof(ngx_http_core_loc_conf_t, limit_rate),<br>
-      NULL },<br>
+      &ngx_http_complex_value_size_p },<br>
<br>
     { ngx_string("limit_rate_after"),<br>
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF<br>
                         |NGX_CONF_TAKE1,<br>
-      ngx_conf_set_size_slot,<br>
+      ngx_http_set_complex_value_slot,<br>
       NGX_HTTP_LOC_CONF_OFFSET,<br>
       offsetof(ngx_http_core_loc_conf_t, limit_rate_after),<br>
-      NULL },<br>
+      &ngx_http_complex_value_size_p },<br>
<br>
     { ngx_string("keepalive_timeout"),<br>
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,<br>
@@ -1431,6 +1431,8 @@ ngx_http_core_content_phase(ngx_http_req<br>
 void<br>
 ngx_http_update_location_config(ngx_http_request_t *r)<br>
 {<br>
+    size_t                     limit_rate;<br>
+    ngx_str_t                  val;<br>
     ngx_http_core_loc_conf_t  *clcf;<br>
<br>
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);<br>
@@ -1500,8 +1502,18 @@ ngx_http_update_location_config(ngx_http<br>
         r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;<br>
     }<br>
<br>
-    if (r->limit_rate == 0) {<br>
-        r->limit_rate = clcf->limit_rate;<br>
+    if (r->limit_rate == 0<br>
+        && clcf->limit_rate<br>
+        && ngx_http_complex_value_size(r, clcf->limit_rate, &val, &limit_rate)<br>
+           == NGX_OK)<br>
+    {<br>
+        if (limit_rate != (size_t) NGX_ERROR) {<br>
+            r->limit_rate = limit_rate;<br>
+<br>
+        } else if (val.len) {<br>
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,<br>
+                          "invalid \"limit_rate\" value \"%V\"", &val);<br>
+        }<br>
     }<br>
<br>
     if (clcf->handler) {<br>
@@ -3567,6 +3579,8 @@ ngx_http_core_create_loc_conf(ngx_conf_t<br>
      *     clcf->exact_match = 0;<br>
      *     clcf->auto_redirect = 0;<br>
      *     clcf->alias = 0;<br>
+     *     clcf->limit_rate = NULL;<br>
+     *     clcf->limit_rate_after = NULL;<br>
      *     clcf->gzip_proxied = 0;<br>
      *     clcf->keepalive_disable = 0;<br>
      */<br>
@@ -3596,8 +3610,6 @@ ngx_http_core_create_loc_conf(ngx_conf_t<br>
     clcf->send_timeout = NGX_CONF_UNSET_MSEC;<br>
     clcf->send_lowat = NGX_CONF_UNSET_SIZE;<br>
     clcf->postpone_output = NGX_CONF_UNSET_SIZE;<br>
-    clcf->limit_rate = NGX_CONF_UNSET_SIZE;<br>
-    clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;<br>
     clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;<br>
     clcf->keepalive_header = NGX_CONF_UNSET;<br>
     clcf->keepalive_requests = NGX_CONF_UNSET_UINT;<br>
@@ -3785,6 +3797,14 @@ ngx_http_core_merge_loc_conf(ngx_conf_t <br>
     ngx_conf_merge_msec_value(conf->client_body_timeout,<br>
                               prev->client_body_timeout, 60000);<br>
<br>
+    if (conf->limit_rate == NULL) {<br>
+        conf->limit_rate = prev->limit_rate;<br>
+    }<br>
+<br>
+    if (conf->limit_rate_after == NULL) {<br>
+        conf->limit_rate_after = prev->limit_rate_after;<br>
+    }<br>
+<br>
     ngx_conf_merge_bitmask_value(conf->keepalive_disable,<br>
                               prev->keepalive_disable,<br>
                               (NGX_CONF_BITMASK_SET<br>
@@ -3823,9 +3843,6 @@ ngx_http_core_merge_loc_conf(ngx_conf_t <br>
     ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);<br>
     ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,<br>
                               1460);<br>
-    ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);<br>
-    ngx_conf_merge_size_value(conf->limit_rate_after, prev->limit_rate_after,<br>
-                              0);<br>
     ngx_conf_merge_msec_value(conf->keepalive_timeout,<br>
                               prev->keepalive_timeout, 75000);<br>
     ngx_conf_merge_sec_value(conf->keepalive_header,<br>
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h<br>
--- a/src/http/ngx_http_core_module.h<br>
+++ b/src/http/ngx_http_core_module.h<br>
@@ -358,11 +358,12 @@ struct ngx_http_core_loc_conf_s {<br>
     size_t        client_body_buffer_size; /* client_body_buffer_size */<br>
     size_t        send_lowat;              /* send_lowat */<br>
     size_t        postpone_output;         /* postpone_output */<br>
-    size_t        limit_rate;              /* limit_rate */<br>
-    size_t        limit_rate_after;        /* limit_rate_after */<br>
     size_t        sendfile_max_chunk;      /* sendfile_max_chunk */<br>
     size_t        read_ahead;              /* read_ahead */<br>
<br>
+    ngx_http_complex_value_t  *limit_rate; /* limit_rate */<br>
+    ngx_http_complex_value_t  *limit_rate_after;<br>
+<br>
     ngx_msec_t    client_body_timeout;     /* client_body_timeout */<br>
     ngx_msec_t    send_timeout;            /* send_timeout */<br>
     ngx_msec_t    keepalive_timeout;       /* keepalive_timeout */<br>
diff --git a/src/http/ngx_http_write_filter_module.c b/src/http/ngx_http_write_filter_module.c<br>
--- a/src/http/ngx_http_write_filter_module.c<br>
+++ b/src/http/ngx_http_write_filter_module.c<br>
@@ -48,6 +48,8 @@ ngx_int_t<br>
 ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)<br>
 {<br>
     off_t                      size, sent, nsent, limit;<br>
+    size_t                     limit_rate_after;<br>
+    ngx_str_t                  val;<br>
     ngx_uint_t                 last, flush, sync;<br>
     ngx_msec_t                 delay;<br>
     ngx_chain_t               *cl, *ln, **ll, *chain;<br>
@@ -219,8 +221,20 @@ ngx_http_write_filter(ngx_http_request_t<br>
     }<br>
<br>
     if (r->limit_rate) {<br>
-        if (r->limit_rate_after == 0) {<br>
-            r->limit_rate_after = clcf->limit_rate_after;<br>
+        if (r->limit_rate_after == 0<br>
+            && clcf->limit_rate_after<br>
+            && ngx_http_complex_value_size(r, clcf->limit_rate_after, &val,<br>
+                                           &limit_rate_after)<br>
+               == NGX_OK)<br>
+        {<br>
+            if (limit_rate_after != (size_t) NGX_ERROR) {<br>
+                r->limit_rate_after = limit_rate_after;<br>
+<br>
+            } else if (val.len) {<br>
+                ngx_log_error(NGX_LOG_ERR, c->log, 0,<br>
+                              "invalid \"limit_rate_after\" value \"%V\"",<br>
+                              &val);<br>
+            }<br>
         }<br>
<br>
         limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1)<br>
_______________________________________________<br>
nginx-devel mailing list<br>
<a href="mailto:nginx-devel@nginx.org" target="_blank">nginx-devel@nginx.org</a><br>
<a href="http://mailman.nginx.org/mailman/listinfo/nginx-devel" rel="noreferrer" target="_blank">http://mailman.nginx.org/mailman/listinfo/nginx-devel</a><br>
</blockquote></div>