Re: [PATCH][bugfix] Upstream: clear the delayed flag to prevent blocking from sending.

2017-04-03 Thread 胡聪 (hucc)
Hi,

On Sunday, Apr 2, 2017 9:35 PM +0300, Maxim Dounin wrote:

>On Fri, Feb 17, 2017 at 11:18:48AM +0800, 胡聪 (hucc) wrote:
>
>> Hi,
>>
>> To reproduce the scene of send blocking, there must be more than
>> two subrequests, and the more the better.
>>
>
>Thank you for your report.
>
>After looking into this for a while, I've committed several
>patches to fix various issues with wev->delayed:
>
>http://hg.nginx.org/nginx/rev/7fcf209d40c8
>http://hg.nginx.org/nginx/rev/1c5e5e5b008d
>http://hg.nginx.org/nginx/rev/903fb1ddc07f

After looked at these patches, I confirmed that the problem I encountered should
be solved. Thanks for the great solution.

At the same time, I noticed that the type of rc is int not ngx_int_t in
ngx_http_writer(). The type should be ngx_int_t, right? There was a time the
return type of ngx_http_writer() is int. Later, it became void. Since then there
is no need to do type conversion.

# HG changeset patch
# User hucongcong 
# Date 1491200980 -28800
#  Mon Apr 03 14:29:40 2017 +0800
# Node ID 7c3a0b951d0209612fb50a48abcb10c6ceffbff7
# Parent  903fb1ddc07f6b4345d88428898d95aadfc0223f
fix type

