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

2017-04-24 Thread Piotr Sikora via nginx-devel
Hey Valentin,

> I actually agree with that, but let's try to reduce the size of printing.
>
>   http2 send SETTINGS frame MAX_CONCURRENT_STREAMS
>   http2 send SETTINGS frame INITIAL_WINDOW_SIZE
>   http2 send SETTINGS frame MAX_FRAME_SIZE
>
> This looks like too verbose for just one SETTINGS frame.

What do you suggest instead? All 3 params in the same line?

   http2 send SETTINGS frame MAX_CONCURRENT_STREAMS:%ui
INITIAL_WINDOW_SIZE:%uz MAX_FRAME_SIZE:%ud

What about receiving part, then? Do you want to put all 6 params in
the same line?

   http2 recv SETTINGS frame HEADER_TABLE_SIZE:%ui (ignored)
ENABLE_PUSH:%ui (ignored) MAX_CONCURRENT_STREAMS:%ui (ignored)
INITIAL_WINDOW_SIZE:%ui MAX_FRAME_SIZE:%ui MAX_HEADER_LIST_SIZE:%ui
(ignored)

It makes this way less readable, IMHO.

> Also, literally
> reading these lines can be misinterpreted as sending multiple SETTINGS
> frames.

That's because you skipped the first line, i.e.:

   http2 send SETTINGS frame params:3
   http2 send SETTINGS frame MAX_CONCURRENT_STREAMS
   http2 send SETTINGS frame INITIAL_WINDOW_SIZE
   http2 send SETTINGS frame MAX_FRAME_SIZE

Best regards,
Piotr Sikora
___
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

2017-04-24 Thread Piotr Sikora via nginx-devel
Hey Valentin,

> I think that pseudo-headers have different processing and shouldn't be
> a part of the same block as normal http headers.  That's why I prefer
> the second variant:
>
> http2 pseudo-header: ":method: GET"

Fair enough, patch updated.

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


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

2017-04-24 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 164b95f24f414359c5b8045415da3de82653c4db
# Parent  2c4dbcd6f2e4c9c2a1eb8dc1f0d39c99975ae208
HTTP/2: add debug logging of pseudo-headers and cookies.

Signed-off-by: Piotr Sikora 

diff -r 2c4dbcd6f2e4 -r 164b95f24f41 src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -1589,6 +1589,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 pseudo-header: \":%V: %V\"",
+   &header->name, &header->value);
+
 return ngx_http_v2_state_header_complete(h2c, pos, end);
 }
 
@@ -1630,6 +1634,10 @@ ngx_http_v2_state_process_header(ngx_htt
 NGX_HTTP_V2_INTERNAL_ERROR);
 }
 
+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


[PATCH 4 of 4] HTTP/2: don't send SETTINGS ACK before already queued DATA frames

2017-04-24 Thread Piotr Sikora via nginx-devel
# HG changeset patch
# User Piotr Sikora 
# Date 1493073310 25200
#  Mon Apr 24 15:35:10 2017 -0700
# Node ID 3624fa075acac110a08c0f1c928c545a58c5801f
# Parent  b8d7f4a4d5abb4a27a772910358e263d49c618ef
HTTP/2: don't send SETTINGS ACK before already queued DATA frames.

Previously, SETTINGS ACK was sent immediately upon receipt of SETTINGS
frame, before already queued DATA frames created using old SETTINGS.

This incorrect behavior was source of interoperability issues, because
peers rely on the fact that new SETTINGS are in effect after receiving
SETTINGS ACK.

Reported by Feng Li.

Signed-off-by: Piotr Sikora 

diff -r b8d7f4a4d5ab -r 3624fa075aca src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -2043,7 +2043,7 @@ ngx_http_v2_state_settings_params(ngx_ht
 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
 }
 
-ngx_http_v2_queue_blocked_frame(h2c, frame);
+ngx_http_v2_queue_ordered_frame(h2c, frame);
 
 if (adjustment) {
 if (ngx_http_v2_adjust_windows(h2c, adjustment) != NGX_OK) {
diff -r b8d7f4a4d5ab -r 3624fa075aca src/http/v2/ngx_http_v2.h
--- a/src/http/v2/ngx_http_v2.h
+++ b/src/http/v2/ngx_http_v2.h
@@ -261,6 +261,15 @@ ngx_http_v2_queue_blocked_frame(ngx_http
 }
 
 
+static ngx_inline void
+ngx_http_v2_queue_ordered_frame(ngx_http_v2_connection_t *h2c,
+ngx_http_v2_out_frame_t *frame)
+{
+frame->next = h2c->last_out;
+h2c->last_out = frame;
+}
+
+
 void ngx_http_v2_init(ngx_event_t *rev);
 void ngx_http_v2_request_headers_init(void);
 
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


[PATCH 3 of 4] HTTP/2: make SETTINGS ACK frame reusable

2017-04-24 Thread Piotr Sikora via nginx-devel
# HG changeset patch
# User Piotr Sikora 
# Date 1493073310 25200
#  Mon Apr 24 15:35:10 2017 -0700
# Node ID b8d7f4a4d5abb4a27a772910358e263d49c618ef
# Parent  a8cfd4c454ff5433629bfd16444c6c71ee932fa1
HTTP/2: make SETTINGS ACK frame reusable.

Signed-off-by: Piotr Sikora 

diff -r a8cfd4c454ff -r b8d7f4a4d5ab src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -28,6 +28,7 @@
 #define NGX_HTTP_V2_HTTP_1_1_REQUIRED0xd
 
 /* frame sizes */
+#define NGX_HTTP_V2_SETTINGS_ACK_SIZE0
 #define NGX_HTTP_V2_RST_STREAM_SIZE  4
 #define NGX_HTTP_V2_PRIORITY_SIZE5
 #define NGX_HTTP_V2_PING_SIZE8
@@ -128,8 +129,7 @@ static ngx_http_v2_node_t *ngx_http_v2_g
 #define ngx_http_v2_index_size(h2scf)  (h2scf->streams_index_mask + 1)
 #define ngx_http_v2_index(h2scf, sid)  ((sid >> 1) & h2scf->streams_index_mask)
 
-static ngx_int_t ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c,
-ngx_uint_t ack);
+static ngx_int_t ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c);
 static ngx_int_t ngx_http_v2_settings_frame_handler(
 ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame);
 static ngx_int_t ngx_http_v2_send_window_update(ngx_http_v2_connection_t *h2c,
@@ -269,7 +269,7 @@ ngx_http_v2_init(ngx_event_t *rev)
 return;
 }
 
-if (ngx_http_v2_send_settings(h2c, 0) == NGX_ERROR) {
+if (ngx_http_v2_send_settings(h2c) == NGX_ERROR) {
 ngx_http_close_connection(c);
 return;
 }
@@ -1980,7 +1980,8 @@ static u_char *
 ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos,
 u_char *end)
 {
-ngx_uint_t  id, value, adjustment;
+ngx_uint_tid, value, adjustment;
+ngx_http_v2_out_frame_t  *frame;
 
 adjustment = 0;
 
@@ -2035,7 +2036,14 @@ ngx_http_v2_state_settings_params(ngx_ht
 pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE;
 }
 
-ngx_http_v2_send_settings(h2c, 1);
+frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_SETTINGS_ACK_SIZE,
+  NGX_HTTP_V2_SETTINGS_FRAME,
+  NGX_HTTP_V2_ACK_FLAG, 0);
+if (frame == NULL) {
+return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
+}
+
+ngx_http_v2_queue_blocked_frame(h2c, frame);
 
 if (adjustment) {
 if (ngx_http_v2_adjust_windows(h2c, adjustment) != NGX_OK) {
@@ -2487,7 +2495,7 @@ ngx_http_v2_parse_int(ngx_http_v2_connec
 
 
 static ngx_int_t
-ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c, ngx_uint_t ack)
+ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c)
 {
 size_tlen;
 ngx_buf_t*buf;
@@ -2495,8 +2503,8 @@ 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);
+ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+   "http2 send SETTINGS frame params:3");
 
 frame = ngx_palloc(h2c->pool, sizeof(ngx_http_v2_out_frame_t));
 if (frame == NULL) {
@@ -2508,7 +2516,7 @@ ngx_http_v2_send_settings(ngx_http_v2_co
 return NGX_ERROR;
 }
 
-len = ack ? 0 : (sizeof(uint16_t) + sizeof(uint32_t)) * 3;
+len = NGX_HTTP_V2_SETTINGS_PARAM_SIZE * 3;
 
 buf = ngx_create_temp_buf(h2c->pool, NGX_HTTP_V2_FRAME_HEADER_SIZE + len);
 if (buf == NULL) {
@@ -2532,28 +2540,26 @@ ngx_http_v2_send_settings(ngx_http_v2_co
 buf->last = ngx_http_v2_write_len_and_type(buf->last, len,
NGX_HTTP_V2_SETTINGS_FRAME);
 
-*buf->last++ = ack ? NGX_HTTP_V2_ACK_FLAG : NGX_HTTP_V2_NO_FLAG;
+*buf->last++ = NGX_HTTP_V2_NO_FLAG;
 
 buf->last = ngx_http_v2_write_sid(buf->last, 0);
 
-if (!ack) {
-h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
- ngx_http_v2_module);
-
-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);
-
-buf->last = ngx_http_v2_write_uint16(buf->last,
+h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
+ ngx_http_v2_module);
+
+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);
+
+buf->last = ngx_http_v2_write_uint16(buf->last,
  NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING);
-buf->last = ngx_http_v2_wri

[PATCH 2 of 4] HTTP/2: send SETTINGS ACK after applying all SETTINGS params

2017-04-24 Thread Piotr Sikora via nginx-devel
# HG changeset patch
# User Piotr Sikora 
# Date 1493073310 25200
#  Mon Apr 24 15:35:10 2017 -0700
# Node ID a8cfd4c454ff5433629bfd16444c6c71ee932fa1
# Parent  07adf0a7009c3244de4b795c0c06927f4316a87f
HTTP/2: send SETTINGS ACK after applying all SETTINGS params.

This avoids sending unnecessary SETTINGS ACK in case of PROTOCOL_ERROR.

Signed-off-by: Piotr Sikora 

diff -r 07adf0a7009c -r a8cfd4c454ff src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -1972,8 +1972,6 @@ ngx_http_v2_state_settings(ngx_http_v2_c
 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
 }
 
-ngx_http_v2_send_settings(h2c, 1);
-
 return ngx_http_v2_state_settings_params(h2c, pos, end);
 }
 
@@ -2037,6 +2035,8 @@ ngx_http_v2_state_settings_params(ngx_ht
 pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE;
 }
 
+ngx_http_v2_send_settings(h2c, 1);
+
 if (adjustment) {
 if (ngx_http_v2_adjust_windows(h2c, adjustment) != NGX_OK) {
 return ngx_http_v2_connection_error(h2c,
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


[PATCH 1 of 4] HTTP/2: emit new frames only after applying all SETTINGS params

2017-04-24 Thread Piotr Sikora via nginx-devel
# HG changeset patch
# User Piotr Sikora 
# Date 1493073310 25200
#  Mon Apr 24 15:35:10 2017 -0700
# Node ID 07adf0a7009c3244de4b795c0c06927f4316a87f
# Parent  2c4dbcd6f2e4c9c2a1eb8dc1f0d39c99975ae208
HTTP/2: emit new frames only after applying all SETTINGS params.

Previously, new frames could be emitted in the middle of applying
new (and already acknowledged) SETTINGS params, which is illegal.

Signed-off-by: Piotr Sikora 

diff -r 2c4dbcd6f2e4 -r 07adf0a7009c src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -1982,7 +1982,9 @@ static u_char *
 ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos,
 u_char *end)
 {
-ngx_uint_t  id, value;
+ngx_uint_t  id, value, adjustment;
+
+adjustment = 0;
 
 while (h2c->state.length) {
 if (end - pos < NGX_HTTP_V2_SETTINGS_PARAM_SIZE) {
@@ -2008,13 +2010,7 @@ ngx_http_v2_state_settings_params(ngx_ht
   NGX_HTTP_V2_FLOW_CTRL_ERROR);
 }
 
-if (ngx_http_v2_adjust_windows(h2c, value - h2c->init_window)
-!= NGX_OK)
-{
-return ngx_http_v2_connection_error(h2c,
-
NGX_HTTP_V2_INTERNAL_ERROR);
-}
-
+adjustment = value - h2c->init_window;
 h2c->init_window = value;
 break;
 
@@ -2041,6 +2037,13 @@ ngx_http_v2_state_settings_params(ngx_ht
 pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE;
 }
 
+if (adjustment) {
+if (ngx_http_v2_adjust_windows(h2c, adjustment) != NGX_OK) {
+return ngx_http_v2_connection_error(h2c,
+NGX_HTTP_V2_INTERNAL_ERROR);
+}
+}
+
 return ngx_http_v2_state_complete(h2c, pos, end);
 }
 
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [nginx] Cleaned up r->headers_out.headers allocation error handling.

2017-04-24 Thread Maxim Dounin
Hello!

On Mon, Apr 24, 2017 at 07:23:13PM +0300, Sorin Manole wrote:

> >> For the Cache-Control header, the fix is to postpone pushing
> >> r->headers_out.cache_control until its value is completed.
> 
> Why not do the same thing for a bunch of other places like:
> ngx_http_auth_basic_set_realm
> ngx_http_range_not_satisfiable
> 
> That is, for the latter, first initialize content_range, and then add it to
> headers.
> Looks like a safer strategy then rolling back a change in case of failure.

This was considered in earlier versions of the patch.  The result 
seems harder to read though, and also requires much more code 
changes.

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


Re: [nginx] Cleaned up r->headers_out.headers allocation error handling.

2017-04-24 Thread Sorin Manole
Hello!

>> For the Cache-Control header, the fix is to postpone pushing
>> r->headers_out.cache_control until its value is completed.

Why not do the same thing for a bunch of other places like:
ngx_http_auth_basic_set_realm
ngx_http_range_not_satisfiable

That is, for the latter, first initialize content_range, and then add it to
headers.
Looks like a safer strategy then rolling back a change in case of failure.

Thank you!


2017-04-20 19:33 GMT+03:00 Sergey Kandaurov :

> details:   http://hg.nginx.org/nginx/rev/0cdee26605f3
> branches:
> changeset: 6986:0cdee26605f3
> user:  Sergey Kandaurov 
> date:  Thu Apr 20 18:26:37 2017 +0300
> description:
> Cleaned up r->headers_out.headers allocation error handling.
>
> If initialization of a header failed for some reason after ngx_list_push(),
> leaving the header as is can result in uninitialized memory access by
> the header filter or the log module.  The fix is to clear partially
> initialized headers in case of errors.
>
> For the Cache-Control header, the fix is to postpone pushing
> r->headers_out.cache_control until its value is completed.
>
> diffstat:
>
>  src/http/modules/ngx_http_auth_basic_module.c |   2 ++
>  src/http/modules/ngx_http_dav_module.c|   1 +
>  src/http/modules/ngx_http_headers_filter_module.c |  21
> +++--
>  src/http/modules/ngx_http_range_filter_module.c   |   4 
>  src/http/modules/ngx_http_static_module.c |   1 +
>  src/http/modules/perl/nginx.xs|   2 ++
>  src/http/ngx_http_core_module.c   |   1 +
>  src/http/ngx_http_upstream.c  |  13 +++--
>  8 files changed, 29 insertions(+), 16 deletions(-)
>
> diffs (162 lines):
>
> diff -r 23ecffd5bcfe -r 0cdee26605f3 src/http/modules/ngx_http_
> auth_basic_module.c
> --- a/src/http/modules/ngx_http_auth_basic_module.c Thu Apr 20
> 13:58:16 2017 +0300
> +++ b/src/http/modules/ngx_http_auth_basic_module.c Thu Apr 20
> 18:26:37 2017 +0300
> @@ -361,6 +361,8 @@ ngx_http_auth_basic_set_realm(ngx_http_r
>
>  basic = ngx_pnalloc(r->pool, len);
>  if (basic == NULL) {
> +r->headers_out.www_authenticate->hash = 0;
> +r->headers_out.www_authenticate = NULL;
>  return NGX_HTTP_INTERNAL_SERVER_ERROR;
>  }
>
> diff -r 23ecffd5bcfe -r 0cdee26605f3 src/http/modules/ngx_http_dav_
> module.c
> --- a/src/http/modules/ngx_http_dav_module.cThu Apr 20 13:58:16 2017
> +0300
> +++ b/src/http/modules/ngx_http_dav_module.cThu Apr 20 18:26:37 2017
> +0300
> @@ -1080,6 +1080,7 @@ ngx_http_dav_location(ngx_http_request_t
>  } else {
>  location = ngx_pnalloc(r->pool, r->uri.len);
>  if (location == NULL) {
> +ngx_http_clear_location(r);
>  return NGX_ERROR;
>  }
>
> diff -r 23ecffd5bcfe -r 0cdee26605f3 src/http/modules/ngx_http_
> headers_filter_module.c
> --- a/src/http/modules/ngx_http_headers_filter_module.c Thu Apr 20
> 13:58:16 2017 +0300
> +++ b/src/http/modules/ngx_http_headers_filter_module.c Thu Apr 20
> 18:26:37 2017 +0300
> @@ -271,11 +271,6 @@ ngx_http_set_expires(ngx_http_request_t
>  return NGX_ERROR;
>  }
>
> -ccp = ngx_array_push(&r->headers_out.cache_control);
> -if (ccp == NULL) {
> -return NGX_ERROR;
> -}
> -
>  cc = ngx_list_push(&r->headers_out.headers);
>  if (cc == NULL) {
>  return NGX_ERROR;
> @@ -283,6 +278,12 @@ ngx_http_set_expires(ngx_http_request_t
>
>  cc->hash = 1;
>  ngx_str_set(&cc->key, "Cache-Control");
> +
> +ccp = ngx_array_push(&r->headers_out.cache_control);
> +if (ccp == NULL) {
> +return NGX_ERROR;
> +}
> +
>  *ccp = cc;
>
>  } else {
> @@ -470,11 +471,6 @@ ngx_http_add_cache_control(ngx_http_requ
>  }
>  }
>
> -ccp = ngx_array_push(&r->headers_out.cache_control);
> -if (ccp == NULL) {
> -return NGX_ERROR;
> -}
> -
>  cc = ngx_list_push(&r->headers_out.headers);
>  if (cc == NULL) {
>  return NGX_ERROR;
> @@ -484,6 +480,11 @@ ngx_http_add_cache_control(ngx_http_requ
>  ngx_str_set(&cc->key, "Cache-Control");
>  cc->value = *value;
>
> +ccp = ngx_array_push(&r->headers_out.cache_control);
> +if (ccp == NULL) {
> +return NGX_ERROR;
> +}
> +
>  *ccp = cc;
>
>  return NGX_OK;
> diff -r 23ecffd5bcfe -r 0cdee26605f3 src/http/modules/ngx_http_
> range_filter_module.c
> --- a/src/http/modules/ngx_http_range_filter_module.c   Thu Apr 20
> 13:58:16 2017 +0300
> +++ b/src/http/modules/ngx_http_range_filter_module.c   Thu Apr 20
> 18:26:37 2017 +0300
> @@ -425,6 +425,8 @@ ngx_http_range_singlepart_header(ngx_htt
>  content_range->value.data = ngx_pnalloc(r->pool,
>  sizeof("bytes -/") - 1 + 3 *
> NGX_OFF_T_LEN);
>  if (content_range->value.data == NULL) {
> +content_range->hash = 0;
> + 

Re: [PATCH] FYI: Fix FTBFS on Debian GNU/kFreeBSD

2017-04-24 Thread Maxim Dounin
Hello!

On Mon, Apr 24, 2017 at 10:58:26AM +0900, HAYASHI Kentaro wrote:

> Hi.
> 
> I'm happy if the following patch is merged into upstream.
> 
>   nginx-kfreebsd.diff
> 
> https://bugs.debian.org/cgi-bin/bugreport.cgi?att=1;bug=826061;filename=nginx-kfreebsd.diff;msg=10
> 
> Here is more detail about this patch:
> 
> Above patch is aimed to fix FTBFS on Debian GNU/kFreeBSD.
> This FTBFS bug is already fixed on Debian [1], and patch is maintained
> as
> debian/patches/0003-define_gnu_source-on-other-glibc-based-platforms.patch.
> 
> [1]  nginx: FTBFS on kfreebsd: incomplete type 'struct in6_pktinfo'
>   https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=826061
> 
> I think this patch should be forwarded to upstream and merged because third
> party software
> which bundles nginx on kFreeBSD also shoots in the legs without this patch.

https://trac.nginx.org/nginx/ticket/1028

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


[nginx] HTTP/2: reduced difference to HTTP/1.x in reading request body.

2017-04-24 Thread Valentin Bartenev
details:   http://hg.nginx.org/nginx/rev/2c4dbcd6f2e4
branches:  
changeset: 6989:2c4dbcd6f2e4
user:  Valentin Bartenev 
date:  Mon Apr 24 14:17:13 2017 +0300
description:
HTTP/2: reduced difference to HTTP/1.x in reading request body.

Particularly, this eliminates difference in behavior for requests without body
and deduplicates code.

Prodded by Piotr Sikora.

diffstat:

 src/http/ngx_http_request_body.c |  20 
 src/http/v2/ngx_http_v2.c|  28 +---
 src/http/v2/ngx_http_v2.h|   3 +--
 3 files changed, 18 insertions(+), 33 deletions(-)

diffs (115 lines):

diff -r cc823122d50d -r 2c4dbcd6f2e4 src/http/ngx_http_request_body.c
--- a/src/http/ngx_http_request_body.c  Mon Apr 24 14:16:57 2017 +0300
+++ b/src/http/ngx_http_request_body.c  Mon Apr 24 14:17:13 2017 +0300
@@ -46,13 +46,6 @@ ngx_http_read_client_request_body(ngx_ht
 return NGX_OK;
 }
 
-#if (NGX_HTTP_V2)
-if (r->stream) {
-rc = ngx_http_v2_read_request_body(r, post_handler);
-goto done;
-}
-#endif
-
 if (ngx_http_test_expect(r) != NGX_OK) {
 rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
 goto done;
@@ -85,6 +78,13 @@ ngx_http_read_client_request_body(ngx_ht
 return NGX_OK;
 }
 
+#if (NGX_HTTP_V2)
+if (r->stream) {
+rc = ngx_http_v2_read_request_body(r);
+goto done;
+}
+#endif
+
 preread = r->header_in->last - r->header_in->pos;
 
 if (preread) {
@@ -805,7 +805,11 @@ ngx_http_test_expect(ngx_http_request_t 
 
 if (r->expect_tested
 || r->headers_in.expect == NULL
-|| r->http_version < NGX_HTTP_VERSION_11)
+|| r->http_version < NGX_HTTP_VERSION_11
+#if (NGX_HTTP_V2)
+|| r->stream != NULL
+#endif
+   )
 {
 return NGX_OK;
 }
diff -r cc823122d50d -r 2c4dbcd6f2e4 src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c Mon Apr 24 14:16:57 2017 +0300
+++ b/src/http/v2/ngx_http_v2.c Mon Apr 24 14:17:13 2017 +0300
@@ -3522,8 +3522,7 @@ ngx_http_v2_run_request(ngx_http_request
 
 
 ngx_int_t
-ngx_http_v2_read_request_body(ngx_http_request_t *r,
-ngx_http_client_body_handler_pt post_handler)
+ngx_http_v2_read_request_body(ngx_http_request_t *r)
 {
 off_t  len;
 size_t size;
@@ -3536,33 +3535,14 @@ ngx_http_v2_read_request_body(ngx_http_r
 ngx_http_v2_connection_t  *h2c;
 
 stream = r->stream;
+rb = r->request_body;
 
 if (stream->skip_data) {
 r->request_body_no_buffering = 0;
-post_handler(r);
+rb->post_handler(r);
 return NGX_OK;
 }
 
-rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
-if (rb == NULL) {
-return NGX_HTTP_INTERNAL_SERVER_ERROR;
-}
-
-/*
- * set by ngx_pcalloc():
- *
- * rb->bufs = NULL;
- * rb->buf = NULL;
- * rb->received = 0;
- * rb->free = NULL;
- * rb->busy = NULL;
- */
-
-rb->rest = 1;
-rb->post_handler = post_handler;
-
-r->request_body = rb;
-
 h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module);
 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
@@ -3612,6 +3592,8 @@ ngx_http_v2_read_request_body(ngx_http_r
 return NGX_HTTP_INTERNAL_SERVER_ERROR;
 }
 
+rb->rest = 1;
+
 buf = stream->preread;
 
 if (stream->in_closed) {
diff -r cc823122d50d -r 2c4dbcd6f2e4 src/http/v2/ngx_http_v2.h
--- a/src/http/v2/ngx_http_v2.h Mon Apr 24 14:16:57 2017 +0300
+++ b/src/http/v2/ngx_http_v2.h Mon Apr 24 14:17:13 2017 +0300
@@ -264,8 +264,7 @@ ngx_http_v2_queue_blocked_frame(ngx_http
 void ngx_http_v2_init(ngx_event_t *rev);
 void ngx_http_v2_request_headers_init(void);
 
-ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r,
-ngx_http_client_body_handler_pt post_handler);
+ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r);
 ngx_int_t ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r);
 
 void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc);
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


[nginx] HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.

2017-04-24 Thread Valentin Bartenev
details:   http://hg.nginx.org/nginx/rev/cc823122d50d
branches:  
changeset: 6988:cc823122d50d
user:  Valentin Bartenev 
date:  Mon Apr 24 14:16:57 2017 +0300
description:
HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.

It's required by RFC 7540.  While there is no real harm from such frames,
that should help to detect broken clients.

Based on a patch by Piotr Sikora.

diffstat:

 src/http/v2/ngx_http_v2.c |  38 ++
 1 files changed, 38 insertions(+), 0 deletions(-)

diffs (48 lines):

diff -r 5116cfea1e9a -r cc823122d50d src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c Thu Apr 20 18:26:38 2017 +0300
+++ b/src/http/v2/ngx_http_v2.c Mon Apr 24 14:16:57 2017 +0300
@@ -2166,6 +2166,44 @@ ngx_http_v2_state_window_update(ngx_http
"http2 WINDOW_UPDATE frame sid:%ui window:%uz",
h2c->state.sid, window);
 
+if (window == 0) {
+if (h2c->state.sid == 0) {
+ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
+  "client sent WINDOW_UPDATE frame "
+  "with incorrect window increment 0");
+
+return ngx_http_v2_connection_error(h2c,
+NGX_HTTP_V2_PROTOCOL_ERROR);
+}
+
+ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
+  "client sent WINDOW_UPDATE frame for stream %ui "
+  "with incorrect window increment 0", h2c->state.sid);
+
+node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);
+
+if (node && node->stream) {
+if (ngx_http_v2_terminate_stream(h2c, node->stream,
+ NGX_HTTP_V2_PROTOCOL_ERROR)
+== NGX_ERROR)
+{
+return ngx_http_v2_connection_error(h2c,
+
NGX_HTTP_V2_INTERNAL_ERROR);
+}
+
+} else {
+if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid,
+NGX_HTTP_V2_PROTOCOL_ERROR)
+== NGX_ERROR)
+{
+return ngx_http_v2_connection_error(h2c,
+
NGX_HTTP_V2_INTERNAL_ERROR);
+}
+}
+
+return ngx_http_v2_state_complete(h2c, pos, end);
+}
+
 if (h2c->state.sid) {
 node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);
 
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel