Discussion:
limit_rate_after support variables
Miroslav Novy
2018-08-14 08:22:14 UTC
Permalink
# HG changeset patch
# User Miroslav NovÜ <***@gmail.com>
# Date 1534234559 0
# Tue Aug 14 08:15:59 2018 +0000
# Node ID 1a8327b50f7844cbe68226f54de60632189327f4
# Parent 70c6b08973a02551612da4a4273757dc77c70ae2
limit_rate_after support variables

Example of use:
location / {
root /var/www/default/;
index index.html index.htm;

set $my_limit_rate_after 2m;

limit_rate_after $my_limit_rate_after;
limit_rate 2k;

access_by_lua_block {
ngx.var.my_limit_rate_after = '10m'
}

}

diff -r 70c6b08973a0 -r 1a8327b50f78 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Fri Aug 10 21:54:46 2018 +0300
+++ b/src/http/ngx_http_core_module.c Tue Aug 14 08:15:59 2018 +0000
@@ -487,7 +487,7 @@
{ ngx_string("limit_rate_after"),

NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
+ ngx_http_set_complex_value_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
NULL },
@@ -3364,6 +3364,7 @@
* clcf->alias = 0;
* clcf->gzip_proxied = 0;
* clcf->keepalive_disable = 0;
+ * clcf->limit_rate_after = NULL;
*/

clcf->client_max_body_size = NGX_CONF_UNSET;
@@ -3393,7 +3394,6 @@
clcf->send_lowat = NGX_CONF_UNSET_SIZE;
clcf->postpone_output = NGX_CONF_UNSET_SIZE;
clcf->limit_rate = NGX_CONF_UNSET_SIZE;
- clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
clcf->keepalive_header = NGX_CONF_UNSET;
clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
@@ -3623,8 +3623,8 @@
ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
1460);
ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
- ngx_conf_merge_size_value(conf->limit_rate_after,
prev->limit_rate_after,
- 0);
+ ngx_conf_merge_ptr_value(conf->limit_rate_after,
prev->limit_rate_after,
+ NULL);
ngx_conf_merge_msec_value(conf->keepalive_timeout,
prev->keepalive_timeout, 75000);
ngx_conf_merge_sec_value(conf->keepalive_header,
diff -r 70c6b08973a0 -r 1a8327b50f78 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h Fri Aug 10 21:54:46 2018 +0300
+++ b/src/http/ngx_http_core_module.h Tue Aug 14 08:15:59 2018 +0000
@@ -351,7 +351,7 @@
size_t send_lowat; /* send_lowat */
size_t postpone_output; /* postpone_output */
size_t limit_rate; /* limit_rate */
- size_t limit_rate_after; /* limit_rate_after */
+ ngx_http_complex_value_t *limit_rate_after; /*
limit_rate_after */
size_t sendfile_max_chunk; /* sendfile_max_chunk */
size_t read_ahead; /* read_ahead */
size_t subrequest_output_buffer_size;
diff -r 70c6b08973a0 -r 1a8327b50f78 src/http/ngx_http_write_filter_module.c
--- a/src/http/ngx_http_write_filter_module.c Fri Aug 10 21:54:46 2018 +0300
+++ b/src/http/ngx_http_write_filter_module.c Tue Aug 14 08:15:59 2018 +0000
@@ -220,7 +220,26 @@

if (r->limit_rate) {
if (r->limit_rate_after == 0) {
- r->limit_rate_after = clcf->limit_rate_after;
+ r->limit_rate_after = 0;
+
+ if (clcf->limit_rate_after != NULL) {
+ ngx_str_t res;
+ size_t st;
+
+ if (ngx_http_complex_value(r, clcf->limit_rate_after, &res)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ st = ngx_parse_size(&res);
+ if (st != (size_t) NGX_ERROR) {
+ r->limit_rate_after = st;
+ } else {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+ "limit_rate_after has bad value");
+ }
+ }
}

limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1)
Ruslan Ermilov
2018-08-27 11:28:47 UTC
Permalink
Hi,
Post by Miroslav Novy
# HG changeset patch
# Date 1534234559 0
# Tue Aug 14 08:15:59 2018 +0000
# Node ID 1a8327b50f7844cbe68226f54de60632189327f4
# Parent 70c6b08973a02551612da4a4273757dc77c70ae2
limit_rate_after support variables
location / {
root /var/www/default/;
index index.html index.htm;
set $my_limit_rate_after 2m;
limit_rate_after $my_limit_rate_after;
limit_rate 2k;
access_by_lua_block {
ngx.var.my_limit_rate_after = '10m'
}
}
diff -r 70c6b08973a0 -r 1a8327b50f78 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Fri Aug 10 21:54:46 2018 +0300
+++ b/src/http/ngx_http_core_module.c Tue Aug 14 08:15:59 2018 +0000
@@ -487,7 +487,7 @@
{ ngx_string("limit_rate_after"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
+ ngx_http_set_complex_value_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
NULL },
@@ -3364,6 +3364,7 @@
* clcf->alias = 0;
* clcf->gzip_proxied = 0;
* clcf->keepalive_disable = 0;
+ * clcf->limit_rate_after = NULL;
*/
clcf->client_max_body_size = NGX_CONF_UNSET;
@@ -3393,7 +3394,6 @@
clcf->send_lowat = NGX_CONF_UNSET_SIZE;
clcf->postpone_output = NGX_CONF_UNSET_SIZE;
clcf->limit_rate = NGX_CONF_UNSET_SIZE;
- clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
clcf->keepalive_header = NGX_CONF_UNSET;
clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
@@ -3623,8 +3623,8 @@
ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
1460);
ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
- ngx_conf_merge_size_value(conf->limit_rate_after,
prev->limit_rate_after,
- 0);
+ ngx_conf_merge_ptr_value(conf->limit_rate_after,
prev->limit_rate_after,
+ NULL);
This won't work because create_loc_conf() initialized clcf->limit_rate_after
to NULL instead of NGX_CONF_UNSET_PTR. I suggest using a simple "== NULL"
check here.
Post by Miroslav Novy
ngx_conf_merge_msec_value(conf->keepalive_timeout,
prev->keepalive_timeout, 75000);
ngx_conf_merge_sec_value(conf->keepalive_header,
diff -r 70c6b08973a0 -r 1a8327b50f78 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h Fri Aug 10 21:54:46 2018 +0300
+++ b/src/http/ngx_http_core_module.h Tue Aug 14 08:15:59 2018 +0000
@@ -351,7 +351,7 @@
size_t send_lowat; /* send_lowat */
size_t postpone_output; /* postpone_output */
size_t limit_rate; /* limit_rate */
- size_t limit_rate_after; /* limit_rate_after */
+ ngx_http_complex_value_t *limit_rate_after; /*
limit_rate_after */
size_t sendfile_max_chunk; /* sendfile_max_chunk */
size_t read_ahead; /* read_ahead */
size_t subrequest_output_buffer_size;
diff -r 70c6b08973a0 -r 1a8327b50f78 src/http/ngx_http_write_filter_module.c
--- a/src/http/ngx_http_write_filter_module.c Fri Aug 10 21:54:46 2018 +0300
+++ b/src/http/ngx_http_write_filter_module.c Tue Aug 14 08:15:59 2018 +0000
@@ -220,7 +220,26 @@
if (r->limit_rate) {
if (r->limit_rate_after == 0) {
- r->limit_rate_after = clcf->limit_rate_after;
+ r->limit_rate_after = 0;
This assignment is pointless.
Post by Miroslav Novy
+
+ if (clcf->limit_rate_after != NULL) {
You can omit the "!= NULL" part of the check.
Post by Miroslav Novy
+ ngx_str_t res;
+ size_t st;
There are style issues here, please see
http://nginx.org/en/docs/dev/development_guide.html#code_style

Also, I suggest renaming "st" to "s" here, and changing its type to
ssize_t.
Post by Miroslav Novy
+
+ if (ngx_http_complex_value(r, clcf->limit_rate_after, &res)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ st = ngx_parse_size(&res);
+ if (st != (size_t) NGX_ERROR) {
+ r->limit_rate_after = st;
+ } else {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+ "limit_rate_after has bad value");
+ }
+ }
}
limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1)
P.S. Please find another MUA that doesn't break text attachments.
--
Ruslan Ermilov
Assume stupidity not malice
Miroslav Novy
2018-08-27 13:37:04 UTC
Permalink
Hello,
thank you for your comments. I'm sending their incorporation.

Best regards
Míra

diff -r 70c6b08973a0 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Fri Aug 10 21:54:46 2018 +0300
+++ b/src/http/ngx_http_core_module.c Mon Aug 27 13:31:45 2018 +0000
@@ -487,7 +487,7 @@
{ ngx_string("limit_rate_after"),

NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
+ ngx_http_set_complex_value_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
NULL },
@@ -3364,6 +3364,7 @@
* clcf->alias = 0;
* clcf->gzip_proxied = 0;
* clcf->keepalive_disable = 0;
+ * clcf->limit_rate_after = NULL;
*/

clcf->client_max_body_size = NGX_CONF_UNSET;
@@ -3393,7 +3394,6 @@
clcf->send_lowat = NGX_CONF_UNSET_SIZE;
clcf->postpone_output = NGX_CONF_UNSET_SIZE;
clcf->limit_rate = NGX_CONF_UNSET_SIZE;
- clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
clcf->keepalive_header = NGX_CONF_UNSET;
clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
@@ -3623,8 +3623,11 @@
ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
1460);
ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
- ngx_conf_merge_size_value(conf->limit_rate_after,
prev->limit_rate_after,
- 0);
+
+ if (conf->limit_rate_after == NULL) {
+ conf->limit_rate_after = prev->limit_rate_after;
+ }
+
ngx_conf_merge_msec_value(conf->keepalive_timeout,
prev->keepalive_timeout, 75000);
ngx_conf_merge_sec_value(conf->keepalive_header,
diff -r 70c6b08973a0 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h Fri Aug 10 21:54:46 2018 +0300
+++ b/src/http/ngx_http_core_module.h Mon Aug 27 13:31:45 2018 +0000
@@ -351,7 +351,7 @@
size_t send_lowat; /* send_lowat */
size_t postpone_output; /* postpone_output */
size_t limit_rate; /* limit_rate */
- size_t limit_rate_after; /* limit_rate_after */
+ ngx_http_complex_value_t *limit_rate_after; /*
limit_rate_after */
size_t sendfile_max_chunk; /* sendfile_max_chunk */
size_t read_ahead; /* read_ahead */
size_t subrequest_output_buffer_size;
diff -r 70c6b08973a0 src/http/ngx_http_write_filter_module.c
--- a/src/http/ngx_http_write_filter_module.c Fri Aug 10 21:54:46 2018 +0300
+++ b/src/http/ngx_http_write_filter_module.c Mon Aug 27 13:31:45 2018 +0000
@@ -220,7 +220,24 @@

if (r->limit_rate) {
if (r->limit_rate_after == 0) {
- r->limit_rate_after = clcf->limit_rate_after;
+ if (clcf->limit_rate_after) {
+ ngx_str_t res;
+ ssize_t s;
+
+ if (ngx_http_complex_value(r, clcf->limit_rate_after, &res)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ s = ngx_parse_size(&res);
+ if (s == NGX_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+ "limit_rate_after has bad value");
+ } else {
+ r->limit_rate_after = s;
+ }
+ }
}

limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1)
Post by Miroslav Novy
Hi,
Post by Miroslav Novy
# HG changeset patch
# Date 1534234559 0
# Tue Aug 14 08:15:59 2018 +0000
# Node ID 1a8327b50f7844cbe68226f54de60632189327f4
# Parent 70c6b08973a02551612da4a4273757dc77c70ae2
limit_rate_after support variables
location / {
root /var/www/default/;
index index.html index.htm;
set $my_limit_rate_after 2m;
limit_rate_after $my_limit_rate_after;
limit_rate 2k;
access_by_lua_block {
ngx.var.my_limit_rate_after = '10m'
}
}
diff -r 70c6b08973a0 -r 1a8327b50f78 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Fri Aug 10 21:54:46 2018 +0300
+++ b/src/http/ngx_http_core_module.c Tue Aug 14 08:15:59 2018 +0000
@@ -487,7 +487,7 @@
{ ngx_string("limit_rate_after"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
+ ngx_http_set_complex_value_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
NULL },
@@ -3364,6 +3364,7 @@
* clcf->alias = 0;
* clcf->gzip_proxied = 0;
* clcf->keepalive_disable = 0;
+ * clcf->limit_rate_after = NULL;
*/
clcf->client_max_body_size = NGX_CONF_UNSET;
@@ -3393,7 +3394,6 @@
clcf->send_lowat = NGX_CONF_UNSET_SIZE;
clcf->postpone_output = NGX_CONF_UNSET_SIZE;
clcf->limit_rate = NGX_CONF_UNSET_SIZE;
- clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
clcf->keepalive_header = NGX_CONF_UNSET;
clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
@@ -3623,8 +3623,8 @@
ngx_conf_merge_size_value(conf->postpone_output,
prev->postpone_output,
Post by Miroslav Novy
1460);
ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
- ngx_conf_merge_size_value(conf->limit_rate_after,
prev->limit_rate_after,
- 0);
+ ngx_conf_merge_ptr_value(conf->limit_rate_after,
prev->limit_rate_after,
+ NULL);
This won't work because create_loc_conf() initialized
clcf->limit_rate_after
to NULL instead of NGX_CONF_UNSET_PTR. I suggest using a simple "== NULL"
check here.
Post by Miroslav Novy
ngx_conf_merge_msec_value(conf->keepalive_timeout,
prev->keepalive_timeout, 75000);
ngx_conf_merge_sec_value(conf->keepalive_header,
diff -r 70c6b08973a0 -r 1a8327b50f78 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h Fri Aug 10 21:54:46 2018 +0300
+++ b/src/http/ngx_http_core_module.h Tue Aug 14 08:15:59 2018 +0000
@@ -351,7 +351,7 @@
size_t send_lowat; /* send_lowat */
size_t postpone_output; /* postpone_output */
size_t limit_rate; /* limit_rate */
- size_t limit_rate_after; /* limit_rate_after */
+ ngx_http_complex_value_t *limit_rate_after; /*
limit_rate_after */
size_t sendfile_max_chunk; /* sendfile_max_chunk */
size_t read_ahead; /* read_ahead */
size_t subrequest_output_buffer_size;
diff -r 70c6b08973a0 -r 1a8327b50f78
src/http/ngx_http_write_filter_module.c
Post by Miroslav Novy
--- a/src/http/ngx_http_write_filter_module.c Fri Aug 10 21:54:46 2018
+0300
Post by Miroslav Novy
+++ b/src/http/ngx_http_write_filter_module.c Tue Aug 14 08:15:59 2018
+0000
Post by Miroslav Novy
@@ -220,7 +220,26 @@
if (r->limit_rate) {
if (r->limit_rate_after == 0) {
- r->limit_rate_after = clcf->limit_rate_after;
+ r->limit_rate_after = 0;
This assignment is pointless.
Post by Miroslav Novy
+
+ if (clcf->limit_rate_after != NULL) {
You can omit the "!= NULL" part of the check.
Post by Miroslav Novy
+ ngx_str_t res;
+ size_t st;
There are style issues here, please see
http://nginx.org/en/docs/dev/development_guide.html#code_style
Also, I suggest renaming "st" to "s" here, and changing its type to
ssize_t.
Post by Miroslav Novy
+
+ if (ngx_http_complex_value(r, clcf->limit_rate_after,
&res)
Post by Miroslav Novy
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ st = ngx_parse_size(&res);
+ if (st != (size_t) NGX_ERROR) {
+ r->limit_rate_after = st;
+ } else {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+ "limit_rate_after has bad value");
+ }
+ }
}
limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1)
P.S. Please find another MUA that doesn't break text attachments.
--
Ruslan Ermilov
Assume stupidity not malice
_______________________________________________
nginx-devel mailing list
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Ruslan Ermilov
2018-08-27 16:00:21 UTC
Permalink
Also, Maxim Dounin reminded me that I prepared the patch set
to add variables support to limit_rate_after roughly a year ago,
which I have successfully forgotten now. Here it is, for your
consideration, in the state it was a year ago.

# HG changeset patch
# Parent e3723f2a11b7ec1c196d59c331739bc21d9d9afd
Added post processing to ngx_http_set_complex_value_slot().

diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -214,6 +214,7 @@ ngx_http_set_complex_value_slot(ngx_conf
char *p = conf;

ngx_str_t *value;
+ ngx_conf_post_t *post;
ngx_http_complex_value_t **cv;
ngx_http_compile_complex_value_t ccv;

@@ -240,6 +241,11 @@ ngx_http_set_complex_value_slot(ngx_conf
return NGX_CONF_ERROR;
}

+ if (cmd->post) {
+ post = cmd->post;
+ return post->post_handler(cf, post, *cv);
+ }
+
return NGX_CONF_OK;
}

# HG changeset patch
# Parent 2b522e0bcd9fd218026f923f58a1b8bfed864b2a
Added size_t type support to ngx_http_set_complex_value_slot().

If a complex value is expected to be size_t, and the compiled value
is constant, the ngx_http_complex_value_size_p post handler will
remember the constant size_t value.

The value is accessed through ngx_http_complex_value_size() which
either returns the remembered constant or evaluates the expression
and parses it as size_t.

diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -10,6 +10,13 @@
#include <ngx_http.h>


+static char *ngx_http_complex_value_set_size(ngx_conf_t *cf, void *post,
+ void *data);
+
+ngx_conf_post_handler_pt ngx_http_complex_value_size_p =
+ ngx_http_complex_value_set_size;
+
+
static ngx_int_t ngx_http_script_init_arrays(ngx_http_script_compile_t *sc);
static ngx_int_t ngx_http_script_done(ngx_http_script_compile_t *sc);
static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc,
@@ -105,6 +112,25 @@ ngx_http_complex_value(ngx_http_request_


ngx_int_t
+ngx_http_complex_value_size(ngx_http_request_t *r,
+ ngx_http_complex_value_t *val, ngx_str_t *value, size_t *size)
+{
+ if (val->lengths == NULL) {
+ *size = val->u.size;
+ return NGX_OK;
+ }
+
+ if (ngx_http_complex_value(r, val, value) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ *size = ngx_parse_size(value);
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)
{
ngx_str_t *v;
@@ -250,6 +276,24 @@ ngx_http_set_complex_value_slot(ngx_conf
}


+static char *
+ngx_http_complex_value_set_size(ngx_conf_t *cf, void *post, void *data)
+{
+ ngx_http_complex_value_t *cv = data;
+
+ if (cv->lengths) {
+ return NGX_CONF_OK;
+ }
+
+ cv->u.size = ngx_parse_size(&cv->value);
+ if (cv->u.size == (size_t) NGX_ERROR) {
+ return "invalid value";
+ }
+
+ return NGX_CONF_OK;
+}
+
+
ngx_int_t
ngx_http_test_predicates(ngx_http_request_t *r, ngx_array_t *predicates)
{
diff --git a/src/http/ngx_http_script.h b/src/http/ngx_http_script.h
--- a/src/http/ngx_http_script.h
+++ b/src/http/ngx_http_script.h
@@ -68,6 +68,10 @@ typedef struct {
ngx_uint_t *flushes;
void *lengths;
void *values;
+
+ union {
+ size_t size;
+ } u;
} ngx_http_complex_value_t;


@@ -207,6 +211,8 @@ void ngx_http_script_flush_complex_value
ngx_http_complex_value_t *val);
ngx_int_t ngx_http_complex_value(ngx_http_request_t *r,
ngx_http_complex_value_t *val, ngx_str_t *value);
+ngx_int_t ngx_http_complex_value_size(ngx_http_request_t *r,
+ ngx_http_complex_value_t *val, ngx_str_t *value, size_t *size);
ngx_int_t ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv);
char *ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
@@ -254,4 +260,7 @@ void ngx_http_script_var_code(ngx_http_s
void ngx_http_script_nop_code(ngx_http_script_engine_t *e);


+extern ngx_conf_post_handler_pt ngx_http_complex_value_size_p;
+
+
#endif /* _NGX_HTTP_SCRIPT_H_INCLUDED_ */
# HG changeset patch
# Parent fbf2ea9783be4eeaa938bc4173dbac1149b762dc
Variables support in limit_rate and limit_rate_after (ticket #293).

diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -474,18 +474,18 @@ static ngx_command_t ngx_http_core_comm
{ ngx_string("limit_rate"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
+ ngx_http_set_complex_value_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, limit_rate),
- NULL },
+ &ngx_http_complex_value_size_p },

{ ngx_string("limit_rate_after"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
+ ngx_http_set_complex_value_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
- NULL },
+ &ngx_http_complex_value_size_p },

{ ngx_string("keepalive_timeout"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
@@ -1431,6 +1431,8 @@ ngx_http_core_content_phase(ngx_http_req
void
ngx_http_update_location_config(ngx_http_request_t *r)
{
+ size_t limit_rate;
+ ngx_str_t val;
ngx_http_core_loc_conf_t *clcf;

clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
@@ -1500,8 +1502,18 @@ ngx_http_update_location_config(ngx_http
r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
}

- if (r->limit_rate == 0) {
- r->limit_rate = clcf->limit_rate;
+ if (r->limit_rate == 0
+ && clcf->limit_rate
+ && ngx_http_complex_value_size(r, clcf->limit_rate, &val, &limit_rate)
+ == NGX_OK)
+ {
+ if (limit_rate != (size_t) NGX_ERROR) {
+ r->limit_rate = limit_rate;
+
+ } else if (val.len) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "invalid \"limit_rate\" value \"%V\"", &val);
+ }
}

if (clcf->handler) {
@@ -3567,6 +3579,8 @@ ngx_http_core_create_loc_conf(ngx_conf_t
* clcf->exact_match = 0;
* clcf->auto_redirect = 0;
* clcf->alias = 0;
+ * clcf->limit_rate = NULL;
+ * clcf->limit_rate_after = NULL;
* clcf->gzip_proxied = 0;
* clcf->keepalive_disable = 0;
*/
@@ -3596,8 +3610,6 @@ ngx_http_core_create_loc_conf(ngx_conf_t
clcf->send_timeout = NGX_CONF_UNSET_MSEC;
clcf->send_lowat = NGX_CONF_UNSET_SIZE;
clcf->postpone_output = NGX_CONF_UNSET_SIZE;
- clcf->limit_rate = NGX_CONF_UNSET_SIZE;
- clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
clcf->keepalive_header = NGX_CONF_UNSET;
clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
@@ -3785,6 +3797,14 @@ ngx_http_core_merge_loc_conf(ngx_conf_t
ngx_conf_merge_msec_value(conf->client_body_timeout,
prev->client_body_timeout, 60000);

+ if (conf->limit_rate == NULL) {
+ conf->limit_rate = prev->limit_rate;
+ }
+
+ if (conf->limit_rate_after == NULL) {
+ conf->limit_rate_after = prev->limit_rate_after;
+ }
+
ngx_conf_merge_bitmask_value(conf->keepalive_disable,
prev->keepalive_disable,
(NGX_CONF_BITMASK_SET
@@ -3823,9 +3843,6 @@ ngx_http_core_merge_loc_conf(ngx_conf_t
ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
1460);
- ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
- ngx_conf_merge_size_value(conf->limit_rate_after, prev->limit_rate_after,
- 0);
ngx_conf_merge_msec_value(conf->keepalive_timeout,
prev->keepalive_timeout, 75000);
ngx_conf_merge_sec_value(conf->keepalive_header,
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -358,11 +358,12 @@ struct ngx_http_core_loc_conf_s {
size_t client_body_buffer_size; /* client_body_buffer_size */
size_t send_lowat; /* send_lowat */
size_t postpone_output; /* postpone_output */
- size_t limit_rate; /* limit_rate */
- size_t limit_rate_after; /* limit_rate_after */
size_t sendfile_max_chunk; /* sendfile_max_chunk */
size_t read_ahead; /* read_ahead */

+ ngx_http_complex_value_t *limit_rate; /* limit_rate */
+ ngx_http_complex_value_t *limit_rate_after;
+
ngx_msec_t client_body_timeout; /* client_body_timeout */
ngx_msec_t send_timeout; /* send_timeout */
ngx_msec_t keepalive_timeout; /* keepalive_timeout */
diff --git a/src/http/ngx_http_write_filter_module.c b/src/http/ngx_http_write_filter_module.c
--- a/src/http/ngx_http_write_filter_module.c
+++ b/src/http/ngx_http_write_filter_module.c
@@ -48,6 +48,8 @@ ngx_int_t
ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
off_t size, sent, nsent, limit;
+ size_t limit_rate_after;
+ ngx_str_t val;
ngx_uint_t last, flush, sync;
ngx_msec_t delay;
ngx_chain_t *cl, *ln, **ll, *chain;
@@ -219,8 +221,20 @@ ngx_http_write_filter(ngx_http_request_t
}

if (r->limit_rate) {
- if (r->limit_rate_after == 0) {
- r->limit_rate_after = clcf->limit_rate_after;
+ if (r->limit_rate_after == 0
+ && clcf->limit_rate_after
+ && ngx_http_complex_value_size(r, clcf->limit_rate_after, &val,
+ &limit_rate_after)
+ == NGX_OK)
+ {
+ if (limit_rate_after != (size_t) NGX_ERROR) {
+ r->limit_rate_after = limit_rate_after;
+
+ } else if (val.len) {
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
+ "invalid \"limit_rate_after\" value \"%V\"",
+ &val);
+ }
}

limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1)
Miroslav Novy
2018-08-28 07:21:31 UTC
Permalink
Hi,
thank you for your patch. I will look at it. Why did not you merge him to
repository?

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

I tried your patch with actual sources, the solution is very similar to my,
you just use the functions. It is better.

I tried it with this configuration:

...
location / {
root /var/www/default/;
index index.html index.htm;

set $my_limit_rate 2k;
set $my_limit_rate_after 2m;

limit_rate $my_limit_rate;
limit_rate_after $my_limit_rate_after;

access_by_lua_block {
ngx.var.my_limit_rate = '4k'
ngx.var.my_limit_rate_after = '10m'
}
}
...

Settings of limit_rate_after works good :) But settings of limit_rate
throws warning and value is always set to zero. The problem is that they
try to retrieve the value of the variable before it is set by the set
command.

2018/08/28 10:36:22 [warn] 8180#0: *1 using uninitialized "my_limit_rate"
variable, client: 10.255.255.10, server: localhost, request: "GET
/iloveyou_words.mp4 HTTP/1.1", host: "mira-nginx.dev.srw.cz"
2018/08/28 10:36:22 [debug] 8180#0: *1 http script var: ""
2018/08/28 10:36:22 [debug] 8180#0: *1 http cl:-1 max:1048576
2018/08/28 10:36:22 [debug] 8180#0: *1 rewrite phase: 2
2018/08/28 10:36:22 [debug] 8180#0: *1 http script value: "2k"
2018/08/28 10:36:22 [debug] 8180#0: *1 http script set $my_limit_rate

Can you help me with this?

Thanks
Míra NovÜ
Miroslav Novy
2018-10-17 10:49:13 UTC
Permalink
Hello,

I prepare patch on actual sources. Settings limit_rate and limit_rate_after
works good. Please make code review, our testing and merge to main branche.
Thank you
Miroslav NovÜ

Example of configration:
location / {
root /var/www/default/;
index index.html index.htm;

set $my_limit_rate 4k;
set $my_limit_rate_after 4m;

limit_rate $my_limit_rate;
limit_rate_after $my_limit_rate_after;

access_by_lua_block {
ngx.var.my_limit_rate = '2k'
ngx.var.my_limit_rate_after = '10m'
}
}


# HG changeset patch
# User Miroslav NovÜ <***@gmail.com>
# Date 1539773045 0
# Wed Oct 17 10:44:05 2018 +0000
# Node ID 0de0d409a946b9f33284c036fdf3dcdaec0853c2
# Parent 8b68d50090e4f134a35da60146fefd5e63770759
limit_rate and limit_rate_after support variables

diff -r 8b68d50090e4 -r 0de0d409a946 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Wed Oct 03 14:08:51 2018 +0300
+++ b/src/http/ngx_http_core_module.c Wed Oct 17 10:44:05 2018 +0000
@@ -479,18 +479,18 @@
{ ngx_string("limit_rate"),

NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
+ ngx_http_set_complex_value_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, limit_rate),
- NULL },
+ &ngx_http_complex_value_size_p },

{ ngx_string("limit_rate_after"),

NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
+ ngx_http_set_complex_value_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
- NULL },
+ &ngx_http_complex_value_size_p },

{ ngx_string("keepalive_timeout"),

NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
@@ -1281,10 +1281,6 @@
r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
}

- if (r->limit_rate == 0) {
- r->limit_rate = clcf->limit_rate;
- }
-
if (clcf->handler) {
r->content_handler = clcf->handler;
}
@@ -3362,6 +3358,8 @@
* clcf->exact_match = 0;
* clcf->auto_redirect = 0;
* clcf->alias = 0;
+ * clcf->limit_rate = NULL;
+ * clcf->limit_rate_after = NULL;
* clcf->gzip_proxied = 0;
* clcf->keepalive_disable = 0;
*/
@@ -3392,8 +3390,6 @@
clcf->send_timeout = NGX_CONF_UNSET_MSEC;
clcf->send_lowat = NGX_CONF_UNSET_SIZE;
clcf->postpone_output = NGX_CONF_UNSET_SIZE;
- clcf->limit_rate = NGX_CONF_UNSET_SIZE;
- clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
clcf->keepalive_header = NGX_CONF_UNSET;
clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
@@ -3581,6 +3577,14 @@
ngx_conf_merge_msec_value(conf->client_body_timeout,
prev->client_body_timeout, 60000);

+ if (conf->limit_rate == NULL) {
+ conf->limit_rate = prev->limit_rate;
+ }
+
+ if (conf->limit_rate_after == NULL) {
+ conf->limit_rate_after = prev->limit_rate_after;
+ }
+
ngx_conf_merge_bitmask_value(conf->keepalive_disable,
prev->keepalive_disable,
(NGX_CONF_BITMASK_SET
@@ -3622,9 +3626,7 @@
ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
1460);
- ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
- ngx_conf_merge_size_value(conf->limit_rate_after,
prev->limit_rate_after,
- 0);
+
ngx_conf_merge_msec_value(conf->keepalive_timeout,
prev->keepalive_timeout, 75000);
ngx_conf_merge_sec_value(conf->keepalive_header,
diff -r 8b68d50090e4 -r 0de0d409a946 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h Wed Oct 03 14:08:51 2018 +0300
+++ b/src/http/ngx_http_core_module.h Wed Oct 17 10:44:05 2018 +0000
@@ -350,8 +350,9 @@
size_t client_body_buffer_size; /* client_body_buffer_size */
size_t send_lowat; /* send_lowat */
size_t postpone_output; /* postpone_output */
- size_t limit_rate; /* limit_rate */
- size_t limit_rate_after; /* limit_rate_after */
+ ngx_http_complex_value_t *limit_rate; /* limit_rate */
+ ngx_http_complex_value_t *limit_rate_after;
+ /* limit_rate_after */
size_t sendfile_max_chunk; /* sendfile_max_chunk */
size_t read_ahead; /* read_ahead */
size_t subrequest_output_buffer_size;
diff -r 8b68d50090e4 -r 0de0d409a946 src/http/ngx_http_script.c
--- a/src/http/ngx_http_script.c Wed Oct 03 14:08:51 2018 +0300
+++ b/src/http/ngx_http_script.c Wed Oct 17 10:44:05 2018 +0000
@@ -9,7 +9,8 @@
#include <ngx_core.h>
#include <ngx_http.h>

-
+static char *ngx_http_complex_value_set_size(ngx_conf_t *cf, void *post,
+ void *data);
static ngx_int_t ngx_http_script_init_arrays(ngx_http_script_compile_t
*sc);
static ngx_int_t ngx_http_script_done(ngx_http_script_compile_t *sc);
static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t
*sc,
@@ -31,6 +32,8 @@

static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL;

+ngx_conf_post_handler_pt ngx_http_complex_value_size_p =
+ ngx_http_complex_value_set_size;

void
ngx_http_script_flush_complex_value(ngx_http_request_t *r,
@@ -103,6 +106,23 @@
return NGX_OK;
}

+ngx_int_t
+ngx_http_complex_value_size(ngx_http_request_t *r,
+ ngx_http_complex_value_t *val, ngx_str_t *value, ssize_t *size)
+{
+ if (val->lengths == NULL) {
+ *size = val->u.size;
+ return NGX_OK;
+ }
+
+ if (ngx_http_complex_value(r, val, value) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ *size = ngx_parse_size(value);
+
+ return NGX_OK;
+}

ngx_int_t
ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)
@@ -214,6 +234,7 @@
char *p = conf;

ngx_str_t *value;
+ ngx_conf_post_t *post;
ngx_http_complex_value_t **cv;
ngx_http_compile_complex_value_t ccv;

@@ -240,6 +261,29 @@
return NGX_CONF_ERROR;
}

+ if (cmd->post) {
+ post = cmd->post;
+ return post->post_handler(cf, post, *cv);
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_http_complex_value_set_size(ngx_conf_t *cf, void *post, void *data)
+{
+ ngx_http_complex_value_t *cv = data;
+
+ if (cv->lengths) {
+ return NGX_CONF_OK;
+ }
+
+ cv->u.size = ngx_parse_size(&cv->value);
+ if (cv->u.size == (size_t) NGX_ERROR) {
+ return "invalid value";
+ }
+
return NGX_CONF_OK;
}

diff -r 8b68d50090e4 -r 0de0d409a946 src/http/ngx_http_script.h
--- a/src/http/ngx_http_script.h Wed Oct 03 14:08:51 2018 +0300
+++ b/src/http/ngx_http_script.h Wed Oct 17 10:44:05 2018 +0000
@@ -68,6 +68,10 @@
ngx_uint_t *flushes;
void *lengths;
void *values;
+
+ union {
+ size_t size;
+ } u;
} ngx_http_complex_value_t;


@@ -205,6 +209,8 @@

void ngx_http_script_flush_complex_value(ngx_http_request_t *r,
ngx_http_complex_value_t *val);
+ngx_int_t ngx_http_complex_value_size(ngx_http_request_t *r,
+ ngx_http_complex_value_t *val, ngx_str_t *value, ssize_t *size);
ngx_int_t ngx_http_complex_value(ngx_http_request_t *r,
ngx_http_complex_value_t *val, ngx_str_t *value);
ngx_int_t ngx_http_compile_complex_value(ngx_http_compile_complex_value_t
*ccv);
@@ -253,5 +259,6 @@
void ngx_http_script_var_code(ngx_http_script_engine_t *e);
void ngx_http_script_nop_code(ngx_http_script_engine_t *e);

+extern ngx_conf_post_handler_pt ngx_http_complex_value_size_p;

#endif /* _NGX_HTTP_SCRIPT_H_INCLUDED_ */
diff -r 8b68d50090e4 -r 0de0d409a946 src/http/ngx_http_write_filter_module.c
--- a/src/http/ngx_http_write_filter_module.c Wed Oct 03 14:08:51 2018 +0300
+++ b/src/http/ngx_http_write_filter_module.c Wed Oct 17 10:44:05 2018 +0000
@@ -48,6 +48,8 @@
ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
off_t size, sent, nsent, limit;
+ ssize_t limit_rate, limit_rate_after;
+ ngx_str_t val;
ngx_uint_t last, flush, sync;
ngx_msec_t delay;
ngx_chain_t *cl, *ln, **ll, *chain;
@@ -218,9 +220,38 @@
return NGX_ERROR;
}

+ if (r->limit_rate == 0
+ && clcf->limit_rate
+ && ngx_http_complex_value_size(r, clcf->limit_rate, &val,
+ &limit_rate)
+ == NGX_OK)
+ {
+ if (limit_rate_after != NGX_ERROR) {
+ r->limit_rate = limit_rate;
+
+ } else if (val.len) {
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
+ "invalid \"limit_rate\" value \"%V\"",
+ &val);
+ }
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http limit rate
\"%z\"", r->limit_rate);
+
if (r->limit_rate) {
- if (r->limit_rate_after == 0) {
- r->limit_rate_after = clcf->limit_rate_after;
+ if (r->limit_rate_after == 0
+ && clcf->limit_rate_after
+ && ngx_http_complex_value_size(r, clcf->limit_rate_after, &val,
+ &limit_rate_after)
+ == NGX_OK)
+ {
+ if (limit_rate_after != NGX_ERROR) {
+ r->limit_rate_after = limit_rate_after;
+ } else if (val.len) {
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
+ "invalid \"limit_rate_after\" value \"%V\"",
+ &val);
+ }
}

limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1)
Ruslan Ermilov
2018-11-20 14:10:05 UTC
Permalink
Hi Miroslav,
Post by Miroslav Novy
Hello,
I prepare patch on actual sources. Settings limit_rate and limit_rate_after
works good. Please make code review, our testing and merge to main branche.
Thank you
Miroslav Nový
location / {
root /var/www/default/;
index index.html index.htm;
set $my_limit_rate 4k;
set $my_limit_rate_after 4m;
limit_rate $my_limit_rate;
limit_rate_after $my_limit_rate_after;
access_by_lua_block {
ngx.var.my_limit_rate = '2k'
ngx.var.my_limit_rate_after = '10m'
}
}
As I wrote on August 29, the patch is pending a code review. The
patch you submitted is garbled by your email client, is somewhat
different from the patch I submitted, also the while patch series
became a single patch.

I've updated my version of the patch series. You can help with the
code review and testing, if you like:

# HG changeset patch
# User Ruslan Ermilov <***@nginx.com>
# Date 1542721399 -10800
# Tue Nov 20 16:43:19 2018 +0300
# Node ID 9926926b9d63c8cc9779877cb6c0f5e64193f1a8
# Parent 650574a445058a0ed9e9a83c29183a7bc13e85ba
Added post processing to ngx_http_set_complex_value_slot().

diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -214,6 +214,7 @@ ngx_http_set_complex_value_slot(ngx_conf
char *p = conf;

ngx_str_t *value;
+ ngx_conf_post_t *post;
ngx_http_complex_value_t **cv;
ngx_http_compile_complex_value_t ccv;

@@ -240,6 +241,11 @@ ngx_http_set_complex_value_slot(ngx_conf
return NGX_CONF_ERROR;
}

+ if (cmd->post) {
+ post = cmd->post;
+ return post->post_handler(cf, post, *cv);
+ }
+
return NGX_CONF_OK;
}

# HG changeset patch
# User Ruslan Ermilov <***@nginx.com>
# Date 1542721408 -10800
# Tue Nov 20 16:43:28 2018 +0300
# Node ID cb171b06b70daa8ab230924eafa152fa28870cb5
# Parent 9926926b9d63c8cc9779877cb6c0f5e64193f1a8
Added size_t type support to ngx_http_set_complex_value_slot().

If a complex value is expected to be size_t, and the compiled value
is constant, the ngx_http_complex_value_size_p post handler will
remember the constant size_t value.

The value is accessed through ngx_http_complex_value_size() which
either returns the remembered constant or evaluates the expression
and parses it as size_t.

diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -10,6 +10,13 @@
#include <ngx_http.h>


+static char *ngx_http_complex_value_set_size(ngx_conf_t *cf, void *post,
+ void *data);
+
+ngx_conf_post_handler_pt ngx_http_complex_value_size_p =
+ ngx_http_complex_value_set_size;
+
+
static ngx_int_t ngx_http_script_init_arrays(ngx_http_script_compile_t *sc);
static ngx_int_t ngx_http_script_done(ngx_http_script_compile_t *sc);
static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc,
@@ -105,6 +112,25 @@ ngx_http_complex_value(ngx_http_request_


ngx_int_t
+ngx_http_complex_value_size(ngx_http_request_t *r,
+ ngx_http_complex_value_t *val, ngx_str_t *value, size_t *size)
+{
+ if (val->lengths == NULL) {
+ *size = val->u.size;
+ return NGX_OK;
+ }
+
+ if (ngx_http_complex_value(r, val, value) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ *size = ngx_parse_size(value);
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)
{
ngx_str_t *v;
@@ -250,6 +276,24 @@ ngx_http_set_complex_value_slot(ngx_conf
}


+static char *
+ngx_http_complex_value_set_size(ngx_conf_t *cf, void *post, void *data)
+{
+ ngx_http_complex_value_t *cv = data;
+
+ if (cv->lengths) {
+ return NGX_CONF_OK;
+ }
+
+ cv->u.size = ngx_parse_size(&cv->value);
+ if (cv->u.size == (size_t) NGX_ERROR) {
+ return "invalid value";
+ }
+
+ return NGX_CONF_OK;
+}
+
+
ngx_int_t
ngx_http_test_predicates(ngx_http_request_t *r, ngx_array_t *predicates)
{
diff --git a/src/http/ngx_http_script.h b/src/http/ngx_http_script.h
--- a/src/http/ngx_http_script.h
+++ b/src/http/ngx_http_script.h
@@ -68,6 +68,10 @@ typedef struct {
ngx_uint_t *flushes;
void *lengths;
void *values;
+
+ union {
+ size_t size;
+ } u;
} ngx_http_complex_value_t;


@@ -207,6 +211,8 @@ void ngx_http_script_flush_complex_value
ngx_http_complex_value_t *val);
ngx_int_t ngx_http_complex_value(ngx_http_request_t *r,
ngx_http_complex_value_t *val, ngx_str_t *value);
+ngx_int_t ngx_http_complex_value_size(ngx_http_request_t *r,
+ ngx_http_complex_value_t *val, ngx_str_t *value, size_t *size);
ngx_int_t ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv);
char *ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
@@ -254,4 +260,7 @@ void ngx_http_script_var_code(ngx_http_s
void ngx_http_script_nop_code(ngx_http_script_engine_t *e);


+extern ngx_conf_post_handler_pt ngx_http_complex_value_size_p;
+
+
#endif /* _NGX_HTTP_SCRIPT_H_INCLUDED_ */
# HG changeset patch
# User Ruslan Ermilov <***@nginx.com>
# Date 1542722018 -10800
# Tue Nov 20 16:53:38 2018 +0300
# Node ID 1ab7dc1eb5fca6798e7412401302393023cd1ec6
# Parent cb171b06b70daa8ab230924eafa152fa28870cb5
Variables support in limit_rate and limit_rate_after (ticket #293).

diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -479,18 +479,18 @@ static ngx_command_t ngx_http_core_comm
{ ngx_string("limit_rate"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
+ ngx_http_set_complex_value_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, limit_rate),
- NULL },
+ &ngx_http_complex_value_size_p },

{ ngx_string("limit_rate_after"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
+ ngx_http_set_complex_value_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
- NULL },
+ &ngx_http_complex_value_size_p },

{ ngx_string("keepalive_timeout"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
@@ -1212,6 +1212,8 @@ ngx_http_core_content_phase(ngx_http_req
void
ngx_http_update_location_config(ngx_http_request_t *r)
{
+ size_t limit_rate;
+ ngx_str_t val;
ngx_http_core_loc_conf_t *clcf;

clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
@@ -1281,8 +1283,18 @@ ngx_http_update_location_config(ngx_http
r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
}

- if (r->limit_rate == 0) {
- r->limit_rate = clcf->limit_rate;
+ if (r->limit_rate == 0
+ && clcf->limit_rate
+ && ngx_http_complex_value_size(r, clcf->limit_rate, &val, &limit_rate)
+ == NGX_OK)
+ {
+ if (limit_rate != (size_t) NGX_ERROR) {
+ r->limit_rate = limit_rate;
+
+ } else if (val.len) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "invalid \"limit_rate\" value \"%V\"", &val);
+ }
}

if (clcf->handler) {
@@ -3362,6 +3374,8 @@ ngx_http_core_create_loc_conf(ngx_conf_t
* clcf->exact_match = 0;
* clcf->auto_redirect = 0;
* clcf->alias = 0;
+ * clcf->limit_rate = NULL;
+ * clcf->limit_rate_after = NULL;
* clcf->gzip_proxied = 0;
* clcf->keepalive_disable = 0;
*/
@@ -3392,8 +3406,6 @@ ngx_http_core_create_loc_conf(ngx_conf_t
clcf->send_timeout = NGX_CONF_UNSET_MSEC;
clcf->send_lowat = NGX_CONF_UNSET_SIZE;
clcf->postpone_output = NGX_CONF_UNSET_SIZE;
- clcf->limit_rate = NGX_CONF_UNSET_SIZE;
- clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
clcf->keepalive_header = NGX_CONF_UNSET;
clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
@@ -3581,6 +3593,14 @@ ngx_http_core_merge_loc_conf(ngx_conf_t
ngx_conf_merge_msec_value(conf->client_body_timeout,
prev->client_body_timeout, 60000);

+ if (conf->limit_rate == NULL) {
+ conf->limit_rate = prev->limit_rate;
+ }
+
+ if (conf->limit_rate_after == NULL) {
+ conf->limit_rate_after = prev->limit_rate_after;
+ }
+
ngx_conf_merge_bitmask_value(conf->keepalive_disable,
prev->keepalive_disable,
(NGX_CONF_BITMASK_SET
@@ -3622,9 +3642,6 @@ ngx_http_core_merge_loc_conf(ngx_conf_t
ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
1460);
- ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
- ngx_conf_merge_size_value(conf->limit_rate_after, prev->limit_rate_after,
- 0);
ngx_conf_merge_msec_value(conf->keepalive_timeout,
prev->keepalive_timeout, 75000);
ngx_conf_merge_sec_value(conf->keepalive_header,
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -350,13 +350,14 @@ struct ngx_http_core_loc_conf_s {
size_t client_body_buffer_size; /* client_body_buffer_size */
size_t send_lowat; /* send_lowat */
size_t postpone_output; /* postpone_output */
- size_t limit_rate; /* limit_rate */
- size_t limit_rate_after; /* limit_rate_after */
size_t sendfile_max_chunk; /* sendfile_max_chunk */
size_t read_ahead; /* read_ahead */
size_t subrequest_output_buffer_size;
/* subrequest_output_buffer_size */

+ ngx_http_complex_value_t *limit_rate; /* limit_rate */
+ ngx_http_complex_value_t *limit_rate_after; /* limit_rate_after */
+
ngx_msec_t client_body_timeout; /* client_body_timeout */
ngx_msec_t send_timeout; /* send_timeout */
ngx_msec_t keepalive_timeout; /* keepalive_timeout */
diff --git a/src/http/ngx_http_write_filter_module.c b/src/http/ngx_http_write_filter_module.c
--- a/src/http/ngx_http_write_filter_module.c
+++ b/src/http/ngx_http_write_filter_module.c
@@ -48,6 +48,8 @@ ngx_int_t
ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
off_t size, sent, nsent, limit;
+ size_t limit_rate_after;
+ ngx_str_t val;
ngx_uint_t last, flush, sync;
ngx_msec_t delay;
ngx_chain_t *cl, *ln, **ll, *chain;
@@ -219,8 +221,20 @@ ngx_http_write_filter(ngx_http_request_t
}

if (r->limit_rate) {
- if (r->limit_rate_after == 0) {
- r->limit_rate_after = clcf->limit_rate_after;
+ if (r->limit_rate_after == 0
+ && clcf->limit_rate_after
+ && ngx_http_complex_value_size(r, clcf->limit_rate_after, &val,
+ &limit_rate_after)
+ == NGX_OK)
+ {
+ if (limit_rate_after != (size_t) NGX_ERROR) {
+ r->limit_rate_after = limit_rate_after;
+
+ } else if (val.len) {
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
+ "invalid \"limit_rate_after\" value \"%V\"",
+ &val);
+ }
}

limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1)
Miroslav Novy
2018-11-21 11:11:10 UTC
Permalink
Hi Ruslan,
Post by Ruslan Ermilov
I've updated my version of the patch series.
Thank you :)
Yes, of corse.

The first patch from the series "Added post processing to
ngx_http_set_complex_value_slot()" is ok.

For second patch "Added size_t type support to
ngx_http_set_complex_value_slot()" I prepared fix, becouse
return type of ngx_parse_size is ssize_t. These is my fix

# HG changeset patch
# User Miroslav Nový <***@gmail.com>
# Date 1542796801 0
# Wed Nov 21 10:40:01 2018 +0000
# Node ID 82eed7650622fd780dcd4a86661de7b80b44199c
# Parent 1090756c530aabe5e63882dcbf278b23807568d0
Added size_t type support to ngx_http_set_complex_value_slot() fix

Return type of function ngx_parse_size is ssize_t

diff -r 1090756c530a -r 82eed7650622 src/http/ngx_http_script.c
--- a/src/http/ngx_http_script.c Tue Nov 20 16:53:38 2018 +0300
+++ b/src/http/ngx_http_script.c Wed Nov 21 10:40:01 2018 +0000
@@ -113,7 +113,7 @@

ngx_int_t
ngx_http_complex_value_size(ngx_http_request_t *r,
- ngx_http_complex_value_t *val, ngx_str_t *value, size_t *size)
+ ngx_http_complex_value_t *val, ngx_str_t *value, ssize_t *size)
{
if (val->lengths == NULL) {
*size = val->u.size;
diff -r 1090756c530a -r 82eed7650622 src/http/ngx_http_script.h
--- a/src/http/ngx_http_script.h Tue Nov 20 16:53:38 2018 +0300
+++ b/src/http/ngx_http_script.h Wed Nov 21 10:40:01 2018 +0000
@@ -212,7 +212,7 @@
ngx_int_t ngx_http_complex_value(ngx_http_request_t *r,
ngx_http_complex_value_t *val, ngx_str_t *value);
ngx_int_t ngx_http_complex_value_size(ngx_http_request_t *r,
- ngx_http_complex_value_t *val, ngx_str_t *value, size_t *size);
+ ngx_http_complex_value_t *val, ngx_str_t *value, ssize_t *size);
ngx_int_t ngx_http_compile_complex_value(ngx_http_compile_complex_value_t
*ccv);
char *ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);

The last patch "Variables support in limit_rate and limit_rate_after
(ticket #293)." throws warning "using uninitialized variable!. I am
going to make the fix today later.

Best regards
Miroslav Nový
Miroslav Novy
2018-11-21 14:50:30 UTC
Permalink
Hi Ruslan,
there is my fix to remove warning "using uninitialized variable".

I have moved the reading value of limit_rate variable from function
ngx_http_update_location_config to function ngx_http_write_filter
because value is initialized later.

Best regards
Miroslav Nový

# HG changeset patch
# User Miroslav Nový <***@gmail.com>
# Date 1542811768 0
# Wed Nov 21 14:49:28 2018 +0000
# Node ID e2139cd62c7263dc182b11a847a6eaf2d9560a0d
# Parent 82eed7650622fd780dcd4a86661de7b80b44199c
Variables support in limit_rate and limit_rate_after fix

Reading value of limit_rate variable moved to function
ngx_http_write_filter because in function
ngx_http_update_location_config is not inicialized yet.

diff -r 82eed7650622 -r e2139cd62c72 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Wed Nov 21 10:40:01 2018 +0000
+++ b/src/http/ngx_http_core_module.c Wed Nov 21 14:49:28 2018 +0000
@@ -1212,8 +1212,6 @@
void
ngx_http_update_location_config(ngx_http_request_t *r)
{
- size_t limit_rate;
- ngx_str_t val;
ngx_http_core_loc_conf_t *clcf;

clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
@@ -1283,20 +1281,6 @@
r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
}

- if (r->limit_rate == 0
- && clcf->limit_rate
- && ngx_http_complex_value_size(r, clcf->limit_rate, &val, &limit_rate)
- == NGX_OK)
- {
- if (limit_rate != (size_t) NGX_ERROR) {
- r->limit_rate = limit_rate;
-
- } else if (val.len) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid \"limit_rate\" value \"%V\"", &val);
- }
- }
-
if (clcf->handler) {
r->content_handler = clcf->handler;
}
diff -r 82eed7650622 -r e2139cd62c72 src/http/ngx_http_write_filter_module.c
--- a/src/http/ngx_http_write_filter_module.c Wed Nov 21 10:40:01 2018 +0000
+++ b/src/http/ngx_http_write_filter_module.c Wed Nov 21 14:49:28 2018 +0000
@@ -48,7 +48,7 @@
ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
off_t size, sent, nsent, limit;
- size_t limit_rate_after;
+ ssize_t limit_rate, limit_rate_after;
ngx_str_t val;
ngx_uint_t last, flush, sync;
ngx_msec_t delay;
@@ -220,6 +220,25 @@
return NGX_ERROR;
}

+ if (r->limit_rate == 0
+ && clcf->limit_rate
+ && ngx_http_complex_value_size(r, clcf->limit_rate, &val,
+ &limit_rate)
+ == NGX_OK)
+ {
+ if (limit_rate_after != NGX_ERROR) {
+ r->limit_rate = limit_rate;
+
+ } else if (val.len) {
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
+ "invalid \"limit_rate\" value \"%V\"",
+ &val);
+ }
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http limit rate \"%z\"",
+ r->limit_rate);
+
if (r->limit_rate) {
if (r->limit_rate_after == 0
&& clcf->limit_rate_after
@@ -227,7 +246,7 @@
&limit_rate_after)
== NGX_OK)
{
- if (limit_rate_after != (size_t) NGX_ERROR) {
+ if (limit_rate_after != NGX_ERROR) {
r->limit_rate_after = limit_rate_after;

} else if (val.len) {

Loading...