diff -r 903fb1ddc07f -r 7c3a0b951d02 src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c   Sun Apr 02 14:32:29 2017 +0300
+++ b/src/http/ngx_http_request.c   Mon Apr 03 14:29:40 2017 +0800
@@ -2612,7 +2612,7 @@ ngx_http_set_write_handler(ngx_http_requ
 static void
 ngx_http_writer(ngx_http_request_t *r)
 {
-intrc;
+ngx_int_t  rc;
 ngx_event_t   *wev;
 ngx_connection_t  *c;
 ngx_http_core_loc_conf_t  *clcf;
@@ -2652,7 +2652,7 @@ ngx_http_writer(ngx_http_request_t *r)
 rc = ngx_http_output_filter(r, NULL);

 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
-   "http writer output filter: %d, \"%V?%V\"",
+   "http writer output filter: %i, \"%V?%V\"",
rc, &r->uri, &r->args);

 if (rc == NGX_ERROR) {
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

[PATCH 1 of 3] HTTP: add support for trailers in HTTP responses

2017-04-03 Thread Piotr Sikora via nginx-devel
# HG changeset patch
# User Piotr Sikora 
# Date 1490351854 25200
#  Fri Mar 24 03:37:34 2017 -0700
# Node ID 8af81a0d66c0f69bcf501edcf10deed4c8f7fbd4
# Parent  39ff6939266e913e8bfd400e60f9520e70725a4d
HTTP: add support for trailers in HTTP responses.

Example:

   ngx_table_elt_t  *h;

   h = ngx_list_push(&r->headers_out.trailers);
   if (h == NULL) {
   return NGX_ERROR;
   }

   ngx_str_set(&h->key, "Fun");
   ngx_str_set(&h->value, "with trailers");
   h->hash = ngx_hash_key_lc(h->key.data, h->key.len);

The code above adds "Fun: with trailers" trailer to the response to
the request with "TE: trailers" header (which indicates support for
trailers).

Modules that want to emit trailers must set r->expect_trailers = 1,
otherwise they are going to be ignored.

This change also adds $sent_trailer_* variables.

Signed-off-by: Piotr Sikora 

diff -r 39ff6939266e -r 8af81a0d66c0 
src/http/modules/ngx_http_chunked_filter_module.c
--- a/src/http/modules/ngx_http_chunked_filter_module.c
+++ b/src/http/modules/ngx_http_chunked_filter_module.c
@@ -17,6 +17,7 @@ typedef struct {
 
 
 static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf);
+static ngx_chain_t *ngx_http_chunked_create_trailers(ngx_http_request_t *r);
 
 
 static ngx_http_module_t  ngx_http_chunked_filter_module_ctx = {
@@ -69,28 +70,33 @@ ngx_http_chunked_header_filter(ngx_http_
 return ngx_http_next_header_filter(r);
 }
 
-if (r->headers_out.content_length_n == -1) {
+clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+if (clcf->chunked_transfer_encoding
+&& r->allow_trailers && r->expect_trailers)
+{
+ngx_http_clear_content_length(r);
+r->chunked = 1;
+
+} else if (r->headers_out.content_length_n == -1) {
 if (r->http_version < NGX_HTTP_VERSION_11) {
 r->keepalive = 0;
 
+} else if (clcf->chunked_transfer_encoding) {
+r->chunked = 1;
+
 } else {
-clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+r->keepalive = 0;
+}
+}
 
-if (clcf->chunked_transfer_encoding) {
-r->chunked = 1;
+if (r->chunked) {
+ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_chunked_filter_ctx_t));
+if (ctx == NULL) {
+return NGX_ERROR;
+}
 
-ctx = ngx_pcalloc(r->pool,
-  sizeof(ngx_http_chunked_filter_ctx_t));
-if (ctx == NULL) {
-return NGX_ERROR;
-}
-
-ngx_http_set_ctx(r, ctx, ngx_http_chunked_filter_module);
-
-} else {
-r->keepalive = 0;
-}
-}
+ngx_http_set_ctx(r, ctx, ngx_http_chunked_filter_module);
 }
 
 return ngx_http_next_header_filter(r);
@@ -201,6 +207,15 @@ ngx_http_chunked_body_filter(ngx_http_re
 b->pos += 2;
 }
 
+if (r->allow_trailers && r->expect_trailers) {
+tl->next = ngx_http_chunked_create_trailers(r);
+
+if (tl->next != NULL) {
+b->last -= 2;
+b->last_buf = 0;
+}
+}
+
 } else if (size > 0) {
 tl = ngx_chain_get_free_buf(r->pool, &ctx->free);
 if (tl == NULL) {
@@ -230,6 +245,108 @@ ngx_http_chunked_body_filter(ngx_http_re
 }
 
 
+static ngx_chain_t *
+ngx_http_chunked_create_trailers(ngx_http_request_t *r)
+{
+size_t  len;
+ngx_buf_t  *b;
+ngx_uint_t  i;
+ngx_chain_t*cl;
+ngx_list_part_t*part;
+ngx_table_elt_t*header;
+ngx_http_chunked_filter_ctx_t  *ctx;
+
+len = 0;
+
+part = &r->headers_out.trailers.part;
+header = part->elts;
+
+for (i = 0; /* void */; i++) {
+
+if (i >= part->nelts) {
+if (part->next == NULL) {
+break;
+}
+
+part = part->next;
+header = part->elts;
+i = 0;
+}
+
+if (header[i].hash == 0) {
+continue;
+}
+
+len += header[i].key.len + sizeof(": ") - 1
+   + header[i].value.len + sizeof(CRLF) - 1;
+}
+
+if (len == 0) {
+return NULL;
+}
+
+len += sizeof(CRLF) - 1;
+
+ctx = ngx_http_get_module_ctx(r, ngx_http_chunked_filter_module);
+
+cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
+if (cl == NULL) {
+return NULL;
+}
+
+b = cl->buf;
+
+b->tag = (ngx_buf_tag_t) &ngx_http_chunked_filter_module;
+b->temporary = 0;
+b->memory = 1;
+b->last_buf = 1;
+
+b->start = ngx_palloc(r->pool, len);
+if (b->start == NULL) {
+return NULL;
+}
+
+b->end = b->last + len;
+b->pos = b->start;
+b->last = b->start;
+
+part = &r->headers_out.trailers.part;
+header = part->elts;
+
+for (i = 0; /* void */; i++) {
+
+   

[PATCH 2 of 3] Headers filter: add "add_trailer" directive

2017-04-03 Thread Piotr Sikora via nginx-devel
# HG changeset patch
# User Piotr Sikora 
# Date 1490351854 25200
#  Fri Mar 24 03:37:34 2017 -0700
# Node ID 5bab17ebe2b1f8ec42cf069bf484489c2a92c7a8
# Parent  8af81a0d66c0f69bcf501edcf10deed4c8f7fbd4
Headers filter: add "add_trailer" directive.

Trailers added using this directive are evaluated after response body
is processed by output filters (but before it's written to the wire),
so it's possible to use variables calculated from the response body
as the trailer value.

Signed-off-by: Piotr Sikora 

diff -r 8af81a0d66c0 -r 5bab17ebe2b1 
src/http/modules/ngx_http_chunked_filter_module.c
--- a/src/http/modules/ngx_http_chunked_filter_module.c
+++ b/src/http/modules/ngx_http_chunked_filter_module.c
@@ -256,6 +256,10 @@ ngx_http_chunked_create_trailers(ngx_htt
 ngx_table_elt_t*header;
 ngx_http_chunked_filter_ctx_t  *ctx;
 
+if (ngx_http_eval_trailers(r) != NGX_OK) {
+return NULL;
+}
+
 len = 0;
 
 part = &r->headers_out.trailers.part;
diff -r 8af81a0d66c0 -r 5bab17ebe2b1 
src/http/modules/ngx_http_headers_filter_module.c
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -48,6 +48,7 @@ typedef struct {
 time_t expires_time;
 ngx_http_complex_value_t  *expires_value;
 ngx_array_t   *headers;
+ngx_array_t   *trailers;
 } ngx_http_headers_conf_t;
 
 
@@ -72,6 +73,8 @@ static char *ngx_http_headers_expires(ng
 void *conf);
 static char *ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd,
 void *conf);
+static char *ngx_http_headers_add_trailer(ngx_conf_t *cf, ngx_command_t *cmd,
+void *conf);
 
 
 static ngx_http_set_header_t  ngx_http_set_headers[] = {
@@ -108,6 +111,14 @@ static ngx_command_t  ngx_http_headers_f
   0,
   NULL},
 
+{ ngx_string("add_trailer"),
+  NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
+|NGX_CONF_TAKE23,
+  ngx_http_headers_add_trailer,
+  NGX_HTTP_LOC_CONF_OFFSET,
+  0,
+  NULL},
+
   ngx_null_command
 };
 
@@ -149,15 +160,24 @@ static ngx_http_output_header_filter_pt 
 static ngx_int_t
 ngx_http_headers_filter(ngx_http_request_t *r)
 {
-ngx_str_t value;
-ngx_uint_ti, safe_status;
-ngx_http_header_val_t*h;
-ngx_http_headers_conf_t  *conf;
+u_char*p, *data;
+size_t len;
+ngx_str_t  value;
+ngx_uint_t i, safe_status;
+ngx_table_elt_t   *t;
+ngx_http_header_val_t *h;
+ngx_http_headers_conf_t   *conf;
+ngx_http_core_loc_conf_t  *clcf;
+
+if (r != r->main) {
+return ngx_http_next_header_filter(r);
+}
 
 conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module);
 
-if ((conf->expires == NGX_HTTP_EXPIRES_OFF && conf->headers == NULL)
-|| r != r->main)
+if (conf->expires == NGX_HTTP_EXPIRES_OFF
+&& conf->headers == NULL
+&& conf->trailers == NULL)
 {
 return ngx_http_next_header_filter(r);
 }
@@ -205,6 +225,84 @@ ngx_http_headers_filter(ngx_http_request
 }
 }
 
+if (conf->trailers && r->allow_trailers) {
+
+if (r->http_version < NGX_HTTP_VERSION_20) {
+if (r->header_only
+|| r->headers_out.status == NGX_HTTP_NOT_MODIFIED
+|| r->headers_out.status == NGX_HTTP_NO_CONTENT
+|| r->headers_out.status < NGX_HTTP_OK
+|| r->method == NGX_HTTP_HEAD)
+{
+   return ngx_http_next_header_filter(r);
+}
+
+clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+if (!clcf->chunked_transfer_encoding) {
+return ngx_http_next_header_filter(r);
+}
+}
+
+len = 0;
+
+h = conf->trailers->elts;
+for (i = 0; i < conf->trailers->nelts; i++) {
+
+if (!safe_status && !h[i].always) {
+continue;
+}
+
+if (h[i].value.value.len) {
+len += h[i].key.len + sizeof(", ") - 1;
+}
+}
+
+if (len == 0) {
+return ngx_http_next_header_filter(r);
+}
+
+len -= sizeof(", ") - 1;
+
+t = ngx_list_push(&r->headers_out.headers);
+if (t == NULL) {
+return NGX_ERROR;
+}
+
+data = ngx_pnalloc(r->pool, len);
+if (data == NULL) {
+return NGX_ERROR;
+}
+
+p = data;
+
+h = conf->trailers->elts;
+for (i = 0; i < conf->trailers->nelts; i++) {
+
+if (!safe_status && !h[i].always) {
+continue;
+}
+
+if (h[i].value.value.len) {
+p = ngx_copy(p, h[i].key.data, h[i].key.len);
+
+if (p == data + len) {
+

[PATCH 3 of 3] Upstream: add support for trailers in HTTP responses

2017-04-03 Thread Piotr Sikora via nginx-devel
# HG changeset patch
# User Piotr Sikora 
# Date 1490351854 25200
#  Fri Mar 24 03:37:34 2017 -0700
# Node ID 488c59bd49dcb1503144fe4d712165b69d1a5945
# Parent  5bab17ebe2b1f8ec42cf069bf484489c2a92c7a8
Upstream: add support for trailers in HTTP responses.

Please note that due to how upstream module terminates processing of
responses that cannot have message body (responses to HEAD requests,
and responses with 1xx, 204 and 304 status codes), trailers of those
responses won't be passed to the downstream.

This change also adds $upstream_trailer_* variables.

Signed-off-by: Piotr Sikora 

diff -r 5bab17ebe2b1 -r 488c59bd49dc src/http/modules/ngx_http_fastcgi_module.c
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -2784,10 +2784,10 @@ ngx_http_fastcgi_create_loc_conf(ngx_con
 
 conf->upstream.intercept_errors = NGX_CONF_UNSET;
 
-/* "fastcgi_cyclic_temp_file" is disabled */
+/* the hardcoded values */
 conf->upstream.cyclic_temp_file = 0;
-
 conf->upstream.change_buffering = 1;
+conf->upstream.pass_trailers = 0;
 
 conf->catch_stderr = NGX_CONF_UNSET_PTR;
 
diff -r 5bab17ebe2b1 -r 488c59bd49dc 
src/http/modules/ngx_http_memcached_module.c
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -619,6 +619,7 @@ ngx_http_memcached_create_loc_conf(ngx_c
 conf->upstream.pass_request_headers = 0;
 conf->upstream.pass_request_body = 0;
 conf->upstream.force_ranges = 1;
+conf->upstream.pass_trailers = 0;
 
 conf->index = NGX_CONF_UNSET;
 conf->gzip_flag = NGX_CONF_UNSET_UINT;
diff -r 5bab17ebe2b1 -r 488c59bd49dc src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -2886,11 +2886,12 @@ ngx_http_proxy_create_loc_conf(ngx_conf_
 conf->ssl_passwords = NGX_CONF_UNSET_PTR;
 #endif
 
-/* "proxy_cyclic_temp_file" is disabled */
+/* the hardcoded values */
 conf->upstream.cyclic_temp_file = 0;
+conf->upstream.change_buffering = 1;
+conf->upstream.pass_trailers = 0;
 
 conf->redirect = NGX_CONF_UNSET;
-conf->upstream.change_buffering = 1;
 
 conf->cookie_domains = NGX_CONF_UNSET_PTR;
 conf->cookie_paths = NGX_CONF_UNSET_PTR;
diff -r 5bab17ebe2b1 -r 488c59bd49dc src/http/modules/ngx_http_scgi_module.c
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -1234,10 +1234,10 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t
 
 conf->upstream.intercept_errors = NGX_CONF_UNSET;
 
-/* "scgi_cyclic_temp_file" is disabled */
+/* the hardcoded values */
 conf->upstream.cyclic_temp_file = 0;
-
 conf->upstream.change_buffering = 1;
+conf->upstream.pass_trailers = 0;
 
 ngx_str_set(&conf->upstream.module, "scgi");
 
diff -r 5bab17ebe2b1 -r 488c59bd49dc src/http/modules/ngx_http_uwsgi_module.c
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -1448,10 +1448,10 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_
 conf->ssl_passwords = NGX_CONF_UNSET_PTR;
 #endif
 
-/* "uwsgi_cyclic_temp_file" is disabled */
+/* the hardcoded values */
 conf->upstream.cyclic_temp_file = 0;
-
 conf->upstream.change_buffering = 1;
+conf->upstream.pass_trailers = 0;
 
 ngx_str_set(&conf->upstream.module, "uwsgi");
 
diff -r 5bab17ebe2b1 -r 488c59bd49dc src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -55,6 +55,8 @@ static ngx_int_t ngx_http_upstream_inter
 static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c);
 static ngx_int_t ngx_http_upstream_process_headers(ngx_http_request_t *r,
 ngx_http_upstream_t *u);
+static ngx_int_t ngx_http_upstream_process_trailers(ngx_http_request_t *r,
+ngx_http_upstream_t *u);
 static void ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
 ngx_http_upstream_t *u);
 static void ngx_http_upstream_send_response(ngx_http_request_t *r,
@@ -149,6 +151,8 @@ static ngx_int_t ngx_http_upstream_rewri
 ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
 ngx_table_elt_t *h, ngx_uint_t offset);
+static ngx_int_t ngx_http_upstream_copy_trailer(ngx_http_request_t *r,
+ngx_table_elt_t *h, ngx_uint_t offset);
 
 #if (NGX_HTTP_GZIP)
 static ngx_int_t ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r,
@@ -166,6 +170,8 @@ static ngx_int_t ngx_http_upstream_respo
 ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
 ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_upstream_trailer_variable(ngx_http_request_t *r,
+ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
  

Re: [PATCH 3 of 3] Upstream: add support for trailers in HTTP responses

2017-04-03 Thread Piotr Sikora via nginx-devel
Hey,

> +static ngx_int_t
> +ngx_http_upstream_copy_trailer(ngx_http_request_t *r,
> +ngx_table_elt_t *h, ngx_uint_t offset)
> +{
> +ngx_table_elt_t  *ho;
> +
> +if (!r->upstream->conf->pass_trailers
> +|| !r->allow_trailers || !r->expect_trailers)
> +{
> +return NGX_OK;
> +}
> +
> +ho = ngx_list_push(&r->headers_out.headers);
> +if (ho == NULL) {
> +return NGX_ERROR;
> +}
> +
> +*ho = *h;
> +
> +return NGX_OK;
> +}

Patch updated so that "Trailer" header is only forwarded with trailers.

Best regards,
Piotr Sikora
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


[nginx] Slice filter: allowed at most one subrequest at a time.

2017-04-03 Thread Roman Arutyunyan
details:   http://hg.nginx.org/nginx/rev/a97ad1663ef4
branches:  
changeset: 6962:a97ad1663ef4
user:  Roman Arutyunyan 
date:  Tue Mar 28 14:03:57 2017 +0300
description:
Slice filter: allowed at most one subrequest at a time.

Previously, if slice main request write handler was called while a slice
subrequest was running, a new subrequest for the same slice was started.

diffstat:

 src/http/modules/ngx_http_slice_filter_module.c |  28 ++--
 1 files changed, 16 insertions(+), 12 deletions(-)

diffs (73 lines):

diff -r 903fb1ddc07f -r a97ad1663ef4 
src/http/modules/ngx_http_slice_filter_module.c
--- a/src/http/modules/ngx_http_slice_filter_module.c   Sun Apr 02 14:32:29 
2017 +0300
+++ b/src/http/modules/ngx_http_slice_filter_module.c   Tue Mar 28 14:03:57 
2017 +0300
@@ -11,23 +11,24 @@
 
 
 typedef struct {
-size_t  size;
+size_t   size;
 } ngx_http_slice_loc_conf_t;
 
 
 typedef struct {
-off_t   start;
-off_t   end;
-ngx_str_t   range;
-ngx_str_t   etag;
-ngx_uint_t  last;  /* unsigned  last:1; */
+off_tstart;
+off_tend;
+ngx_str_trange;
+ngx_str_tetag;
+ngx_uint_t   last;  /* unsigned  last:1; */
+ngx_http_request_t  *sr;
 } ngx_http_slice_ctx_t;
 
 
 typedef struct {
-off_t   start;
-off_t   end;
-off_t   complete_length;
+off_tstart;
+off_tend;
+off_tcomplete_length;
 } ngx_http_slice_content_range_t;
 
 
@@ -209,7 +210,6 @@ ngx_http_slice_body_filter(ngx_http_requ
 {
 ngx_int_t   rc;
 ngx_chain_t*cl;
-ngx_http_request_t *sr;
 ngx_http_slice_ctx_t   *ctx;
 ngx_http_slice_loc_conf_t  *slcf;
 
@@ -234,6 +234,10 @@ ngx_http_slice_body_filter(ngx_http_requ
 return rc;
 }
 
+if (ctx->sr && !ctx->sr->done) {
+return rc;
+}
+
 if (ctx->start >= ctx->end) {
 ngx_http_set_ctx(r, NULL, ngx_http_slice_filter_module);
 ngx_http_send_special(r, NGX_HTTP_LAST);
@@ -244,14 +248,14 @@ ngx_http_slice_body_filter(ngx_http_requ
 return rc;
 }
 
-if (ngx_http_subrequest(r, &r->uri, &r->args, &sr, NULL,
+if (ngx_http_subrequest(r, &r->uri, &r->args, &ctx->sr, NULL,
 NGX_HTTP_SUBREQUEST_CLONE)
 != NGX_OK)
 {
 return NGX_ERROR;
 }
 
-ngx_http_set_ctx(sr, ctx, ngx_http_slice_filter_module);
+ngx_http_set_ctx(ctx->sr, ctx, ngx_http_slice_filter_module);
 
 slcf = ngx_http_get_module_loc_conf(r, ngx_http_slice_filter_module);
 
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


[nginx] Slice filter: prevented slice redirection (ticket #1219).

2017-04-03 Thread Roman Arutyunyan
details:   http://hg.nginx.org/nginx/rev/3ff293cfdab8
branches:  
changeset: 6963:3ff293cfdab8
user:  Roman Arutyunyan 
date:  Fri Mar 31 21:47:56 2017 +0300
description:
Slice filter: prevented slice redirection (ticket #1219).

When a slice subrequest was redirected to a new location, its context was lost.
After its completion, a new slice subrequest for the same slice was created.
This could lead to infinite loop.  Now the slice module makes sure each slice
subrequest starts output with the slice context available.

diffstat:

 src/http/modules/ngx_http_slice_filter_module.c |  12 +++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diffs (43 lines):

diff -r a97ad1663ef4 -r 3ff293cfdab8 
src/http/modules/ngx_http_slice_filter_module.c
--- a/src/http/modules/ngx_http_slice_filter_module.c   Tue Mar 28 14:03:57 
2017 +0300
+++ b/src/http/modules/ngx_http_slice_filter_module.c   Fri Mar 31 21:47:56 
2017 +0300
@@ -20,7 +20,8 @@ typedef struct {
 off_tend;
 ngx_str_trange;
 ngx_str_tetag;
-ngx_uint_t   last;  /* unsigned  last:1; */
+unsigned last:1;
+unsigned active:1;
 ngx_http_request_t  *sr;
 } ngx_http_slice_ctx_t;
 
@@ -170,6 +171,7 @@ ngx_http_slice_header_filter(ngx_http_re
 }
 
 ctx->start = end;
+ctx->active = 1;
 
 r->headers_out.status = NGX_HTTP_OK;
 r->headers_out.status_line.len = 0;
@@ -238,6 +240,12 @@ ngx_http_slice_body_filter(ngx_http_requ
 return rc;
 }
 
+if (!ctx->active) {
+ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+  "missing slice response");
+return NGX_ERROR;
+}
+
 if (ctx->start >= ctx->end) {
 ngx_http_set_ctx(r, NULL, ngx_http_slice_filter_module);
 ngx_http_send_special(r, NGX_HTTP_LAST);
@@ -263,6 +271,8 @@ ngx_http_slice_body_filter(ngx_http_requ
  ctx->start + (off_t) slcf->size - 1)
  - ctx->range.data;
 
+ctx->active = 0;
+
 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http slice subrequest: \"%V\"", &ctx->range);
 
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Array iterators optimizations.

2017-04-03 Thread Igor Sysoev
details:   http://hg.nginx.org/njs/rev/cee288760080
branches:  
changeset: 328:cee288760080
user:  Igor Sysoev 
date:  Sun Apr 02 12:35:11 2017 +0300
description:
Array iterators optimizations.

diffstat:

 njs/njs_array.c  |  221 +-
 njs/test/njs_unit_test.c |4 +
 2 files changed, 122 insertions(+), 103 deletions(-)

diffs (498 lines):

diff -r 8f59eeb8ee2d -r cee288760080 njs/njs_array.c
--- a/njs/njs_array.c   Sat Apr 01 15:32:04 2017 +0300
+++ b/njs/njs_array.c   Sun Apr 02 12:35:11 2017 +0300
@@ -44,7 +44,7 @@ typedef struct {
  */
 njs_value_t retval;
 
-uint32_tnext_index;
+uint32_tindex;
 uint32_tlength;
 } njs_array_iter_t;
 
@@ -59,7 +59,6 @@ typedef struct {
 typedef struct {
 njs_array_iter_titer;
 njs_array_t *array;
-uint32_tindex;
 } njs_array_map_t;
 
 
@@ -95,17 +94,20 @@ static njs_ret_t njs_array_prototype_fil
 njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
 static njs_ret_t njs_array_prototype_map_continuation(njs_vm_t *vm,
 njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
+static nxt_noinline uint32_t njs_array_prototype_map_index(njs_array_t *array,
+njs_array_map_t *map);
+static nxt_noinline njs_ret_t njs_array_iterator_args(njs_vm_t *vm,
+njs_value_t *args, nxt_uint_t nargs);
+static nxt_noinline uint32_t njs_array_iterator_index(njs_array_t *array,
+njs_array_iter_t *iter);
+static nxt_noinline njs_ret_t njs_array_iterator_apply(njs_vm_t *vm,
+njs_array_iter_t *iter, njs_value_t *args, nxt_uint_t nargs);
 static njs_ret_t njs_array_prototype_reduce_continuation(njs_vm_t *vm,
 njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
 static njs_ret_t njs_array_prototype_reduce_right_continuation(njs_vm_t *vm,
 njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
-static nxt_noinline njs_ret_t njs_array_iterator_args(njs_vm_t *vm,
-njs_value_t *args, nxt_uint_t nargs);
-static nxt_noinline uint32_t njs_array_iterator_next(njs_array_t *array,
-uint32_t n, uint32_t length);
-static nxt_noinline njs_ret_t njs_array_iterator_apply(njs_vm_t *vm,
-njs_array_iter_t *iter, njs_value_t *args, nxt_uint_t nargs);
-static uint32_t njs_array_reduce_right_next(njs_array_t *array, uint32_t n);
+static uint32_t njs_array_reduce_right_index(njs_array_t *array,
+njs_array_iter_t *iter);
 static njs_ret_t njs_array_prototype_sort_continuation(njs_vm_t *vm,
 njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
 
@@ -1222,11 +1224,14 @@ static njs_ret_t
 njs_array_prototype_for_each_continuation(njs_vm_t *vm, njs_value_t *args,
 nxt_uint_t nargs, njs_index_t unused)
 {
+uint32_t  index;
 njs_array_iter_t  *iter;
 
 iter = njs_vm_continuation(vm);
 
-if (iter->next_index >= args[0].data.u.array->length) {
+index = njs_array_iterator_index(args[0].data.u.array, iter);
+
+if (index == NJS_ARRAY_INVALID_INDEX) {
 vm->retval = njs_value_void;
 return NXT_OK;
 }
@@ -1259,6 +1264,7 @@ static njs_ret_t
 njs_array_prototype_some_continuation(njs_vm_t *vm, njs_value_t *args,
 nxt_uint_t nargs, njs_index_t unused)
 {
+uint32_t   index;
 njs_array_iter_t   *iter;
 const njs_value_t  *retval;
 
@@ -1267,11 +1273,15 @@ njs_array_prototype_some_continuation(nj
 if (njs_is_true(&iter->retval)) {
 retval = &njs_value_true;
 
-} else if (iter->next_index >= args[0].data.u.array->length) {
-retval = &njs_value_false;
-
 } else {
-return njs_array_iterator_apply(vm, iter, args, nargs);
+index = njs_array_iterator_index(args[0].data.u.array, iter);
+
+if (index == NJS_ARRAY_INVALID_INDEX) {
+retval = &njs_value_false;
+
+} else {
+return njs_array_iterator_apply(vm, iter, args, nargs);
+}
 }
 
 vm->retval = *retval;
@@ -1304,6 +1314,7 @@ static njs_ret_t
 njs_array_prototype_every_continuation(njs_vm_t *vm, njs_value_t *args,
 nxt_uint_t nargs, njs_index_t unused)
 {
+uint32_t   index;
 njs_array_iter_t   *iter;
 const njs_value_t  *retval;
 
@@ -1312,11 +1323,15 @@ njs_array_prototype_every_continuation(n
 if (!njs_is_true(&iter->retval)) {
 retval = &njs_value_false;
 
-} else if (iter->next_index >= args[0].data.u.array->length) {
-retval = &njs_value_true;
-
 } else {
-return njs_array_iterator_apply(vm, iter, args, nargs);
+index = njs_array_iterator_index(args[0].data.u.array, iter);
+
+if (index == NJS_ARRAY_INVALID_INDEX) {
+retval = &njs_value_true;
+
+} else {
+return njs_array_iterator_apply(vm, iter, args, nargs);
+}
 }
 
 vm->retval = *retval;
@@ -1417,6 +1432,7 @@ static njs_ret_t
 njs_array_prototype_filter_continuation(njs_vm_t *vm, njs_val

[njs] Variables may be accessed incorrectly by nested functions.

2017-04-03 Thread Igor Sysoev
details:   http://hg.nginx.org/njs/rev/c46da90ca064
branches:  
changeset: 329:c46da90ca064
user:  Igor Sysoev 
date:  Sun Apr 02 12:36:05 2017 +0300
description:
Variables may be accessed incorrectly by nested functions.

diffstat:

 njs/njs_parser.c |  5 +
 njs/test/njs_unit_test.c |  5 +
 2 files changed, 10 insertions(+), 0 deletions(-)

diffs (30 lines):

diff -r cee288760080 -r c46da90ca064 njs/njs_parser.c
--- a/njs/njs_parser.c  Sun Apr 02 12:35:11 2017 +0300
+++ b/njs/njs_parser.c  Sun Apr 02 12:36:05 2017 +0300
@@ -215,6 +215,11 @@ njs_parser_scope_begin(njs_vm_t *vm, njs
 
 if (parent != NULL) {
 nxt_queue_insert_tail(&parent->nested, &scope->link);
+
+if (nesting == 0) {
+/* Inherit function nesting in blocks. */
+scope->nesting = parent->nesting;
+}
 }
 
 return NXT_OK;
diff -r cee288760080 -r c46da90ca064 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c  Sun Apr 02 12:35:11 2017 +0300
+++ b/njs/test/njs_unit_test.c  Sun Apr 02 12:36:05 2017 +0300
@@ -4221,6 +4221,11 @@ static njs_unit_test_t  njs_test[] =
  "var y = f(); y()"),
   nxt_string("4") },
 
+{ nxt_string("function f() { var x = 4;"
+ "function g() { if (1) { return 2 + x; } }; return g }"
+ "var y = f(); y()"),
+  nxt_string("6") },
+
 /* Recursive fibonacci. */
 
 { nxt_string("function fibo(n) {"
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Large indexes processing has been fixed in

2017-04-03 Thread Igor Sysoev
details:   http://hg.nginx.org/njs/rev/8f59eeb8ee2d
branches:  
changeset: 327:8f59eeb8ee2d
user:  Igor Sysoev 
date:  Sat Apr 01 15:32:04 2017 +0300
description:
Large indexes processing has been fixed in
Array.prototype.reduceRight().

diffstat:

 njs/njs_array.c |  2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diffs (12 lines):

diff -r dc8af19bf47d -r 8f59eeb8ee2d njs/njs_array.c
--- a/njs/njs_array.c   Fri Mar 31 14:05:44 2017 +0300
+++ b/njs/njs_array.c   Sat Apr 01 15:32:04 2017 +0300
@@ -1716,7 +1716,7 @@ njs_array_prototype_reduce_right_continu
 
 iter = njs_vm_continuation(vm);
 
-if ((int32_t) iter->next_index < 0) {
+if (iter->next_index == NJS_ARRAY_INVALID_INDEX) {
 vm->retval = iter->retval;
 return NXT_OK;
 }
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


[nginx] Fixed type.

2017-04-03 Thread Maxim Dounin
details:   http://hg.nginx.org/nginx/rev/5d3d9b52327d
branches:  
changeset: 6964:5d3d9b52327d
user:  hucongcong 
date:  Mon Apr 03 14:29:40 2017 +0800
description:
Fixed type.

diffstat:

 src/http/ngx_http_request.c |  4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diffs (21 lines):

diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2612,7 +2612,7 @@ ngx_http_set_write_handler(ngx_http_requ
 static void
 ngx_http_writer(ngx_http_request_t *r)
 {
-intrc;
+ngx_int_t  rc;
 ngx_event_t   *wev;
 ngx_connection_t  *c;
 ngx_http_core_loc_conf_t  *clcf;
@@ -2652,7 +2652,7 @@ ngx_http_writer(ngx_http_request_t *r)
 rc = ngx_http_output_filter(r, NULL);
 
 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
-   "http writer output filter: %d, \"%V?%V\"",
+   "http writer output filter: %i, \"%V?%V\"",
rc, &r->uri, &r->args);
 
 if (rc == NGX_ERROR) {
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH][bugfix] Upstream: clear the delayed flag to prevent blocking from sending.

2017-04-03 Thread Maxim Dounin
Hello!

On Mon, Apr 03, 2017 at 04:02:07PM +0800, 胡聪 (hucc) wrote:

[...]

> At the same time, I noticed that the type of rc is int not ngx_int_t in
> ngx_http_writer(). The type should be ngx_int_t, right? There was a time the
> return type of ngx_http_writer() is int. Later, it became void. Since then 
> there
> is no need to do type conversion.

The "int" here was introduced at the time when there were no 
ngx_int_t and all functions simply used int.  When ngx_int_t was 
introduced and relevant functions was changed to use it, the type 
in ngx_http_writer() wasn't changed.  This isn't a problem as 
there is no real difference, though it certainly make sense to use 
correct type here at least from style point of view.

> 
> # HG changeset patch
> # User hucongcong 
> # Date 1491200980 -28800
> #  Mon Apr 03 14:29:40 2017 +0800
> # Node ID 7c3a0b951d0209612fb50a48abcb10c6ceffbff7
> # Parent  903fb1ddc07f6b4345d88428898d95aadfc0223f
> fix type
> 
> diff -r 903fb1ddc07f -r 7c3a0b951d02 src/http/ngx_http_request.c
> --- a/src/http/ngx_http_request.c Sun Apr 02 14:32:29 2017 +0300
> +++ b/src/http/ngx_http_request.c Mon Apr 03 14:29:40 2017 +0800
> @@ -2612,7 +2612,7 @@ ngx_http_set_write_handler(ngx_http_requ
>  static void
>  ngx_http_writer(ngx_http_request_t *r)
>  {
> -intrc;
> +ngx_int_t  rc;
>  ngx_event_t   *wev;
>  ngx_connection_t  *c;
>  ngx_http_core_loc_conf_t  *clcf;
> @@ -2652,7 +2652,7 @@ ngx_http_writer(ngx_http_request_t *r)
>  rc = ngx_http_output_filter(r, NULL);
> 
>  ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
> -   "http writer output filter: %d, \"%V?%V\"",
> +   "http writer output filter: %i, \"%V?%V\"",
> rc, &r->uri, &r->args);
> 
>  if (rc == NGX_ERROR) {

Committed with the commit log changed to match our style, thanks.

-- 
Maxim Dounin
http://nginx.org/
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

[nginx] Added support for "429 Too Many Requests" response (RFC6585).

2017-04-03 Thread Maxim Dounin
details:   http://hg.nginx.org/nginx/rev/3ef4cadfad7f
branches:  
changeset: 6965:3ef4cadfad7f
user:  Piotr Sikora 
date:  Fri Mar 24 02:48:03 2017 -0700
description:
Added support for "429 Too Many Requests" response (RFC6585).

This change adds reason phrase in status line and pretty response body
when "429" status code is used in "return", "limit_conn_status" and/or
"limit_req_status" directives.

Signed-off-by: Piotr Sikora 

diffstat:

 src/http/ngx_http_header_filter_module.c |  14 +-
 src/http/ngx_http_request.h  |   1 +
 src/http/ngx_http_special_response.c |  18 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

diffs (72 lines):

diff --git a/src/http/ngx_http_header_filter_module.c 
b/src/http/ngx_http_header_filter_module.c
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -101,12 +101,16 @@ static ngx_str_t ngx_http_status_lines[]
 ngx_null_string,  /* "419 unused" */
 ngx_null_string,  /* "420 unused" */
 ngx_string("421 Misdirected Request"),
+ngx_null_string,  /* "422 Unprocessable Entity" */
+ngx_null_string,  /* "423 Locked" */
+ngx_null_string,  /* "424 Failed Dependency" */
+ngx_null_string,  /* "425 unused" */
+ngx_null_string,  /* "426 Upgrade Required" */
+ngx_null_string,  /* "427 unused" */
+ngx_null_string,  /* "428 Precondition Required" */
+ngx_string("429 Too Many Requests"),
 
-/* ngx_null_string, */  /* "422 Unprocessable Entity" */
-/* ngx_null_string, */  /* "423 Locked" */
-/* ngx_null_string, */  /* "424 Failed Dependency" */
-
-#define NGX_HTTP_LAST_4XX  422
+#define NGX_HTTP_LAST_4XX  430
 #define NGX_HTTP_OFF_5XX   (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)
 
 ngx_string("500 Internal Server Error"),
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -98,6 +98,7 @@
 #define NGX_HTTP_UNSUPPORTED_MEDIA_TYPE415
 #define NGX_HTTP_RANGE_NOT_SATISFIABLE 416
 #define NGX_HTTP_MISDIRECTED_REQUEST   421
+#define NGX_HTTP_TOO_MANY_REQUESTS 429
 
 
 /* Our own HTTP codes */
diff --git a/src/http/ngx_http_special_response.c 
b/src/http/ngx_http_special_response.c
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -225,6 +225,14 @@ static char ngx_http_error_421_page[] =
 ;
 
 
+static char ngx_http_error_429_page[] =
+"" CRLF
+"429 Too Many Requests" CRLF
+"" CRLF
+"429 Too Many Requests" CRLF
+;
+
+
 static char ngx_http_error_494_page[] =
 "" CRLF
 "400 Request Header Or Cookie Too Large"
@@ -354,8 +362,16 @@ static ngx_str_t ngx_http_error_pages[] 
 ngx_null_string, /* 419 */
 ngx_null_string, /* 420 */
 ngx_string(ngx_http_error_421_page),
+ngx_null_string, /* 422 */
+ngx_null_string, /* 423 */
+ngx_null_string, /* 424 */
+ngx_null_string, /* 425 */
+ngx_null_string, /* 426 */
+ngx_null_string, /* 427 */
+ngx_null_string, /* 428 */
+ngx_string(ngx_http_error_429_page),
 
-#define NGX_HTTP_LAST_4XX  422
+#define NGX_HTTP_LAST_4XX  430
 #define NGX_HTTP_OFF_5XX   (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)
 
 ngx_string(ngx_http_error_494_page), /* 494, request header too large */
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


[nginx] Upstream: allow recovery from "429 Too Many Requests" response.

2017-04-03 Thread Maxim Dounin
details:   http://hg.nginx.org/nginx/rev/fa56ab75cffc
branches:  
changeset: 6966:fa56ab75cffc
user:  Piotr Sikora 
date:  Fri Mar 24 02:48:03 2017 -0700
description:
Upstream: allow recovery from "429 Too Many Requests" response.

This change adds "http_429" parameter to "proxy_next_upstream" for
retrying rate-limited requests, and to "proxy_cache_use_stale" for
serving stale cached responses after being rate-limited.

Signed-off-by: Piotr Sikora 

diffstat:

 src/http/modules/ngx_http_fastcgi_module.c |   1 +
 src/http/modules/ngx_http_proxy_module.c   |   1 +
 src/http/modules/ngx_http_scgi_module.c|   1 +
 src/http/modules/ngx_http_uwsgi_module.c   |   1 +
 src/http/ngx_http_upstream.c   |   5 +
 src/http/ngx_http_upstream.h   |  12 +++-
 6 files changed, 16 insertions(+), 5 deletions(-)

diffs (95 lines):

diff --git a/src/http/modules/ngx_http_fastcgi_module.c 
b/src/http/modules/ngx_http_fastcgi_module.c
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -211,6 +211,7 @@ static ngx_conf_bitmask_t  ngx_http_fast
 { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
 { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
 { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+{ ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
 { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
 { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
 { ngx_null_string, 0 }
diff --git a/src/http/modules/ngx_http_proxy_module.c 
b/src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -220,6 +220,7 @@ static ngx_conf_bitmask_t  ngx_http_prox
 { ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 },
 { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
 { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+{ ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
 { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
 { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
 { ngx_null_string, 0 }
diff --git a/src/http/modules/ngx_http_scgi_module.c 
b/src/http/modules/ngx_http_scgi_module.c
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -82,6 +82,7 @@ static ngx_conf_bitmask_t ngx_http_scgi_
 { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
 { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
 { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+{ ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
 { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
 { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
 { ngx_null_string, 0 }
diff --git a/src/http/modules/ngx_http_uwsgi_module.c 
b/src/http/modules/ngx_http_uwsgi_module.c
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -114,6 +114,7 @@ static ngx_conf_bitmask_t ngx_http_uwsgi
 { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
 { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
 { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+{ ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
 { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
 { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
 { ngx_null_string, 0 }
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -436,6 +436,7 @@ static ngx_http_upstream_next_t  ngx_htt
 { 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 },
 { 403, NGX_HTTP_UPSTREAM_FT_HTTP_403 },
 { 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+{ 429, NGX_HTTP_UPSTREAM_FT_HTTP_429 },
 { 0, 0 }
 };
 
@@ -4126,6 +4127,10 @@ ngx_http_upstream_next(ngx_http_request_
 status = NGX_HTTP_NOT_FOUND;
 break;
 
+case NGX_HTTP_UPSTREAM_FT_HTTP_429:
+status = NGX_HTTP_TOO_MANY_REQUESTS;
+break;
+
 /*
  * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING
  * never reach here
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -26,10 +26,11 @@
 #define NGX_HTTP_UPSTREAM_FT_HTTP_5040x0080
 #define NGX_HTTP_UPSTREAM_FT_HTTP_4030x0100
 #define NGX_HTTP_UPSTREAM_FT_HTTP_4040x0200
-#define NGX_HTTP_UPSTREAM_FT_UPDATING0x0400
-#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK   0x0800
-#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x1000
-#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT  0x2000
+#define NGX_HTTP_UPSTREAM_FT_HTTP_4290x0400
+#define NGX_HTTP_UPSTREAM_FT_UPDATING0x0800
+#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK   0x1000
+#define NGX_HTTP_UPSTREAM_FT_MAX_W

Re: [PATCH 1 of 2] HTTP: add support for "429 Too Many Requests" response (RFC6585)

2017-04-03 Thread Maxim Dounin
Hello!

On Fri, Mar 24, 2017 at 03:47:40AM -0700, Piotr Sikora via nginx-devel wrote:

> # HG changeset patch
> # User Piotr Sikora 
> # Date 1490348883 25200
> #  Fri Mar 24 02:48:03 2017 -0700
> # Node ID 799ef976b58cadbc212bd790a666033d3777c10d
> # Parent  39ff6939266e913e8bfd400e60f9520e70725a4d
> HTTP: add support for "429 Too Many Requests" response (RFC6585).
> 
> This change adds reason phrase in status line and pretty response body
> when "429" status code is used in "return", "limit_conn_status" and/or
> "limit_req_status" directives.
> 
> Signed-off-by: Piotr Sikora 

We do not use "HTTP:" prefix, and prefer past tense in commit 
messages.  Overwise looks good, committed, thanks.

[...]

-- 
Maxim Dounin
http://nginx.org/
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH 2 of 2] Upstream: allow recovery from "429 Too Many Requests" response

2017-04-03 Thread Maxim Dounin
Hello!

On Fri, Mar 24, 2017 at 03:47:41AM -0700, Piotr Sikora via nginx-devel wrote:

> # HG changeset patch
> # User Piotr Sikora 
> # Date 1490348883 25200
> #  Fri Mar 24 02:48:03 2017 -0700
> # Node ID b377cfedf632b14a3d459e12342a0557a25a790c
> # Parent  799ef976b58cadbc212bd790a666033d3777c10d
> Upstream: allow recovery from "429 Too Many Requests" response.
> 
> This change adds "http_429" parameter to "proxy_next_upstream" for
> retrying rate-limited requests, and to "proxy_cache_use_stale" for
> serving stale cached responses after being rate-limited.
> 
> Signed-off-by: Piotr Sikora 

[...]

Committed, thanks.

-- 
Maxim Dounin
http://nginx.org/
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


[PATCH] HTTP/2: add debug logging of control frames

2017-04-03 Thread Piotr Sikora via nginx-devel
# HG changeset patch
# User Piotr Sikora 
# Date 1490516711 25200
#  Sun Mar 26 01:25:11 2017 -0700
# Node ID 06d6418afe6e73604aea707ef9c5802f5bf27bf4
# Parent  22be63bf21edaa1b8ea916c7d8cd4e5fe4892061
HTTP/2: add debug logging of control frames.

Signed-off-by: Piotr Sikora 

diff -r 22be63bf21ed -r 06d6418afe6e src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -1955,6 +1955,9 @@ ngx_http_v2_state_settings(ngx_http_v2_c
 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
 }
 
+ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+   "http2 SETTINGS frame ack:1");
+
 h2c->settings_ack = 1;
 
 return ngx_http_v2_state_complete(h2c, pos, end);
@@ -1968,6 +1971,10 @@ ngx_http_v2_state_settings(ngx_http_v2_c
 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
 }
 
+ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+   "http2 SETTINGS frame params:%uz",
+   h2c->state.length / NGX_HTTP_V2_SETTINGS_PARAM_SIZE);
+
 ngx_http_v2_send_settings(h2c, 1);
 
 return ngx_http_v2_state_settings_params(h2c, pos, end);
@@ -2004,6 +2011,10 @@ ngx_http_v2_state_settings_params(ngx_ht
   NGX_HTTP_V2_FLOW_CTRL_ERROR);
 }
 
+ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+   "http2 SETTINGS frame INITIAL_WINDOW_SIZE:%ui",
+   value);
+
 if (ngx_http_v2_adjust_windows(h2c, value - h2c->init_window)
 != NGX_OK)
 {
@@ -2026,6 +2037,10 @@ ngx_http_v2_state_settings_params(ngx_ht
 
NGX_HTTP_V2_PROTOCOL_ERROR);
 }
 
+ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+   "http2 SETTINGS frame MAX_FRAME_SIZE:%ui",
+   value);
+
 h2c->frame_size = value;
 break;
 
@@ -2070,12 +2085,16 @@ ngx_http_v2_state_ping(ngx_http_v2_conne
 }
 
 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
-   "http2 PING frame, flags: %ud", h2c->state.flags);
+   "http2 PING frame ack:%ud",
+   h2c->state.flags & NGX_HTTP_V2_ACK_FLAG ? 1 : 0);
 
 if (h2c->state.flags & NGX_HTTP_V2_ACK_FLAG) {
 return ngx_http_v2_state_skip(h2c, pos, end);
 }
 
+ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+   "http2 send PING frame ack:1");
+
 frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_PING_SIZE,
   NGX_HTTP_V2_PING_FRAME,
   NGX_HTTP_V2_ACK_FLAG, 0);
@@ -2449,8 +2468,18 @@ ngx_http_v2_send_settings(ngx_http_v2_co
 ngx_http_v2_srv_conf_t   *h2scf;
 ngx_http_v2_out_frame_t  *frame;
 
-ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
-   "http2 send SETTINGS frame ack:%ui", ack);
+if (ack) {
+ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+   "http2 send SETTINGS frame ack:1");
+
+len = 0;
+
+} else {
+ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+   "http2 send SETTINGS frame params:3");
+
+len = NGX_HTTP_V2_SETTINGS_PARAM_SIZE * 3;
+}
 
 frame = ngx_palloc(h2c->pool, sizeof(ngx_http_v2_out_frame_t));
 if (frame == NULL) {
@@ -2462,8 +2491,6 @@ ngx_http_v2_send_settings(ngx_http_v2_co
 return NGX_ERROR;
 }
 
-len = ack ? 0 : (sizeof(uint16_t) + sizeof(uint32_t)) * 3;
-
 buf = ngx_create_temp_buf(h2c->pool, NGX_HTTP_V2_FRAME_HEADER_SIZE + len);
 if (buf == NULL) {
 return NGX_ERROR;
@@ -2494,15 +2521,27 @@ ngx_http_v2_send_settings(ngx_http_v2_co
 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
  ngx_http_v2_module);
 
+ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+   "http2 send SETTINGS frame MAX_CONCURRENT_STREAMS:%ui",
+   h2scf->concurrent_streams);
+
 buf->last = ngx_http_v2_write_uint16(buf->last,
  NGX_HTTP_V2_MAX_STREAMS_SETTING);
 buf->last = ngx_http_v2_write_uint32(buf->last,
  h2scf->concurrent_streams);
 
+ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+   "http2 send SETTINGS frame INITIAL_WINDOW_SIZE:%uz",
+   h2scf->preread_size);
+
 buf->last = ngx_http_v2_write_uint16(buf->last,
  NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING);
 buf->last = ngx_http_v2_write_uint32(buf->last, h2scf->preread_size);
 
+ngx

[PATCH] HTTP/2: add debug logging of pseudo-headers

2017-04-03 Thread Piotr Sikora via nginx-devel
# HG changeset patch
# User Piotr Sikora 
# Date 1490516711 25200
#  Sun Mar 26 01:25:11 2017 -0700
# Node ID 3d72ae17c41990774721a678c50b8307ecb684c8
# Parent  22be63bf21edaa1b8ea916c7d8cd4e5fe4892061
HTTP/2: add debug logging of pseudo-headers.

Signed-off-by: Piotr Sikora 

diff -r 22be63bf21ed -r 3d72ae17c419 src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -1585,6 +1585,10 @@ ngx_http_v2_state_process_header(ngx_htt
 rc = ngx_http_v2_pseudo_header(r, header);
 
 if (rc == NGX_OK) {
+ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+   "http2 http header: \":%V: %V\"",
+   &header->name, &header->value);
+
 return ngx_http_v2_state_header_complete(h2c, pos, end);
 }
 
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] HTTP/2: add debug logging of pseudo-headers and control frames

2017-04-03 Thread Piotr Sikora via nginx-devel
Hey,

> # HG changeset patch
> # User Piotr Sikora 
> # Date 1490516711 25200
> #  Sun Mar 26 01:25:11 2017 -0700
> # Node ID 6990fb6463ce47705e06ff6d0fbd9ae6696aeb37
> # Parent  22be63bf21edaa1b8ea916c7d8cd4e5fe4892061
> HTTP/2: add debug logging of pseudo-headers and control frames.
>
> Signed-off-by: Piotr Sikora 

This was split into:
http://mailman.nginx.org/pipermail/nginx-devel/2017-April/009767.html
http://mailman.nginx.org/pipermail/nginx-devel/2017-April/009768.html

Best regards,
Piotr Sikora
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel