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 nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel