From mdounin at mdounin.ru Fri Apr 1 01:18:28 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 01 Apr 2016 01:18:28 +0000 Subject: [nginx] Trailing space fix. Message-ID: details: http://hg.nginx.org/nginx/rev/58b2ad162ca9 branches: changeset: 6493:58b2ad162ca9 user: Maxim Dounin date: Fri Apr 01 04:17:00 2016 +0300 description: Trailing space fix. diffstat: docs/xml/nginx/changes.xml | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -89,7 +89,7 @@ and a client closed a connection prematu -??? ????????????? ??????????? +??? ????????????? ??????????? ?????????? ? ????????? ????? ??????????? ??? ?????????????.
??????? Justin Li.
From mdounin at mdounin.ru Fri Apr 1 10:27:25 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 01 Apr 2016 10:27:25 +0000 Subject: [nginx] Core: removed incorrect GCC 2.7 check. Message-ID: details: http://hg.nginx.org/nginx/rev/5805301f990f branches: changeset: 6494:5805301f990f user: Maxim Dounin date: Fri Apr 01 13:17:12 2016 +0300 description: Core: removed incorrect GCC 2.7 check. It was broken since introduction (__GNU__ instead of __GNUC__) and did nothing. Moreover, GCC 2.7 is happy with the normal version of the code. Reported by Joel Cunningham, http://mailman.nginx.org/pipermail/nginx-devel/2016-March/007964.html. diffstat: src/core/ngx_config.h | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-) diffs (16 lines): diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -125,12 +125,7 @@ typedef intptr_t ngx_flag_t; #endif -#if ((__GNU__ == 2) && (__GNUC_MINOR__ < 8)) -#define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffffLL -#else #define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffff -#endif - #define NGX_MAX_INT32_VALUE (uint32_t) 0x7fffffff From mdounin at mdounin.ru Fri Apr 1 10:44:23 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 1 Apr 2016 13:44:23 +0300 Subject: [PATCH] Correct reference to GCC compiler macro In-Reply-To: <799188E3-3E8F-4D16-86E2-ECAA3613B437@me.com> References: <799188E3-3E8F-4D16-86E2-ECAA3613B437@me.com> Message-ID: <20160401104423.GR36620@mdounin.ru> Hello! On Tue, Mar 01, 2016 at 01:40:13PM -0600, Joel Cunningham wrote: > # HG changeset patch > # User Joel Cunningham > # Date 1456860378 21600 > # Tue Mar 01 13:26:18 2016 -0600 > # Node ID cce5f2f6ed76ffa0f6890e90e7b1b68718ffa8a9 > # Parent 3b9fe734a76ca0863ec87596369690831e9f4086 > Correct reference to GCC compiler macro > > This commit corrects a small typo where __GNU__ was used in place of > __GNUC__ > > This was identified on a GCC system that built with undefined macros > treated as errors when used with #if > > diff -r 3b9fe734a76c -r cce5f2f6ed76 src/core/ngx_config.h > --- a/src/core/ngx_config.h Tue Mar 01 15:18:07 2016 +0300 > +++ b/src/core/ngx_config.h Tue Mar 01 13:26:18 2016 -0600 > @@ -125,7 +125,7 @@ > #endif > > > -#if ((__GNU__ == 2) && (__GNUC_MINOR__ < 8)) > +#if ((__GNUC__ == 2) && (__GNUC_MINOR__ < 8)) > #define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffffLL > #else > #define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffff I've tested with GCC 2.7 and commited a patch to remove this preprocessor check: http://hg.nginx.org/nginx/rev/5805301f990f Thanks for reporting. -- Maxim Dounin http://nginx.org/ From vbart at nginx.com Fri Apr 1 12:57:25 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 01 Apr 2016 12:57:25 +0000 Subject: [nginx] HTTP/2: sending RST_STREAM with NO_ERROR to discard request body. Message-ID: details: http://hg.nginx.org/nginx/rev/92464ebace8e branches: changeset: 6495:92464ebace8e user: Valentin Bartenev date: Fri Apr 01 15:56:03 2016 +0300 description: HTTP/2: sending RST_STREAM with NO_ERROR to discard request body. RFC 7540 states that "A server can send a complete response prior to the client sending an entire request if the response does not depend on any portion of the request that has not been sent and received. When this is true, a server MAY request that the client abort transmission of a request without error by sending a RST_STREAM with an error code of NO_ERROR after sending a complete response (i.e., a frame with the END_STREAM flag)." This should prevent a client from blocking on the stream window, since it isn't maintained for closed streams. Currently, quite big initial stream windows are used, so such blocking is very unlikly, but that will be changed in the further patches. diffstat: src/http/v2/ngx_http_v2.c | 38 ++++++++++++++++++++++++-------------- src/http/v2/ngx_http_v2.h | 1 + 2 files changed, 25 insertions(+), 14 deletions(-) diffs (84 lines): diff -r 5805301f990f -r 92464ebace8e src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Fri Apr 01 13:17:12 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Fri Apr 01 15:56:03 2016 +0300 @@ -3709,7 +3709,7 @@ ngx_http_v2_terminate_stream(ngx_http_v2 return NGX_ERROR; } - stream->out_closed = 1; + stream->rst_sent = 1; fc = stream->request->connection; fc->error = 1; @@ -3744,13 +3744,23 @@ ngx_http_v2_close_stream(ngx_http_v2_str return; } - if (!stream->out_closed) { - if (ngx_http_v2_send_rst_stream(h2c, node->id, - fc->timedout ? NGX_HTTP_V2_PROTOCOL_ERROR - : NGX_HTTP_V2_INTERNAL_ERROR) - != NGX_OK) - { - h2c->connection->error = 1; + if (!stream->rst_sent && !h2c->connection->error) { + + if (!stream->out_closed) { + if (ngx_http_v2_send_rst_stream(h2c, node->id, + fc->timedout ? NGX_HTTP_V2_PROTOCOL_ERROR + : NGX_HTTP_V2_INTERNAL_ERROR) + != NGX_OK) + { + h2c->connection->error = 1; + } + + } else if (!stream->in_closed) { + if (ngx_http_v2_send_rst_stream(h2c, node->id, NGX_HTTP_V2_NO_ERROR) + != NGX_OK) + { + h2c->connection->error = 1; + } } } @@ -3942,23 +3952,23 @@ ngx_http_v2_finalize_connection(ngx_http c = h2c->connection; - if (h2c->state.stream) { - h2c->state.stream->out_closed = 1; - ngx_http_v2_close_stream(h2c->state.stream, NGX_HTTP_BAD_REQUEST); - } - h2c->blocked = 1; if (!c->error && ngx_http_v2_send_goaway(h2c, status) != NGX_ERROR) { (void) ngx_http_v2_send_output_queue(h2c); } + c->error = 1; + + if (h2c->state.stream) { + ngx_http_v2_close_stream(h2c->state.stream, NGX_HTTP_BAD_REQUEST); + } + if (!h2c->processing) { ngx_http_close_connection(c); return; } - c->error = 1; c->read->handler = ngx_http_empty_handler; c->write->handler = ngx_http_empty_handler; diff -r 5805301f990f -r 92464ebace8e src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Fri Apr 01 13:17:12 2016 +0300 +++ b/src/http/v2/ngx_http_v2.h Fri Apr 01 15:56:03 2016 +0300 @@ -194,6 +194,7 @@ struct ngx_http_v2_stream_s { unsigned exhausted:1; unsigned in_closed:1; unsigned out_closed:1; + unsigned rst_sent:1; unsigned skip_data:2; }; From vbart at nginx.com Fri Apr 1 12:57:28 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 01 Apr 2016 12:57:28 +0000 Subject: [nginx] HTTP/2: rewritten handling of request body. Message-ID: details: http://hg.nginx.org/nginx/rev/887cca40ba6a branches: changeset: 6496:887cca40ba6a user: Valentin Bartenev date: Fri Apr 01 15:56:03 2016 +0300 description: HTTP/2: rewritten handling of request body. There are two improvements: 1. Support for request body filters; 2. Receiving of request body is started only after the ngx_http_read_client_request_body() call. The last one fixes the problem when the client_max_body_size value might not be respected from the right location if the location was changed either during the process of receiving body or after the whole body had been received. diffstat: src/http/ngx_http_request.h | 3 + src/http/ngx_http_request_body.c | 26 +- src/http/v2/ngx_http_v2.c | 548 ++++++++++++++++++-------------------- src/http/v2/ngx_http_v2.h | 7 +- 4 files changed, 282 insertions(+), 302 deletions(-) diffs (768 lines): diff -r 92464ebace8e -r 887cca40ba6a src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h Fri Apr 01 15:56:03 2016 +0300 +++ b/src/http/ngx_http_request.h Fri Apr 01 15:56:03 2016 +0300 @@ -284,6 +284,9 @@ typedef struct { ngx_chain_t *bufs; ngx_buf_t *buf; off_t rest; +#if (NGX_HTTP_V2) + off_t received; +#endif ngx_chain_t *free; ngx_chain_t *busy; ngx_http_chunked_t *chunked; diff -r 92464ebace8e -r 887cca40ba6a src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c Fri Apr 01 15:56:03 2016 +0300 +++ b/src/http/ngx_http_request_body.c Fri Apr 01 15:56:03 2016 +0300 @@ -40,20 +40,20 @@ ngx_http_read_client_request_body(ngx_ht r->main->count++; + if (r != r->main || r->request_body || r->discard_body) { + r->request_body_no_buffering = 0; + post_handler(r); + return NGX_OK; + } + #if (NGX_HTTP_V2) - if (r->stream && r == r->main) { + if (r->stream) { r->request_body_no_buffering = 0; rc = ngx_http_v2_read_request_body(r, post_handler); goto done; } #endif - if (r != r->main || r->request_body || r->discard_body) { - r->request_body_no_buffering = 0; - post_handler(r); - return NGX_OK; - } - if (ngx_http_test_expect(r) != NGX_OK) { rc = NGX_HTTP_INTERNAL_SERVER_ERROR; goto done; @@ -503,17 +503,17 @@ ngx_http_discard_request_body(ngx_http_r ngx_int_t rc; ngx_event_t *rev; + if (r != r->main || r->discard_body || r->request_body) { + return NGX_OK; + } + #if (NGX_HTTP_V2) - if (r->stream && r == r->main) { - r->stream->skip_data = NGX_HTTP_V2_DATA_DISCARD; + if (r->stream) { + r->stream->skip_data = 1; return NGX_OK; } #endif - if (r != r->main || r->discard_body || r->request_body) { - return NGX_OK; - } - if (ngx_http_test_expect(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff -r 92464ebace8e -r 887cca40ba6a src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Fri Apr 01 15:56:03 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Fri Apr 01 15:56:03 2016 +0300 @@ -51,6 +51,8 @@ #define NGX_HTTP_V2_MAX_WINDOW ((1U << 31) - 1) #define NGX_HTTP_V2_DEFAULT_WINDOW 65535 +#define NGX_HTTP_V2_INITIAL_WINDOW 0 + #define NGX_HTTP_V2_ROOT (void *) -1 @@ -163,7 +165,9 @@ static ngx_int_t ngx_http_v2_cookie(ngx_ ngx_http_v2_header_t *header); static ngx_int_t ngx_http_v2_construct_cookie_header(ngx_http_request_t *r); static void ngx_http_v2_run_request(ngx_http_request_t *r); -static ngx_int_t ngx_http_v2_init_request_body(ngx_http_request_t *r); +static ngx_int_t ngx_http_v2_process_request_body(ngx_http_request_t *r, + u_char *pos, size_t size, ngx_uint_t last); +static ngx_int_t ngx_http_v2_filter_request_body(ngx_http_request_t *r); static void ngx_http_v2_read_client_request_body_handler(ngx_http_request_t *r); static ngx_int_t ngx_http_v2_terminate_stream(ngx_http_v2_connection_t *h2c, @@ -762,8 +766,7 @@ ngx_http_v2_state_data(ngx_http_v2_conne if (h2c->state.length == 0) { ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, "client sent padded DATA frame " - "with incorrect length: %uz", - h2c->state.length); + "with incorrect length: 0"); return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); } @@ -845,8 +848,9 @@ ngx_http_v2_state_data(ngx_http_v2_conne stream->recv_window -= h2c->state.length; - if (stream->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4) { - + if (stream->no_flow_control + && stream->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4) + { if (ngx_http_v2_send_window_update(h2c, node->id, NGX_HTTP_V2_MAX_WINDOW - stream->recv_window) @@ -875,6 +879,8 @@ ngx_http_v2_state_data(ngx_http_v2_conne return ngx_http_v2_state_skip_padded(h2c, pos, end); } + stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG; + h2c->state.stream = stream; return ngx_http_v2_state_read_data(h2c, pos, end); @@ -885,16 +891,10 @@ static u_char * ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) { - size_t size; - ssize_t n; - ngx_buf_t *buf; - ngx_int_t rc; - ngx_temp_file_t *tf; - ngx_connection_t *fc; - ngx_http_request_t *r; - ngx_http_v2_stream_t *stream; - ngx_http_request_body_t *rb; - ngx_http_core_loc_conf_t *clcf; + size_t size; + ngx_int_t rc; + ngx_uint_t last; + ngx_http_v2_stream_t *stream; stream = h2c->state.stream; @@ -903,168 +903,42 @@ ngx_http_v2_state_read_data(ngx_http_v2_ } if (stream->skip_data) { - stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG; - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, - "skipping http2 DATA frame, reason: %d", - stream->skip_data); + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "skipping http2 DATA frame"); return ngx_http_v2_state_skip_padded(h2c, pos, end); } size = end - pos; - if (size > h2c->state.length) { + if (size >= h2c->state.length) { size = h2c->state.length; - } - - r = stream->request; - - if (r->request_body == NULL - && ngx_http_v2_init_request_body(r) != NGX_OK) - { - stream->skip_data = NGX_HTTP_V2_DATA_INTERNAL_ERROR; - return ngx_http_v2_state_skip_padded(h2c, pos, end); - } - - fc = r->connection; - rb = r->request_body; - tf = rb->temp_file; - buf = rb->buf; - - if (size) { - rb->rest += size; - - if (r->headers_in.content_length_n != -1 - && r->headers_in.content_length_n < rb->rest) - { - ngx_log_error(NGX_LOG_INFO, fc->log, 0, - "client intended to send body data " - "larger than declared"); - - stream->skip_data = NGX_HTTP_V2_DATA_ERROR; - goto error; - - } else { - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - - if (clcf->client_max_body_size - && clcf->client_max_body_size < rb->rest) - { - ngx_log_error(NGX_LOG_ERR, fc->log, 0, - "client intended to send " - "too large chunked body: %O bytes", rb->rest); - - stream->skip_data = NGX_HTTP_V2_DATA_ERROR; - goto error; - } - } - - h2c->state.length -= size; - - if (tf) { - buf->start = pos; - buf->pos = pos; - - pos += size; - - buf->end = pos; - buf->last = pos; - - n = ngx_write_chain_to_temp_file(tf, rb->bufs); - - /* TODO: n == 0 or not complete and level event */ - - if (n == NGX_ERROR) { - stream->skip_data = NGX_HTTP_V2_DATA_INTERNAL_ERROR; - goto error; - } - - tf->offset += n; - - } else { - buf->last = ngx_cpymem(buf->last, pos, size); - pos += size; - } - - r->request_length += size; - } + last = stream->in_closed; + + } else { + last = 0; + } + + rc = ngx_http_v2_process_request_body(stream->request, pos, size, last); + + if (rc != NGX_OK) { + stream->skip_data = 1; + ngx_http_finalize_request(stream->request, rc); + } + + pos += size; + h2c->state.length -= size; if (h2c->state.length) { - if (rb->post_handler) { - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - ngx_add_timer(fc->read, clcf->client_body_timeout); - } - return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_read_data); } - if (h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG) { - stream->in_closed = 1; - - if (r->headers_in.content_length_n < 0) { - r->headers_in.content_length_n = rb->rest; - - } else if (r->headers_in.content_length_n != rb->rest) { - ngx_log_error(NGX_LOG_INFO, fc->log, 0, - "client prematurely closed stream: " - "only %O out of %O bytes of request body received", - rb->rest, r->headers_in.content_length_n); - - stream->skip_data = NGX_HTTP_V2_DATA_ERROR; - goto error; - } - - if (tf) { - ngx_memzero(buf, sizeof(ngx_buf_t)); - - buf->in_file = 1; - buf->file_last = tf->file.offset; - buf->file = &tf->file; - - rb->buf = NULL; - } - - if (rb->post_handler) { - if (fc->read->timer_set) { - ngx_del_timer(fc->read); - } - - r->read_event_handler = ngx_http_block_reading; - rb->post_handler(r); - } - - } else if (rb->post_handler) { - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - ngx_add_timer(fc->read, clcf->client_body_timeout); - } - if (h2c->state.padding) { return ngx_http_v2_state_skip_padded(h2c, pos, end); } return ngx_http_v2_state_complete(h2c, pos, end); - -error: - - if (rb->post_handler) { - if (fc->read->timer_set) { - ngx_del_timer(fc->read); - } - - if (stream->skip_data == NGX_HTTP_V2_DATA_ERROR) { - rc = (r->headers_in.content_length_n == -1) - ? NGX_HTTP_REQUEST_ENTITY_TOO_LARGE : NGX_HTTP_BAD_REQUEST; - - } else { - rc = NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - ngx_http_finalize_request(r, rc); - } - - return ngx_http_v2_state_skip_padded(h2c, pos, end); } @@ -2556,7 +2430,7 @@ ngx_http_v2_send_settings(ngx_http_v2_co 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, - NGX_HTTP_V2_MAX_WINDOW); + NGX_HTTP_V2_INITIAL_WINDOW); buf->last = ngx_http_v2_write_uint16(buf->last, NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING); @@ -2878,7 +2752,7 @@ ngx_http_v2_create_stream(ngx_http_v2_co stream->connection = h2c; stream->send_window = h2c->init_window; - stream->recv_window = NGX_HTTP_V2_MAX_WINDOW; + stream->recv_window = NGX_HTTP_V2_INITIAL_WINDOW; h2c->processing++; @@ -3515,7 +3389,7 @@ ngx_http_v2_run_request(ngx_http_request ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client prematurely closed stream"); - r->stream->skip_data = NGX_HTTP_V2_DATA_ERROR; + r->stream->skip_data = 1; ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return; @@ -3525,142 +3399,248 @@ ngx_http_v2_run_request(ngx_http_request } -static ngx_int_t -ngx_http_v2_init_request_body(ngx_http_request_t *r) -{ - ngx_buf_t *buf; - ngx_temp_file_t *tf; - ngx_http_request_body_t *rb; - ngx_http_core_loc_conf_t *clcf; - - rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); - if (rb == NULL) { - return NGX_ERROR; - } - - r->request_body = rb; - - if (r->stream->in_closed) { - return NGX_OK; - } - - rb->rest = r->headers_in.content_length_n; - - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - - if (r->request_body_in_file_only - || rb->rest > (off_t) clcf->client_body_buffer_size - || rb->rest < 0) - { - tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); - if (tf == NULL) { - return NGX_ERROR; - } - - tf->file.fd = NGX_INVALID_FILE; - tf->file.log = r->connection->log; - tf->path = clcf->client_body_temp_path; - tf->pool = r->pool; - tf->warn = "a client request body is buffered to a temporary file"; - tf->log_level = r->request_body_file_log_level; - tf->persistent = r->request_body_in_persistent_file; - tf->clean = r->request_body_in_clean_file; - - if (r->request_body_file_group_access) { - tf->access = 0660; - } - - rb->temp_file = tf; - - if (r->stream->in_closed - && ngx_create_temp_file(&tf->file, tf->path, tf->pool, - tf->persistent, tf->clean, tf->access) - != NGX_OK) - { - return NGX_ERROR; - } - - buf = ngx_calloc_buf(r->pool); - if (buf == NULL) { - return NGX_ERROR; - } - - } else { - - if (rb->rest == 0) { - return NGX_OK; - } - - buf = ngx_create_temp_buf(r->pool, (size_t) rb->rest); - if (buf == NULL) { - return NGX_ERROR; - } - } - - rb->buf = buf; - - rb->bufs = ngx_alloc_chain_link(r->pool); - if (rb->bufs == NULL) { - return NGX_ERROR; - } - - rb->bufs->buf = buf; - rb->bufs->next = NULL; - - rb->rest = 0; - - return NGX_OK; -} - - ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r, ngx_http_client_body_handler_pt post_handler) { + off_t len; ngx_http_v2_stream_t *stream; + ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http2 read request body"); - stream = r->stream; - switch (stream->skip_data) { - - case NGX_HTTP_V2_DATA_DISCARD: + if (stream->skip_data) { + r->request_body_no_buffering = 0; post_handler(r); return NGX_OK; - - case NGX_HTTP_V2_DATA_ERROR: + } + + 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; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + len = r->headers_in.content_length_n; + + if (len >= 0 && len <= (off_t) clcf->client_body_buffer_size + && !r->request_body_in_file_only) + { + rb->buf = ngx_create_temp_buf(r->pool, (size_t) len); + + } else { + rb->buf = ngx_calloc_buf(r->pool); + + if (rb->buf != NULL) { + rb->buf->sync = 1; + } + } + + if (rb->buf == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + if (stream->in_closed) { + return ngx_http_v2_process_request_body(r, NULL, 0, 1); + } + + stream->no_flow_control = 1; + + stream->recv_window = NGX_HTTP_V2_MAX_WINDOW; + + if (ngx_http_v2_send_window_update(stream->connection, stream->node->id, + stream->recv_window) + == NGX_ERROR) + { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + ngx_add_timer(r->connection->read, clcf->client_body_timeout); + + r->read_event_handler = ngx_http_v2_read_client_request_body_handler; + r->write_event_handler = ngx_http_request_empty_handler; + + return NGX_AGAIN; +} + + +static ngx_int_t +ngx_http_v2_process_request_body(ngx_http_request_t *r, u_char *pos, + size_t size, ngx_uint_t last) +{ + ngx_buf_t *buf; + ngx_int_t rc; + ngx_connection_t *fc; + ngx_http_request_body_t *rb; + ngx_http_core_loc_conf_t *clcf; + + rb = r->request_body; + + if (rb == NULL) { + return NGX_OK; + } + + fc = r->connection; + buf = rb->buf; + + if (size) { + if (buf->sync) { + buf->pos = buf->start = pos; + buf->last = buf->end = pos + size; + + } else { + if (size > (size_t) (buf->end - buf->last)) { + ngx_log_error(NGX_LOG_INFO, fc->log, 0, + "client intended to send body data " + "larger than declared"); + + return NGX_HTTP_BAD_REQUEST; + } + + buf->last = ngx_cpymem(buf->last, pos, size); + } + } + + if (last) { + rb->rest = 0; + + if (fc->read->timer_set) { + ngx_del_timer(fc->read); + } + + rc = ngx_http_v2_filter_request_body(r); + + if (rc != NGX_OK) { + return rc; + } + + if (buf->sync) { + /* prevent reusing this buffer in the upstream module */ + rb->buf = NULL; + } + if (r->headers_in.content_length_n == -1) { - return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; + r->headers_in.content_length_n = rb->received; + } + + r->read_event_handler = ngx_http_block_reading; + rb->post_handler(r); + + return NGX_OK; + } + + if (size == 0) { + return NGX_OK; + } + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + ngx_add_timer(fc->read, clcf->client_body_timeout); + + if (buf->sync) { + return ngx_http_v2_filter_request_body(r); + } + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_v2_filter_request_body(ngx_http_request_t *r) +{ + ngx_buf_t *b, *buf; + ngx_int_t rc; + ngx_chain_t *cl; + ngx_http_request_body_t *rb; + ngx_http_core_loc_conf_t *clcf; + + rb = r->request_body; + buf = rb->buf; + + cl = ngx_chain_get_free_buf(r->pool, &rb->free); + if (cl == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + b = cl->buf; + + ngx_memzero(b, sizeof(ngx_buf_t)); + + if (buf->pos != buf->last) { + r->request_length += buf->last - buf->pos; + rb->received += buf->last - buf->pos; + + if (r->headers_in.content_length_n != -1) { + if (rb->received > r->headers_in.content_length_n) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client intended to send body data " + "larger than declared"); + + return NGX_HTTP_BAD_REQUEST; + } + } else { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->client_max_body_size + && rb->received > clcf->client_max_body_size) + { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "client intended to send too large chunked body: " + "%O bytes", rb->received); + + return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; + } + } + + b->temporary = 1; + b->pos = buf->pos; + b->last = buf->last; + b->start = b->pos; + b->end = b->last; + + buf->pos = buf->last; + } + + if (!rb->rest) { + if (r->headers_in.content_length_n != -1 + && r->headers_in.content_length_n != rb->received) + { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client prematurely closed stream: " + "only %O out of %O bytes of request body received", + rb->received, r->headers_in.content_length_n); + return NGX_HTTP_BAD_REQUEST; } - case NGX_HTTP_V2_DATA_INTERNAL_ERROR: - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - if (!r->request_body && ngx_http_v2_init_request_body(r) != NGX_OK) { - stream->skip_data = NGX_HTTP_V2_DATA_INTERNAL_ERROR; - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - if (stream->in_closed) { - post_handler(r); - return NGX_OK; - } - - r->request_body->post_handler = post_handler; - - r->read_event_handler = ngx_http_v2_read_client_request_body_handler; - r->write_event_handler = ngx_http_request_empty_handler; - - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - ngx_add_timer(r->connection->read, clcf->client_body_timeout); - - return NGX_AGAIN; + b->last_buf = 1; + } + + b->tag = (ngx_buf_tag_t) &ngx_http_v2_filter_request_body; + + rc = ngx_http_top_request_body_filter(r, cl); + + ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &cl, + (ngx_buf_tag_t) &ngx_http_v2_filter_request_body); + + return rc; } @@ -3678,7 +3658,7 @@ ngx_http_v2_read_client_request_body_han ngx_log_error(NGX_LOG_INFO, fc->log, NGX_ETIMEDOUT, "client timed out"); fc->timedout = 1; - r->stream->skip_data = NGX_HTTP_V2_DATA_DISCARD; + r->stream->skip_data = 1; ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); return; @@ -3688,7 +3668,7 @@ ngx_http_v2_read_client_request_body_han ngx_log_error(NGX_LOG_INFO, fc->log, 0, "client prematurely closed stream"); - r->stream->skip_data = NGX_HTTP_V2_DATA_DISCARD; + r->stream->skip_data = 1; ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST); return; diff -r 92464ebace8e -r 887cca40ba6a src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Fri Apr 01 15:56:03 2016 +0300 +++ b/src/http/v2/ngx_http_v2.h Fri Apr 01 15:56:03 2016 +0300 @@ -24,10 +24,6 @@ #define NGX_HTTP_V2_MAX_FIELD \ (127 + (1 << (NGX_HTTP_V2_INT_OCTETS - 1) * 7) - 1) -#define NGX_HTTP_V2_DATA_DISCARD 1 -#define NGX_HTTP_V2_DATA_ERROR 2 -#define NGX_HTTP_V2_DATA_INTERNAL_ERROR 3 - #define NGX_HTTP_V2_FRAME_HEADER_SIZE 9 /* frame types */ @@ -195,7 +191,8 @@ struct ngx_http_v2_stream_s { unsigned in_closed:1; unsigned out_closed:1; unsigned rst_sent:1; - unsigned skip_data:2; + unsigned no_flow_control:1; + unsigned skip_data:1; }; From vbart at nginx.com Fri Apr 1 12:57:31 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 01 Apr 2016 12:57:31 +0000 Subject: [nginx] HTTP/2: support for unbuffered upload of request body. Message-ID: details: http://hg.nginx.org/nginx/rev/9d66d7ed2abb branches: changeset: 6497:9d66d7ed2abb user: Valentin Bartenev date: Fri Apr 01 15:57:10 2016 +0300 description: HTTP/2: support for unbuffered upload of request body. diffstat: src/http/ngx_http_request_body.c | 13 +++- src/http/v2/ngx_http_v2.c | 129 ++++++++++++++++++++++++++++++++++++++- src/http/v2/ngx_http_v2.h | 1 + 3 files changed, 139 insertions(+), 4 deletions(-) diffs (232 lines): diff -r 887cca40ba6a -r 9d66d7ed2abb src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c Fri Apr 01 15:56:03 2016 +0300 +++ b/src/http/ngx_http_request_body.c Fri Apr 01 15:57:10 2016 +0300 @@ -48,7 +48,6 @@ ngx_http_read_client_request_body(ngx_ht #if (NGX_HTTP_V2) if (r->stream) { - r->request_body_no_buffering = 0; rc = ngx_http_v2_read_request_body(r, post_handler); goto done; } @@ -215,6 +214,18 @@ ngx_http_read_unbuffered_request_body(ng { ngx_int_t rc; +#if (NGX_HTTP_V2) + if (r->stream) { + rc = ngx_http_v2_read_unbuffered_request_body(r); + + if (rc == NGX_OK) { + r->reading_body = 0; + } + + return rc; + } +#endif + if (r->connection->read->timedout) { r->connection->timedout = 1; return NGX_HTTP_REQUEST_TIME_OUT; diff -r 887cca40ba6a -r 9d66d7ed2abb src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Fri Apr 01 15:56:03 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Fri Apr 01 15:57:10 2016 +0300 @@ -3395,6 +3395,8 @@ ngx_http_v2_run_request(ngx_http_request return; } + r->headers_in.chunked = (r->headers_in.content_length_n == -1); + ngx_http_process_request(r); } @@ -3440,6 +3442,18 @@ ngx_http_v2_read_request_body(ngx_http_r len = r->headers_in.content_length_n; + if (r->request_body_no_buffering && !stream->in_closed) { + r->request_body_in_file_only = 0; + + if (len < 0 || len > (off_t) clcf->client_body_buffer_size) { + len = clcf->client_body_buffer_size; + } + + if (len > NGX_HTTP_V2_MAX_WINDOW) { + len = NGX_HTTP_V2_MAX_WINDOW; + } + } + if (len >= 0 && len <= (off_t) clcf->client_body_buffer_size && !r->request_body_in_file_only) { @@ -3458,12 +3472,18 @@ ngx_http_v2_read_request_body(ngx_http_r } if (stream->in_closed) { + r->request_body_no_buffering = 0; return ngx_http_v2_process_request_body(r, NULL, 0, 1); } - stream->no_flow_control = 1; - - stream->recv_window = NGX_HTTP_V2_MAX_WINDOW; + if (r->request_body_no_buffering) { + stream->no_flow_control = 0; + stream->recv_window = (size_t) len; + + } else { + stream->no_flow_control = 1; + stream->recv_window = NGX_HTTP_V2_MAX_WINDOW; + } if (ngx_http_v2_send_window_update(stream->connection, stream->node->id, stream->recv_window) @@ -3525,6 +3545,11 @@ ngx_http_v2_process_request_body(ngx_htt ngx_del_timer(fc->read); } + if (r->request_body_no_buffering) { + ngx_post_event(fc->read, &ngx_posted_events); + return NGX_OK; + } + rc = ngx_http_v2_filter_request_body(r); if (rc != NGX_OK) { @@ -3553,6 +3578,11 @@ ngx_http_v2_process_request_body(ngx_htt clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); ngx_add_timer(fc->read, clcf->client_body_timeout); + if (r->request_body_no_buffering) { + ngx_post_event(fc->read, &ngx_posted_events); + return NGX_OK; + } + if (buf->sync) { return ngx_http_v2_filter_request_body(r); } @@ -3573,6 +3603,11 @@ ngx_http_v2_filter_request_body(ngx_http rb = r->request_body; buf = rb->buf; + if (buf->pos == buf->last && rb->rest) { + cl = NULL; + goto update; + } + cl = ngx_chain_get_free_buf(r->pool, &rb->free); if (cl == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; @@ -3634,6 +3669,9 @@ ngx_http_v2_filter_request_body(ngx_http } b->tag = (ngx_buf_tag_t) &ngx_http_v2_filter_request_body; + b->flush = r->request_body_no_buffering; + +update: rc = ngx_http_top_request_body_filter(r, cl); @@ -3676,6 +3714,91 @@ ngx_http_v2_read_client_request_body_han } +ngx_int_t +ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r) +{ + size_t window; + ngx_buf_t *buf; + ngx_int_t rc; + ngx_connection_t *fc; + ngx_http_v2_stream_t *stream; + ngx_http_v2_connection_t *h2c; + ngx_http_core_loc_conf_t *clcf; + + stream = r->stream; + fc = r->connection; + + if (fc->read->timedout) { + if (stream->recv_window) { + stream->skip_data = 1; + fc->timedout = 1; + + return NGX_HTTP_REQUEST_TIME_OUT; + } + + fc->read->timedout = 0; + } + + if (fc->error) { + stream->skip_data = 1; + return NGX_HTTP_BAD_REQUEST; + } + + rc = ngx_http_v2_filter_request_body(r); + + if (rc != NGX_OK) { + stream->skip_data = 1; + return rc; + } + + if (!r->request_body->rest) { + return NGX_OK; + } + + if (r->request_body->busy != NULL) { + return NGX_AGAIN; + } + + buf = r->request_body->buf; + + buf->pos = buf->start; + buf->last = buf->start; + + window = buf->end - buf->start; + h2c = stream->connection; + + if (h2c->state.stream == stream) { + window -= h2c->state.length; + } + + if (window == stream->recv_window) { + return NGX_AGAIN; + } + + if (ngx_http_v2_send_window_update(h2c, stream->node->id, + window - stream->recv_window) + == NGX_ERROR) + { + stream->skip_data = 1; + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) { + stream->skip_data = 1; + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + if (stream->recv_window == 0) { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + ngx_add_timer(fc->read, clcf->client_body_timeout); + } + + stream->recv_window = window; + + return NGX_AGAIN; +} + + static ngx_int_t ngx_http_v2_terminate_stream(ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream, ngx_uint_t status) diff -r 887cca40ba6a -r 9d66d7ed2abb src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Fri Apr 01 15:56:03 2016 +0300 +++ b/src/http/v2/ngx_http_v2.h Fri Apr 01 15:57:10 2016 +0300 @@ -260,6 +260,7 @@ void ngx_http_v2_request_headers_init(vo 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_unbuffered_request_body(ngx_http_request_t *r); void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc); From mdounin at mdounin.ru Fri Apr 1 13:45:00 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 01 Apr 2016 13:45:00 +0000 Subject: [nginx] Configure: fixed autotest source code logging. Message-ID: details: http://hg.nginx.org/nginx/rev/82a76258a142 branches: changeset: 6498:82a76258a142 user: Maxim Dounin date: Fri Apr 01 16:38:28 2016 +0300 description: Configure: fixed autotest source code logging. Fixed a regression introduced in rev. 434548349838 that prevented auto/types/sizeof and auto/types/typedef properly reporting autotest source code to autoconf.err in case of test failure. diffstat: auto/types/sizeof | 8 +++++--- auto/types/typedef | 7 ++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diffs (50 lines): diff --git a/auto/types/sizeof b/auto/types/sizeof --- a/auto/types/sizeof +++ b/auto/types/sizeof @@ -45,9 +45,6 @@ if [ -x $NGX_AUTOTEST ]; then fi -rm -rf $NGX_AUTOTEST* - - case $ngx_size in 4) ngx_max_value=2147483647 @@ -69,6 +66,11 @@ case $ngx_size in echo $ngx_test >> $NGX_AUTOCONF_ERR echo "----------" >> $NGX_AUTOCONF_ERR + rm -rf $NGX_AUTOTEST* + exit 1 esac + +rm -rf $NGX_AUTOTEST* + diff --git a/auto/types/typedef b/auto/types/typedef --- a/auto/types/typedef +++ b/auto/types/typedef @@ -49,8 +49,6 @@ END fi fi - rm -rf $NGX_AUTOTEST* - if [ $ngx_found = no ]; then echo $ngx_n " $ngx_try not found$ngx_c" @@ -59,8 +57,11 @@ END echo "----------" >> $NGX_AUTOCONF_ERR echo $ngx_test >> $NGX_AUTOCONF_ERR echo "----------" >> $NGX_AUTOCONF_ERR + fi - else + rm -rf $NGX_AUTOTEST* + + if [ $ngx_found != no ]; then break fi done From mdounin at mdounin.ru Fri Apr 1 13:45:02 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 01 Apr 2016 13:45:02 +0000 Subject: [nginx] Configure: improved multiple types handling in auto/types/typedef. Message-ID: details: http://hg.nginx.org/nginx/rev/e20bf454e58b branches: changeset: 6499:e20bf454e58b user: Maxim Dounin date: Fri Apr 01 16:38:30 2016 +0300 description: Configure: improved multiple types handling in auto/types/typedef. diffstat: auto/types/typedef | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diffs (16 lines): diff --git a/auto/types/typedef b/auto/types/typedef --- a/auto/types/typedef +++ b/auto/types/typedef @@ -50,7 +50,11 @@ END fi if [ $ngx_found = no ]; then - echo $ngx_n " $ngx_try not found$ngx_c" + if [ $ngx_try = $ngx_type ]; then + echo $ngx_n " $ngx_try not found$ngx_c" + else + echo $ngx_n ", $ngx_try not found$ngx_c" + fi echo "----------" >> $NGX_AUTOCONF_ERR cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR From mdounin at mdounin.ru Fri Apr 1 13:45:04 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 01 Apr 2016 13:45:04 +0000 Subject: [nginx] Compatibility with FreeBSD 2.2.9. Message-ID: details: http://hg.nginx.org/nginx/rev/8426275a13fd branches: changeset: 6500:8426275a13fd user: Maxim Dounin date: Fri Apr 01 16:38:31 2016 +0300 description: Compatibility with FreeBSD 2.2.9. Added (RTLD_NOW | RTLD_GLOBAL) to dlopen() test. There is no RTLD_GLOBAL on FreeBSD 2.2.9. Added uint32_t test, with fallback to u_int32_t, similar to uint64_t one. Added fallback to u_int32_t in in_addr_t test. With these changes it is now possible to compile nginx on FreeBSD 2.2.9 with only few minor warnings (assuming -Wno-error). diffstat: auto/unix | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (29 lines): diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -260,7 +260,7 @@ ngx_feature_run=no ngx_feature_incs="#include " ngx_feature_path= ngx_feature_libs= -ngx_feature_test="dlopen(NULL, 0); dlsym(NULL, NULL)" +ngx_feature_test="dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); dlsym(NULL, NULL)" . auto/feature @@ -547,6 +547,7 @@ ngx_param=NGX_PTR_SIZE; ngx_value=$ngx_s NGX_INCLUDE_AUTO_CONFIG_H="#include \"ngx_auto_config.h\"" +ngx_type="uint32_t"; ngx_types="u_int32_t"; . auto/types/typedef ngx_type="uint64_t"; ngx_types="u_int64_t"; . auto/types/typedef ngx_type="sig_atomic_t"; ngx_types="int"; . auto/types/typedef @@ -555,7 +556,7 @@ ngx_param=NGX_SIG_ATOMIC_T_SIZE; ngx_val ngx_type="socklen_t"; ngx_types="int"; . auto/types/typedef -ngx_type="in_addr_t"; ngx_types="uint32_t"; . auto/types/typedef +ngx_type="in_addr_t"; ngx_types="uint32_t u_int32_t"; . auto/types/typedef ngx_type="in_port_t"; ngx_types="u_short"; . auto/types/typedef From junpei.yoshino at gmail.com Sat Apr 2 13:48:42 2016 From: junpei.yoshino at gmail.com (junpei yoshino) Date: Sat, 2 Apr 2016 22:48:42 +0900 Subject: [PATCH]add proxy_protocol_port variable for rfc6302 In-Reply-To: References: <20151203190316.GG74233@mdounin.ru> <20151207025141.GT74233@mdounin.ru> Message-ID: Hi I wrote additional patch. support port information in realip module. if you use "real_port_header X-Forwarded-Port;" or "real_port_header proxy_protocol;", $remote_port and $realip_remote_port are replaced. # HG changeset patch # User Junpei Yoshino # Date 1449499172 -32400 # Mon Dec 07 23:39:32 2015 +0900 # Node ID f1ac7ecb90147b25a1b034a0a5dad663b1afa126 # Parent 8426275a13fdfac6dfe6955b7b3e999430eb373d Http: add proxy_protocol_port variable for rfc6302 diff -r 8426275a13fd -r f1ac7ecb9014 src/core/ngx_connection.h --- a/src/core/ngx_connection.h Fri Apr 01 16:38:31 2016 +0300 +++ b/src/core/ngx_connection.h Mon Dec 07 23:39:32 2015 +0900 @@ -149,6 +149,7 @@ ngx_str_t addr_text; ngx_str_t proxy_protocol_addr; + ngx_int_t proxy_protocol_port; #if (NGX_SSL) ngx_ssl_connection_t *ssl; diff -r 8426275a13fd -r f1ac7ecb9014 src/core/ngx_proxy_protocol.c --- a/src/core/ngx_proxy_protocol.c Fri Apr 01 16:38:31 2016 +0300 +++ b/src/core/ngx_proxy_protocol.c Mon Dec 07 23:39:32 2015 +0900 @@ -13,7 +13,7 @@ ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) { size_t len; - u_char ch, *p, *addr; + u_char ch, *p, *addr, *port; p = buf; len = last - buf; @@ -71,8 +71,40 @@ ngx_memcpy(c->proxy_protocol_addr.data, addr, len); c->proxy_protocol_addr.len = len; - ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, - "PROXY protocol address: \"%V\"", &c->proxy_protocol_addr); + for ( ;; ) { + if (p == last) { + goto invalid; + } + + ch = *p++; + + if (ch == ' ') { + break; + } + } + port = p; + for ( ;; ) { + if (p == last) { + goto invalid; + } + + ch = *p++; + + if (ch == ' ') { + break; + } + + if (ch < '0' || ch > '9') + { + goto invalid; + } + } + len = p - port - 1; + c->proxy_protocol_port = ngx_atoi(port,len); + + ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0, + "PROXY protocol address: \"%V\", PROXY protocol port: \"%d\"", + &c->proxy_protocol_addr, c->proxy_protocol_port); skip: diff -r 8426275a13fd -r f1ac7ecb9014 src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c Fri Apr 01 16:38:31 2016 +0300 +++ b/src/http/ngx_http_variables.c Mon Dec 07 23:39:32 2015 +0900 @@ -58,6 +58,8 @@ ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r, @@ -192,6 +194,9 @@ { ngx_string("proxy_protocol_addr"), NULL, ngx_http_variable_proxy_protocol_addr, 0, 0, 0 }, + { ngx_string("proxy_protocol_port"), NULL, + ngx_http_variable_proxy_protocol_port, 0, 0, 0 }, + { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 }, { ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 }, @@ -1250,6 +1255,29 @@ static ngx_int_t +ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + ngx_int_t port = r->connection->proxy_protocol_port; + + v->len = 0; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1); + + if (v->data == NULL) { + return NGX_ERROR; + } + if (port > 0 && port < 65536) { + v->len = ngx_sprintf(v->data, "%ui", port) - v->data; + } + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { # HG changeset patch # User Junpei Yoshino # Date 1459602896 -32400 # Sat Apr 02 22:14:56 2016 +0900 # Node ID 5eb9a53367f1bb4d217b9f86b662f835d86a76c2 # Parent f1ac7ecb90147b25a1b034a0a5dad663b1afa126 support port information in realip module diff -r f1ac7ecb9014 -r 5eb9a53367f1 src/core/ngx_connection.h --- a/src/core/ngx_connection.h Mon Dec 07 23:39:32 2015 +0900 +++ b/src/core/ngx_connection.h Sat Apr 02 22:14:56 2016 +0900 @@ -147,6 +147,7 @@ struct sockaddr *sockaddr; socklen_t socklen; ngx_str_t addr_text; + ngx_uint_t port; ngx_str_t proxy_protocol_addr; ngx_int_t proxy_protocol_port; diff -r f1ac7ecb9014 -r 5eb9a53367f1 src/core/ngx_inet.c --- a/src/core/ngx_inet.c Mon Dec 07 23:39:32 2015 +0900 +++ b/src/core/ngx_inet.c Sat Apr 02 22:14:56 2016 +0900 @@ -256,6 +256,38 @@ } +ngx_uint_t +ngx_sock_get_port(struct sockaddr *sa, socklen_t socklen) +{ + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif + + switch (sa->sa_family) { + + case AF_INET: + sin = (struct sockaddr_in *) sa; + return ntohs(sin->sin_port); + break; + +#if (NGX_HAVE_INET6) + + case AF_INET6: + + sin6 = (struct sockaddr_in6 *) sa; + + return ntohs(sin6->sin6_port); + + break; +#endif + + default: + return 0; + } +} + + size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len) { diff -r f1ac7ecb9014 -r 5eb9a53367f1 src/core/ngx_inet.h --- a/src/core/ngx_inet.h Mon Dec 07 23:39:32 2015 +0900 +++ b/src/core/ngx_inet.h Sat Apr 02 22:14:56 2016 +0900 @@ -109,6 +109,7 @@ #endif size_t ngx_sock_ntop(struct sockaddr *sa, socklen_t socklen, u_char *text, size_t len, ngx_uint_t port); +ngx_uint_t ngx_sock_get_port(struct sockaddr *sa, socklen_t socklen); size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len); ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr); ngx_int_t ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, diff -r f1ac7ecb9014 -r 5eb9a53367f1 src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c Mon Dec 07 23:39:32 2015 +0900 +++ b/src/event/ngx_event_accept.c Sat Apr 02 22:14:56 2016 +0900 @@ -278,6 +278,7 @@ ngx_close_accepted_connection(c); return; } + c->port = ngx_sock_get_port(c->sockaddr, c->socklen); } #if (NGX_DEBUG) diff -r f1ac7ecb9014 -r 5eb9a53367f1 src/http/modules/ngx_http_realip_module.c --- a/src/http/modules/ngx_http_realip_module.c Mon Dec 07 23:39:32 2015 +0900 +++ b/src/http/modules/ngx_http_realip_module.c Sat Apr 02 22:14:56 2016 +0900 @@ -15,6 +15,9 @@ #define NGX_HTTP_REALIP_HEADER 2 #define NGX_HTTP_REALIP_PROXY 3 +#define NGX_HTTP_REALPORT_XFWD 1 +#define NGX_HTTP_REALPORT_PROXY 2 +#define NGX_HTTP_REALPORT_HEADER 3 typedef struct { ngx_array_t *from; /* array of ngx_cidr_t */ @@ -22,6 +25,9 @@ ngx_uint_t hash; ngx_str_t header; ngx_flag_t recursive; + ngx_uint_t porttype; + ngx_uint_t porthash; + ngx_str_t portheader; } ngx_http_realip_loc_conf_t; @@ -30,16 +36,18 @@ struct sockaddr *sockaddr; socklen_t socklen; ngx_str_t addr_text; + ngx_uint_t port; } ngx_http_realip_ctx_t; static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r); static ngx_int_t ngx_http_realip_set_addr(ngx_http_request_t *r, - ngx_addr_t *addr); + ngx_addr_t *addr, ngx_uint_t port); static void ngx_http_realip_cleanup(void *data); static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_real_port(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); @@ -49,6 +57,8 @@ static ngx_int_t ngx_http_realip_remote_addr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_realip_remote_port_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_command_t ngx_http_realip_commands[] = { @@ -67,6 +77,13 @@ 0, NULL }, + { ngx_string("real_port_header"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_http_real_port, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + { ngx_string("real_ip_recursive"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -115,6 +132,9 @@ { ngx_string("realip_remote_addr"), NULL, ngx_http_realip_remote_addr_variable, 0, 0, 0 }, + { ngx_string("realip_remote_port"), NULL, + ngx_http_realip_remote_port_variable, 0, 0, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; @@ -127,6 +147,8 @@ ngx_str_t *value; ngx_uint_t i, hash; ngx_addr_t addr; + ngx_uint_t port; + ngx_str_t *port_value; ngx_array_t *xfwd; ngx_list_part_t *part; ngx_table_elt_t *header; @@ -172,7 +194,6 @@ break; case NGX_HTTP_REALIP_PROXY: - value = &r->connection->proxy_protocol_addr; if (value->len == 0) { @@ -211,14 +232,69 @@ value = &header[i].value; xfwd = NULL; - goto found; + goto portphase; } } return NGX_DECLINED; } -found: +portphase: + + port = r->connection->port; + + switch (rlcf->porttype) { + + case NGX_CONF_UNSET_UINT: + break; + + case NGX_HTTP_REALPORT_XFWD: + port_value = &r->headers_in.x_forwarded_port->value; + + if (port_value == NULL) { + break; + } + + port = ngx_atoi(port_value->data,port_value->len); + + break; + + case NGX_HTTP_REALPORT_PROXY: + port = r->connection->proxy_protocol_port; + + break; + + default: /* NGX_HTTP_REALPORT_HEADER */ + + part = &r->headers_in.headers.part; + header = part->elts; + + hash = rlcf->porthash; + len = rlcf->portheader.len; + p = rlcf->portheader.data; + + for (i = 0; /* void */ ; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + header = part->elts; + i = 0; + } + + if (hash == header[i].hash + && len == header[i].key.len + && ngx_strncmp(p, header[i].lowcase_key, len) == 0) + { + port=ngx_atoi(header[i].value.data, header[i].value.len); + + break; + } + } + } c = r->connection; @@ -230,7 +306,7 @@ rlcf->recursive) != NGX_DECLINED) { - return ngx_http_realip_set_addr(r, &addr); + return ngx_http_realip_set_addr(r, &addr, port); } return NGX_DECLINED; @@ -238,7 +314,7 @@ static ngx_int_t -ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr) +ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr, ngx_uint_t port) { size_t len; u_char *p; @@ -276,11 +352,13 @@ ctx->sockaddr = c->sockaddr; ctx->socklen = c->socklen; ctx->addr_text = c->addr_text; + ctx->port = c->port; c->sockaddr = addr->sockaddr; c->socklen = addr->socklen; c->addr_text.len = len; c->addr_text.data = p; + c->port = port; return NGX_DECLINED; } @@ -298,6 +376,7 @@ c->sockaddr = ctx->sockaddr; c->socklen = ctx->socklen; c->addr_text = ctx->addr_text; + c->port = ctx->port; } @@ -383,6 +462,33 @@ } +static char * +ngx_http_real_port(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_realip_loc_conf_t *rlcf = conf; + + ngx_str_t *value; + + value = cf->args->elts; + + if (ngx_strcmp(value[1].data, "X-Forwarded-Port") == 0) { + rlcf->porttype = NGX_HTTP_REALPORT_XFWD; + return NGX_CONF_OK; + } + + if (ngx_strcmp(value[1].data, "proxy_protocol") == 0) { + rlcf->porttype = NGX_HTTP_REALPORT_PROXY; + return NGX_CONF_OK; + } + + rlcf->porttype = NGX_HTTP_REALPORT_HEADER; + rlcf->porthash = ngx_hash_strlow(value[1].data, value[1].data, value[1].len); + rlcf->portheader = value[1]; + + return NGX_CONF_OK; +} + + static void * ngx_http_realip_create_loc_conf(ngx_conf_t *cf) { @@ -399,9 +505,12 @@ * conf->from = NULL; * conf->hash = 0; * conf->header = { 0, NULL }; + * conf->porthash = 0 + * conf->portheader = { 0, NULL }; */ conf->type = NGX_CONF_UNSET_UINT; + conf->porttype = NGX_CONF_UNSET_UINT; conf->recursive = NGX_CONF_UNSET; return conf; @@ -510,3 +619,50 @@ return NGX_OK; } + + +static ngx_int_t +ngx_http_realip_remote_port_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + ngx_uint_t port; + ngx_pool_cleanup_t *cln; + ngx_http_realip_ctx_t *ctx; + + ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module); + + if (ctx == NULL && (r->internal || r->filter_finalize)) { + + /* + * if module context was reset, the original port + * can still be found in the cleanup handler + */ + + for (cln = r->pool->cleanup; cln; cln = cln->next) { + if (cln->handler == ngx_http_realip_cleanup) { + ctx = cln->data; + break; + } + } + } + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "piyo %ui %ui",ctx->port,r->connection->port); + + + port = ctx ? ctx->port : r->connection->port; + + v->len = 0; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1); + + if (v->data == NULL) { + return NGX_ERROR; + } + if (port > 0 && port < 65536) { + v->len = ngx_sprintf(v->data, "%ui", port) - v->data; + } + + return NGX_OK; +} diff -r f1ac7ecb9014 -r 5eb9a53367f1 src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Mon Dec 07 23:39:32 2015 +0900 +++ b/src/http/ngx_http_request.c Sat Apr 02 22:14:56 2016 +0900 @@ -153,6 +153,10 @@ { ngx_string("X-Forwarded-For"), offsetof(ngx_http_headers_in_t, x_forwarded_for), ngx_http_process_multi_header_lines }, + + { ngx_string("X-Forwarded-Port"), + offsetof(ngx_http_headers_in_t, x_forwarded_port), + ngx_http_process_header_line }, #endif #if (NGX_HTTP_REALIP) diff -r f1ac7ecb9014 -r 5eb9a53367f1 src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h Mon Dec 07 23:39:32 2015 +0900 +++ b/src/http/ngx_http_request.h Sat Apr 02 22:14:56 2016 +0900 @@ -202,6 +202,7 @@ #if (NGX_HTTP_X_FORWARDED_FOR) ngx_array_t x_forwarded_for; + ngx_table_elt_t *x_forwarded_port; #endif #if (NGX_HTTP_REALIP) diff -r f1ac7ecb9014 -r 5eb9a53367f1 src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c Mon Dec 07 23:39:32 2015 +0900 +++ b/src/http/ngx_http_variables.c Sat Apr 02 22:14:56 2016 +0900 @@ -171,6 +171,9 @@ #if (NGX_HTTP_X_FORWARDED_FOR) { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_headers, offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 }, + + { ngx_string("http_x_forwarded_port"), NULL, ngx_http_variable_header, + offsetof(ngx_http_request_t, headers_in.x_forwarded_port), 0, 0 }, #endif { ngx_string("http_cookie"), NULL, ngx_http_variable_cookies, @@ -1195,12 +1198,7 @@ ngx_http_variable_remote_port(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - ngx_uint_t port; - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif - + ngx_uint_t port; v->len = 0; v->valid = 1; v->no_cacheable = 0; @@ -1210,27 +1208,8 @@ if (v->data == NULL) { return NGX_ERROR; } - - switch (r->connection->sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) r->connection->sockaddr; - port = ntohs(sin6->sin6_port); - break; -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - case AF_UNIX: - port = 0; - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) r->connection->sockaddr; - port = ntohs(sin->sin_port); - break; - } + + port = r->connection->port; if (port > 0 && port < 65536) { v->len = ngx_sprintf(v->data, "%ui", port) - v->data; On Sat, Feb 20, 2016 at 2:44 AM, Tomoya Kabe wrote: > Hi, > > Can anybody check this patch? > I'm eager to use this feature. > > 2015-12-08 9:35 GMT+09:00 junpei yoshino : >> >> Hello, >> >> I made merged patch. >> >> # HG changeset patch >> # User Junpei Yoshino >> # Date 1449499172 -32400 >> # Mon Dec 07 23:39:32 2015 +0900 >> # Node ID f4cd90a03eca5c330f51ac4ba2673e64348c622e >> # Parent 29f35e60840b8eed2927dd3495ef2d8e524862f7 >> Http: add proxy_protocol_port variable for rfc6302 >> >> diff -r 29f35e60840b -r f4cd90a03eca src/core/ngx_connection.h >> --- a/src/core/ngx_connection.h Mon Dec 07 16:30:48 2015 +0300 >> +++ b/src/core/ngx_connection.h Mon Dec 07 23:39:32 2015 +0900 >> @@ -146,6 +146,7 @@ >> ngx_str_t addr_text; >> >> ngx_str_t proxy_protocol_addr; >> + ngx_int_t proxy_protocol_port; >> >> #if (NGX_SSL) >> ngx_ssl_connection_t *ssl; >> diff -r 29f35e60840b -r f4cd90a03eca src/core/ngx_proxy_protocol.c >> --- a/src/core/ngx_proxy_protocol.c Mon Dec 07 16:30:48 2015 +0300 >> +++ b/src/core/ngx_proxy_protocol.c Mon Dec 07 23:39:32 2015 +0900 >> @@ -13,7 +13,7 @@ >> ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) >> { >> size_t len; >> - u_char ch, *p, *addr; >> + u_char ch, *p, *addr, *port; >> >> p = buf; >> len = last - buf; >> @@ -71,8 +71,40 @@ >> ngx_memcpy(c->proxy_protocol_addr.data, addr, len); >> c->proxy_protocol_addr.len = len; >> >> - ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, >> - "PROXY protocol address: \"%V\"", >> &c->proxy_protocol_addr); >> + for ( ;; ) { >> + if (p == last) { >> + goto invalid; >> + } >> + >> + ch = *p++; >> + >> + if (ch == ' ') { >> + break; >> + } >> + } >> + port = p; >> + for ( ;; ) { >> + if (p == last) { >> + goto invalid; >> + } >> + >> + ch = *p++; >> + >> + if (ch == ' ') { >> + break; >> + } >> + >> + if (ch < '0' || ch > '9') >> + { >> + goto invalid; >> + } >> + } >> + len = p - port - 1; >> + c->proxy_protocol_port = ngx_atoi(port,len); >> + >> + ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0, >> + "PROXY protocol address: \"%V\", PROXY protocol >> port: \"%d\"", >> + &c->proxy_protocol_addr, c->proxy_protocol_port); >> >> skip: >> >> diff -r 29f35e60840b -r f4cd90a03eca src/http/ngx_http_variables.c >> --- a/src/http/ngx_http_variables.c Mon Dec 07 16:30:48 2015 +0300 >> +++ b/src/http/ngx_http_variables.c Mon Dec 07 23:39:32 2015 +0900 >> @@ -58,6 +58,8 @@ >> ngx_http_variable_value_t *v, uintptr_t data); >> static ngx_int_t ngx_http_variable_proxy_protocol_addr(ngx_http_request_t >> *r, >> ngx_http_variable_value_t *v, uintptr_t data); >> +static ngx_int_t ngx_http_variable_proxy_protocol_port(ngx_http_request_t >> *r, >> + ngx_http_variable_value_t *v, uintptr_t data); >> static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, >> ngx_http_variable_value_t *v, uintptr_t data); >> static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r, >> @@ -192,6 +194,9 @@ >> { ngx_string("proxy_protocol_addr"), NULL, >> ngx_http_variable_proxy_protocol_addr, 0, 0, 0 }, >> >> + { ngx_string("proxy_protocol_port"), NULL, >> + ngx_http_variable_proxy_protocol_port, 0, 0, 0 }, >> + >> { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, >> 0, 0, 0 }, >> >> { ngx_string("server_port"), NULL, ngx_http_variable_server_port, >> 0, 0, 0 }, >> @@ -1250,6 +1255,29 @@ >> >> >> static ngx_int_t >> +ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, >> + ngx_http_variable_value_t *v, uintptr_t data) >> +{ >> + ngx_int_t port = r->connection->proxy_protocol_port; >> + >> + v->len = 0; >> + v->valid = 1; >> + v->no_cacheable = 0; >> + v->not_found = 0; >> + v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1); >> + >> + if (v->data == NULL) { >> + return NGX_ERROR; >> + } >> + if (port > 0 && port < 65536) { >> + v->len = ngx_sprintf(v->data, "%ui", port) - v->data; >> + } >> + >> + return NGX_OK; >> +} >> + >> + >> +static ngx_int_t >> ngx_http_variable_server_addr(ngx_http_request_t *r, >> ngx_http_variable_value_t *v, uintptr_t data) >> { >> >> >> On Tue, Dec 8, 2015 at 12:56 AM, junpei yoshino >> wrote: >> > Hello. >> > >> > I wrote additional patch. >> > >> > # HG changeset patch >> > # User Junpei Yoshino >> > # Date 1449499172 -32400 >> > # Mon Dec 07 23:39:32 2015 +0900 >> > # Node ID e2984af905ff8cf523b22860620a9f3ff22d555a >> > # Parent 59cadccedf402ec325b078cb72a284465639e0fe >> > Change definition of proxy_protocol_port >> > >> > diff -r 59cadccedf40 -r e2984af905ff src/core/ngx_connection.h >> > --- a/src/core/ngx_connection.h Thu Nov 05 20:36:47 2015 +0900 >> > +++ b/src/core/ngx_connection.h Mon Dec 07 23:39:32 2015 +0900 >> > @@ -146,7 +146,7 @@ >> > ngx_str_t addr_text; >> > >> > ngx_str_t proxy_protocol_addr; >> > - ngx_str_t proxy_protocol_port; >> > + ngx_int_t proxy_protocol_port; >> > >> > #if (NGX_SSL) >> > ngx_ssl_connection_t *ssl; >> > diff -r 59cadccedf40 -r e2984af905ff src/core/ngx_proxy_protocol.c >> > --- a/src/core/ngx_proxy_protocol.c Thu Nov 05 20:36:47 2015 +0900 >> > +++ b/src/core/ngx_proxy_protocol.c Mon Dec 07 23:39:32 2015 +0900 >> > @@ -81,14 +81,6 @@ >> > if (ch == ' ') { >> > break; >> > } >> > - >> > - if (ch != ':' && ch != '.' >> > - && (ch < 'a' || ch > 'f') >> > - && (ch < 'A' || ch > 'F') >> > - && (ch < '0' || ch > '9')) >> > - { >> > - goto invalid; >> > - } >> > } >> > port = p; >> > for ( ;; ) { >> > @@ -108,19 +100,11 @@ >> > } >> > } >> > len = p - port - 1; >> > - c->proxy_protocol_port.data = ngx_pnalloc(c->pool, len); >> > + c->proxy_protocol_port = ngx_atoi(port,len); >> > >> > - if (c->proxy_protocol_port.data == NULL) { >> > - return NULL; >> > - } >> > - >> > - ngx_memcpy(c->proxy_protocol_port.data, port, len); >> > - c->proxy_protocol_port.len = len; >> > - >> > - ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, >> > - "PROXY protocol address: \"%V\"", >> > &c->proxy_protocol_addr); >> > - ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, >> > - "PROXY protocol port: \"%V\"", >> > &c->proxy_protocol_port); >> > + ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0, >> > + "PROXY protocol address: \"%V\", PROXY protocol >> > port: \"%d\"", >> > + &c->proxy_protocol_addr, c->proxy_protocol_port); >> > >> > skip: >> > >> > diff -r 59cadccedf40 -r e2984af905ff src/http/ngx_http_variables.c >> > --- a/src/http/ngx_http_variables.c Thu Nov 05 20:36:47 2015 +0900 >> > +++ b/src/http/ngx_http_variables.c Mon Dec 07 23:39:32 2015 +0900 >> > @@ -1258,11 +1258,20 @@ >> > ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, >> > ngx_http_variable_value_t *v, uintptr_t data) >> > { >> > - v->len = r->connection->proxy_protocol_port.len; >> > + ngx_int_t port = r->connection->proxy_protocol_port; >> > + >> > + v->len = 0; >> > v->valid = 1; >> > v->no_cacheable = 0; >> > v->not_found = 0; >> > - v->data = r->connection->proxy_protocol_port.data; >> > + v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1); >> > + >> > + if (v->data == NULL) { >> > + return NGX_ERROR; >> > + } >> > + if (port > 0 && port < 65536) { >> > + v->len = ngx_sprintf(v->data, "%ui", port) - v->data; >> > + } >> > >> > return NGX_OK; >> > } >> > >> > >> > On Mon, Dec 7, 2015 at 11:51 AM, Maxim Dounin >> > wrote: >> >> Hello! >> >> >> >> On Mon, Dec 07, 2015 at 12:14:38AM +0900, junpei yoshino wrote: >> >> >> >>> > but we need someone to do the rest of the work. >> >>> >> >>> Could I contribute it? >> >>> At first, I will revise this patch along your review. >> >> >> >> It may be a bit too many for someone with small nginx coding >> >> experience, but you may try to. >> >> >> >> -- >> >> Maxim Dounin >> >> http://nginx.org/ >> >> >> >> _______________________________________________ >> >> nginx-devel mailing list >> >> nginx-devel at nginx.org >> >> http://mailman.nginx.org/mailman/listinfo/nginx-devel >> > >> > >> > >> > -- >> > junpei.yoshino at gmail.com >> >> >> >> -- >> junpei.yoshino at gmail.com >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > > -- > Tomoya KABE > Mail : limit.usus at gmail.com > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -- junpei.yoshino at gmail.com From mdounin at mdounin.ru Mon Apr 4 15:30:57 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 4 Apr 2016 18:30:57 +0300 Subject: [PATCH]add proxy_protocol_port variable for rfc6302 In-Reply-To: References: <20151203190316.GG74233@mdounin.ru> <20151207025141.GT74233@mdounin.ru> Message-ID: <20160404153057.GH36620@mdounin.ru> Hello! On Sat, Apr 02, 2016 at 10:48:42PM +0900, junpei yoshino wrote: > Hi > > I wrote additional patch. > support port information in realip module. > > if you use "real_port_header X-Forwarded-Port;" > or "real_port_header proxy_protocol;", > $remote_port and $realip_remote_port are replaced. I don't think that X-Forwarded-Port is a good idea: - where seen, it's used for other purposes - to indicate _server_ port of a load balancer, not client port; - it should be easily possible to use the same header to pass to both addresses and ports; this is how it is defined in RFC 7239 for the Forwarded header, and we can use something similar at least for custom headers. -- Maxim Dounin http://nginx.org/ From junpei.yoshino at gmail.com Mon Apr 4 17:12:21 2016 From: junpei.yoshino at gmail.com (junpei yoshino) Date: Tue, 5 Apr 2016 02:12:21 +0900 Subject: [PATCH]add proxy_protocol_port variable for rfc6302 In-Reply-To: <20160404153057.GH36620@mdounin.ru> References: <20151203190316.GG74233@mdounin.ru> <20151207025141.GT74233@mdounin.ru> <20160404153057.GH36620@mdounin.ru> Message-ID: Hi Thank you for your information and for reading my code. I took a mistake. You are right. Forwarded header is good. I rewrite patch. which is better way ? 1. "real_ip_from Forwarded" replace remote_addr and remote_port. And proxy_protocol also replace remote_addr and remote_port, too. 2. "real_port_from Forwarded" replace port only. ip and port is independent. Also proxy protocol must configure real_ip_from and real_port_from. 3. At first, not care Forwarded header. delete code related x-forwarded-port. support only custom http header including port number. 4. another way Best Regards, Junpei Yoshino On Tue, Apr 5, 2016 at 12:30 AM, Maxim Dounin wrote: > Hello! > > On Sat, Apr 02, 2016 at 10:48:42PM +0900, junpei yoshino wrote: > >> Hi >> >> I wrote additional patch. >> support port information in realip module. >> >> if you use "real_port_header X-Forwarded-Port;" >> or "real_port_header proxy_protocol;", >> $remote_port and $realip_remote_port are replaced. > > I don't think that X-Forwarded-Port is a good idea: > > - where seen, it's used for other purposes - to indicate _server_ > port of a load balancer, not client port; > > - it should be easily possible to use the same header to pass to > both addresses and ports; this is how it is defined in RFC > 7239 for the Forwarded header, and we can use something similar at > least for custom headers. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -- junpei.yoshino at gmail.com From mdounin at mdounin.ru Mon Apr 4 17:56:33 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 4 Apr 2016 20:56:33 +0300 Subject: [PATCH]add proxy_protocol_port variable for rfc6302 In-Reply-To: References: <20151203190316.GG74233@mdounin.ru> <20151207025141.GT74233@mdounin.ru> <20160404153057.GH36620@mdounin.ru> Message-ID: <20160404175633.GL36620@mdounin.ru> Hello! On Tue, Apr 05, 2016 at 02:12:21AM +0900, junpei yoshino wrote: > which is better way ? > 1. > "real_ip_from Forwarded" replace remote_addr and remote_port. > And proxy_protocol also replace remote_addr and remote_port, too. While support for Forwarded is a good thing to have, it looks like a separate and big work, so I wouldn't recommend trying to do this now. > 2. > "real_port_from Forwarded" replace port only. > ip and port is independent. > Also proxy protocol must configure real_ip_from and real_port_from. This approach looks wrong. If we know client port it should be used. But see above about Forwarded. > 3. > At first, not care Forwarded header. > delete code related x-forwarded-port. > support only custom http header including port number. This option looks most appropriate for now. (Assuming this also includes "proxy_protocol also replace remote_addr and remote_port" as in 1.) -- Maxim Dounin http://nginx.org/ From junpei.yoshino at gmail.com Tue Apr 5 00:50:59 2016 From: junpei.yoshino at gmail.com (junpei yoshino) Date: Tue, 5 Apr 2016 09:50:59 +0900 Subject: [PATCH]add proxy_protocol_port variable for rfc6302 In-Reply-To: <20160404175633.GL36620@mdounin.ru> References: <20151203190316.GG74233@mdounin.ru> <20151207025141.GT74233@mdounin.ru> <20160404153057.GH36620@mdounin.ru> <20160404175633.GL36620@mdounin.ru> Message-ID: Hello! Thank you for your comment. I rewrote patch in way 3. Best Regards, Junpei Yoshino # HG changeset patch # User Junpei Yoshino # Date 1459816952 -32400 # Tue Apr 05 09:42:32 2016 +0900 # Node ID cdaf19070ed1687a4f942936a0e7339355b98bfa # Parent 8426275a13fdfac6dfe6955b7b3e999430eb373d Http: add proxy_protocol_port variable for rfc6302 & support in realip module real_port_header is not needed if "real_ip_header proxy_protocol" configured. replace remote_port with request header if you set real_port_header. diff -r 8426275a13fd -r cdaf19070ed1 src/core/ngx_connection.h --- a/src/core/ngx_connection.h Fri Apr 01 16:38:31 2016 +0300 +++ b/src/core/ngx_connection.h Tue Apr 05 09:42:32 2016 +0900 @@ -147,8 +147,10 @@ struct sockaddr *sockaddr; socklen_t socklen; ngx_str_t addr_text; + ngx_uint_t port; ngx_str_t proxy_protocol_addr; + ngx_int_t proxy_protocol_port; #if (NGX_SSL) ngx_ssl_connection_t *ssl; diff -r 8426275a13fd -r cdaf19070ed1 src/core/ngx_inet.c --- a/src/core/ngx_inet.c Fri Apr 01 16:38:31 2016 +0300 +++ b/src/core/ngx_inet.c Tue Apr 05 09:42:32 2016 +0900 @@ -256,6 +256,38 @@ } +ngx_uint_t +ngx_sock_get_port(struct sockaddr *sa, socklen_t socklen) +{ + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif + + switch (sa->sa_family) { + + case AF_INET: + sin = (struct sockaddr_in *) sa; + return ntohs(sin->sin_port); + break; + +#if (NGX_HAVE_INET6) + + case AF_INET6: + + sin6 = (struct sockaddr_in6 *) sa; + + return ntohs(sin6->sin6_port); + + break; +#endif + + default: + return 0; + } +} + + size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len) { diff -r 8426275a13fd -r cdaf19070ed1 src/core/ngx_inet.h --- a/src/core/ngx_inet.h Fri Apr 01 16:38:31 2016 +0300 +++ b/src/core/ngx_inet.h Tue Apr 05 09:42:32 2016 +0900 @@ -109,6 +109,7 @@ #endif size_t ngx_sock_ntop(struct sockaddr *sa, socklen_t socklen, u_char *text, size_t len, ngx_uint_t port); +ngx_uint_t ngx_sock_get_port(struct sockaddr *sa, socklen_t socklen); size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len); ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr); ngx_int_t ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, diff -r 8426275a13fd -r cdaf19070ed1 src/core/ngx_proxy_protocol.c --- a/src/core/ngx_proxy_protocol.c Fri Apr 01 16:38:31 2016 +0300 +++ b/src/core/ngx_proxy_protocol.c Tue Apr 05 09:42:32 2016 +0900 @@ -13,7 +13,7 @@ ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) { size_t len; - u_char ch, *p, *addr; + u_char ch, *p, *addr, *port; p = buf; len = last - buf; @@ -71,8 +71,40 @@ ngx_memcpy(c->proxy_protocol_addr.data, addr, len); c->proxy_protocol_addr.len = len; - ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, - "PROXY protocol address: \"%V\"", &c->proxy_protocol_addr); + for ( ;; ) { + if (p == last) { + goto invalid; + } + + ch = *p++; + + if (ch == ' ') { + break; + } + } + port = p; + for ( ;; ) { + if (p == last) { + goto invalid; + } + + ch = *p++; + + if (ch == ' ') { + break; + } + + if (ch < '0' || ch > '9') + { + goto invalid; + } + } + len = p - port - 1; + c->proxy_protocol_port = ngx_atoi(port,len); + + ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0, + "PROXY protocol address: \"%V\", PROXY protocol port: \"%d\"", + &c->proxy_protocol_addr, c->proxy_protocol_port); skip: diff -r 8426275a13fd -r cdaf19070ed1 src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c Fri Apr 01 16:38:31 2016 +0300 +++ b/src/event/ngx_event_accept.c Tue Apr 05 09:42:32 2016 +0900 @@ -278,6 +278,7 @@ ngx_close_accepted_connection(c); return; } + c->port = ngx_sock_get_port(c->sockaddr, c->socklen); } #if (NGX_DEBUG) diff -r 8426275a13fd -r cdaf19070ed1 src/http/modules/ngx_http_realip_module.c --- a/src/http/modules/ngx_http_realip_module.c Fri Apr 01 16:38:31 2016 +0300 +++ b/src/http/modules/ngx_http_realip_module.c Tue Apr 05 09:42:32 2016 +0900 @@ -15,6 +15,8 @@ #define NGX_HTTP_REALIP_HEADER 2 #define NGX_HTTP_REALIP_PROXY 3 +#define NGX_HTTP_REALPORT_PROXY 1 +#define NGX_HTTP_REALPORT_HEADER 2 typedef struct { ngx_array_t *from; /* array of ngx_cidr_t */ @@ -22,6 +24,9 @@ ngx_uint_t hash; ngx_str_t header; ngx_flag_t recursive; + ngx_uint_t porttype; + ngx_uint_t porthash; + ngx_str_t portheader; } ngx_http_realip_loc_conf_t; @@ -30,16 +35,18 @@ struct sockaddr *sockaddr; socklen_t socklen; ngx_str_t addr_text; + ngx_uint_t port; } ngx_http_realip_ctx_t; static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r); static ngx_int_t ngx_http_realip_set_addr(ngx_http_request_t *r, - ngx_addr_t *addr); + ngx_addr_t *addr, ngx_uint_t port); static void ngx_http_realip_cleanup(void *data); static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_real_port(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); @@ -49,6 +56,8 @@ static ngx_int_t ngx_http_realip_remote_addr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_realip_remote_port_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_command_t ngx_http_realip_commands[] = { @@ -67,6 +76,13 @@ 0, NULL }, + { ngx_string("real_port_header"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_http_real_port, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + { ngx_string("real_ip_recursive"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -115,6 +131,9 @@ { ngx_string("realip_remote_addr"), NULL, ngx_http_realip_remote_addr_variable, 0, 0, 0 }, + { ngx_string("realip_remote_port"), NULL, + ngx_http_realip_remote_port_variable, 0, 0, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; @@ -127,6 +146,7 @@ ngx_str_t *value; ngx_uint_t i, hash; ngx_addr_t addr; + ngx_uint_t port; ngx_array_t *xfwd; ngx_list_part_t *part; ngx_table_elt_t *header; @@ -146,6 +166,8 @@ return NGX_DECLINED; } + port = r->connection->port; + switch (rlcf->type) { case NGX_HTTP_REALIP_XREALIP: @@ -172,8 +194,8 @@ break; case NGX_HTTP_REALIP_PROXY: - value = &r->connection->proxy_protocol_addr; + port = r->connection->proxy_protocol_port; if (value->len == 0) { return NGX_DECLINED; @@ -211,14 +233,52 @@ value = &header[i].value; xfwd = NULL; - goto found; + goto portphase; } } return NGX_DECLINED; } -found: +portphase: + + + switch (rlcf->porttype) { + + case NGX_CONF_UNSET_UINT: + break; + + default: /* NGX_HTTP_REALPORT_HEADER */ + + part = &r->headers_in.headers.part; + header = part->elts; + + hash = rlcf->porthash; + len = rlcf->portheader.len; + p = rlcf->portheader.data; + + for (i = 0; /* void */ ; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + header = part->elts; + i = 0; + } + + if (hash == header[i].hash + && len == header[i].key.len + && ngx_strncmp(p, header[i].lowcase_key, len) == 0) + { + port=ngx_atoi(header[i].value.data, header[i].value.len); + + break; + } + } + } c = r->connection; @@ -230,7 +290,7 @@ rlcf->recursive) != NGX_DECLINED) { - return ngx_http_realip_set_addr(r, &addr); + return ngx_http_realip_set_addr(r, &addr, port); } return NGX_DECLINED; @@ -238,7 +298,7 @@ static ngx_int_t -ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr) +ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr, ngx_uint_t port) { size_t len; u_char *p; @@ -276,11 +336,13 @@ ctx->sockaddr = c->sockaddr; ctx->socklen = c->socklen; ctx->addr_text = c->addr_text; + ctx->port = c->port; c->sockaddr = addr->sockaddr; c->socklen = addr->socklen; c->addr_text.len = len; c->addr_text.data = p; + c->port = port; return NGX_DECLINED; } @@ -298,6 +360,7 @@ c->sockaddr = ctx->sockaddr; c->socklen = ctx->socklen; c->addr_text = ctx->addr_text; + c->port = ctx->port; } @@ -383,6 +446,28 @@ } +static char * +ngx_http_real_port(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_realip_loc_conf_t *rlcf = conf; + + ngx_str_t *value; + + value = cf->args->elts; + + if (ngx_strcmp(value[1].data, "proxy_protocol") == 0) { + rlcf->porttype = NGX_HTTP_REALPORT_PROXY; + return NGX_CONF_OK; + } + + rlcf->porttype = NGX_HTTP_REALPORT_HEADER; + rlcf->porthash = ngx_hash_strlow(value[1].data, value[1].data, value[1].len); + rlcf->portheader = value[1]; + + return NGX_CONF_OK; +} + + static void * ngx_http_realip_create_loc_conf(ngx_conf_t *cf) { @@ -399,9 +484,12 @@ * conf->from = NULL; * conf->hash = 0; * conf->header = { 0, NULL }; + * conf->porthash = 0 + * conf->portheader = { 0, NULL }; */ conf->type = NGX_CONF_UNSET_UINT; + conf->porttype = NGX_CONF_UNSET_UINT; conf->recursive = NGX_CONF_UNSET; return conf; @@ -510,3 +598,50 @@ return NGX_OK; } + + +static ngx_int_t +ngx_http_realip_remote_port_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + ngx_uint_t port; + ngx_pool_cleanup_t *cln; + ngx_http_realip_ctx_t *ctx; + + ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module); + + if (ctx == NULL && (r->internal || r->filter_finalize)) { + + /* + * if module context was reset, the original port + * can still be found in the cleanup handler + */ + + for (cln = r->pool->cleanup; cln; cln = cln->next) { + if (cln->handler == ngx_http_realip_cleanup) { + ctx = cln->data; + break; + } + } + } + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "piyo %ui %ui",ctx->port,r->connection->port); + + + port = ctx ? ctx->port : r->connection->port; + + v->len = 0; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1); + + if (v->data == NULL) { + return NGX_ERROR; + } + if (port > 0 && port < 65536) { + v->len = ngx_sprintf(v->data, "%ui", port) - v->data; + } + + return NGX_OK; +} diff -r 8426275a13fd -r cdaf19070ed1 src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c Fri Apr 01 16:38:31 2016 +0300 +++ b/src/http/ngx_http_variables.c Tue Apr 05 09:42:32 2016 +0900 @@ -58,6 +58,8 @@ ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r, @@ -192,6 +194,9 @@ { ngx_string("proxy_protocol_addr"), NULL, ngx_http_variable_proxy_protocol_addr, 0, 0, 0 }, + { ngx_string("proxy_protocol_port"), NULL, + ngx_http_variable_proxy_protocol_port, 0, 0, 0 }, + { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 }, { ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 }, @@ -1190,12 +1195,7 @@ ngx_http_variable_remote_port(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - ngx_uint_t port; - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif - + ngx_uint_t port; v->len = 0; v->valid = 1; v->no_cacheable = 0; @@ -1205,27 +1205,8 @@ if (v->data == NULL) { return NGX_ERROR; } - - switch (r->connection->sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) r->connection->sockaddr; - port = ntohs(sin6->sin6_port); - break; -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - case AF_UNIX: - port = 0; - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) r->connection->sockaddr; - port = ntohs(sin->sin_port); - break; - } + + port = r->connection->port; if (port > 0 && port < 65536) { v->len = ngx_sprintf(v->data, "%ui", port) - v->data; @@ -1250,6 +1231,29 @@ static ngx_int_t +ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + ngx_int_t port = r->connection->proxy_protocol_port; + + v->len = 0; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1); + + if (v->data == NULL) { + return NGX_ERROR; + } + if (port > 0 && port < 65536) { + v->len = ngx_sprintf(v->data, "%ui", port) - v->data; + } + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { On Tue, Apr 5, 2016 at 2:56 AM, Maxim Dounin wrote: > Hello! > > On Tue, Apr 05, 2016 at 02:12:21AM +0900, junpei yoshino wrote: > >> which is better way ? >> 1. >> "real_ip_from Forwarded" replace remote_addr and remote_port. >> And proxy_protocol also replace remote_addr and remote_port, too. > > While support for Forwarded is a good thing to have, it looks like > a separate and big work, so I wouldn't recommend trying to do this > now. > >> 2. >> "real_port_from Forwarded" replace port only. >> ip and port is independent. >> Also proxy protocol must configure real_ip_from and real_port_from. > > This approach looks wrong. If we know client port it should be > used. But see above about Forwarded. > >> 3. >> At first, not care Forwarded header. >> delete code related x-forwarded-port. >> support only custom http header including port number. > > This option looks most appropriate for now. > > (Assuming this also includes "proxy_protocol also replace > remote_addr and remote_port" as in 1.) > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -- junpei.yoshino at gmail.com From tony.fouchard at blablacar.com Tue Apr 5 07:55:53 2016 From: tony.fouchard at blablacar.com (Tony Fouchard) Date: Tue, 5 Apr 2016 09:55:53 +0200 Subject: [PATCH] proxy protocol proxified client port Message-ID: Hi guys, I need to log the user remote port at nginx level when requests are passed through proxy protocol (legal requirement), but looking at implementation I saw that all of the work stopped after reading source IP. In my setup, I have bgp sessions mounted on haproxy instances, but the haproxy acts at level 4 and only route traffic to different nginx farms depending of TLS extension value provided by client : it permits to serve for example both spdy and h2 over alpn. I have tried to implement what I needed and update the test case. Regards. # HG changeset patch # User Tony Fouchard # Date 1459438244 -7200 # Thu Mar 31 17:30:44 2016 +0200 # Node ID 708e5e9873798be8786aa0234c9712ef94b5a1e2 # Parent 5debefd670bcbc1d4344913bd4754452892f4cb2 Retrieve the proxy protocol client port provided diff -r 5debefd670bc -r 708e5e987379 proxy_protocol.t --- a/proxy_protocol.t Mon Mar 28 19:47:38 2016 +0300 +++ b/proxy_protocol.t Thu Mar 31 17:30:44 2016 +0200 @@ -26,7 +26,7 @@ my $t = Test::Nginx->new()->has(qw/http access ipv6 realip/); -$t->write_file_expand('nginx.conf', <<'EOF')->plan(18); +$t->write_file_expand('nginx.conf', <<'EOF')->plan(22); %%TEST_GLOBALS%% @@ -38,7 +38,7 @@ http { %%TEST_GLOBALS_HTTP%% - log_format pp '$remote_addr $request'; + log_format pp '$remote_addr $request $proxy_protocol_port'; server { listen 127.0.0.1:8080 proxy_protocol; @@ -47,6 +47,7 @@ set_real_ip_from 127.0.0.1/32; add_header X-IP $remote_addr; add_header X-PP $proxy_protocol_addr; + add_header X-PORT $proxy_protocol_port; location /pp { real_ip_header proxy_protocol; @@ -81,11 +82,14 @@ $r = pp_get('/t1', $tcp4); like($r, qr/SEE-THIS/, 'tcp4 request'); like($r, qr/X-PP: 192.0.2.1/, 'tcp4 proxy'); +like($r, qr/X-PORT: 1234/, 'tcp4 proxy port'); unlike($r, qr/X-IP: 192.0.2.1/, 'tcp4 client'); $r = pp_get('/t1', $tcp6); like($r, qr/SEE-THIS/, 'tcp6 request'); +like($r, qr/X-PORT: 1234/, 'tcp6 proxy port'); like($r, qr/X-PP: 2001:DB8::1/i, 'tcp6 proxy'); + unlike($r, qr/X-IP: 2001:DB8::1/i, 'tcp6 client'); like(pp_get('/t1', $unk1), qr/SEE-THIS/, 'unknown request 1'); @@ -96,11 +100,13 @@ $r = pp_get('/pp', $tcp4); like($r, qr/SEE-THIS/, 'tcp4 request realip'); like($r, qr/X-PP: 192.0.2.1/, 'tcp4 proxy realip'); +like($r, qr/X-PORT: 1234/, 'tcp4 proxy port realip'); like($r, qr/X-IP: 192.0.2.1/, 'tcp4 client realip'); $r = pp_get('/pp', $tcp6); like($r, qr/SEE-THIS/, 'tcp6 request realip'); like($r, qr/X-PP: 2001:DB8::1/i, 'tcp6 proxy realip'); +like($r, qr/X-PORT: 1234/, 'tcp6 proxy port realip'); like($r, qr/X-IP: 2001:DB8::1/i, 'tcp6 client realip'); # access @@ -125,8 +131,8 @@ close LOG; } -like($log, qr!^192\.0\.2\.1 GET /pp_4!m, 'tcp4 access log'); -like($log, qr!^2001:DB8::1 GET /pp_6!mi, 'tcp6 access log'); +like($log, qr!^192\.0\.2\.1 GET /pp_4 HTTP/1.0 1234!m, 'tcp4 access log'); +like($log, qr!^2001:DB8::1 GET /pp_6 HTTP/1.0 1234!mi, 'tcp6 access log'); ############################################################################### # HG changeset patch # User Tony Fouchard # Date 1459438562 -7200 # Thu Mar 31 17:36:02 2016 +0200 # Branch feat-proxy-protocol-port # Node ID 6cd4f889089344db865cd07400c15e4d5966aa01 # Parent 2b7dacb381ed1c4583aa048f1b22bdc141259407 Retrieve the proxy protocol client port provided diff -r 2b7dacb381ed -r 6cd4f8890893 src/core/ngx_connection.h --- a/src/core/ngx_connection.h Thu Mar 31 02:34:04 2016 +0300 +++ b/src/core/ngx_connection.h Thu Mar 31 17:36:02 2016 +0200 @@ -149,6 +149,7 @@ ngx_str_t addr_text; ngx_str_t proxy_protocol_addr; + ngx_str_t proxy_protocol_port; #if (NGX_SSL) ngx_ssl_connection_t *ssl; diff -r 2b7dacb381ed -r 6cd4f8890893 src/core/ngx_proxy_protocol.c --- a/src/core/ngx_proxy_protocol.c Thu Mar 31 02:34:04 2016 +0300 +++ b/src/core/ngx_proxy_protocol.c Thu Mar 31 17:36:02 2016 +0200 @@ -12,8 +12,8 @@ u_char * ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) { - size_t len; - u_char ch, *p, *addr; + size_t len, plen; + u_char ch, *p, *addr, *paddr; p = buf; len = last - buf; @@ -74,6 +74,57 @@ ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, "PROXY protocol address: \"%V\"", &c->proxy_protocol_addr); + for ( ;; ) { + if (p == last) { + goto invalid; + } + + ch = *p++; + + if (ch == ' ') { + break; + } + + if (ch != ':' && ch != '.' + && (ch < 'a' || ch > 'f') + && (ch < 'A' || ch > 'F') + && (ch < '0' || ch > '9')) + { + goto invalid; + } + } + + paddr = p; + + for ( ;; ) { + if (p == last) { + goto invalid; + } + + ch = *p++; + + if (ch == ' ') { + break; + } + + if (ch < '0' || ch > '9') { + goto invalid; + } + } + + plen = p - paddr - 1; + c->proxy_protocol_port.data = ngx_pnalloc(c->pool, plen); + + if (c->proxy_protocol_port.data == NULL) { + return NULL; + } + + ngx_memcpy(c->proxy_protocol_port.data, paddr, plen); + c->proxy_protocol_port.len = plen; + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, + "PROXY protocol port: \"%V\"", &c->proxy_protocol_port); + skip: for ( /* void */ ; p < last - 1; p++) { diff -r 2b7dacb381ed -r 6cd4f8890893 src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c Thu Mar 31 02:34:04 2016 +0300 +++ b/src/http/ngx_http_variables.c Thu Mar 31 17:36:02 2016 +0200 @@ -58,6 +58,8 @@ ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r, @@ -192,6 +194,9 @@ { ngx_string("proxy_protocol_addr"), NULL, ngx_http_variable_proxy_protocol_addr, 0, 0, 0 }, + { ngx_string("proxy_protocol_port"), NULL, + ngx_http_variable_proxy_protocol_port, 0, 0, 0 }, + { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 }, { ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 }, @@ -1250,6 +1255,20 @@ static ngx_int_t +ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + v->len = r->connection->proxy_protocol_port.len; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = r->connection->proxy_protocol_port.data; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { -------------- next part -------------- An HTML attachment was scrubbed... URL: From al-nginx at none.at Tue Apr 5 08:19:15 2016 From: al-nginx at none.at (Aleksandar Lazic) Date: Tue, 05 Apr 2016 10:19:15 +0200 Subject: [PATCH] proxy protocol proxified client port In-Reply-To: References: Message-ID: <8291902505491898a0901f1e104495c9@none.at> Hi, Am 05-04-2016 09:55, schrieb Tony Fouchard: > Hi guys, > > I need to log the user remote port at nginx level when requests are > passed through proxy protocol (legal requirement), but looking at > implementation I saw that all of the work stopped after reading source > IP. > > In my setup, I have bgp sessions mounted on haproxy instances, but the > haproxy acts at level 4 and only route traffic to different nginx farms > depending of TLS extension value provided by client : it permits to > serve for example both spdy and h2 over alpn. > > I have tried to implement what I needed and update the test case. Could this be the same request? PATCH]add proxy_protocol_port variable for rfc6302 http://thread.gmane.org/gmane.comp.web.nginx.devel/4273/focus=4390 Cheers aleks > Regards. > > # HG changeset patch > # User Tony Fouchard > # Date 1459438244 -7200 > # Thu Mar 31 17:30:44 2016 +0200 > # Node ID 708e5e9873798be8786aa0234c9712ef94b5a1e2 > # Parent 5debefd670bcbc1d4344913bd4754452892f4cb2 > Retrieve the proxy protocol client port provided > > diff -r 5debefd670bc -r 708e5e987379 proxy_protocol.t > --- a/proxy_protocol.t Mon Mar 28 19:47:38 2016 +0300 > +++ b/proxy_protocol.t Thu Mar 31 17:30:44 2016 +0200 > @@ -26,7 +26,7 @@ > > my $t = Test::Nginx->new()->has(qw/http access ipv6 realip/); > > -$t->write_file_expand('nginx.conf', <<'EOF')->plan(18); > +$t->write_file_expand('nginx.conf', <<'EOF')->plan(22); > > %%TEST_GLOBALS%% > > @@ -38,7 +38,7 @@ > http { > %%TEST_GLOBALS_HTTP%% > > - log_format pp '$remote_addr $request'; > + log_format pp '$remote_addr $request $proxy_protocol_port'; > > server { > listen 127.0.0.1:8080 [1] proxy_protocol; > @@ -47,6 +47,7 @@ > set_real_ip_from 127.0.0.1/32 [2]; > add_header X-IP $remote_addr; > add_header X-PP $proxy_protocol_addr; > + add_header X-PORT $proxy_protocol_port; > > location /pp { > real_ip_header proxy_protocol; > @@ -81,11 +82,14 @@ > $r = pp_get('/t1', $tcp4); > like($r, qr/SEE-THIS/, 'tcp4 request'); > like($r, qr/X-PP: 192.0.2.1/ [3], 'tcp4 proxy'); > +like($r, qr/X-PORT: 1234/, 'tcp4 proxy port'); > unlike($r, qr/X-IP: 192.0.2.1/ [3], 'tcp4 client'); > > $r = pp_get('/t1', $tcp6); > like($r, qr/SEE-THIS/, 'tcp6 request'); > +like($r, qr/X-PORT: 1234/, 'tcp6 proxy port'); > like($r, qr/X-PP: 2001:DB8::1/i, 'tcp6 proxy'); > + > unlike($r, qr/X-IP: 2001:DB8::1/i, 'tcp6 client'); > > like(pp_get('/t1', $unk1), qr/SEE-THIS/, 'unknown request 1'); > @@ -96,11 +100,13 @@ > $r = pp_get('/pp', $tcp4); > like($r, qr/SEE-THIS/, 'tcp4 request realip'); > like($r, qr/X-PP: 192.0.2.1/ [3], 'tcp4 proxy realip'); > +like($r, qr/X-PORT: 1234/, 'tcp4 proxy port realip'); > like($r, qr/X-IP: 192.0.2.1/ [3], 'tcp4 client realip'); > > $r = pp_get('/pp', $tcp6); > like($r, qr/SEE-THIS/, 'tcp6 request realip'); > like($r, qr/X-PP: 2001:DB8::1/i, 'tcp6 proxy realip'); > +like($r, qr/X-PORT: 1234/, 'tcp6 proxy port realip'); > like($r, qr/X-IP: 2001:DB8::1/i, 'tcp6 client realip'); > > # access > @@ -125,8 +131,8 @@ > close LOG; > } > > -like($log, qr!^192\.0\.2\.1 GET /pp_4!m, 'tcp4 access log'); > -like($log, qr!^2001:DB8::1 GET /pp_6!mi, 'tcp6 access log'); > +like($log, qr!^192\.0\.2\.1 GET /pp_4 HTTP/1.0 1234!m, 'tcp4 access > log'); > +like($log, qr!^2001:DB8::1 GET /pp_6 HTTP/1.0 1234!mi, 'tcp6 access > log'); > > > ############################################################################### > > # HG changeset patch > # User Tony Fouchard > # Date 1459438562 -7200 > # Thu Mar 31 17:36:02 2016 +0200 > # Branch feat-proxy-protocol-port > # Node ID 6cd4f889089344db865cd07400c15e4d5966aa01 > # Parent 2b7dacb381ed1c4583aa048f1b22bdc141259407 > Retrieve the proxy protocol client port provided > > diff -r 2b7dacb381ed -r 6cd4f8890893 src/core/ngx_connection.h > --- a/src/core/ngx_connection.h Thu Mar 31 02:34:04 2016 +0300 > +++ b/src/core/ngx_connection.h Thu Mar 31 17:36:02 2016 +0200 > @@ -149,6 +149,7 @@ > ngx_str_t addr_text; > > ngx_str_t proxy_protocol_addr; > + ngx_str_t proxy_protocol_port; > > #if (NGX_SSL) > ngx_ssl_connection_t *ssl; > diff -r 2b7dacb381ed -r 6cd4f8890893 src/core/ngx_proxy_protocol.c > --- a/src/core/ngx_proxy_protocol.c Thu Mar 31 02:34:04 2016 +0300 > +++ b/src/core/ngx_proxy_protocol.c Thu Mar 31 17:36:02 2016 +0200 > @@ -12,8 +12,8 @@ > u_char * > ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char > *last) > { > - size_t len; > - u_char ch, *p, *addr; > + size_t len, plen; > + u_char ch, *p, *addr, *paddr; > > p = buf; > len = last - buf; > @@ -74,6 +74,57 @@ > ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, > "PROXY protocol address: \"%V\"", > &c->proxy_protocol_addr); > > + for ( ;; ) { > + if (p == last) { > + goto invalid; > + } > + > + ch = *p++; > + > + if (ch == ' ') { > + break; > + } > + > + if (ch != ':' && ch != '.' > + && (ch < 'a' || ch > 'f') > + && (ch < 'A' || ch > 'F') > + && (ch < '0' || ch > '9')) > + { > + goto invalid; > + } > + } > + > + paddr = p; > > + > + for ( ;; ) { > + if (p == last) { > + goto invalid; > + } > + > + ch = *p++; > + > + if (ch == ' ') { > + break; > + } > + > + if (ch < '0' || ch > '9') { > + goto invalid; > + } > + } > + > + plen = p - paddr - 1; > + c->proxy_protocol_port.data = ngx_pnalloc(c->pool, plen); > + > + if (c->proxy_protocol_port.data == NULL) { > + return NULL; > + } > + > + ngx_memcpy(c->proxy_protocol_port.data, paddr, plen); > + c->proxy_protocol_port.len = plen; > + > + ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, > + "PROXY protocol port: \"%V\"", > &c->proxy_protocol_port); > + > skip: > > for ( /* void */ ; p < last - 1; p++) { > diff -r 2b7dacb381ed -r 6cd4f8890893 src/http/ngx_http_variables.c > --- a/src/http/ngx_http_variables.c Thu Mar 31 02:34:04 2016 +0300 > +++ b/src/http/ngx_http_variables.c Thu Mar 31 17:36:02 2016 +0200 > @@ -58,6 +58,8 @@ > ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t > ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data); > +static ngx_int_t > ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, > + ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r, > @@ -192,6 +194,9 @@ > { ngx_string("proxy_protocol_addr"), NULL, > ngx_http_variable_proxy_protocol_addr, 0, 0, 0 }, > > + { ngx_string("proxy_protocol_port"), NULL, > + ngx_http_variable_proxy_protocol_port, 0, 0, 0 }, > + > { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, > 0, 0, 0 }, > > { ngx_string("server_port"), NULL, ngx_http_variable_server_port, > 0, 0, 0 }, > @@ -1250,6 +1255,20 @@ > > static ngx_int_t > +ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, > + ngx_http_variable_value_t *v, uintptr_t data) > +{ > + v->len = r->connection->proxy_protocol_port.len; > + v->valid = 1; > + v->no_cacheable = 0; > + v->not_found = 0; > + v->data = r->connection->proxy_protocol_port.data; > + > + return NGX_OK; > +} > + > + > +static ngx_int_t > ngx_http_variable_server_addr(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data) > { > > > > Links: > ------ > [1] http://127.0.0.1:8080 > [2] http://127.0.0.1/32 > [3] http://192.0.2.1/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From tony.fouchard at blablacar.com Tue Apr 5 08:39:06 2016 From: tony.fouchard at blablacar.com (Tony Fouchard) Date: Tue, 5 Apr 2016 10:39:06 +0200 Subject: [PATCH] proxy protocol proxified client port In-Reply-To: <8291902505491898a0901f1e104495c9@none.at> References: <8291902505491898a0901f1e104495c9@none.at> Message-ID: Hi guys, Aim is the same, i think, approach is different. I want to extract user source port from proxy protocol following the v1 of the protocol discribed here: http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt 2016-04-05 10:19 GMT+02:00 Aleksandar Lazic : > Hi, > > Am 05-04-2016 09:55, schrieb Tony Fouchard: > >> Hi guys, >> >> I need to log the user remote port at nginx level when requests are >> passed through proxy protocol (legal requirement), but looking at >> implementation I saw that all of the work stopped after reading source >> IP. >> >> In my setup, I have bgp sessions mounted on haproxy instances, but the >> haproxy acts at level 4 and only route traffic to different nginx farms >> depending of TLS extension value provided by client : it permits to >> serve for example both spdy and h2 over alpn. >> >> I have tried to implement what I needed and update the test case. >> > > Could this be the same request? > > > PATCH]add proxy_protocol_port variable for rfc6302 > http://thread.gmane.org/gmane.comp.web.nginx.devel/4273/focus=4390 > > Cheers aleks > > Regards. >> >> # HG changeset patch >> # User Tony Fouchard >> # Date 1459438244 -7200 >> # Thu Mar 31 17:30:44 2016 +0200 >> # Node ID 708e5e9873798be8786aa0234c9712ef94b5a1e2 >> # Parent 5debefd670bcbc1d4344913bd4754452892f4cb2 >> Retrieve the proxy protocol client port provided >> >> diff -r 5debefd670bc -r 708e5e987379 proxy_protocol.t >> --- a/proxy_protocol.t Mon Mar 28 19:47:38 2016 +0300 >> +++ b/proxy_protocol.t Thu Mar 31 17:30:44 2016 +0200 >> @@ -26,7 +26,7 @@ >> >> my $t = Test::Nginx->new()->has(qw/http access ipv6 realip/); >> >> -$t->write_file_expand('nginx.conf', <<'EOF')->plan(18); >> +$t->write_file_expand('nginx.conf', <<'EOF')->plan(22); >> >> %%TEST_GLOBALS%% >> >> @@ -38,7 +38,7 @@ >> http { >> %%TEST_GLOBALS_HTTP%% >> >> - log_format pp '$remote_addr $request'; >> + log_format pp '$remote_addr $request $proxy_protocol_port'; >> >> server { >> listen 127.0.0.1:8080 [1] proxy_protocol; >> @@ -47,6 +47,7 @@ >> set_real_ip_from 127.0.0.1/32 [2]; >> add_header X-IP $remote_addr; >> add_header X-PP $proxy_protocol_addr; >> + add_header X-PORT $proxy_protocol_port; >> >> location /pp { >> real_ip_header proxy_protocol; >> @@ -81,11 +82,14 @@ >> $r = pp_get('/t1', $tcp4); >> like($r, qr/SEE-THIS/, 'tcp4 request'); >> like($r, qr/X-PP: 192.0.2.1/ [3], 'tcp4 proxy'); >> +like($r, qr/X-PORT: 1234/, 'tcp4 proxy port'); >> unlike($r, qr/X-IP: 192.0.2.1/ [3], 'tcp4 client'); >> >> $r = pp_get('/t1', $tcp6); >> like($r, qr/SEE-THIS/, 'tcp6 request'); >> +like($r, qr/X-PORT: 1234/, 'tcp6 proxy port'); >> like($r, qr/X-PP: 2001:DB8::1/i, 'tcp6 proxy'); >> + >> unlike($r, qr/X-IP: 2001:DB8::1/i, 'tcp6 client'); >> >> like(pp_get('/t1', $unk1), qr/SEE-THIS/, 'unknown request 1'); >> @@ -96,11 +100,13 @@ >> $r = pp_get('/pp', $tcp4); >> like($r, qr/SEE-THIS/, 'tcp4 request realip'); >> like($r, qr/X-PP: 192.0.2.1/ [3], 'tcp4 proxy realip'); >> +like($r, qr/X-PORT: 1234/, 'tcp4 proxy port realip'); >> like($r, qr/X-IP: 192.0.2.1/ [3], 'tcp4 client realip'); >> >> >> $r = pp_get('/pp', $tcp6); >> like($r, qr/SEE-THIS/, 'tcp6 request realip'); >> like($r, qr/X-PP: 2001:DB8::1/i, 'tcp6 proxy realip'); >> +like($r, qr/X-PORT: 1234/, 'tcp6 proxy port realip'); >> like($r, qr/X-IP: 2001:DB8::1/i, 'tcp6 client realip'); >> >> # access >> @@ -125,8 +131,8 @@ >> close LOG; >> } >> >> -like($log, qr!^192\.0\.2\.1 GET /pp_4!m, 'tcp4 access log'); >> -like($log, qr!^2001:DB8::1 GET /pp_6!mi, 'tcp6 access log'); >> +like($log, qr!^192\.0\.2\.1 GET /pp_4 HTTP/1.0 1234!m, 'tcp4 access >> log'); >> +like($log, qr!^2001:DB8::1 GET /pp_6 HTTP/1.0 1234!mi, 'tcp6 access >> log'); >> >> >> ############################################################################### >> >> # HG changeset patch >> # User Tony Fouchard >> # Date 1459438562 -7200 >> # Thu Mar 31 17:36:02 2016 +0200 >> # Branch feat-proxy-protocol-port >> # Node ID 6cd4f889089344db865cd07400c15e4d5966aa01 >> # Parent 2b7dacb381ed1c4583aa048f1b22bdc141259407 >> Retrieve the proxy protocol client port provided >> >> diff -r 2b7dacb381ed -r 6cd4f8890893 src/core/ngx_connection.h >> --- a/src/core/ngx_connection.h Thu Mar 31 02:34:04 2016 +0300 >> +++ b/src/core/ngx_connection.h Thu Mar 31 17:36:02 2016 +0200 >> @@ -149,6 +149,7 @@ >> ngx_str_t addr_text; >> >> ngx_str_t proxy_protocol_addr; >> + ngx_str_t proxy_protocol_port; >> >> #if (NGX_SSL) >> ngx_ssl_connection_t *ssl; >> diff -r 2b7dacb381ed -r 6cd4f8890893 src/core/ngx_proxy_protocol.c >> --- a/src/core/ngx_proxy_protocol.c Thu Mar 31 02:34:04 2016 +0300 >> +++ b/src/core/ngx_proxy_protocol.c Thu Mar 31 17:36:02 2016 +0200 >> @@ -12,8 +12,8 @@ >> u_char * >> ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) >> { >> - size_t len; >> - u_char ch, *p, *addr; >> + size_t len, plen; >> + u_char ch, *p, *addr, *paddr; >> >> p = buf; >> len = last - buf; >> @@ -74,6 +74,57 @@ >> ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, >> "PROXY protocol address: \"%V\"", >> &c->proxy_protocol_addr); >> >> + for ( ;; ) { >> + if (p == last) { >> + goto invalid; >> + } >> + >> + ch = *p++; >> + >> + if (ch == ' ') { >> + break; >> + } >> + >> + if (ch != ':' && ch != '.' >> + && (ch < 'a' || ch > 'f') >> + && (ch < 'A' || ch > 'F') >> + && (ch < '0' || ch > '9')) >> + { >> + goto invalid; >> + } >> + } >> + >> + paddr = p; >> >> + >> + for ( ;; ) { >> + if (p == last) { >> + goto invalid; >> + } >> + >> + ch = *p++; >> + >> + if (ch == ' ') { >> + break; >> + } >> + >> + if (ch < '0' || ch > '9') { >> + goto invalid; >> + } >> + } >> + >> + plen = p - paddr - 1; >> + c->proxy_protocol_port.data = ngx_pnalloc(c->pool, plen); >> + >> + if (c->proxy_protocol_port.data == NULL) { >> + return NULL; >> + } >> + >> + ngx_memcpy(c->proxy_protocol_port.data, paddr, plen); >> + c->proxy_protocol_port.len = plen; >> + >> + ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, >> + "PROXY protocol port: \"%V\"", >> &c->proxy_protocol_port); >> + >> skip: >> >> for ( /* void */ ; p < last - 1; p++) { >> diff -r 2b7dacb381ed -r 6cd4f8890893 src/http/ngx_http_variables.c >> --- a/src/http/ngx_http_variables.c Thu Mar 31 02:34:04 2016 +0300 >> +++ b/src/http/ngx_http_variables.c Thu Mar 31 17:36:02 2016 +0200 >> @@ -58,6 +58,8 @@ >> ngx_http_variable_value_t *v, uintptr_t data); >> static ngx_int_t >> ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r, >> ngx_http_variable_value_t *v, uintptr_t data); >> +static ngx_int_t >> ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, >> + ngx_http_variable_value_t *v, uintptr_t data); >> static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, >> ngx_http_variable_value_t *v, uintptr_t data); >> static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r, >> @@ -192,6 +194,9 @@ >> { ngx_string("proxy_protocol_addr"), NULL, >> ngx_http_variable_proxy_protocol_addr, 0, 0, 0 }, >> >> + { ngx_string("proxy_protocol_port"), NULL, >> + ngx_http_variable_proxy_protocol_port, 0, 0, 0 }, >> + >> { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, >> 0, 0, 0 }, >> >> { ngx_string("server_port"), NULL, ngx_http_variable_server_port, >> 0, 0, 0 }, >> @@ -1250,6 +1255,20 @@ >> >> static ngx_int_t >> +ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, >> + ngx_http_variable_value_t *v, uintptr_t data) >> +{ >> + v->len = r->connection->proxy_protocol_port.len; >> + v->valid = 1; >> + v->no_cacheable = 0; >> + v->not_found = 0; >> + v->data = r->connection->proxy_protocol_port.data; >> + >> + return NGX_OK; >> +} >> + >> + >> +static ngx_int_t >> ngx_http_variable_server_addr(ngx_http_request_t *r, >> ngx_http_variable_value_t *v, uintptr_t data) >> { >> >> >> >> Links: >> ------ >> [1] http://127.0.0.1:8080 >> [2] http://127.0.0.1/32 >> [3] http://192.0.2.1/ >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Tue Apr 5 14:59:00 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 05 Apr 2016 14:59:00 +0000 Subject: [nginx] nginx-1.9.14-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/4106db71cbcb branches: changeset: 6501:4106db71cbcb user: Maxim Dounin date: Tue Apr 05 17:57:08 2016 +0300 description: nginx-1.9.14-RELEASE diffstat: docs/xml/nginx/changes.xml | 58 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 58 insertions(+), 0 deletions(-) diffs (68 lines): diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,64 @@ + + + + +????????????? ? OpenSSL 1.1.0. + + +OpenSSL 1.1.0 compatibility. + + + + + +????????? proxy_request_buffering, fastcgi_request_buffering, +scgi_request_buffering ? uwsgi_request_buffering +?????? ???????? ??? ????????????? HTTP/2. + + +the "proxy_request_buffering", "fastcgi_request_buffering", +"scgi_request_buffering", and "uwsgi_request_buffering" directives +now work with HTTP/2. + + + + + +??? ????????????? HTTP/2 +? ????? ????? ?????????? ????????? "zero size buf in output". + + +"zero size buf in output" alerts might appear in logs +when using HTTP/2. + + + + + +??? ????????????? HTTP/2 +????????? client_max_body_size ????? ???????? ???????. + + +the "client_max_body_size" directive might work incorrectly +when using HTTP/2. + + + + + +?????????????? ?????? ????????????. + + +of minor bugs in logging. + + + + + + From mdounin at mdounin.ru Tue Apr 5 14:59:03 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 05 Apr 2016 14:59:03 +0000 Subject: [nginx] release-1.9.14 tag Message-ID: details: http://hg.nginx.org/nginx/rev/15f9446165e2 branches: changeset: 6502:15f9446165e2 user: Maxim Dounin date: Tue Apr 05 17:57:08 2016 +0300 description: release-1.9.14 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -396,3 +396,4 @@ be00ca08e41a69e585b6aff70a725ed6c9e1a876 fe66cff450a95beed36a2515210eb2d7ef62c9d3 release-1.9.11 ead3907d74f90a14d1646f1b2b56ba01d3d11702 release-1.9.12 5936b7ed929237f1a73b467f662611cdc0309e51 release-1.9.13 +4106db71cbcb9c8274700199ac17e520902c6c0f release-1.9.14 From timeless at gmail.com Thu Apr 7 04:42:08 2016 From: timeless at gmail.com (timeless) Date: Thu, 7 Apr 2016 00:42:08 -0400 Subject: Fwd: [PATCH 1 of 6] brand: Linux In-Reply-To: References: Message-ID: # HG changeset patch # User timeless at gmail.com # Date 1459808102 0 # Mon Apr 04 22:15:02 2016 +0000 # Node ID f72d428baff12201d77101dea3e78ad67a192674 # Parent 15f9446165e2f929c02b6415e3c125247e3ae546 brand: Linux diff -r 15f9446165e2 -r f72d428baff1 auto/cc/icc --- a/auto/cc/icc Tue Apr 05 17:57:08 2016 +0300 +++ b/auto/cc/icc Mon Apr 04 22:15:02 2016 +0000 @@ -89,7 +89,7 @@ case "$NGX_ICC_VER" in 9.*) - # "cc" clobber ignored, warnings for Liunx's htonl()/htons() + # "cc" clobber ignored, warnings for Linux's htonl()/htons() CFLAGS="$CFLAGS -wd1469" # explicit conversion of a 64-bit integral type to a smaller # integral type @@ -103,7 +103,7 @@ ;; 8.*) - # "cc" clobber ignored, warnings for Liunx's htonl()/htons() + # "cc" clobber ignored, warnings for Linux's htonl()/htons() CFLAGS="$CFLAGS -wd1469" # floating-point equality and inequality comparisons are unreliable, # warning on SvTRUE() From timeless at gmail.com Thu Apr 7 05:42:35 2016 From: timeless at gmail.com (timeless) Date: Thu, 7 Apr 2016 01:42:35 -0400 Subject: [PATCH 2 of 6] spelling: failed Message-ID: # HG changeset patch # User timeless at gmail.com # Date 1459807987 0 # Mon Apr 04 22:13:07 2016 +0000 # Node ID 2b30d743c04a6fb6236e2486da9f4265fbd04f0b # Parent f72d428baff12201d77101dea3e78ad67a192674 spelling: failed diff -r f72d428baff1 -r 2b30d743c04a src/event/ngx_event_acceptex.c --- a/src/event/ngx_event_acceptex.c Mon Apr 04 22:15:02 2016 +0000 +++ b/src/event/ngx_event_acceptex.c Mon Apr 04 22:13:07 2016 +0000 @@ -189,7 +189,7 @@ err = ngx_socket_errno; if (err != WSA_IO_PENDING) { ngx_log_error(NGX_LOG_ALERT, &ls->log, err, - "AcceptEx() %V falied", &ls->addr_text); + "AcceptEx() %V failed", &ls->addr_text); ngx_close_posted_connection(c); return NGX_ERROR; diff -r f72d428baff1 -r 2b30d743c04a src/os/win32/ngx_win32_init.c --- a/src/os/win32/ngx_win32_init.c Mon Apr 04 22:15:02 2016 +0000 +++ b/src/os/win32/ngx_win32_init.c Mon Apr 04 22:13:07 2016 +0000 @@ -152,7 +152,7 @@ s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (s == (ngx_socket_t) -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - ngx_socket_n " falied"); + ngx_socket_n " failed"); return NGX_ERROR; } From timeless at gmail.com Thu Apr 7 05:43:07 2016 From: timeless at gmail.com (timeless) Date: Thu, 7 Apr 2016 01:43:07 -0400 Subject: [PATCH 3 of 6] spelling: inclusion Message-ID: # HG changeset patch # User timeless at gmail.com # Date 1459808040 0 # Mon Apr 04 22:14:00 2016 +0000 # Node ID 2077be955ef0d48a97541fad17f1c4d0d32c4a9e # Parent 2b30d743c04a6fb6236e2486da9f4265fbd04f0b spelling: inclusion diff -r 2b30d743c04a -r 2077be955ef0 src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c Mon Apr 04 22:13:07 2016 +0000 +++ b/src/http/modules/ngx_http_ssi_filter_module.c Mon Apr 04 22:14:00 2016 +0000 @@ -2005,7 +2005,7 @@ if (uri && file) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "inlcusion may be either virtual=\"%V\" or file=\"%V\"", + "inclusion may be either virtual=\"%V\" or file=\"%V\"", uri, file); return NGX_HTTP_SSI_ERROR; } From timeless at gmail.com Thu Apr 7 05:43:37 2016 From: timeless at gmail.com (timeless) Date: Thu, 7 Apr 2016 01:43:37 -0400 Subject: [PATCH 4 of 6] spelling: provides Message-ID: # HG changeset patch # User timeless at gmail.com # Date 1459808258 0 # Mon Apr 04 22:17:38 2016 +0000 # Node ID 5d72ea3437830f42fcddf86496c873f99f2dd936 # Parent 2077be955ef0d48a97541fad17f1c4d0d32c4a9e spelling: provides diff -r 2077be955ef0 -r 5d72ea343783 contrib/vim/syntax/nginx.vim --- a/contrib/vim/syntax/nginx.vim Mon Apr 04 22:14:00 2016 +0000 +++ b/contrib/vim/syntax/nginx.vim Mon Apr 04 22:17:38 2016 +0000 @@ -604,7 +604,7 @@ syn keyword ngxDirectiveThirdParty echo_subrequest_async " Events Module -" Privides options for start/stop events. +" Provides options for start/stop events. syn keyword ngxDirectiveThirdParty on_start syn keyword ngxDirectiveThirdParty on_stop From timeless at gmail.com Thu Apr 7 05:44:02 2016 From: timeless at gmail.com (timeless) Date: Thu, 7 Apr 2016 01:44:02 -0400 Subject: [PATCH 5 of 6] spelling: height Message-ID: # HG changeset patch # User timeless at gmail.com # Date 1459808979 0 # Mon Apr 04 22:29:39 2016 +0000 # Node ID 684e585d6edb33726c4979104ed9e43b71fa3bf8 # Parent 5d72ea3437830f42fcddf86496c873f99f2dd936 spelling: height diff -r 5d72ea343783 -r 684e585d6edb src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c Mon Apr 04 22:17:38 2016 +0000 +++ b/src/http/modules/ngx_http_mp4_module.c Mon Apr 04 22:29:39 2016 +0000 @@ -1436,7 +1436,7 @@ u_char reverved3[2]; u_char matrix[36]; u_char width[4]; - u_char heigth[4]; + u_char height[4]; } ngx_mp4_tkhd_atom_t; typedef struct { @@ -1456,7 +1456,7 @@ u_char reverved3[2]; u_char matrix[36]; u_char width[4]; - u_char heigth[4]; + u_char height[4]; } ngx_mp4_tkhd64_atom_t; From timeless at gmail.com Thu Apr 7 05:44:24 2016 From: timeless at gmail.com (timeless) Date: Thu, 7 Apr 2016 01:44:24 -0400 Subject: [PATCH 6 of 6] spelling: reserved Message-ID: # HG changeset patch # User timeless at gmail.com # Date 1459808286 0 # Mon Apr 04 22:18:06 2016 +0000 # Node ID 4fade1836ca68896e0044b3ab11f1324a03667b7 # Parent 684e585d6edb33726c4979104ed9e43b71fa3bf8 spelling: reserved diff -r 684e585d6edb -r 4fade1836ca6 src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c Mon Apr 04 22:29:39 2016 +0000 +++ b/src/http/modules/ngx_http_mp4_module.c Mon Apr 04 22:18:06 2016 +0000 @@ -1433,7 +1433,7 @@ u_char layer[2]; u_char group[2]; u_char volume[2]; - u_char reverved3[2]; + u_char reserved3[2]; u_char matrix[36]; u_char width[4]; u_char height[4]; @@ -1453,7 +1453,7 @@ u_char layer[2]; u_char group[2]; u_char volume[2]; - u_char reverved3[2]; + u_char reserved3[2]; u_char matrix[36]; u_char width[4]; u_char height[4]; From pulsarpietro at posteo.net Wed Apr 6 20:45:44 2016 From: pulsarpietro at posteo.net (Pietro) Date: Wed, 06 Apr 2016 21:45:44 +0100 Subject: Building instruction Message-ID: <87oa9m5uvb.fsf@posteo.net> Hi everybody, I would be interested in building the project from the sources and I have checked out the nginx source code following the instruction: http://nginx.org/en/docs/configure.html I can't figure out where I should start, in fact I do not see a configure script at the top level, quite naively this is what I have done : cd auto ./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid ./configure: 10: .: Can't open auto/options I have the feeling I am getting it all wrong but I can't find clearer building instruction, how do I build NGINX ? Have I missed some crucial docs present in the website or inside the source repo itself ? Cheers, Pietro From vbart at nginx.com Thu Apr 7 09:19:41 2016 From: vbart at nginx.com (=?utf-8?B?0JLQsNC70LXQvdGC0LjQvSDQkdCw0YDRgtC10L3QtdCy?=) Date: Thu, 07 Apr 2016 12:19:41 +0300 Subject: Building instruction In-Reply-To: <87oa9m5uvb.fsf@posteo.net> References: <87oa9m5uvb.fsf@posteo.net> Message-ID: <1568246.8OVmWsgnJU@vbart-laptop> On Wednesday 06 April 2016 21:45:44 Pietro wrote: > Hi everybody, > > I would be interested in building the project from the sources and I > have checked out the nginx source code following the instruction: > > http://nginx.org/en/docs/configure.html > > I can't figure out where I should start, in fact I do not see a > configure script at the top level, quite naively this is what I have > done : > > cd auto > ./configure --sbin-path=/usr/local/nginx/nginx --conf- path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid > ./configure: 10: .: Can't open auto/options > > I have the feeling I am getting it all wrong but I can't find clearer > building instruction, how do I build NGINX ? Have I missed some crucial > docs present in the website or inside the source repo itself ? > This instruction is valid for release sources from: http://nginx.org/en/download.html If you build it out of repository, you have to use "auto/configure" instead. wbr, Valentin V. Bartenev From ru at nginx.com Thu Apr 7 16:10:39 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 07 Apr 2016 16:10:39 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/abc3be8d92ef branches: changeset: 6503:abc3be8d92ef user: Ruslan Ermilov date: Thu Apr 07 19:09:42 2016 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r 15f9446165e2 -r abc3be8d92ef src/core/nginx.h --- a/src/core/nginx.h Tue Apr 05 17:57:08 2016 +0300 +++ b/src/core/nginx.h Thu Apr 07 19:09:42 2016 +0300 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1009014 -#define NGINX_VERSION "1.9.14" +#define nginx_version 1009015 +#define NGINX_VERSION "1.9.15" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From timeless at gmail.com Thu Apr 7 16:10:41 2016 From: timeless at gmail.com (Josh Soref) Date: Thu, 07 Apr 2016 16:10:41 +0000 Subject: [nginx] Fixed spelling. Message-ID: details: http://hg.nginx.org/nginx/rev/293413010217 branches: changeset: 6504:293413010217 user: Josh Soref date: Thu Apr 07 11:50:13 2016 +0300 description: Fixed spelling. diffstat: auto/cc/icc | 4 ++-- contrib/vim/syntax/nginx.vim | 2 +- src/event/ngx_event_acceptex.c | 2 +- src/http/modules/ngx_http_mp4_module.c | 8 ++++---- src/http/modules/ngx_http_ssi_filter_module.c | 2 +- src/os/win32/ngx_win32_init.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diffs (98 lines): diff -r abc3be8d92ef -r 293413010217 auto/cc/icc --- a/auto/cc/icc Thu Apr 07 19:09:42 2016 +0300 +++ b/auto/cc/icc Thu Apr 07 11:50:13 2016 +0300 @@ -89,7 +89,7 @@ CFLAGS="$CFLAGS -wd1419" case "$NGX_ICC_VER" in 9.*) - # "cc" clobber ignored, warnings for Liunx's htonl()/htons() + # "cc" clobber ignored, warnings for Linux's htonl()/htons() CFLAGS="$CFLAGS -wd1469" # explicit conversion of a 64-bit integral type to a smaller # integral type @@ -103,7 +103,7 @@ case "$NGX_ICC_VER" in ;; 8.*) - # "cc" clobber ignored, warnings for Liunx's htonl()/htons() + # "cc" clobber ignored, warnings for Linux's htonl()/htons() CFLAGS="$CFLAGS -wd1469" # floating-point equality and inequality comparisons are unreliable, # warning on SvTRUE() diff -r abc3be8d92ef -r 293413010217 contrib/vim/syntax/nginx.vim --- a/contrib/vim/syntax/nginx.vim Thu Apr 07 19:09:42 2016 +0300 +++ b/contrib/vim/syntax/nginx.vim Thu Apr 07 11:50:13 2016 +0300 @@ -604,7 +604,7 @@ syn keyword ngxDirectiveThirdParty echo_ syn keyword ngxDirectiveThirdParty echo_subrequest_async " Events Module -" Privides options for start/stop events. +" Provides options for start/stop events. syn keyword ngxDirectiveThirdParty on_start syn keyword ngxDirectiveThirdParty on_stop diff -r abc3be8d92ef -r 293413010217 src/event/ngx_event_acceptex.c --- a/src/event/ngx_event_acceptex.c Thu Apr 07 19:09:42 2016 +0300 +++ b/src/event/ngx_event_acceptex.c Thu Apr 07 11:50:13 2016 +0300 @@ -189,7 +189,7 @@ ngx_event_post_acceptex(ngx_listening_t err = ngx_socket_errno; if (err != WSA_IO_PENDING) { ngx_log_error(NGX_LOG_ALERT, &ls->log, err, - "AcceptEx() %V falied", &ls->addr_text); + "AcceptEx() %V failed", &ls->addr_text); ngx_close_posted_connection(c); return NGX_ERROR; diff -r abc3be8d92ef -r 293413010217 src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c Thu Apr 07 19:09:42 2016 +0300 +++ b/src/http/modules/ngx_http_mp4_module.c Thu Apr 07 11:50:13 2016 +0300 @@ -1433,10 +1433,10 @@ typedef struct { u_char layer[2]; u_char group[2]; u_char volume[2]; - u_char reverved3[2]; + u_char reserved3[2]; u_char matrix[36]; u_char width[4]; - u_char heigth[4]; + u_char height[4]; } ngx_mp4_tkhd_atom_t; typedef struct { @@ -1453,10 +1453,10 @@ typedef struct { u_char layer[2]; u_char group[2]; u_char volume[2]; - u_char reverved3[2]; + u_char reserved3[2]; u_char matrix[36]; u_char width[4]; - u_char heigth[4]; + u_char height[4]; } ngx_mp4_tkhd64_atom_t; diff -r abc3be8d92ef -r 293413010217 src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c Thu Apr 07 19:09:42 2016 +0300 +++ b/src/http/modules/ngx_http_ssi_filter_module.c Thu Apr 07 11:50:13 2016 +0300 @@ -2005,7 +2005,7 @@ ngx_http_ssi_include(ngx_http_request_t if (uri && file) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "inlcusion may be either virtual=\"%V\" or file=\"%V\"", + "inclusion may be either virtual=\"%V\" or file=\"%V\"", uri, file); return NGX_HTTP_SSI_ERROR; } diff -r abc3be8d92ef -r 293413010217 src/os/win32/ngx_win32_init.c --- a/src/os/win32/ngx_win32_init.c Thu Apr 07 19:09:42 2016 +0300 +++ b/src/os/win32/ngx_win32_init.c Thu Apr 07 11:50:13 2016 +0300 @@ -152,7 +152,7 @@ ngx_os_init(ngx_log_t *log) s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (s == (ngx_socket_t) -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - ngx_socket_n " falied"); + ngx_socket_n " failed"); return NGX_ERROR; } From pulsarpietro at posteo.net Thu Apr 7 20:25:44 2016 From: pulsarpietro at posteo.net (Pietro) Date: Thu, 07 Apr 2016 21:25:44 +0100 Subject: Building instruction References: <87oa9m5uvb.fsf@posteo.net> <1568246.8OVmWsgnJU@vbart-laptop> Message-ID: <87egah5fp3.fsf@posteo.net> ???????? ???????? writes: > On Wednesday 06 April 2016 21:45:44 Pietro wrote: >> Hi everybody, >> >> I would be interested in building the project from the sources and I >> have checked out the nginx source code following the instruction: >> >> http://nginx.org/en/docs/configure.html >> >> I can't figure out where I should start, in fact I do not see a >> configure script at the top level, quite naively this is what I have >> done : >> >> cd auto >> ./configure --sbin-path=/usr/local/nginx/nginx --conf- > path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid >> ./configure: 10: .: Can't open auto/options >> >> I have the feeling I am getting it all wrong but I can't find clearer >> building instruction, how do I build NGINX ? Have I missed some crucial >> docs present in the website or inside the source repo itself ? >> > > This instruction is valid for release sources from: > http://nginx.org/en/download.html > > If you build it out of repository, you have to use "auto/configure" instead. > > wbr, Valentin V. Bartenev Hi, thanks for your answer, I must admit I still do not get it, what do I need to do ? Thanks, P. From vlad.shabanov at gmail.com Fri Apr 8 08:19:17 2016 From: vlad.shabanov at gmail.com (Vladislav Shabanov) Date: Fri, 8 Apr 2016 11:19:17 +0300 Subject: patch proposal Message-ID: ??????! ???? ??? ?????? ?? ??????? ?? ???????, ? ???, ???????, ???????? ?? ??????????, ?? ???????? ?? ????-???? ??????? ?????????? :) ????, ????? ??????, ?? ??????? limit_req_zone $whitelisted_remote_addr zone=IPRATELIMIT_EXT_GET:20m rate=30r/s; ??? ??? ????????, ???? ????? ?????? IP-???????, ????????? ??????? ???????. ??? ??? ???? ??????? ??????? ?? fastcgi-???????, ???? limit_req zone=IPRATELIMIT_EXT_GET burst=15; ??????????? ???????? ????????? ?????? ?????????? ? ?????: 1) GET /?fr=??????_??????&foo=bar ??? ? ????? ?????????? cookie fr ? ???? ????????? ? ?????? redirect ?? /?foo=bar ???????? ???????? ????? ?????? ? ????? ?? ?????? ??????. 2) GET /foo=bar ? ???? ?????? ??????? ???????? ?????????? ??-?? limit_req, ??????? ?????? ??????????. ??? ?????????? ?????? ?? ?????, ?? ?? ???? ?? ????????. ????? ????????? nodelay, ?? ????? ??????? ???????? ???? ?? ????? ???????? ???????? ? ???????? ????? ???????? ?? ?????? ?? ?????? 503. ????? ???????, ??? ?????, ????? ??? ?????????????? ?????????? ??????? ????????? nodelay ?? ????, ? ??? ???????????? ?????????? ??, ????????, ??? ? ??????? ?? ???????? ????????? ????? ?? 503 ??????. ? ?????? ????, ??????? ??????? ????????? ????? ????????? nodelay. ???? ??? nodelay ??? ? ??????? ?????? ?????? nodelay ??? ?????????, ?? ??? ???????? ?? ???????. ???? ?? ??????? nodelay=N, ?? ??? excess ???????, ??? 1000*N, ???????? ???, ? ??? ?????? excess ????????? ??? ????????, ???????? ??????????. ? ???? ?????? ?????????? ????????????: limit_req zone=IPRATELIMIT_EXT_GET burst=15 nodelay=1; ? ???? ?? ????????? ?????? ??? ??????????? ???? ???? ??????, ?????? ???????? ?????, ?? ???????, ??? ????? ????? ???? ??????? ?? ?????? ???. ? ?????????, ????????? ???????, GrinDin.ru -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: ngx_http_limit_req_module.patch Type: application/octet-stream Size: 2069 bytes Desc: not available URL: -------------- next part -------------- An HTML attachment was scrubbed... URL: From luky-37 at hotmail.com Fri Apr 8 08:36:36 2016 From: luky-37 at hotmail.com (Lukas Tribus) Date: Fri, 8 Apr 2016 10:36:36 +0200 Subject: Building instruction In-Reply-To: <87egah5fp3.fsf@posteo.net> References: <87oa9m5uvb.fsf@posteo.net> <1568246.8OVmWsgnJU@vbart-laptop>,<87egah5fp3.fsf@posteo.net> Message-ID: >> If you build it out of repository, you have to use "auto/configure" instead. >> >> wbr, Valentin V. Bartenev > > Hi, > > thanks for your answer, I must admit I still do not get it, what do I > need to do ? Don't cd in the auto directory, remain in the nginx root directory and call configure from there: ~/nginx$ auto/configure From vbart at nginx.com Fri Apr 8 13:45:39 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 08 Apr 2016 13:45:39 +0000 Subject: [nginx] Merged implementations of ngx_udp_unix_recv(). Message-ID: details: http://hg.nginx.org/nginx/rev/5ad379eab6fa branches: changeset: 6505:5ad379eab6fa user: Valentin Bartenev date: Fri Apr 08 16:38:42 2016 +0300 description: Merged implementations of ngx_udp_unix_recv(). There's no real need in two separate implementations, with and without kqueue support. diffstat: src/os/unix/ngx_udp_recv.c | 53 ++++----------------------------------------- 1 files changed, 5 insertions(+), 48 deletions(-) diffs (81 lines): diff -r 293413010217 -r 5ad379eab6fa src/os/unix/ngx_udp_recv.c --- a/src/os/unix/ngx_udp_recv.c Thu Apr 07 11:50:13 2016 +0300 +++ b/src/os/unix/ngx_udp_recv.c Fri Apr 08 16:38:42 2016 +0300 @@ -10,8 +10,6 @@ #include -#if (NGX_HAVE_KQUEUE) - ssize_t ngx_udp_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) { @@ -28,6 +26,9 @@ ngx_udp_unix_recv(ngx_connection_t *c, u "recv: fd:%d %z of %uz", c->fd, n, size); if (n >= 0) { + +#if (NGX_HAVE_KQUEUE) + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { rev->available -= n; @@ -42,6 +43,8 @@ ngx_udp_unix_recv(ngx_connection_t *c, u } } +#endif + return n; } @@ -67,49 +70,3 @@ ngx_udp_unix_recv(ngx_connection_t *c, u return n; } - -#else /* ! NGX_HAVE_KQUEUE */ - -ssize_t -ngx_udp_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) -{ - ssize_t n; - ngx_err_t err; - ngx_event_t *rev; - - rev = c->read; - - do { - n = recv(c->fd, buf, size, 0); - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "recv: fd:%d %z of %uz", c->fd, n, size); - - if (n >= 0) { - return n; - } - - err = ngx_socket_errno; - - if (err == NGX_EAGAIN || err == NGX_EINTR) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, - "recv() not ready"); - n = NGX_AGAIN; - - } else { - n = ngx_connection_error(c, err, "recv() failed"); - break; - } - - } while (err == NGX_EINTR); - - rev->ready = 0; - - if (n == NGX_ERROR) { - rev->error = 1; - } - - return n; -} - -#endif /* NGX_HAVE_KQUEUE */ From vbart at nginx.com Fri Apr 8 13:45:42 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 08 Apr 2016 13:45:42 +0000 Subject: [nginx] Fixed small inconsistency in handling EOF among receive functions. Message-ID: details: http://hg.nginx.org/nginx/rev/dc1ae0056a1e branches: changeset: 6506:dc1ae0056a1e user: Valentin Bartenev date: Fri Apr 08 16:39:49 2016 +0300 description: Fixed small inconsistency in handling EOF among receive functions. Now all functions always drop the ready flag in this case. diffstat: src/os/unix/ngx_readv_chain.c | 48 ++++++++++++++++++++---------------------- src/os/unix/ngx_recv.c | 35 ++++++++++++++++--------------- 2 files changed, 41 insertions(+), 42 deletions(-) diffs (139 lines): diff -r 5ad379eab6fa -r dc1ae0056a1e src/os/unix/ngx_readv_chain.c --- a/src/os/unix/ngx_readv_chain.c Fri Apr 08 16:38:42 2016 +0300 +++ b/src/os/unix/ngx_readv_chain.c Fri Apr 08 16:39:49 2016 +0300 @@ -106,7 +106,27 @@ ngx_readv_chain(ngx_connection_t *c, ngx do { n = readv(c->fd, (struct iovec *) vec.elts, vec.nelts); - if (n >= 0) { + if (n == 0) { + rev->ready = 0; + rev->eof = 1; + +#if (NGX_HAVE_KQUEUE) + + /* + * on FreeBSD readv() may return 0 on closed socket + * even if kqueue reported about available data + */ + + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { + rev->available = 0; + } + +#endif + + return 0; + } + + if (n > 0) { #if (NGX_HAVE_KQUEUE) @@ -115,7 +135,7 @@ ngx_readv_chain(ngx_connection_t *c, ngx /* * rev->available may be negative here because some additional - * bytes may be received between kevent() and recv() + * bytes may be received between kevent() and readv() */ if (rev->available <= 0) { @@ -128,37 +148,15 @@ ngx_readv_chain(ngx_connection_t *c, ngx } } - if (n == 0) { - - /* - * on FreeBSD recv() may return 0 on closed socket - * even if kqueue reported about available data - */ - -#if 0 - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "readv() returned 0 while kevent() reported " - "%d available bytes", rev->available); -#endif - - rev->ready = 0; - rev->eof = 1; - rev->available = 0; - } - return n; } -#endif /* NGX_HAVE_KQUEUE */ +#endif if (n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) { rev->ready = 0; } - if (n == 0) { - rev->eof = 1; - } - return n; } diff -r 5ad379eab6fa -r dc1ae0056a1e src/os/unix/ngx_recv.c --- a/src/os/unix/ngx_recv.c Fri Apr 08 16:38:42 2016 +0300 +++ b/src/os/unix/ngx_recv.c Fri Apr 08 16:39:49 2016 +0300 @@ -54,7 +54,24 @@ ngx_unix_recv(ngx_connection_t *c, u_cha ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "recv: fd:%d %z of %uz", c->fd, n, size); - if (n >= 0) { + if (n == 0) { + rev->ready = 0; + rev->eof = 1; + + /* + * on FreeBSD recv() may return 0 on closed socket + * even if kqueue reported about available data + */ + + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { + rev->available = 0; + } + + return 0; + } + + if (n > 0) { + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { rev->available -= n; @@ -73,18 +90,6 @@ ngx_unix_recv(ngx_connection_t *c, u_cha } } - if (n == 0) { - - /* - * on FreeBSD recv() may return 0 on closed socket - * even if kqueue reported about available data - */ - - rev->ready = 0; - rev->eof = 1; - rev->available = 0; - } - return n; } @@ -94,10 +99,6 @@ ngx_unix_recv(ngx_connection_t *c, u_cha rev->ready = 0; } - if (n == 0) { - rev->eof = 1; - } - return n; } From vbart at nginx.com Fri Apr 8 13:45:44 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 08 Apr 2016 13:45:44 +0000 Subject: [nginx] Merged implementations of ngx_unix_recv(). Message-ID: details: http://hg.nginx.org/nginx/rev/8ee94ecd3a50 branches: changeset: 6507:8ee94ecd3a50 user: Valentin Bartenev date: Fri Apr 08 16:41:45 2016 +0300 description: Merged implementations of ngx_unix_recv(). There's no real need in two separate implementations, with and without kqueue support. diffstat: src/os/unix/ngx_recv.c | 72 ++++++++----------------------------------------- 1 files changed, 12 insertions(+), 60 deletions(-) diffs (126 lines): diff -r dc1ae0056a1e -r 8ee94ecd3a50 src/os/unix/ngx_recv.c --- a/src/os/unix/ngx_recv.c Fri Apr 08 16:39:49 2016 +0300 +++ b/src/os/unix/ngx_recv.c Fri Apr 08 16:41:45 2016 +0300 @@ -10,8 +10,6 @@ #include -#if (NGX_HAVE_KQUEUE) - ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) { @@ -21,6 +19,8 @@ ngx_unix_recv(ngx_connection_t *c, u_cha rev = c->read; +#if (NGX_HAVE_KQUEUE) + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "recv: eof:%d, avail:%d, err:%d", @@ -48,6 +48,8 @@ ngx_unix_recv(ngx_connection_t *c, u_cha } } +#endif + do { n = recv(c->fd, buf, size, 0); @@ -58,6 +60,8 @@ ngx_unix_recv(ngx_connection_t *c, u_cha rev->ready = 0; rev->eof = 1; +#if (NGX_HAVE_KQUEUE) + /* * on FreeBSD recv() may return 0 on closed socket * even if kqueue reported about available data @@ -67,11 +71,15 @@ ngx_unix_recv(ngx_connection_t *c, u_cha rev->available = 0; } +#endif + return 0; } if (n > 0) { +#if (NGX_HAVE_KQUEUE) + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { rev->available -= n; @@ -93,6 +101,8 @@ ngx_unix_recv(ngx_connection_t *c, u_cha return n; } +#endif + if ((size_t) n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) { @@ -124,61 +134,3 @@ ngx_unix_recv(ngx_connection_t *c, u_cha return n; } - -#else /* ! NGX_HAVE_KQUEUE */ - -ssize_t -ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) -{ - ssize_t n; - ngx_err_t err; - ngx_event_t *rev; - - rev = c->read; - - do { - n = recv(c->fd, buf, size, 0); - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "recv: fd:%d %z of %uz", c->fd, n, size); - - if (n == 0) { - rev->ready = 0; - rev->eof = 1; - return n; - - } else if (n > 0) { - - if ((size_t) n < size - && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) - { - rev->ready = 0; - } - - return n; - } - - err = ngx_socket_errno; - - if (err == NGX_EAGAIN || err == NGX_EINTR) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, - "recv() not ready"); - n = NGX_AGAIN; - - } else { - n = ngx_connection_error(c, err, "recv() failed"); - break; - } - - } while (err == NGX_EINTR); - - rev->ready = 0; - - if (n == NGX_ERROR) { - rev->error = 1; - } - - return n; -} - -#endif /* NGX_HAVE_KQUEUE */ From vbart at nginx.com Fri Apr 8 13:49:50 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 08 Apr 2016 13:49:50 +0000 Subject: [nginx] Simplified ngx_unix_recv() and ngx_readv_chain(). Message-ID: details: http://hg.nginx.org/nginx/rev/151fd02a4317 branches: changeset: 6508:151fd02a4317 user: Ruslan Ermilov date: Fri Apr 08 16:49:35 2016 +0300 description: Simplified ngx_unix_recv() and ngx_readv_chain(). This makes ngx_unix_recv() and ngx_udp_unix_recv() differ minimally. diffstat: src/os/unix/ngx_readv_chain.c | 4 +--- src/os/unix/ngx_recv.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diffs (28 lines): diff -r 8ee94ecd3a50 -r 151fd02a4317 src/os/unix/ngx_readv_chain.c --- a/src/os/unix/ngx_readv_chain.c Fri Apr 08 16:41:45 2016 +0300 +++ b/src/os/unix/ngx_readv_chain.c Fri Apr 08 16:49:35 2016 +0300 @@ -143,9 +143,7 @@ ngx_readv_chain(ngx_connection_t *c, ngx rev->ready = 0; } - if (rev->available < 0) { - rev->available = 0; - } + rev->available = 0; } return n; diff -r 8ee94ecd3a50 -r 151fd02a4317 src/os/unix/ngx_recv.c --- a/src/os/unix/ngx_recv.c Fri Apr 08 16:41:45 2016 +0300 +++ b/src/os/unix/ngx_recv.c Fri Apr 08 16:49:35 2016 +0300 @@ -93,9 +93,7 @@ ngx_unix_recv(ngx_connection_t *c, u_cha rev->ready = 0; } - if (rev->available < 0) { - rev->available = 0; - } + rev->available = 0; } return n; From muffinmonster64 at gmail.com Fri Apr 8 15:26:02 2016 From: muffinmonster64 at gmail.com (John Doe) Date: Fri, 8 Apr 2016 11:26:02 -0400 Subject: Subrequest request body streaming Message-ID: Hi All, I'm writing a content phase handler module, which executes sub requests to an internal location in my nginx config, and in specific, a proxy_pass. It also modifies headers, request body, and response body as the request streams through. location / { my_module; } location /internal { proxy_pass http://.... } GET requests work ok, but for PUT, the entire body has to first be read in by my module, because request_body_no_buffering does not work for sub requests. I got around this for the PUT sub request by adding a flag to ngx_connection_t, wrapping the ngx_connection_t ->recv function with my own function, and finally modifying the sub request check in ngx_http_read_client_request_body to be ignored if my flag is set. The recv wrapper is necessary, because the content length header in the sub request is larger than the content length in the main request, and ngx_http_request_body.c does its accounting based on the recv function, and not ngx_http_top_request_body_filter. Is there a better way of doing this? Any feedback or suggestions would be greatly appreciated. Thanks! John -------------- next part -------------- An HTML attachment was scrubbed... URL: From igor at sysoev.ru Fri Apr 8 15:49:39 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 08 Apr 2016 15:49:39 +0000 Subject: [njs] Date() function. Message-ID: details: http://hg.nginx.org/njs/rev/39557c1b3088 branches: changeset: 94:39557c1b3088 user: Igor Sysoev date: Fri Apr 08 18:19:43 2016 +0300 description: Date() function. diffstat: Makefile | 16 + njs/njs_builtin.c | 9 + njs/njs_date.c | 2104 ++++++++++++++++++++++++++++++++++++++++++++++ njs/njs_date.h | 25 + njs/njs_function.h | 1 + njs/njs_generator.c | 1 + njs/njs_lexer_keyword.c | 1 + njs/njs_object.c | 3 + njs/njs_object_hash.h | 15 + njs/njs_parser.c | 4 + njs/njs_parser.h | 5 +- njs/njs_vm.c | 8 + njs/njs_vm.h | 14 +- njs/test/njs_unit_test.c | 305 ++++++ nxt/auto/configure | 1 + nxt/auto/time | 39 + 16 files changed, 2547 insertions(+), 4 deletions(-) diffs (truncated from 2813 to 1000 lines): diff -r 91543c86f412 -r 39557c1b3088 Makefile --- a/Makefile Tue Mar 29 13:38:18 2016 +0300 +++ b/Makefile Fri Apr 08 18:19:43 2016 +0300 @@ -18,6 +18,7 @@ NXT_BUILDDIR = build $(NXT_BUILDDIR)/njs_array.o \ $(NXT_BUILDDIR)/njs_function.o \ $(NXT_BUILDDIR)/njs_regexp.o \ + $(NXT_BUILDDIR)/njs_date.o \ $(NXT_BUILDDIR)/njs_math.o \ $(NXT_BUILDDIR)/njs_extern.o \ $(NXT_BUILDDIR)/njs_variable.o \ @@ -48,6 +49,7 @@ NXT_BUILDDIR = build $(NXT_BUILDDIR)/njs_array.o \ $(NXT_BUILDDIR)/njs_function.o \ $(NXT_BUILDDIR)/njs_regexp.o \ + $(NXT_BUILDDIR)/njs_date.o \ $(NXT_BUILDDIR)/njs_math.o \ $(NXT_BUILDDIR)/njs_extern.o \ $(NXT_BUILDDIR)/njs_variable.o \ @@ -224,6 +226,20 @@ tarball: -I$(NXT_LIB) -Injs $(NXT_PCRE_CFLAGS) \ njs/njs_regexp.c +$(NXT_BUILDDIR)/njs_date.o: \ + $(NXT_BUILDDIR)/libnxt.a \ + njs/njscript.h \ + njs/njs_vm.h \ + njs/njs_string.h \ + njs/njs_object.h \ + njs/njs_function.h \ + njs/njs_date.h \ + njs/njs_date.c \ + + $(NXT_CC) -c -o $(NXT_BUILDDIR)/njs_date.o $(NXT_CFLAGS) \ + -I$(NXT_LIB) -Injs $(NXT_PCRE_CFLAGS) \ + njs/njs_date.c + $(NXT_BUILDDIR)/njs_math.o: \ $(NXT_BUILDDIR)/libnxt.a \ njs/njscript.h \ diff -r 91543c86f412 -r 39557c1b3088 njs/njs_builtin.c --- a/njs/njs_builtin.c Tue Mar 29 13:38:18 2016 +0300 +++ b/njs/njs_builtin.c Fri Apr 08 18:19:43 2016 +0300 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,7 @@ njs_builtin_objects_create(njs_vm_t *vm) &njs_string_prototype_init, &njs_function_prototype_init, &njs_regexp_prototype_init, + &njs_date_prototype_init, }; static const njs_object_init_t *function_init[] = { @@ -56,6 +58,7 @@ njs_builtin_objects_create(njs_vm_t *vm) &njs_string_constructor_init, &njs_function_constructor_init, &njs_regexp_constructor_init, + &njs_date_constructor_init, &njs_eval_function_init, }; @@ -70,6 +73,8 @@ njs_builtin_objects_create(njs_vm_t *vm) { njs_function_constructor, { 0 } }, { njs_regexp_constructor, { NJS_SKIP_ARG, NJS_STRING_ARG, NJS_STRING_ARG } }, + { njs_date_constructor, { 0 } }, + { njs_eval_function, { 0 } }, }; @@ -178,6 +183,10 @@ njs_builtin_objects_create(njs_vm_t *vm) * RegExp.__proto__ -> Function_Prototype, * RegExp_Prototype.__proto__ -> Object_Prototype, * + * Date(), + * Date.__proto__ -> Function_Prototype, + * Date_Prototype.__proto__ -> Object_Prototype, + * * eval(), * eval.__proto__ -> Function_Prototype. */ diff -r 91543c86f412 -r 39557c1b3088 njs/njs_date.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/njs/njs_date.c Fri Apr 08 18:19:43 2016 +0300 @@ -0,0 +1,2104 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * njs_timegm() is used because + * Solaris lacks timegm(), + * FreeBSD and MacOSX timegm() cannot handle years before 1900. + */ + +#define NJS_ISO_DATE_TIME_LEN sizeof("+001970-09-28T12:00:00.000Z") + +#define NJS_DATE_TIME_LEN \ + sizeof("Mon Sep 28 1970 12:00:00 GMT+0600 (XXXXX)") + + +static nxt_noinline double njs_date_string_parse(njs_value_t *date); +static const u_char *njs_date_skip_week_day(const u_char *p, const u_char *end); +static const u_char *njs_date_skip_spaces(const u_char *p, const u_char *end); +static nxt_noinline nxt_int_t njs_date_month_parse(const u_char *p, + const u_char *end); +static nxt_noinline const u_char *njs_date_time_parse(struct tm *tm, + const u_char *p, const u_char *end); +static nxt_noinline nxt_int_t njs_date_gmtoff_parse(const u_char *start, + const u_char *end); +static nxt_noinline const u_char *njs_date_number_parse(int *value, + const u_char *p, const u_char *end, size_t size); +static int64_t njs_timegm(struct tm *tm); +static nxt_noinline njs_ret_t njs_date_string(njs_vm_t *vm, const char *fmt, + double time); +static nxt_noinline double njs_date_time(struct tm *tm, int64_t ms); +static double njs_date_utc_time(struct tm *tm, double time); +static njs_ret_t njs_date_prototype_to_json_continuation(njs_vm_t *vm, + njs_value_t *args, nxt_uint_t nargs, njs_index_t retval); + + +static const njs_value_t njs_string_invalid_date = njs_string("Invalid Date"); + + +static nxt_noinline uint64_t +njs_gettime(void) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + return (uint64_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + + +njs_ret_t +njs_date_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + int64_t time, values[8]; + nxt_uint_t i, n; + njs_date_t *date; + struct tm tm; + + if (vm->frame->ctor) { + + if (nargs == 0) { + time = njs_gettime(); + + } else if (nargs == 2 && njs_is_string(&args[1])) { + time = njs_date_string_parse(&args[1]); + + } else { + memset(values, 0, 8 * sizeof(int64_t)); + /* Month. */ + values[2] = 1; + + n = nxt_min(8, nargs); + + for (i = 1; i < n; i++) { + if (!njs_is_numeric(&args[i])) { + return NJS_TRAP_NUMBER_ARG; + } + + num = args[i].data.u.number; + + if (njs_is_nan(num)) { + nargs = 0; + break; + } + + values[i] = num; + } + + if (nargs > 2) { + /* Year. */ + if (values[1] > 99) { + values[1] -= 1900; + } + + tm.tm_year = values[1]; + tm.tm_mon = values[2]; + tm.tm_mday = values[3]; + tm.tm_hour = values[4]; + tm.tm_min = values[5]; + tm.tm_sec = values[6]; + tm.tm_isdst = -1; + + time = (int64_t) mktime(&tm) * 1000 + values[7]; + + } else { + time = values[1]; + } + } + + date = nxt_mem_cache_alloc(vm->mem_cache_pool, sizeof(njs_date_t)); + if (nxt_slow_path(date == NULL)) { + return NXT_ERROR; + } + + nxt_lvlhsh_init(&date->object.hash); + nxt_lvlhsh_init(&date->object.shared_hash); + date->object.shared = 0; + date->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_DATE]; + + date->time = time; + + vm->retval.data.u.date = date; + vm->retval.type = NJS_DATE; + vm->retval.data.truth = 1; + + return NXT_OK; + } + + return njs_date_string(vm, "%a %b %d %Y %T GMT%z (%Z)", njs_gettime()); +} + + +static njs_ret_t +njs_date_utc(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num, time; + struct tm tm; + nxt_uint_t i, n; + int32_t values[8]; + + time = NJS_NAN; + + if (nargs > 2) { + memset(values, 0, 8 * sizeof(int32_t)); + + n = nxt_min(8, nargs); + + for (i = 1; i < n; i++) { + if (!njs_is_numeric(&args[i])) { + return NJS_TRAP_NUMBER_ARG; + } + + num = args[i].data.u.number; + + if (njs_is_nan(num)) { + goto done; + } + + values[i] = num; + } + + /* Year. */ + if (values[1] > 99) { + values[1] -= 1900; + } + + tm.tm_year = values[1]; + tm.tm_mon = values[2]; + tm.tm_mday = values[3]; + tm.tm_hour = values[4]; + tm.tm_min = values[5]; + tm.tm_sec = values[6]; + + time = njs_timegm(&tm) * 1000 + values[7]; + } + +done: + + njs_number_set(&vm->retval, time); + + return NXT_OK; +} + + +static int64_t +njs_timegm(struct tm *tm) +{ + int32_t year, month, days; + + year = tm->tm_year + 1900; + + /* + * Shift new year to March 1 and start months + * from 1 (not 0), as required for Gauss' formula. + */ + + month = tm->tm_mon - 1; + + if (month <= 0) { + month += 12; + year -= 1; + } + + /* Gauss' formula for Gregorian days since March 1, 1 BCE. */ + + /* Days in years including leap years since March 1, 1 BCE. */ + days = 365 * year + year / 4 - year / 100 + year / 400; + + /* Days before the month. */ + days += 367 * month / 12 - 30; + + /* Days before the day. */ + if (year >= 0) { + days += tm->tm_mday - 1; + + } else { + /* 1 BCE was a leap year. */ + days += tm->tm_mday - 2; + } + + /* + * 719527 days were between March 1, 1 BCE and March 1, 1970, + * 31 and 28 days were in January and February 1970. + */ + days = days - 719527 + 31 + 28; + + return (int64_t) days * 86400 + + tm->tm_hour * 3600 + + tm->tm_min * 60 + + tm->tm_sec; +} + + +static njs_ret_t +njs_date_now(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + njs_number_set(&vm->retval, njs_gettime()); + + return NXT_OK; +} + + +static njs_ret_t +njs_date_parse(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double time; + + if (nargs > 1) { + time = njs_date_string_parse(&args[1]); + + } else { + time = NJS_NAN; + } + + njs_number_set(&vm->retval, time); + + return NXT_OK; +} + + +static nxt_noinline double +njs_date_string_parse(njs_value_t *date) +{ + int ext, ms, gmtoff; + struct tm tm; + nxt_bool_t sign; + const u_char *p, *next, *end; + njs_string_prop_t string; + + (void) njs_string_prop(&string, date); + + p = string.start; + end = p + string.size; + + if (nxt_slow_path(p + 10 >= end)) { + return NJS_NAN; + } + + if (*p == '+') { + p++; + sign = 1; + + } else if (*p == '-') { + p++; + sign = 1; + + } else { + sign = 0; + } + + next = njs_date_number_parse(&tm.tm_year, p, end, 4); + + if (next != NULL) { + /* ISO-8601 format: "1970-09-28T06:00:00.000Z" */ + + if (*next != '-') { + /* Extended ISO-8601 format: "+001970-09-28T06:00:00.000Z" */ + + next = njs_date_number_parse(&ext, next, end, 2); + if (nxt_slow_path(next == NULL)) { + return NJS_NAN; + } + + tm.tm_year = tm.tm_year * 100 + ext; + + if (string.start[0] == '-') { + if (tm.tm_year == 0) { + return NJS_NAN; + } + + tm.tm_year = -tm.tm_year; + } + + if (*next != '-') { + return NJS_NAN; + } + } + + tm.tm_year -= 1900; + + p = njs_date_number_parse(&tm.tm_mon, next + 1, end, 2); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + tm.tm_mon--; + + if (nxt_slow_path(p >= end || *p != '-')) { + return NJS_NAN; + } + + p = njs_date_number_parse(&tm.tm_mday, p + 1, end, 2); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + if (nxt_slow_path(p >= end || *p != 'T')) { + return NJS_NAN; + } + + p = njs_date_time_parse(&tm, p + 1, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + if (nxt_slow_path(p >= end || *p != '.')) { + return NJS_NAN; + } + + p = njs_date_number_parse(&ms, p + 1, end, 3); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + if (nxt_slow_path(p >= end || *p != 'Z')) { + return NJS_NAN; + } + + return njs_timegm(&tm) * 1000 + ms; + } + + if (sign) { + return NJS_NAN; + } + + p = njs_date_skip_week_day(p, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + p = njs_date_skip_spaces(p, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + next = njs_date_number_parse(&tm.tm_mday, p, end, 2); + + if (next != NULL) { + /* + * RFC 2822 format: + * "Mon, 28 Sep 1970 06:00:00 GMT", + * "Mon, 28 Sep 1970 06:00:00 UTC", + * "Mon, 28 Sep 1970 12:00:00 +0600". + */ + p = njs_date_skip_spaces(next, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + tm.tm_mon = njs_date_month_parse(p, end); + if (nxt_slow_path(tm.tm_mon < 0)) { + return NJS_NAN; + } + + p = njs_date_skip_spaces(p + 3, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + p = njs_date_number_parse(&tm.tm_year, p, end, 4); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + tm.tm_year -= 1900; + + p = njs_date_skip_spaces(p, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + p = njs_date_time_parse(&tm, p, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + p = njs_date_skip_spaces(p, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + if (p + 2 < end) { + + if ((p[0] == 'G' && p[1] == 'M' && p[2] == 'T') + || (p[0] == 'U' && p[1] == 'T' && p[2] == 'C')) + { + gmtoff = 0; + + } else { + gmtoff = njs_date_gmtoff_parse(p, end); + if (nxt_slow_path(gmtoff == -1)) { + return NJS_NAN; + } + } + + return (njs_timegm(&tm) - gmtoff * 60) * 1000; + } + + return NJS_NAN; + } + + /* Date.toString() format: "Mon Sep 28 1970 12:00:00 GMT+0600". */ + + tm.tm_mon = njs_date_month_parse(p, end); + if (nxt_slow_path(tm.tm_mon < 0)) { + return NJS_NAN; + } + + p = njs_date_skip_spaces(p + 3, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + p = njs_date_number_parse(&tm.tm_mday, p, end, 2); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + p = njs_date_skip_spaces(p, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + p = njs_date_number_parse(&tm.tm_year, p, end, 4); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + tm.tm_year -= 1900; + + p = njs_date_skip_spaces(p, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + p = njs_date_time_parse(&tm, p, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + p = njs_date_skip_spaces(p, end); + if (nxt_slow_path(p == NULL)) { + return NJS_NAN; + } + + if (p + 2 < end && p[0] == 'G' && p[1] == 'M' && p[2] == 'T') { + + gmtoff = njs_date_gmtoff_parse(&p[3], end); + + if (nxt_fast_path(gmtoff != -1)) { + return (njs_timegm(&tm) - gmtoff * 60) * 1000; + } + } + + return NJS_NAN; +} + + +static const u_char * +njs_date_skip_week_day(const u_char *p, const u_char *end) +{ + while (p < end) { + if (*p == ' ') { + return p; + } + + p++; + } + + return NULL; +} + + +static const u_char * +njs_date_skip_spaces(const u_char *p, const u_char *end) +{ + if (p < end && *p++ == ' ') { + + while (p < end) { + if (*p != ' ') { + return p; + } + + p++; + } + } + + return NULL; +} + + +static nxt_noinline nxt_int_t +njs_date_month_parse(const u_char *p, const u_char *end) +{ + if (p + 2 < end) { + switch (p[0]) { + + case 'J': + if (p[1] == 'a' && p[2] == 'n') { + return 0; + } + + if (p[1] == 'u') { + if (p[2] == 'n') { + return 5; + } + + if (p[2] == 'l') { + return 6; + } + } + + break; + + case 'F': + if (p[1] == 'e' && p[2] == 'b') { + return 1; + } + + break; + + case 'M': + if (p[1] == 'a') { + if (p[2] == 'r') { + return 2; + } + + if (p[2] == 'y') { + return 4; + } + } + + break; + + case 'A': + if (p[1] == 'p' && p[2] == 'r') { + return 3; + } + + if (p[1] == 'u' && p[2] == 'g') { + return 7; + } + + break; + + case 'S': + if (p[1] == 'e' && p[2] == 'p') { + return 8; + } + + break; + + case 'O': + if (p[1] == 'c' && p[2] == 't') { + return 9; + } + + break; + + case 'N': + if (p[1] == 'o' && p[2] == 'v') { + return 10; + } + + break; + + case 'D': + if (p[1] == 'e' && p[2] == 'c') { + return 11; + } + + break; + } + } + + return -1; +} + + +static nxt_noinline const u_char * +njs_date_time_parse(struct tm *tm, const u_char *p, const u_char *end) +{ + p = njs_date_number_parse(&tm->tm_hour, p, end, 2); + if (nxt_slow_path(p == NULL)) { + return p; + } + + if (nxt_slow_path(p >= end || *p != ':')) { + return NULL; + } + + p = njs_date_number_parse(&tm->tm_min, p + 1, end, 2); + if (nxt_slow_path(p == NULL)) { + return p; + } + + if (nxt_slow_path(p >= end || *p != ':')) { + return NULL; + } + + return njs_date_number_parse(&tm->tm_sec, p + 1, end, 2); +} + + +static nxt_noinline nxt_int_t +njs_date_gmtoff_parse(const u_char *start, const u_char *end) +{ + int gmtoff, hour, min; + const u_char *p; + + if (nxt_fast_path(start + 4 < end && (*start == '+' || *start == '-'))) { + + p = njs_date_number_parse(&hour, start + 1, end, 2); + if (nxt_slow_path(p == NULL)) { + return -1; + } + + p = njs_date_number_parse(&min, p, end, 2); + if (nxt_slow_path(p == NULL)) { + return -1; + } + + gmtoff = hour * 60 + min; + + if (*start == '-') { + gmtoff = -gmtoff; + } + + return gmtoff; + } + + return -1; +} + + +static nxt_noinline const u_char * +njs_date_number_parse(int *value, const u_char *p, const u_char *end, + size_t size) +{ + u_char c; + nxt_int_t n; + + n = 0; + + do { + if (nxt_slow_path(p >= end)) { + return NULL; + } + + c = *p++; + + /* Values below '0' become >= 208. */ + c = c - '0'; + + if (nxt_slow_path(c > 9)) { + return NULL; + } + + n = n * 10 + c; + + size--; + + } while (size != 0); + + *value = n; + + return p; +} + + +static const njs_object_prop_t njs_date_constructor_properties[] = +{ + /* Date.name == "Date". */ + { + .type = NJS_PROPERTY, + .name = njs_string("name"), + .value = njs_string("Date"), + }, + + /* Date.length == 7. */ + { + .type = NJS_PROPERTY, + .name = njs_string("length"), + .value = njs_value(NJS_NUMBER, 1, 7.0), + }, + + /* Date.prototype. */ + { + .type = NJS_NATIVE_GETTER, + .name = njs_string("prototype"), + .value = njs_native_getter(njs_object_prototype_create), + }, + + { + .type = NJS_METHOD, + .name = njs_string("UTC"), + .value = njs_native_function(njs_date_utc, 0, 0), + }, + + { + .type = NJS_METHOD, + .name = njs_string("now"), + .value = njs_native_function(njs_date_now, 0, 0), + }, + + { + .type = NJS_METHOD, + .name = njs_string("parse"), + .value = njs_native_function(njs_date_parse, 0, + NJS_SKIP_ARG, NJS_STRING_ARG), + }, +}; + + +const njs_object_init_t njs_date_constructor_init = { + njs_date_constructor_properties, + nxt_nitems(njs_date_constructor_properties), +}; + + +static njs_ret_t +njs_date_prototype_value_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + njs_number_set(&vm->retval, args[0].data.u.date->time); + + return NXT_OK; +} + + +static njs_ret_t +njs_date_prototype_to_string(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + return njs_date_string(vm, "%a %b %d %Y %T GMT%z (%Z)", + args[0].data.u.date->time); +} + + +static njs_ret_t +njs_date_prototype_to_date_string(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) +{ + return njs_date_string(vm, "%a %b %d %Y", args[0].data.u.date->time); +} + + +static njs_ret_t +njs_date_prototype_to_time_string(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) +{ + return njs_date_string(vm, "%T GMT%z (%Z)", args[0].data.u.date->time); +} + + +static nxt_noinline njs_ret_t +njs_date_string(njs_vm_t *vm, const char *fmt, double time) +{ + size_t size; + time_t clock; + u_char *start; + u_char buf[NJS_DATE_TIME_LEN]; + struct tm tm; + + if (!njs_is_nan(time)) { + clock = time / 1000; + localtime_r(&clock, &tm); + + size = strftime((char *) buf, NJS_DATE_TIME_LEN, fmt, &tm); + + start = njs_string_alloc(vm, &vm->retval, size, size); + + if (nxt_fast_path(start != NULL)) { + memcpy(start, buf, size); + return NXT_OK; + } + + return NXT_ERROR; + } + + vm->retval = njs_string_invalid_date; + + return NXT_OK; +} + + +static njs_ret_t +njs_date_prototype_to_utc_string(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) +{ + double time; + size_t size; + time_t clock; + u_char *start; + u_char buf[NJS_DATE_TIME_LEN]; + struct tm tm; + + static const char *week[] = { "Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat" }; + + static const char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + + time = args[0].data.u.date->time; + + if (!njs_is_nan(time)) { + clock = time / 1000; + gmtime_r(&clock, &tm); + + size = snprintf((char *) buf, NJS_DATE_TIME_LEN, + "%s %s %02d %4d %02d:%02d:%02d GMT", + week[tm.tm_wday], month[tm.tm_mon], + tm.tm_mday, tm.tm_year + 1900, + tm.tm_hour, tm.tm_min, tm.tm_sec); + + start = njs_string_alloc(vm, &vm->retval, size, size); + + if (nxt_fast_path(start != NULL)) { + memcpy(start, buf, size); + return NXT_OK; + } + + return NXT_ERROR; + } + + vm->retval = njs_string_invalid_date; + + return NXT_OK; +} + + +static njs_ret_t +njs_date_prototype_to_iso_string(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) +{ + int32_t year; From igor at sysoev.ru Fri Apr 8 15:59:20 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 08 Apr 2016 15:59:20 +0000 Subject: [njs] Forgotten nxt/nxt_time.h file has been added. Message-ID: details: http://hg.nginx.org/njs/rev/0e62188391a1 branches: changeset: 95:0e62188391a1 user: Igor Sysoev date: Fri Apr 08 18:59:06 2016 +0300 description: Forgotten nxt/nxt_time.h file has been added. diffstat: nxt/nxt_time.h | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+), 0 deletions(-) diffs (28 lines): diff -r 39557c1b3088 -r 0e62188391a1 nxt/nxt_time.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nxt/nxt_time.h Fri Apr 08 18:59:06 2016 +0300 @@ -0,0 +1,24 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#ifndef _NXT_TIME_H_INCLUDED_ +#define _NXT_TIME_H_INCLUDED_ + + +#if (NXT_HAVE_TM_GMTOFF) + +#define nxt_timezone(tm) \ + ((tm)->tm_gmtoff) + +#elif (NXT_HAVE_ALTZONE) + +#define nxt_timezone(tm) \ + (-(((tm)->tm_isdst > 0) ? altzone : timezone)) + +#endif + + +#endif /* _NXT_TIME_H_INCLUDED_ */ From ru at nginx.com Fri Apr 8 16:07:26 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Fri, 08 Apr 2016 16:07:26 +0000 Subject: [nginx] Removed redundant "u" format specifier. Message-ID: details: http://hg.nginx.org/nginx/rev/7640d6c213e1 branches: changeset: 6509:7640d6c213e1 user: Ruslan Ermilov date: Fri Apr 08 15:03:38 2016 +0300 description: Removed redundant "u" format specifier. It is implied for "x" and "X". diffstat: src/core/ngx_inet.c | 2 +- src/core/ngx_resolver.c | 4 ++-- src/event/modules/ngx_epoll_module.c | 2 +- src/os/win32/ngx_process.c | 2 +- src/os/win32/ngx_process_cycle.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diffs (69 lines): diff -r 151fd02a4317 -r 7640d6c213e1 src/core/ngx_inet.c --- a/src/core/ngx_inet.c Fri Apr 08 16:49:35 2016 +0300 +++ b/src/core/ngx_inet.c Fri Apr 08 15:03:38 2016 +0300 @@ -348,7 +348,7 @@ ngx_inet6_ntop(u_char *p, u_char *text, continue; } - dst = ngx_sprintf(dst, "%uxd", p[i] * 256 + p[i + 1]); + dst = ngx_sprintf(dst, "%xd", p[i] * 256 + p[i + 1]); if (i < 14) { *dst++ = ':'; diff -r 151fd02a4317 -r 7640d6c213e1 src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Fri Apr 08 16:49:35 2016 +0300 +++ b/src/core/ngx_resolver.c Fri Apr 08 15:03:38 2016 +0300 @@ -1733,7 +1733,7 @@ ngx_resolver_process_response(ngx_resolv trunc = flags & 0x0200; ngx_log_debug6(NGX_LOG_DEBUG_CORE, r->log, 0, - "resolver DNS response %ui fl:%04Xui %ui/%ui/%ud/%ud", + "resolver DNS response %ui fl:%04Xi %ui/%ui/%ud/%ud", ident, flags, nqs, nan, (response->nns_hi << 8) + response->nns_lo, (response->nar_hi << 8) + response->nar_lo); @@ -1741,7 +1741,7 @@ ngx_resolver_process_response(ngx_resolv /* response to a standard query */ if ((flags & 0xf870) != 0x8000 || (trunc && tcp)) { ngx_log_error(r->log_level, r->log, 0, - "invalid %s DNS response %ui fl:%04Xui", + "invalid %s DNS response %ui fl:%04Xi", tcp ? "TCP" : "UDP", ident, flags); return; } diff -r 151fd02a4317 -r 7640d6c213e1 src/event/modules/ngx_epoll_module.c --- a/src/event/modules/ngx_epoll_module.c Fri Apr 08 16:49:35 2016 +0300 +++ b/src/event/modules/ngx_epoll_module.c Fri Apr 08 15:03:38 2016 +0300 @@ -910,7 +910,7 @@ ngx_epoll_eventfd_handler(ngx_event_t *e for (i = 0; i < events; i++) { ngx_log_debug4(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "io_event: %uXL %uXL %L %L", + "io_event: %XL %XL %L %L", event[i].data, event[i].obj, event[i].res, event[i].res2); diff -r 151fd02a4317 -r 7640d6c213e1 src/os/win32/ngx_process.c --- a/src/os/win32/ngx_process.c Fri Apr 08 16:49:35 2016 +0300 +++ b/src/os/win32/ngx_process.c Fri Apr 08 15:03:38 2016 +0300 @@ -138,7 +138,7 @@ ngx_spawn_process(ngx_cycle_t *cycle, ch } ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "%s process %P exited with code %Xul", + "%s process %P exited with code %Xl", name, pid, code); goto failed; diff -r 151fd02a4317 -r 7640d6c213e1 src/os/win32/ngx_process_cycle.c --- a/src/os/win32/ngx_process_cycle.c Fri Apr 08 16:49:35 2016 +0300 +++ b/src/os/win32/ngx_process_cycle.c Fri Apr 08 15:03:38 2016 +0300 @@ -484,7 +484,7 @@ ngx_reap_worker(ngx_cycle_t *cycle, HAND } ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, - "%s process %P exited with code %Xul", + "%s process %P exited with code %Xl", ngx_processes[n].name, ngx_processes[n].pid, code); ngx_close_handle(ngx_processes[n].reopen); From mdounin at mdounin.ru Fri Apr 8 17:10:16 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 8 Apr 2016 20:10:16 +0300 Subject: patch proposal In-Reply-To: References: Message-ID: <20160408171016.GO36620@mdounin.ru> Hello! On Fri, Apr 08, 2016 at 11:19:17AM +0300, Vladislav Shabanov wrote: > ???? ??? ?????? ?? ??????? ?? ???????, ? ???, ???????, ???????? > ?? ??????????, ?? ???????? ?? ????-???? ??????? ?????????? :) This list language is English. If you want to use Russian - please use nginx-ru@ mailinig list. [...] > ????? ????????? nodelay, ?? ????? ??????? ???????? ???? ?? ????? > ???????? ???????? ? ???????? ????? ???????? ?? ?????? ?? ?????? > 503. > > ????? ???????, ??? ?????, ????? ??? ?????????????? ?????????? > ??????? ????????? nodelay ?? ????, ? ??? ???????????? ?????????? > ??, ????????, ??? ? ??????? ?? ???????? ????????? ????? ?? 503 > ??????. So, the idea is that there should be two states: 1. Requests are passed without being delayed till certain number of requests are accumulated in the bucket. 2. Then further requests are delayed till burst= is reached. So, basically, there are two burst limits now: delay limit (nodelay=, defaults to 0, set to a large value if no argument specified) and reject limit (burst=). Correct? Something like this was discussed couple of times already, though I tend to like the approach which just changes "nodelay" into an additional limit. The patch itself certainly needs more work to be committable, below is an alternative version. (Completely untested though.) I also think that we may consider using some reasonable value by default (something like burst/2?). The delay mode as used by default seems to be misused very often. # HG changeset patch # User Maxim Dounin # Date 1460135272 -10800 # Fri Apr 08 20:07:52 2016 +0300 # Node ID 3cac97f32d5ee71a5b712d1d88ce97966b72a374 # Parent 2e722c177a5b35e4d88229e681b605542dfb1452 Limit req: "nodelay=" parameter. This parameter specifies an additional "soft" burst limit at which requests become delayed (but not yet rejected as it happens if "burst=" limit is exceeded). Defaults to 0, i.e., all excess requests are delayed. Inspired by Vladislav Shabanov, http://mailman.nginx.org/pipermail/nginx-devel/2016-April/008126.html. diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c --- a/src/http/modules/ngx_http_limit_req_module.c +++ b/src/http/modules/ngx_http_limit_req_module.c @@ -44,7 +44,7 @@ typedef struct { ngx_shm_zone_t *shm_zone; /* integer value, 1 corresponds to 0.001 r/s */ ngx_uint_t burst; - ngx_uint_t nodelay; /* unsigned nodelay:1 */ + ngx_uint_t nodelay; } ngx_http_limit_req_limit_t; @@ -491,7 +491,7 @@ ngx_http_limit_req_account(ngx_http_limi excess = *ep; - if (excess == 0 || (*limit)->nodelay) { + if ((ngx_uint_t) excess <= (*limit)->nodelay) { max_delay = 0; } else { @@ -528,7 +528,7 @@ ngx_http_limit_req_account(ngx_http_limi ctx->node = NULL; - if (limits[n].nodelay) { + if ((ngx_uint_t) excess <= limits[n].nodelay) { continue; } @@ -862,9 +862,9 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_c { ngx_http_limit_req_conf_t *lrcf = conf; - ngx_int_t burst; + ngx_int_t burst, nodelay; ngx_str_t *value, s; - ngx_uint_t i, nodelay; + ngx_uint_t i; ngx_shm_zone_t *shm_zone; ngx_http_limit_req_limit_t *limit, *limits; @@ -895,7 +895,7 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_c burst = ngx_atoi(value[i].data + 6, value[i].len - 6); if (burst <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid burst rate \"%V\"", &value[i]); + "invalid burst value \"%V\"", &value[i]); return NGX_CONF_ERROR; } @@ -903,7 +903,19 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_c } if (ngx_strcmp(value[i].data, "nodelay") == 0) { - nodelay = 1; + nodelay = NGX_MAX_INT_T_VALUE / 1000; + continue; + } + + if (ngx_strncmp(value[i].data, "nodelay=", 8) == 0) { + + nodelay = ngx_atoi(value[i].data + 6, value[i].len - 6); + if (nodelay <= 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid nodelay value \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + continue; } @@ -943,7 +955,7 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_c limit->shm_zone = shm_zone; limit->burst = burst * 1000; - limit->nodelay = nodelay; + limit->nodelay = nodelay * 1000; return NGX_CONF_OK; } -- Maxim Dounin http://nginx.org/ From igor at sysoev.ru Sat Apr 9 09:22:48 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Sat, 09 Apr 2016 09:22:48 +0000 Subject: [njs] Segfault has been fixed when array element was added Message-ID: details: http://hg.nginx.org/njs/rev/160e59aaf9bb branches: changeset: 96:160e59aaf9bb user: Igor Sysoev date: Sat Apr 09 12:18:47 2016 +0300 description: Segfault has been fixed when array element was added with assignment. diffstat: njs/njs_vm.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 0e62188391a1 -r 160e59aaf9bb njs/njs_vm.c --- a/njs/njs_vm.c Fri Apr 08 18:59:06 2016 +0300 +++ b/njs/njs_vm.c Sat Apr 09 12:18:47 2016 +0300 @@ -1041,7 +1041,7 @@ njs_array_property_query(njs_vm_t *vm, n } if ((uint32_t) index >= array->size) { - ret = njs_array_realloc(vm, array, 0, index); + ret = njs_array_realloc(vm, array, 0, index + 1); if (nxt_slow_path(ret != NXT_OK)) { return ret; } From igor at sysoev.ru Sat Apr 9 09:22:59 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Sat, 09 Apr 2016 09:22:59 +0000 Subject: [njs] Old array data are freed after array relocation. Message-ID: details: http://hg.nginx.org/njs/rev/24544f647802 branches: changeset: 97:24544f647802 user: Igor Sysoev date: Sat Apr 09 12:21:31 2016 +0300 description: Old array data are freed after array relocation. diffstat: njs/njs_array.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) diffs (31 lines): diff -r 160e59aaf9bb -r 24544f647802 njs/njs_array.c --- a/njs/njs_array.c Sat Apr 09 12:18:47 2016 +0300 +++ b/njs/njs_array.c Sat Apr 09 12:21:31 2016 +0300 @@ -143,7 +143,7 @@ njs_array_realloc(njs_vm_t *vm, njs_arra uint32_t size) { nxt_uint_t n; - njs_value_t *value; + njs_value_t *value, *old; if (size != array->size) { if (size < 16) { @@ -160,8 +160,7 @@ njs_array_realloc(njs_vm_t *vm, njs_arra return NXT_ERROR; } - /* GC: old = array->data */ - + old = array->data; array->data = value; while (prepend != 0) { @@ -185,7 +184,7 @@ njs_array_realloc(njs_vm_t *vm, njs_arra size--; } - /* GC: free old pointer. */ + nxt_mem_cache_free(vm->mem_cache_pool, old); return NXT_OK; } From alessandro at cloudflare.com Mon Apr 11 15:54:35 2016 From: alessandro at cloudflare.com (Alessandro Ghedini) Date: Mon, 11 Apr 2016 16:54:35 +0100 Subject: [PATCH] Fixed typos Message-ID: <892560ebe055092c3bed.1460390075@mandy.local> # HG changeset patch # User Alessandro Ghedini # Date 1460389631 -3600 # Mon Apr 11 16:47:11 2016 +0100 # Node ID 892560ebe055092c3bed769234b2bae19d67fb71 # Parent 7640d6c213e150669c8ca7b4005f4c09bf360070 Fixed typos. diff -r 7640d6c213e1 -r 892560ebe055 src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c Fri Apr 08 15:03:38 2016 +0300 +++ b/src/http/modules/ngx_http_ssi_filter_module.c Mon Apr 11 16:47:11 2016 +0100 @@ -2525,7 +2525,7 @@ ngx_http_ssi_if(ngx_http_request_t *r, n } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "evaluted left: \"%V\"", &left); + "evaluated left: \"%V\"", &left); if (p == last) { if (left.len) { @@ -2589,7 +2589,7 @@ ngx_http_ssi_if(ngx_http_request_t *r, n } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "evaluted right: \"%V\"", &right); + "evaluated right: \"%V\"", &right); if (noregex) { if (left.len != right.len) { From ru at nginx.com Tue Apr 12 06:41:05 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 12 Apr 2016 06:41:05 +0000 Subject: [nginx] Fixed typos. Message-ID: details: http://hg.nginx.org/nginx/rev/a3be359e6c7d branches: changeset: 6510:a3be359e6c7d user: Alessandro Ghedini date: Mon Apr 11 16:47:11 2016 +0100 description: Fixed typos. diffstat: src/http/modules/ngx_http_ssi_filter_module.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 7640d6c213e1 -r a3be359e6c7d src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c Fri Apr 08 15:03:38 2016 +0300 +++ b/src/http/modules/ngx_http_ssi_filter_module.c Mon Apr 11 16:47:11 2016 +0100 @@ -2525,7 +2525,7 @@ ngx_http_ssi_if(ngx_http_request_t *r, n } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "evaluted left: \"%V\"", &left); + "evaluated left: \"%V\"", &left); if (p == last) { if (left.len) { @@ -2589,7 +2589,7 @@ ngx_http_ssi_if(ngx_http_request_t *r, n } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "evaluted right: \"%V\"", &right); + "evaluated right: \"%V\"", &right); if (noregex) { if (left.len != right.len) { From ru at nginx.com Tue Apr 12 06:41:34 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 12 Apr 2016 09:41:34 +0300 Subject: [PATCH] Fixed typos In-Reply-To: <892560ebe055092c3bed.1460390075@mandy.local> References: <892560ebe055092c3bed.1460390075@mandy.local> Message-ID: <20160412064134.GL77616@lo0.su> On Mon, Apr 11, 2016 at 04:54:35PM +0100, Alessandro Ghedini wrote: > # HG changeset patch > # User Alessandro Ghedini > # Date 1460389631 -3600 > # Mon Apr 11 16:47:11 2016 +0100 > # Node ID 892560ebe055092c3bed769234b2bae19d67fb71 > # Parent 7640d6c213e150669c8ca7b4005f4c09bf360070 > Fixed typos. [...] Committed, thanks! From ru at nginx.com Tue Apr 12 16:23:08 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 12 Apr 2016 16:23:08 +0000 Subject: [nginx] Fixed NGX_CONF_TAKE1/NGX_CONF_FLAG misuse (as in e444e8f6538b). Message-ID: details: http://hg.nginx.org/nginx/rev/640288d0e1bc branches: changeset: 6511:640288d0e1bc user: Ruslan Ermilov date: Tue Apr 12 19:01:56 2016 +0300 description: Fixed NGX_CONF_TAKE1/NGX_CONF_FLAG misuse (as in e444e8f6538b). diffstat: src/core/ngx_regex.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r a3be359e6c7d -r 640288d0e1bc src/core/ngx_regex.c --- a/src/core/ngx_regex.c Mon Apr 11 16:47:11 2016 +0100 +++ b/src/core/ngx_regex.c Tue Apr 12 19:01:56 2016 +0300 @@ -32,7 +32,7 @@ static ngx_conf_post_t ngx_regex_pcre_j static ngx_command_t ngx_regex_commands[] = { { ngx_string("pcre_jit"), - NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, + NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, 0, offsetof(ngx_regex_conf_t, pcre_jit), From oschaaf at we-amp.com Tue Apr 12 22:08:43 2016 From: oschaaf at we-amp.com (Otto van der Schaaf) Date: Wed, 13 Apr 2016 00:08:43 +0200 Subject: 1.9.14 - http2 protocol violations Message-ID: Hello, While looking into https://github.com/pagespeed/ngx_pagespeed/issues/1175 I noticed that when performing a POST to a non-existing page, Chrome will complain about the response (net::ERR_SPDY_PROTOCOL_ERROR). This happens with a plain nginx build, configure arguments: --prefix=/home/oschaaf/nginx-tmpbuild --with-http_v2_module --with-http_ssl_module 1.9.14 seems to have introduced some behavioral changes only noticable on http2, there seem to be similar breakages in some of ngx_pagespeed's flows. One thing we do is perform an async lookup in the preaccess phase - doing so when processing a POST request also results in a protocol violation. As this path looks very similar to the limit request module, I tested that as well. And indeed this also seems to give the same error on http/2 Regards, Otto -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Tue Apr 12 22:52:59 2016 From: vbart at nginx.com (=?utf-8?B?0JLQsNC70LXQvdGC0LjQvSDQkdCw0YDRgtC10L3QtdCy?=) Date: Wed, 13 Apr 2016 01:52:59 +0300 Subject: 1.9.14 - http2 protocol violations In-Reply-To: References: Message-ID: <16610767.NbFPjS937S@vbart-laptop> On Wednesday 13 April 2016 00:08:43 Otto van der Schaaf wrote: > Hello, > > While looking into https://github.com/pagespeed/ngx_pagespeed/issues/1175 I > noticed that when performing a POST to a non-existing page, Chrome will > complain about the response (net::ERR_SPDY_PROTOCOL_ERROR). > > This happens with a plain nginx build, configure arguments: > --prefix=/home/oschaaf/nginx-tmpbuild --with-http_v2_module > --with-http_ssl_module > > 1.9.14 seems to have introduced some behavioral changes only noticable on > http2, there seem to be similar breakages in some of ngx_pagespeed's flows. > > One thing we do is perform an async lookup in the preaccess phase - doing > so when processing a POST request also results in a protocol violation. > As this path looks very similar to the limit request module, I tested that > as well. And indeed this also seems to give the same error on http/2 > [..] Could you provide the debug log? wbr, Valentin V. Bartenev From oschaaf at we-amp.com Wed Apr 13 11:54:24 2016 From: oschaaf at we-amp.com (Otto van der Schaaf) Date: Wed, 13 Apr 2016 13:54:24 +0200 Subject: 1.9.14 - http2 protocol violations In-Reply-To: <16610767.NbFPjS937S@vbart-laptop> References: <16610767.NbFPjS937S@vbart-laptop> Message-ID: Sure. - This sample contains to or three requests, the last request is where rate limiting kicks in and the protocol error happens (the earlier requests are problem-free): https://gist.github.com/oschaaf/281b7a0fed9954dd960adac55e96f2cd - This is from a post to a non-existant url: https://gist.github.com/oschaaf/6396a614ce599d5003e50bb8e7106bed Otto On Wed, Apr 13, 2016 at 12:52 AM, ???????? ???????? wrote: > On Wednesday 13 April 2016 00:08:43 Otto van der Schaaf wrote: > > Hello, > > > > While looking into > https://github.com/pagespeed/ngx_pagespeed/issues/1175 I > > noticed that when performing a POST to a non-existing page, Chrome will > > complain about the response (net::ERR_SPDY_PROTOCOL_ERROR). > > > > This happens with a plain nginx build, configure arguments: > > --prefix=/home/oschaaf/nginx-tmpbuild --with-http_v2_module > > --with-http_ssl_module > > > > 1.9.14 seems to have introduced some behavioral changes only noticable on > > http2, there seem to be similar breakages in some of ngx_pagespeed's > flows. > > > > One thing we do is perform an async lookup in the preaccess phase - doing > > so when processing a POST request also results in a protocol violation. > > As this path looks very similar to the limit request module, I tested > that > > as well. And indeed this also seems to give the same error on http/2 > > > [..] > > Could you provide the debug log? > > wbr, Valentin V. Bartenev > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Wed Apr 13 12:30:39 2016 From: vbart at nginx.com (=?utf-8?B?0JLQsNC70LXQvdGC0LjQvSDQkdCw0YDRgtC10L3QtdCy?=) Date: Wed, 13 Apr 2016 15:30:39 +0300 Subject: 1.9.14 - http2 protocol violations In-Reply-To: References: <16610767.NbFPjS937S@vbart-laptop> Message-ID: <1800487.3hFWtVPpv3@vbart-laptop> On Wednesday 13 April 2016 13:54:24 Otto van der Schaaf wrote: > Sure. > > - This sample contains to or three requests, the last request is where rate > limiting kicks in and the protocol error happens (the earlier requests are > problem-free): > https://gist.github.com/oschaaf/281b7a0fed9954dd960adac55e96f2cd > > - This is from a post to a non-existant url: > https://gist.github.com/oschaaf/6396a614ce599d5003e50bb8e7106bed > [..] Are you sure that you saw this problem while were collecting the logs? There's nothing suspicious in them, and no errors are reported by nginx and by the client. The only problem that I could see should be fixed by the patch below. Please try it and let me know if it will help. wbr, Valentin V. Bartenev # HG changeset patch # User Valentin Bartenev # Date 1460529455 -10800 # Wed Apr 13 09:37:35 2016 +0300 # Node ID 80d0c9e314f62b594e634cd9318fe84afc50bb2c # Parent 640288d0e1bc449a54ac1c85905e6fce780fac7d HTTP/2: refuse streams with data until SETTINGS is acknowledged. A client can start sending data before receiving and acknowledging the SETTINGS frame, thus having a wrong idea about the stream's initial window. This can violate flow control. diff -r 640288d0e1bc -r 80d0c9e314f6 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Tue Apr 12 19:01:56 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Wed Apr 13 09:37:35 2016 +0300 @@ -1071,6 +1071,19 @@ ngx_http_v2_state_headers(ngx_http_v2_co return ngx_http_v2_state_header_block(h2c, pos, end); } + if (!h2c->settings_ack && !(h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG)) + { + if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, + NGX_HTTP_V2_REFUSED_STREAM) + != NGX_OK) + { + return ngx_http_v2_connection_error(h2c, + NGX_HTTP_V2_INTERNAL_ERROR); + } + + return ngx_http_v2_state_header_block(h2c, pos, end); + } + node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1); if (node == NULL) { @@ -1883,7 +1896,7 @@ ngx_http_v2_state_settings(ngx_http_v2_c return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); } - /* TODO settings acknowledged */ + h2c->settings_ack = 1; return ngx_http_v2_state_complete(h2c, pos, end); } diff -r 640288d0e1bc -r 80d0c9e314f6 src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Tue Apr 12 19:01:56 2016 +0300 +++ b/src/http/v2/ngx_http_v2.h Wed Apr 13 09:37:35 2016 +0300 @@ -141,6 +141,7 @@ struct ngx_http_v2_connection_s { ngx_uint_t last_sid; unsigned closed_nodes:8; + unsigned settings_ack:1; unsigned blocked:1; }; From vbart at nginx.com Wed Apr 13 12:34:13 2016 From: vbart at nginx.com (=?utf-8?B?0JLQsNC70LXQvdGC0LjQvSDQkdCw0YDRgtC10L3QtdCy?=) Date: Wed, 13 Apr 2016 15:34:13 +0300 Subject: 1.9.14 - http2 protocol violations In-Reply-To: <1800487.3hFWtVPpv3@vbart-laptop> References: <1800487.3hFWtVPpv3@vbart-laptop> Message-ID: <2001487.S0cNQDjUy2@vbart-laptop> On Wednesday 13 April 2016 15:30:39 ???????? ???????? wrote: > On Wednesday 13 April 2016 13:54:24 Otto van der Schaaf wrote: > > Sure. > > > > - This sample contains to or three requests, the last request is where rate > > limiting kicks in and the protocol error happens (the earlier requests are > > problem-free): > > https://gist.github.com/oschaaf/281b7a0fed9954dd960adac55e96f2cd > > > > - This is from a post to a non-existant url: > > https://gist.github.com/oschaaf/6396a614ce599d5003e50bb8e7106bed > > > [..] > > Are you sure that you saw this problem while were collecting the logs? > There's nothing suspicious in them, and no errors are reported by nginx > and by the client. > > The only problem that I could see should be fixed by the patch below. > Please try it and let me know if it will help. > > wbr, Valentin V. Bartenev > > > # HG changeset patch > # User Valentin Bartenev > # Date 1460529455 -10800 > # Wed Apr 13 09:37:35 2016 +0300 > # Node ID 80d0c9e314f62b594e634cd9318fe84afc50bb2c > # Parent 640288d0e1bc449a54ac1c85905e6fce780fac7d > HTTP/2: refuse streams with data until SETTINGS is acknowledged. > > A client can start sending data before receiving and acknowledging > the SETTINGS frame, thus having a wrong idea about the stream's > initial window. This can violate flow control. > [..] Sorry, automatic word wrapping broke the patch. Here is another attempt: # HG changeset patch # User Valentin Bartenev # Date 1460529455 -10800 # Wed Apr 13 09:37:35 2016 +0300 # Node ID 80d0c9e314f62b594e634cd9318fe84afc50bb2c # Parent 640288d0e1bc449a54ac1c85905e6fce780fac7d HTTP/2: refuse streams with data until SETTINGS is acknowledged. A client can start sending data before receiving and acknowledging the SETTINGS frame, thus having a wrong idea about the stream's initial window. This can violate flow control. diff -r 640288d0e1bc -r 80d0c9e314f6 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Tue Apr 12 19:01:56 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Wed Apr 13 09:37:35 2016 +0300 @@ -1071,6 +1071,19 @@ ngx_http_v2_state_headers(ngx_http_v2_co return ngx_http_v2_state_header_block(h2c, pos, end); } + if (!h2c->settings_ack && !(h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG)) + { + if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, + NGX_HTTP_V2_REFUSED_STREAM) + != NGX_OK) + { + return ngx_http_v2_connection_error(h2c, + NGX_HTTP_V2_INTERNAL_ERROR); + } + + return ngx_http_v2_state_header_block(h2c, pos, end); + } + node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1); if (node == NULL) { @@ -1883,7 +1896,7 @@ ngx_http_v2_state_settings(ngx_http_v2_c return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); } - /* TODO settings acknowledged */ + h2c->settings_ack = 1; return ngx_http_v2_state_complete(h2c, pos, end); } diff -r 640288d0e1bc -r 80d0c9e314f6 src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Tue Apr 12 19:01:56 2016 +0300 +++ b/src/http/v2/ngx_http_v2.h Wed Apr 13 09:37:35 2016 +0300 @@ -141,6 +141,7 @@ struct ngx_http_v2_connection_s { ngx_uint_t last_sid; unsigned closed_nodes:8; + unsigned settings_ack:1; unsigned blocked:1; }; From oschaaf at we-amp.com Wed Apr 13 12:44:01 2016 From: oschaaf at we-amp.com (Otto van der Schaaf) Date: Wed, 13 Apr 2016 14:44:01 +0200 Subject: 1.9.14 - http2 protocol violations In-Reply-To: <2001487.S0cNQDjUy2@vbart-laptop> References: <1800487.3hFWtVPpv3@vbart-laptop> <2001487.S0cNQDjUy2@vbart-laptop> Message-ID: I'm pretty sure these logs correlate to the problems I am seeing, yes. Indeed the error.log samples are free from warnings and errors, but it seems the protocol is violated nevertheless. At least Chrome says so. So the client does report an error afaict. I'll patch in the change you posted and let you know how that goes, thanks. Otto On Wed, Apr 13, 2016 at 2:34 PM, ???????? ???????? wrote: > On Wednesday 13 April 2016 15:30:39 ???????? ???????? wrote: > > On Wednesday 13 April 2016 13:54:24 Otto van der Schaaf wrote: > > > Sure. > > > > > > - This sample contains to or three requests, the last request is where > rate > > > limiting kicks in and the protocol error happens (the earlier requests > are > > > problem-free): > > > https://gist.github.com/oschaaf/281b7a0fed9954dd960adac55e96f2cd > > > > > > - This is from a post to a non-existant url: > > > https://gist.github.com/oschaaf/6396a614ce599d5003e50bb8e7106bed > > > > > [..] > > > > Are you sure that you saw this problem while were collecting the logs? > > There's nothing suspicious in them, and no errors are reported by nginx > > and by the client. > > > > The only problem that I could see should be fixed by the patch below. > > Please try it and let me know if it will help. > > > > wbr, Valentin V. Bartenev > > > > > > # HG changeset patch > > # User Valentin Bartenev > > # Date 1460529455 -10800 > > # Wed Apr 13 09:37:35 2016 +0300 > > # Node ID 80d0c9e314f62b594e634cd9318fe84afc50bb2c > > # Parent 640288d0e1bc449a54ac1c85905e6fce780fac7d > > HTTP/2: refuse streams with data until SETTINGS is acknowledged. > > > > A client can start sending data before receiving and acknowledging > > the SETTINGS frame, thus having a wrong idea about the stream's > > initial window. This can violate flow control. > > > [..] > > Sorry, automatic word wrapping broke the patch. > > Here is another attempt: > > # HG changeset patch > # User Valentin Bartenev > # Date 1460529455 -10800 > # Wed Apr 13 09:37:35 2016 +0300 > # Node ID 80d0c9e314f62b594e634cd9318fe84afc50bb2c > # Parent 640288d0e1bc449a54ac1c85905e6fce780fac7d > HTTP/2: refuse streams with data until SETTINGS is acknowledged. > > A client can start sending data before receiving and acknowledging > the SETTINGS frame, thus having a wrong idea about the stream's > initial window. This can violate flow control. > > diff -r 640288d0e1bc -r 80d0c9e314f6 src/http/v2/ngx_http_v2.c > --- a/src/http/v2/ngx_http_v2.c Tue Apr 12 19:01:56 2016 +0300 > +++ b/src/http/v2/ngx_http_v2.c Wed Apr 13 09:37:35 2016 +0300 > @@ -1071,6 +1071,19 @@ ngx_http_v2_state_headers(ngx_http_v2_co > return ngx_http_v2_state_header_block(h2c, pos, end); > } > > + if (!h2c->settings_ack && !(h2c->state.flags & > NGX_HTTP_V2_END_STREAM_FLAG)) > + { > + if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, > + NGX_HTTP_V2_REFUSED_STREAM) > + != NGX_OK) > + { > + return ngx_http_v2_connection_error(h2c, > + > NGX_HTTP_V2_INTERNAL_ERROR); > + } > + > + return ngx_http_v2_state_header_block(h2c, pos, end); > + } > + > node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1); > > if (node == NULL) { > @@ -1883,7 +1896,7 @@ ngx_http_v2_state_settings(ngx_http_v2_c > return ngx_http_v2_connection_error(h2c, > NGX_HTTP_V2_SIZE_ERROR); > } > > - /* TODO settings acknowledged */ > + h2c->settings_ack = 1; > > return ngx_http_v2_state_complete(h2c, pos, end); > } > diff -r 640288d0e1bc -r 80d0c9e314f6 src/http/v2/ngx_http_v2.h > --- a/src/http/v2/ngx_http_v2.h Tue Apr 12 19:01:56 2016 +0300 > +++ b/src/http/v2/ngx_http_v2.h Wed Apr 13 09:37:35 2016 +0300 > @@ -141,6 +141,7 @@ struct ngx_http_v2_connection_s { > ngx_uint_t last_sid; > > unsigned closed_nodes:8; > + unsigned settings_ack:1; > unsigned blocked:1; > }; > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From oschaaf at we-amp.com Wed Apr 13 13:08:29 2016 From: oschaaf at we-amp.com (Otto van der Schaaf) Date: Wed, 13 Apr 2016 15:08:29 +0200 Subject: 1.9.14 - http2 protocol violations In-Reply-To: References: <1800487.3hFWtVPpv3@vbart-laptop> <2001487.S0cNQDjUy2@vbart-laptop> Message-ID: I'm sorry to say that the patch does not make a difference. I collected Chrome's http/2 trace for a post to a non-existant url: https://gist.github.com/oschaaf/da273f96fad5e22890981fcd4a1a4376 I'm wondering about that last HTTP2_SESSION_RST_STREAM entry.. it looks like the httpv2 mod wants to cancel the incoming post data stream at an odd point in time? But I'm no expert, so I'm not sure at all. Otto On Wed, Apr 13, 2016 at 2:44 PM, Otto van der Schaaf wrote: > I'm pretty sure these logs correlate to the problems I am seeing, yes. > Indeed the error.log samples are free from warnings and errors, but it > seems the protocol is violated nevertheless. At least Chrome says so. So > the client does report an error afaict. > I'll patch in the change you posted and let you know how that goes, thanks. > > Otto > > On Wed, Apr 13, 2016 at 2:34 PM, ???????? ???????? > wrote: > >> On Wednesday 13 April 2016 15:30:39 ???????? ???????? wrote: >> > On Wednesday 13 April 2016 13:54:24 Otto van der Schaaf wrote: >> > > Sure. >> > > >> > > - This sample contains to or three requests, the last request is >> where rate >> > > limiting kicks in and the protocol error happens (the earlier >> requests are >> > > problem-free): >> > > https://gist.github.com/oschaaf/281b7a0fed9954dd960adac55e96f2cd >> > > >> > > - This is from a post to a non-existant url: >> > > https://gist.github.com/oschaaf/6396a614ce599d5003e50bb8e7106bed >> > > >> > [..] >> > >> > Are you sure that you saw this problem while were collecting the logs? >> > There's nothing suspicious in them, and no errors are reported by nginx >> > and by the client. >> > >> > The only problem that I could see should be fixed by the patch below. >> > Please try it and let me know if it will help. >> > >> > wbr, Valentin V. Bartenev >> > >> > >> > # HG changeset patch >> > # User Valentin Bartenev >> > # Date 1460529455 -10800 >> > # Wed Apr 13 09:37:35 2016 +0300 >> > # Node ID 80d0c9e314f62b594e634cd9318fe84afc50bb2c >> > # Parent 640288d0e1bc449a54ac1c85905e6fce780fac7d >> > HTTP/2: refuse streams with data until SETTINGS is acknowledged. >> > >> > A client can start sending data before receiving and acknowledging >> > the SETTINGS frame, thus having a wrong idea about the stream's >> > initial window. This can violate flow control. >> > >> [..] >> >> Sorry, automatic word wrapping broke the patch. >> >> Here is another attempt: >> >> # HG changeset patch >> # User Valentin Bartenev >> # Date 1460529455 -10800 >> # Wed Apr 13 09:37:35 2016 +0300 >> # Node ID 80d0c9e314f62b594e634cd9318fe84afc50bb2c >> # Parent 640288d0e1bc449a54ac1c85905e6fce780fac7d >> HTTP/2: refuse streams with data until SETTINGS is acknowledged. >> >> A client can start sending data before receiving and acknowledging >> the SETTINGS frame, thus having a wrong idea about the stream's >> initial window. This can violate flow control. >> >> diff -r 640288d0e1bc -r 80d0c9e314f6 src/http/v2/ngx_http_v2.c >> --- a/src/http/v2/ngx_http_v2.c Tue Apr 12 19:01:56 2016 +0300 >> +++ b/src/http/v2/ngx_http_v2.c Wed Apr 13 09:37:35 2016 +0300 >> @@ -1071,6 +1071,19 @@ ngx_http_v2_state_headers(ngx_http_v2_co >> return ngx_http_v2_state_header_block(h2c, pos, end); >> } >> >> + if (!h2c->settings_ack && !(h2c->state.flags & >> NGX_HTTP_V2_END_STREAM_FLAG)) >> + { >> + if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, >> + NGX_HTTP_V2_REFUSED_STREAM) >> + != NGX_OK) >> + { >> + return ngx_http_v2_connection_error(h2c, >> + >> NGX_HTTP_V2_INTERNAL_ERROR); >> + } >> + >> + return ngx_http_v2_state_header_block(h2c, pos, end); >> + } >> + >> node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1); >> >> if (node == NULL) { >> @@ -1883,7 +1896,7 @@ ngx_http_v2_state_settings(ngx_http_v2_c >> return ngx_http_v2_connection_error(h2c, >> NGX_HTTP_V2_SIZE_ERROR); >> } >> >> - /* TODO settings acknowledged */ >> + h2c->settings_ack = 1; >> >> return ngx_http_v2_state_complete(h2c, pos, end); >> } >> diff -r 640288d0e1bc -r 80d0c9e314f6 src/http/v2/ngx_http_v2.h >> --- a/src/http/v2/ngx_http_v2.h Tue Apr 12 19:01:56 2016 +0300 >> +++ b/src/http/v2/ngx_http_v2.h Wed Apr 13 09:37:35 2016 +0300 >> @@ -141,6 +141,7 @@ struct ngx_http_v2_connection_s { >> ngx_uint_t last_sid; >> >> unsigned closed_nodes:8; >> + unsigned settings_ack:1; >> unsigned blocked:1; >> }; >> >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Wed Apr 13 15:00:26 2016 From: vbart at nginx.com (=?utf-8?B?0JLQsNC70LXQvdGC0LjQvSDQkdCw0YDRgtC10L3QtdCy?=) Date: Wed, 13 Apr 2016 18:00:26 +0300 Subject: 1.9.14 - http2 protocol violations In-Reply-To: References: Message-ID: <2066226.e0z408FIE7@vbart-laptop> On Wednesday 13 April 2016 15:08:29 Otto van der Schaaf wrote: > I'm sorry to say that the patch does not make a difference. > > I collected Chrome's http/2 trace for a post to a non-existant url: > https://gist.github.com/oschaaf/da273f96fad5e22890981fcd4a1a4376 > > I'm wondering about that last HTTP2_SESSION_RST_STREAM entry.. it looks > like > the httpv2 mod wants to cancel the incoming post data stream at an odd > point in time? > But I'm no expert, so I'm not sure at all. > [..] I was able to capture quite the same Chrome trace with the actual bytes sent/received and this last RST_STREAM entry with status 6 (which is FRAME_SIZE_ERROR) looks really strange. It isn't presented in nginx debug log (nginx hasn't sent, nor has received it). Moreover, the actual bytes sent/received trace, that you can get from Chrome if you set the "Include the actual bytes sent/received." flag in chrome://net-internals/#capture), doesn't contain it either. The trace (and nginx log) contains RST_STREAM sent by nginx with status 0 (NO_ERROR), which is correct: t= 94141 [st= 6088] SSL_SOCKET_BYTES_RECEIVED --> byte_count = 13 --> hex_encoded_bytes = 00 00 04 03 00 00 00 00 03 00 00 00 00 As you can see it has 4 bytes length, type 3, flags 0, stream id 3 and error code 0. +-----------------------------------------------+ | Length (24) | +---------------+---------------+---------------+ | Type (8) | Flags (8) | +-+-------------+---------------+-------------------------------+ |R| Stream Identifier (31) | +=+=============================================================+ | Frame Payload (0...) ... +---------------------------------------------------------------+ Figure 1: Frame Layout https://tools.ietf.org/html/rfc7540#section-4.1 +---------------------------------------------------------------+ | Error Code (32) | +---------------------------------------------------------------+ Figure 9: RST_STREAM Frame Payload https://tools.ietf.org/html/rfc7540#section-6.4 I've attached the full trace. Maybe I missed something, but after manual decoding bytes I don't see any problems with the frame sizes received from nginx. However, that can be a result of this change: http://hg.nginx.org/nginx/rev/92464ebace8e Firefox perfectly fine with it. It looks like the problem in Chrome. wbr, Valentin V. Bartenev -------------- next part -------------- 12281: SOCKET ssl/localhost:4433 Start Time: 2016-04-13 16:57:18.765 t= 88053 [st= 0] +SOCKET_ALIVE [dt=16927] --> source_dependency = 12280 (CONNECT_JOB) t= 88053 [st= 0] +TCP_CONNECT [dt=0] --> address_list = ["[::1]:4433","127.0.0.1:4433"] t= 88053 [st= 0] +TCP_CONNECT_ATTEMPT [dt=0] --> address = "[::1]:4433" t= 88053 [st= 0] -TCP_CONNECT_ATTEMPT --> os_error = 111 t= 88053 [st= 0] TCP_CONNECT_ATTEMPT [dt=0] --> address = "127.0.0.1:4433" t= 88053 [st= 0] -TCP_CONNECT --> source_address = "127.0.0.1:35904" t= 88053 [st= 0] +SOCKET_IN_USE [dt=16927] --> source_dependency = 12279 (CONNECT_JOB) t= 88053 [st= 0] +SSL_CONNECT [dt=3] t= 88053 [st= 0] SOCKET_BYTES_SENT --> byte_count = 517 --> hex_encoded_bytes = 16 03 01 02 00 01 00 01 FC 03 03 DC 52 24 92 CC .... . .....R$.. F0 24 33 1A 45 CA DA 1A A7 80 90 92 DB 9F 31 15 .$3.E.........1. F8 BC B4 F9 43 6D 3F 77 79 74 AC 20 B4 EE 6A D6 ....Cm?wyt. ..j. D1 DB 99 40 9B A0 A8 D4 F3 13 46 D3 05 69 0E AB ... at ......F..i.. BF 04 D3 A2 48 88 0A B5 46 3D 42 2B 00 1C C0 2B ....H...F=B+ ..+ C0 2F CC A9 CC A8 CC 14 CC 13 C0 0A C0 14 C0 09 ./.............. C0 13 00 9C 00 35 00 2F 00 0A 01 00 01 97 FF 01 .. . 5 / .. .... 00 01 00 00 00 00 0E 00 0C 00 00 09 6C 6F 63 61 . . . .loca 6C 68 6F 73 74 00 17 00 00 00 23 00 C0 FE CA E1 lhost . # .... 59 34 4A 05 54 33 8D 42 56 A8 48 6F DA BD 35 CE Y4J.T3.BV.Ho..5. 95 31 B2 48 70 74 CC 54 04 E8 B4 56 AF 91 29 12 .1.Hpt.T...V..). 84 26 4A BF 80 A5 80 B0 E7 B3 53 7D F1 68 4B CC .&J.......S}.hK. BD AF 0D 18 B8 5F A4 0F AB 5C 10 E6 71 2F A5 84 ....._...\..q/.. 4E EE 88 0C 94 BA 1C 53 6D 60 A6 22 F4 52 16 B7 N......Sm`.".R.. A3 19 42 4A B4 1C DC 90 9F AD 0B FF 92 48 80 23 ..BJ.........H.# F4 4F B4 15 99 47 AB E5 07 D4 87 43 CE CE AD 2C .O...G.....C..., 0F 36 BA AC 17 D5 47 87 A8 2E D9 EE B8 0F 2A 28 .6....G.......*( E7 5B EB BA B8 03 5B 26 D1 E8 79 8E A5 C3 9D F6 .[....[&..y..... 59 18 CD B2 99 28 CC F3 92 99 1B F8 23 EE 08 53 Y....(......#..S 95 91 14 17 31 58 18 AF 76 9F DF 5E 2C D6 80 70 ....1X..v..^,..p 1B B9 5C 9D 2F 39 A0 57 FF 2A 71 30 CB 00 0D 00 ..\./9.W.*q0. . 12 00 10 06 01 06 03 05 01 05 03 04 01 04 03 02 . .............. 01 02 03 00 05 00 05 01 00 00 00 00 33 74 00 00 ... . .. 3t 00 12 00 00 00 10 00 17 00 15 02 68 32 08 73 70 . . . ..h2.sp 64 79 2F 33 2E 31 08 68 74 74 70 2F 31 2E 31 75 dy/3.1.http/1.1u 50 00 00 00 0B 00 02 01 00 00 0A 00 08 00 06 00 P . .. . . . 1D 00 17 00 18 00 15 00 5C 00 00 00 00 00 00 00 . . . . \ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 t= 88055 [st= 2] SOCKET_BYTES_RECEIVED --> byte_count = 1424 --> hex_encoded_bytes = 16 03 03 00 46 02 00 00 42 03 03 8B F4 98 E8 61 ... F. B......a C4 2A 95 2D E7 4C B8 74 07 78 4A 46 32 27 2D 03 .*.-.L.t.xJF2'-. 97 BF 0C D4 45 7E 4F 12 9E 28 D4 00 C0 2F 00 00 ....E~O..(. ./ 1A FF 01 00 01 00 00 0B 00 04 03 00 01 02 00 23 ... . . .. .. # 00 00 00 10 00 05 00 03 02 68 32 16 03 03 03 E5 . . ..h2..... 0B 00 03 E1 00 03 DE 00 03 DB 30 82 03 D7 30 82 . .. .. ..0...0. 02 BF A0 03 02 01 02 02 09 00 8B C3 CE F0 49 36 ......... ....I6 14 63 30 0D 06 09 2A 86 48 86 F7 0D 01 01 0B 05 .c0...*.H....... 00 30 81 81 31 0B 30 09 06 03 55 04 06 13 02 52 0..1.0...U....R 55 31 0F 30 0D 06 03 55 04 08 0C 06 4D 6F 73 63 U1.0...U....Mosc 6F 77 31 0F 30 0D 06 03 55 04 07 0C 06 4D 6F 73 ow1.0...U....Mos 63 6F 77 31 14 30 12 06 03 55 04 0A 0C 0B 4E 47 cow1.0...U....NG 49 4E 58 2C 20 49 6E 63 2E 31 1A 30 18 06 03 55 INX, Inc.1.0...U 04 03 0C 11 56 61 6C 65 6E 74 69 6E 20 42 61 72 ....Valentin Bar 74 65 6E 65 76 31 1E 30 1C 06 09 2A 86 48 86 F7 tenev1.0...*.H.. 0D 01 09 01 16 0F 76 62 61 72 74 40 6E 67 69 6E ......vbart at ngin 78 2E 63 6F 6D 30 1E 17 0D 31 36 30 34 31 32 32 x.com0...1604122 32 32 33 31 36 5A 17 0D 31 39 30 31 33 31 32 32 22316Z..19013122 32 33 31 36 5A 30 81 81 31 0B 30 09 06 03 55 04 2316Z0..1.0...U. 06 13 02 52 55 31 0F 30 0D 06 03 55 04 08 0C 06 ...RU1.0...U.... 4D 6F 73 63 6F 77 31 0F 30 0D 06 03 55 04 07 0C Moscow1.0...U... 06 4D 6F 73 63 6F 77 31 14 30 12 06 03 55 04 0A .Moscow1.0...U.. 0C 0B 4E 47 49 4E 58 2C 20 49 6E 63 2E 31 1A 30 ..NGINX, Inc.1.0 18 06 03 55 04 03 0C 11 56 61 6C 65 6E 74 69 6E ...U....Valentin 20 42 61 72 74 65 6E 65 76 31 1E 30 1C 06 09 2A Bartenev1.0...* 86 48 86 F7 0D 01 09 01 16 0F 76 62 61 72 74 40 .H........vbart@ 6E 67 69 6E 78 2E 63 6F 6D 30 82 01 22 30 0D 06 nginx.com0.."0.. 09 2A 86 48 86 F7 0D 01 01 01 05 00 03 82 01 0F .*.H....... .... 00 30 82 01 0A 02 82 01 01 00 C9 B4 98 DD 80 B8 0....... ...... 7C EB 6C 46 80 1D 92 F8 EA 3A 72 8E 7D EE 5C 8D |.lF.....:r.}.\. 63 54 C0 9E 5C 1A 66 F1 6A 43 4A 81 75 26 61 44 cT..\.f.jCJ.u&aD A0 9E 3F EC 2C CE 02 2A 86 6B C2 1D EF 53 BA 37 ..?.,..*.k...S.7 0D 55 00 1D AF F3 2F 5E 30 76 CE F8 6A C9 3B 24 .U .../^0v..j.;$ 4C EF D9 C9 0A 75 5F E2 0C 07 22 F3 6A 14 80 D7 L....u_...".j... 0A 00 BC 78 B0 5B 99 54 0A AA 30 37 1D 81 75 AC . .x.[.T..07..u. 47 9F E6 AE 87 C8 ED D8 DB 46 47 7E 14 80 80 8E G........FG~.... 27 4D 38 C1 0D 3A EF 9B DF 6F AE FC D4 AC 18 58 'M8..:...o.....X AB 33 F9 12 7B B2 A0 D7 66 9C D3 FF 63 B1 B7 91 .3..{...f...c... D5 D9 C2 1F 6B 8E 9C 99 95 39 3C 59 7B 19 D3 5F ....k....9z.....O<. DA EB B0 29 46 7A C5 C4 4A EA 4D 50 B9 A4 FE 27 ...)Fz..J.MP...' 76 80 09 31 AF 29 C9 FA 22 02 8F 5A EC DB 8F 03 v..1.).."..Z.... 8D 72 9B 75 6F 16 03 03 01 4D 0C 00 01 49 03 00 .r.uo....M. .I. 17 41 04 2F 61 D4 A3 F1 8C 6E 68 50 0F B5 21 32 .A./a....nhP..!2 5C 83 4D F5 B4 0E DF 8C 79 49 E4 89 06 AE 91 85 \.M.....yI...... 06 4A 3C B3 3F D2 62 D6 0F C5 C7 61 78 3C AD BC .J<.?.b....ax<.. 5D D5 A6 3D A9 E0 1C 37 79 91 28 02 53 C9 88 17 ]..=...7y.(.S... 13 6A 30 06 01 01 00 BA 7F 1E 2C 1C B0 D8 BA 4F .j0... ...,....O 1F 3A 60 71 EB E5 B8 0F A8 79 39 3A 9E E1 A6 6D .:`q.....y9:...m F0 DD 55 9F C4 2C 12 BB C0 C0 92 0F B0 C2 09 07 ..U..,.......... 28 7A 0E 4A 55 34 92 99 B4 B4 28 53 3C F7 83 9A (z.JU4....(S<... 89 07 3E 98 37 86 06 A5 44 E6 6C F7 2C 77 D6 37 ..>.7...D.l.,w.7 22 42 FA 6D AD 1E 9F BA 4A 19 E2 85 B2 AE 30 AC "B.m....J.....0. DE 95 3C 94 7B A9 33 8C 67 D2 C3 AE AC 66 9F C9 ..<.{.3.g....f.. CD BE 33 9B 05 43 81 D4 4C 8A 5D DB 5B 57 12 14 ..3..C..L.].[W.. 4F C3 5C 48 C7 01 23 8A 51 44 69 E6 06 72 30 2F O.\H..#.QDi..r0/ 35 29 88 53 7D F5 9B 54 6A 61 46 E3 F1 CA BE 76 5).S}..TjaF....v C3 FE 9F CE CD 20 96 37 62 1E A0 DD 98 27 CB 0C ..... .7b....'.. B0 F9 AB E0 C7 32 C7 37 8F A1 B5 A8 5E D9 75 E0 .....2.7....^.u. 5A AD 95 60 FF 5D CD 4D 2C D5 D5 15 FF 52 79 B5 Z..`.].M,....Ry. 7D DB 57 7E 50 BB 67 FB 28 0C C2 24 A3 C4 3F D4 }.W~P.g.(..$..?. 80 16 31 1F F7 2B 2D BC 48 7C 55 B5 B4 C9 58 E4 ..1..+-.H|U...X. 10 5A 07 50 CC 4B 8C 46 04 03 A5 25 9F 37 DC 56 .Z.P.K.F...%.7.V 88 56 E5 4E B6 39 95 16 03 03 00 04 0E 00 00 00 .V.N.9.... .. t= 88056 [st= 3] SOCKET_BYTES_SENT --> byte_count = 126 --> hex_encoded_bytes = 16 03 03 00 46 10 00 00 42 41 04 64 F2 D0 42 7B ... F. BA.d..B{ F0 21 4A 39 F7 D5 55 F1 E9 A3 F2 34 A7 34 58 E9 .!J9..U....4.4X. B2 22 B3 96 71 61 B3 B9 07 0C 04 AA 01 1A 0C D6 ."..qa.......... 2E 70 1C CF 85 8B 1A 93 1F C4 0E 1D 89 62 38 8B .p...........b8. 73 C2 8B 35 63 F6 15 9C B7 F0 1A 14 03 03 00 01 s..5c......... . 01 16 03 03 00 28 00 00 00 00 00 00 00 00 C9 A1 .... ( .. 8B 95 F0 85 50 F5 AA E6 31 E8 44 C6 19 FC 99 34 ....P...1.D....4 CE AD 5C FE AA 3E 18 F7 E2 41 9C A8 6B 57 ..\..>...A..kW t= 88056 [st= 3] SSL_CERTIFICATES_RECEIVED --> certificates = -----BEGIN CERTIFICATE----- MIID1zCCAr+gAwIBAgIJAIvDzvBJNhRjMA0GCSqGSIb3DQEBCwUAMIGBMQswCQYD VQQGEwJSVTEPMA0GA1UECAwGTW9zY293MQ8wDQYDVQQHDAZNb3Njb3cxFDASBgNV BAoMC05HSU5YLCBJbmMuMRowGAYDVQQDDBFWYWxlbnRpbiBCYXJ0ZW5ldjEeMBwG CSqGSIb3DQEJARYPdmJhcnRAbmdpbnguY29tMB4XDTE2MDQxMjIyMjMxNloXDTE5 MDEzMTIyMjMxNlowgYExCzAJBgNVBAYTAlJVMQ8wDQYDVQQIDAZNb3Njb3cxDzAN BgNVBAcMBk1vc2NvdzEUMBIGA1UECgwLTkdJTlgsIEluYy4xGjAYBgNVBAMMEVZh bGVudGluIEJhcnRlbmV2MR4wHAYJKoZIhvcNAQkBFg92YmFydEBuZ2lueC5jb20w ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJtJjdgLh862xGgB2S+Oo6 co597lyNY1TAnlwaZvFqQ0qBdSZhRKCeP+wszgIqhmvCHe9TujcNVQAdr/MvXjB2 zvhqyTskTO/ZyQp1X+IMByLzahSA1woAvHiwW5lUCqowNx2BdaxHn+auh8jt2NtG R34UgICOJ004wQ0675vfb6781KwYWKsz+RJ7sqDXZpzT/2Oxt5HV2cIfa46cmZU5 PFl7GdNfYETuLYfwnlqulQraEMN0iatMGA8ruhU9WArdZcUOqamxzY2mbeED+74C niT1uwYIGidKg2ErWO1mUTl0yJo/EcwUHVqTTCorzTxcw2a5G4/wJqyh3tOvGOYJ AgMBAAGjUDBOMB0GA1UdDgQWBBTmyGy5oUlcpQ5qnrPA22AvPBfRlTAfBgNVHSME GDAWgBTmyGy5oUlcpQ5qnrPA22AvPBfRlTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBCwUAA4IBAQCoqNvtVQ49Br3XI98wx4VOXk0OXNxVveq1Q05mGIG4+8ZNDkWF JkGL9yYWAV26fyOav/Ue+1jHkC6wRI8LXg7pwMOYtXusbd7sr4aH700Xr5Saqmru msJactPKDpLoDEqrJ8afhqY2yAXTdpwkhgFBehq7fFm0+AYVW3nYSxHMMIIpbuqY r9BMp8mH4VRksY74r8GrqRqh8YrVOpSr3rrg5/9VKg/pxFFnqdv7PHrF+OI89ETh FhJglSOzitpTEbEURtq3TuFY2MuixWGV2NL0yz56DcjIF4lPPLva67ApRnrFxErq TVC5pP4ndoAJMa8pyfoiAo9a7NuPA41ym3Vv -----END CERTIFICATE----- t= 88056 [st= 3] SIGNED_CERTIFICATE_TIMESTAMPS_RECEIVED --> embedded_scts = "" --> scts_from_ocsp_response = "" --> scts_from_tls_extension = "" t= 88056 [st= 3] SIGNED_CERTIFICATE_TIMESTAMPS_CHECKED --> invalid_scts = [] --> unknown_logs_scts = [] --> verified_scts = [] t= 88056 [st= 3] CERT_CT_COMPLIANCE_CHECKED --> build_timely = true --> certificate = {"certificates":["-----BEGIN CERTIFICATE-----\nMIID1zCCAr+gAwIBAgIJAIvDzvBJNhRjMA0GCSqGSIb3DQEBCwUAMIGBMQswCQYD\nVQQGEwJSVTEPMA0GA1UECAwGTW9zY293MQ8wDQYDVQQHDAZNb3Njb3cxFDASBgNV\nBAoMC05HSU5YLCBJbmMuMRowGAYDVQQDDBFWYWxlbnRpbiBCYXJ0ZW5ldjEeMBwG\nCSqGSIb3DQEJARYPdmJhcnRAbmdpbnguY29tMB4XDTE2MDQxMjIyMjMxNloXDTE5\nMDEzMTIyMjMxNlowgYExCzAJBgNVBAYTAlJVMQ8wDQYDVQQIDAZNb3Njb3cxDzAN\nBgNVBAcMBk1vc2NvdzEUMBIGA1UECgwLTkdJTlgsIEluYy4xGjAYBgNVBAMMEVZh\nbGVudGluIEJhcnRlbmV2MR4wHAYJKoZIhvcNAQkBFg92YmFydEBuZ2lueC5jb20w\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJtJjdgLh862xGgB2S+Oo6\nco597lyNY1TAnlwaZvFqQ0qBdSZhRKCeP+wszgIqhmvCHe9TujcNVQAdr/MvXjB2\nzvhqyTskTO/ZyQp1X+IMByLzahSA1woAvHiwW5lUCqowNx2BdaxHn+auh8jt2NtG\nR34UgICOJ004wQ0675vfb6781KwYWKsz+RJ7sqDXZpzT/2Oxt5HV2cIfa46cmZU5\nPFl7GdNfYETuLYfwnlqulQraEMN0iatMGA8ruhU9WArdZcUOqamxzY2mbeED+74C\nniT1uwYIGidKg2ErWO1mUTl0yJo/EcwUHVqTTCorzTxcw2a5G4/wJqyh3tOvGOYJ\nAgMBAAGjUDBOMB0GA1UdDgQWBBTmyGy5oUlcpQ5qnrPA22AvPBfRlTAfBgNVHSME\nGDAWgBTmyGy5oUlcpQ5qnrPA22AvPBfRlTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3\nDQEBCwUAA4IBAQCoqNvtVQ49Br3XI98wx4VOXk0OXNxVveq1Q05mGIG4+8ZNDkWF\nJkGL9yYWAV26fyOav/Ue+1jHkC6wRI8LXg7pwMOYtXusbd7sr4aH700Xr5Saqmru\nmsJactPKDpLoDEqrJ8afhqY2yAXTdpwkhgFBehq7fFm0+AYVW3nYSxHMMIIpbuqY\nr9BMp8mH4VRksY74r8GrqRqh8YrVOpSr3rrg5/9VKg/pxFFnqdv7PHrF+OI89ETh\nFhJglSOzitpTEbEURtq3TuFY2MuixWGV2NL0yz56DcjIF4lPPLva67ApRnrFxErq\nTVC5pP4ndoAJMa8pyfoiAo9a7NuPA41ym3Vv\n-----END CERTIFICATE-----\n"]} --> ct_compliance_status = "NOT_ENOUGH_SCTS" t= 88056 [st= 3] -SSL_CONNECT t= 88056 [st= 3] +SOCKET_IN_USE [dt=16924] --> source_dependency = 12278 (HTTP_STREAM_JOB) t= 88056 [st= 3] SSL_SOCKET_BYTES_SENT --> byte_count = 24 --> hex_encoded_bytes = 50 52 49 20 2A 20 48 54 54 50 2F 32 2E 30 0D 0A PRI * HTTP/2.0.. 0D 0A 53 4D 0D 0A 0D 0A ..SM.... t= 88056 [st= 3] SOCKET_BYTES_SENT --> byte_count = 53 --> hex_encoded_bytes = 17 03 03 00 30 00 00 00 00 00 00 00 01 56 ED B4 ... 0 .V.. 2D A8 BD B2 71 1B 6C D2 36 C6 70 0F AE 5B E1 63 -...q.l.6.p..[.c 12 29 73 31 6A 92 7A ED 49 B5 FE 6A 4B 07 55 CB .)s1j.z.I..jK.U. C4 CE 9D 4C D0 ...L. t= 88056 [st= 3] SSL_SOCKET_BYTES_SENT --> byte_count = 21 --> hex_encoded_bytes = 00 00 0C 04 00 00 00 00 00 00 03 00 00 03 E8 00 .. . .. 04 00 60 00 00 . ` t= 88056 [st= 3] SOCKET_BYTES_SENT --> byte_count = 50 --> hex_encoded_bytes = 17 03 03 00 2D 00 00 00 00 00 00 00 02 FF B8 6A ... - ...j D8 67 FE A6 4E CF 4B 91 A3 40 23 1D 2D EE 3D 95 .g..N.K..@#.-.=. 6A 84 EE E7 F2 81 39 99 2A ED 1A 89 5B B2 AB 66 j.....9.*...[..f 2D 3C -< t= 88056 [st= 3] SSL_SOCKET_BYTES_SENT --> byte_count = 13 --> hex_encoded_bytes = 00 00 04 08 00 00 00 00 00 00 EF 00 01 .. . . t= 88056 [st= 3] SOCKET_BYTES_SENT --> byte_count = 42 --> hex_encoded_bytes = 17 03 03 00 25 00 00 00 00 00 00 00 03 45 9E 84 ... % .E.. 1A 7F 69 47 D8 4E 66 D2 85 26 35 D0 02 56 40 79 ..iG.Nf..&5..V at y F1 88 3B 74 8F FE 78 DC 93 71 ..;t..x..q t= 88056 [st= 3] SOCKET_BYTES_RECEIVED --> byte_count = 327 --> hex_encoded_bytes = 16 03 03 00 CA 04 00 00 C6 00 00 01 2C 00 C0 F3 ... .. . ., .. DC 69 1A 09 E5 A1 E3 D2 78 93 CC 86 48 79 E6 A9 .i......x...Hy.. F0 95 3E B6 82 8E BD 01 5D 2F F5 5F 57 D5 33 16 ..>.....]/._W.3. 18 1F F2 A2 5A 04 3C 1A 20 29 6B 6A 53 79 DF 3C ....Z.<. )kjSy.< 1D A9 08 52 DF 2E A7 0B FF 37 20 BE F0 CC 6D 7C ...R.....7 ...m| 8B 5E 55 CA 9E EC FB 03 10 FB 89 98 D5 7F 04 4C .^U............L F2 95 AC C9 6E EB DB 5B 6E 2F 40 AE 12 D1 BB 72 ....n..[n/@....r 3D 6D E3 A6 D9 9A D7 46 A1 91 A4 B3 0A 11 E0 90 =m.....F........ 3C D8 05 B0 28 90 F8 92 59 FF A0 9B BB 56 E6 90 <...(...Y....V.. AD A9 79 63 3F 92 AA 8C 34 43 B4 7A 0E 94 44 B4 ..yc?...4C.z..D. 5D 44 47 26 D0 73 63 CF 50 E1 97 4A FA FC 9F 72 ]DG&.sc.P..J...r 45 15 F5 A7 A4 44 81 5D FF EC C8 58 90 3B 9D 51 E....D.]...X.;.Q 34 F9 C6 9A D6 63 EB B9 0F CA D9 9B EB BC F1 14 4....c.......... 03 03 00 01 01 16 03 03 00 28 A0 35 17 C1 DD 34 .. ..... (.5...4 B4 4D 53 14 37 7B FC CD 23 AC C9 57 06 9A 62 ED .MS.7{..#..W..b. A2 A1 39 3A 79 6C 31 97 95 BC 5D 8A 56 39 E4 01 ..9:yl1...].V9.. 12 0E 17 03 03 00 40 A0 35 17 C1 DD 34 B4 4E 6F ..... @.5...4.No 6E 51 3E 7F 02 73 FF 27 3E 00 11 D3 20 71 60 28 nQ>..s.'> .. q`( 57 2C C2 8E 8B 8C 08 EE C0 E3 C2 2E 92 D0 7B ED W,............{. 5C A8 15 00 C9 B5 B4 1E BC 57 1B 03 C5 67 F6 60 \.. .....W...g.` 9B 5F 58 ED 89 48 BD ._X..H. t= 88056 [st= 3] SSL_SOCKET_BYTES_RECEIVED --> byte_count = 40 --> hex_encoded_bytes = 00 00 12 04 00 00 00 00 00 00 03 00 00 00 80 00 .. . . 04 00 00 00 00 00 05 00 FF FF FF 00 00 04 08 00 . . ... .. 00 00 00 00 7F FF 00 00 .. t= 88057 [st= 4] SOCKET_BYTES_RECEIVED --> byte_count = 38 --> hex_encoded_bytes = 17 03 03 00 21 A0 35 17 C1 DD 34 B4 4F 64 93 CE ... !.5...4.Od.. 97 3D A1 F8 56 1F 4E 0F 8C 9B 91 7B BD 68 D4 32 .=..V.N....{.h.2 E9 5C 86 2C 4F 4D .\.,OM t= 88057 [st= 4] SSL_SOCKET_BYTES_RECEIVED --> byte_count = 9 --> hex_encoded_bytes = 00 00 00 04 01 00 00 00 00 .. t= 88057 [st= 4] SSL_SOCKET_BYTES_SENT --> byte_count = 9 --> hex_encoded_bytes = 00 00 00 04 01 00 00 00 00 .. t= 88057 [st= 4] SOCKET_BYTES_SENT --> byte_count = 38 --> hex_encoded_bytes = 17 03 03 00 21 00 00 00 00 00 00 00 04 A6 3E 58 ... ! ..>X 3B 7B D3 B3 3D A2 D3 1C 86 E2 9A EC 62 CF 30 07 ;{..=.......b.0. 1E 67 B0 69 66 E8 .g.if. t= 88057 [st= 4] SSL_SOCKET_BYTES_SENT --> byte_count = 242 --> hex_encoded_bytes = 00 00 E9 01 25 00 00 00 01 80 00 00 00 FF 82 41 ..% .. ..A 8A A0 E4 1D 13 9D 09 B8 D3 4C B3 87 00 84 B9 58 .........L.. ..X D3 3F 87 62 B3 A1 2B CE 9A 68 58 87 A4 7E 56 1C .?.b..+..hX..~V. C5 80 1F 53 B8 49 7C A5 89 D3 4D 1F 43 AE BA 0C ...S.I|...M.C... 41 A4 C7 A9 8F 33 A6 9A 3F DF 9A 68 FA 1D 75 D0 A....3..?..h..u. 62 0D 26 3D 4C 79 A6 8F BE D0 01 77 FE 8D 48 E6 b.&=Ly.....w..H. 2B 1E 0B 1D 7F 5F 2C 7C FD F6 80 0B BD 40 92 B6 +...._,|..... at .. B9 AC 1C 85 58 D5 20 A4 B6 C2 AD 61 7B 5A 54 25 ....X. ....a{ZT% 1F 01 31 7A D0 D0 7F 66 A2 81 B0 DA E0 53 FA FC ..1z...f.....S.. 08 7E D4 CE 6A AD F2 A7 97 9C 89 C6 BF B5 21 AE .~..j.........!. BA 0B C8 B1 E6 32 58 6D 97 57 65 C5 3F AC D8 F7 .....2Xm.We.?... E8 CF F4 A5 06 EA 55 31 14 9D 4F FD A9 7A 7B 0F ......U1..O..z{. 49 58 6C 0B 81 71 38 E0 57 71 C5 37 0E 51 D8 66 IXl..q8.Wq.7.Q.f 1B 65 D5 D9 73 50 8E 9B D9 AB FA 52 42 CB 40 D2 .e..sP.....RB. at . 5F A5 11 21 27 51 8B 2D 4B 70 DD F4 5A BE FB 40 _..!'Q.-Kp..Z..@ 05 DE .. t= 88057 [st= 4] SOCKET_BYTES_SENT --> byte_count = 271 --> hex_encoded_bytes = 17 03 03 01 0A 00 00 00 00 00 00 00 05 91 56 CE ..... ..V. 02 21 35 DA 9E A3 99 70 3C FA 41 E0 B2 31 39 0F .!5....p<.A..19. E8 0A 59 29 35 40 D9 66 A5 E4 63 9F DA ED 77 CC ..Y)5 at .f..c...w. 3B 42 56 CB 22 84 6E 5F 92 3B 45 FD 0A AC 6F 8D ;BV.".n_.;E...o. 86 47 AA 76 F8 1C A7 D7 1C 2B 5C 76 12 F5 2F 7A .G.v.....+\v../z EA 6F 36 5E F0 CC B5 F7 E9 0E 31 71 6E 7D C7 4F .o6^......1qn}.O 1C 88 28 6D 6D 16 7C 2F CF 17 A8 18 01 6E 3C F8 ..(mm.|/.....n<. 68 7E D4 83 F6 C2 FE 58 0F 9F C9 67 B2 3B 24 D7 h~.....X...g.;$. 2D 6E C4 02 89 F2 EC E2 F2 28 B3 CD D6 FE C7 5A -n.......(.....Z 9D F2 76 EF 76 EE 22 C9 7D 17 45 06 75 FE 2F C6 ..v.v.".}.E.u./. BA 1E 36 DD 19 BB 94 8B D1 BC 36 05 2E E7 4F 97 ..6.......6...O. 9E 54 BD A2 E3 11 1D FB 63 E3 68 BD 8E CA A6 5A .T......c.h....Z 38 85 89 8F D4 27 B1 F4 19 CC 98 F7 72 CD E7 0A 8....'......r... 90 11 35 00 45 31 C2 E3 C2 40 7A 29 6B 46 CD 32 ..5 E1... at z)kF.2 A8 B1 0C D7 39 0D 5B B1 9E 72 8A 96 56 8C 3E 73 ....9.[..r..V.>s AA 84 EA F0 DF DB 08 E3 58 4A 2E DB 33 61 0B 6C ........XJ..3a.l 53 76 72 C0 72 BE FA E8 06 3A 28 C8 CB 11 BD Svr.r....:(.... t= 88057 [st= 4] SOCKET_BYTES_RECEIVED --> byte_count = 568 --> hex_encoded_bytes = 17 03 03 02 33 A0 35 17 C1 DD 34 B4 50 7D BD 3F ....3.5...4.P}.? 69 69 36 E9 30 86 2E A4 97 54 1B F7 1C EA 25 A8 ii6.0....T....%. 3A 97 99 46 BB BE 16 32 5F 5D 4F 0F 49 0A D0 D1 :..F...2_]O.I... 56 0F 5F 47 E4 8C FD 72 E3 14 B6 3F 2B A9 6A 49 V._G...r...?+.jI F3 12 76 10 45 06 AB 68 02 52 71 BF 8F 13 14 3B ..v.E..h.Rq....; 7F 86 59 05 F4 A5 EF 76 E9 A4 E2 09 06 E6 15 E8 ..Y....v........ AA 9B 56 31 31 D3 0C B0 D3 8A EF FF 7B CF 04 29 ..V11.......{..) 20 FE 4E D1 1E 4B 6C 05 F9 33 94 19 3F F9 56 E1 .N..Kl..3..?.V. F1 7F 64 EC 9B 9F 5E 63 A9 AF FC 04 65 86 10 BF ..d...^c....e... 82 DA 3E 0E 8E 37 B6 09 80 94 C4 09 67 11 C7 1A ..>..7......g... C9 E2 AD 46 4D E6 85 A2 E0 37 DF 48 77 69 61 21 ...FM....7.Hwia! D3 24 67 B3 CE 99 44 20 C5 7F 77 30 36 B7 8F 03 .$g...D ..w06... 54 C4 33 3D 73 65 96 97 46 2D 4C EB E5 12 FC 72 T.3=se..F-L....r 3B 66 A0 65 6A FD FD B2 22 A8 42 55 8B A0 40 24 ;f.ej...".BU..@$ 37 12 73 97 29 D1 E5 80 EF 6E 40 FB 96 CB 91 7D 7.s.)....n at ....} C5 BE 81 2C 39 2E 35 5A 69 E5 F9 EF 57 0A 38 55 ...,9.5Zi...W.8U C3 6C 53 F9 4B 5B 54 7F 60 51 E2 4B DC A1 A7 9E .lS.K[T.`Q.K.... 0B EE FC 47 C4 96 0D B5 94 B6 42 9D A3 9B A3 37 ...G......B....7 92 D4 C1 97 AB 11 F2 1D 7E AA 67 FA A6 BF 6E EB ........~.g...n. 20 0A D7 12 ED B4 CA 28 5B 37 22 F1 62 49 74 72 ......([7".bItr B0 BF 08 6F 9D 38 AA 27 15 AC 8B 77 9B 54 A1 1B ...o.8.'...w.T.. 72 56 4D A5 DE 61 ED BC 86 84 45 9D 90 F4 3B 17 rVM..a....E...;. D9 82 3D B3 3D B1 A6 6B BF D2 52 C7 0D 76 EF E4 ..=.=..k..R..v.. 8D 73 FB 0D A1 8F 07 04 64 E2 F2 64 EE AC F9 DF .s......d..d.... 0D 8C A5 E1 F5 5D 44 4B 3A 98 6A EA 87 75 65 01 .....]DK:.j..ue. 2A 37 83 D0 91 FD 58 CA CD 4B D0 83 17 E0 01 79 *7....X..K.....y 19 A3 6F 17 88 A0 82 DD C7 E6 62 22 30 6B 97 D6 ..o.......b"0k.. 78 02 83 0B EE EA C5 54 7B 04 6B 6E 74 D5 27 B2 x......T{.knt.'. B4 C1 AB EB FC B5 6D 11 D1 41 97 8B E9 72 CE 1B ......m..A...r.. 5E 7E 7B 84 0E 9C 9A 6A 32 14 A3 7D 09 BF D5 D4 ^~{....j2..}.... 8A A9 B1 DC A2 B1 BF CD A8 AA 2A F8 0F BD 66 B1 ..........*...f. 81 11 27 05 BC 77 40 CF 31 53 16 CF 58 F6 C3 26 ..'..w at .1S..X..& BD 78 D7 1E 67 B1 0C DD 13 8B A4 F8 11 4D 1F 56 .x..g........M.V 64 16 EB 6C FC 59 44 82 CC 37 98 26 F3 B6 ED 34 d..l.YD..7.&...4 51 AD 2C 1F AC AC DA 20 B6 5C 8A 17 9F 24 01 5C Q.,.... .\...$.\ 9E C6 97 69 15 BB EA 58 ...i...X t= 88057 [st= 4] SSL_SOCKET_BYTES_RECEIVED --> byte_count = 539 --> hex_encoded_bytes = 00 00 6B 01 04 00 00 00 01 88 76 89 AA 63 55 E5 k.. ..v..cU. 80 AE FA E1 6F 61 96 E4 59 3E 94 0B 2A 43 5D 8A ....oa..Y>..*C]. 08 01 71 40 B3 71 B7 6E 05 E5 31 68 DF 5F 87 49 ..q at .q.n..1h._.I 7C A5 89 D3 4D 1F 5C 03 34 31 34 6C 96 DF 69 7E |...M.\.414l..i~ 94 08 94 86 BB 14 10 02 E2 82 15 C6 45 71 A7 14 ............Eq.. C5 A3 7F 00 83 2A 47 37 8B FE 5B 74 12 3A EB C5 ... .*G7..[t.:.. 58 2F 97 F9 00 89 19 08 5A D2 B5 83 AA 62 A3 84 X/.. ...Z....b.. 8F D2 4A 8F 00 01 9E 00 01 00 00 00 01 3C 21 44 ..J. .. . ....Welcome to ngi 6E 78 21 3C 2F 74 69 74 6C 65 3E 0A 3C 73 74 79 nx!.. body {. 20 20 20 20 20 20 20 77 69 64 74 68 3A 20 33 35 width: 35 65 6D 3B 0A 20 20 20 20 20 20 20 20 6D 61 72 67 em;. marg 69 6E 3A 20 30 20 61 75 74 6F 3B 0A 20 20 20 20 in: 0 auto;. 20 20 20 20 66 6F 6E 74 2D 66 61 6D 69 6C 79 3A font-family: 20 54 61 68 6F 6D 61 2C 20 56 65 72 64 61 6E 61 Tahoma, Verdana 2C 20 41 72 69 61 6C 2C 20 73 61 6E 73 2D 73 65 , Arial, sans-se 72 69 66 3B 0A 20 20 20 20 7D 0A 3C 2F 73 74 79 rif;. }....
.Choose a 66 69 6C 65 20 74 6F 20 75 70 6C 6F 61 64 3A 20 file to upload: 3C 69 6E 70 75 74 20 6E 61 6D 65 3D 22 66 69 6C
..
.
.. t= 94139 [st= 6086] SSL_SOCKET_BYTES_SENT --> byte_count = 144 --> hex_encoded_bytes = 00 00 87 01 24 00 00 00 03 80 00 00 00 FF 83 C4 ..$ .. ... 87 00 84 B9 58 D3 3F 85 62 DA E8 38 E4 5C 85 0B . ..X.?.b..8.\.. CE B6 FB 9F C4 C3 40 85 3D 86 98 D5 7F 90 9D 29 ...... at .=......) AD 17 18 62 83 90 74 4E 74 26 E3 4D 32 CF C3 C2 ...b..tNt&.M2... 5F B3 A6 DA 12 6A C7 62 58 94 F6 52 B4 83 48 FE _....j.bX..R..H. D4 8C F6 D5 20 EC F5 02 CB 2C B7 22 C7 98 C9 C2 .... ....,.".... 7B 29 BA 7B 6A 90 76 7A D9 54 73 85 E4 73 C3 6D {).{j.vz.Ts..s.m D7 9F 06 EB BF 73 97 9D 29 AD 17 18 62 83 90 74 .....s..)...b..t 4E 74 26 E3 4D 32 CB 15 9D 09 5E 74 D3 47 90 C2 Nt&.M2....^t.G.. t= 94139 [st= 6086] SOCKET_BYTES_SENT --> byte_count = 173 --> hex_encoded_bytes = 17 03 03 00 A8 00 00 00 00 00 00 00 06 3D BC EF ... . .=.. 8C 6B F2 E0 90 19 CF 92 8B D3 CA EE 3C 81 1A 45 .k..........<..E 3C 9E 8C F3 CB 32 EE 1B 7C 3F 58 A8 90 B8 B0 00 <....2..|?X.... 67 84 20 6F 32 B2 75 14 35 08 8B 87 AF 70 DB 9A g. o2.u.5....p.. 25 A3 82 80 18 15 31 96 76 71 1A 4F 12 09 6E 71 %.....1.vq.O..nq 50 76 79 90 8F 3B AD 30 32 25 42 53 2C E0 87 1F Pvy..;.02%BS,... 61 7E 15 ED D7 EB F6 8C 25 6A 6A B9 DE F4 73 A6 a~......%jj...s. BF E0 A4 BA 3C 88 F8 73 49 C4 10 98 04 78 B9 33 ....<..sI....x.3 9E 61 73 96 C2 B1 03 60 FB 5D F7 AB 03 89 51 E5 .as....`.]....Q. 96 F8 71 FB 03 EC 68 B1 D2 0D 1B 70 FA FF 1A AF ..q...h....p.... D7 22 C0 6E AB FC 86 5D FB A8 08 36 63 .".n...]...6c t= 94140 [st= 6087] SOCKET_BYTES_RECEIVED --> byte_count = 676 --> hex_encoded_bytes = 17 03 03 02 9F A0 35 17 C1 DD 34 B4 51 0B DE 11 ......5...4.Q... 70 95 D0 EA D7 2C CC 76 87 4F 98 C0 DA 8C F6 59 p....,.v.O.....Y 6F F9 EB B5 D3 31 24 5D 79 4E A4 2B 9C E8 69 88 o....1$]yN.+..i. 38 42 78 70 EF AF F1 6E 61 64 FC C7 91 5F 7D AA 8Bxp...nad..._}. DB 43 7F 27 65 C1 47 8C 3D E6 90 2F 61 7E FC FE .C.'e.G.=../a~.. EC 4D E8 BF 98 E2 3A 01 BB A4 1B 99 5F 21 48 7D .M....:....._!H} FA 89 BF DE B3 D3 16 EC E7 27 67 1B BC 8C 53 3B .........'g...S; B5 95 A3 F1 C5 B1 F8 88 56 76 C9 DC 4B 87 21 59 ........Vv..K.!Y A9 8E 83 E8 5D 58 4E 07 6E 39 38 4D B3 4A AC 59 ....]XN.n98M.J.Y 84 95 AE 92 5F A1 DD AF 24 0C 57 8A 3F E9 1D 13 ...._...$.W.?... A1 4E BC EF 05 BC 75 F4 98 5F 95 98 F9 19 B0 B5 .N....u.._...... 2E CD 5A 57 A2 03 1E 29 20 EE 97 5C 91 0B FC 70 ..ZW...) ..\...p 26 1A 33 D9 68 E8 3F B6 DE 39 63 16 A2 F6 9C BB &.3.h.?..9c..... EC 6D DE B0 3C 7C 4A 11 98 21 BE 26 C2 62 61 21 .m..<|J..!.&.ba! A7 4B 00 D1 76 0A F2 1C 88 2A 28 1A 70 B7 02 4D .K .v....*(.p..M 99 38 A3 A7 54 1D F7 A7 02 5B 3D 41 32 43 68 02 .8..T....[=A2Ch. 99 2E DB F4 06 0A 3A 60 07 BA 54 C1 7D 50 91 07 ......:`..T.}P.. 91 B9 1E 60 BB BA 77 DC 43 67 57 1C 65 85 6F D6 ...`..w.CgW.e.o. 58 E2 2A 48 B4 E9 D5 E4 93 25 75 80 DB 3F BC 33 X.*H.....%u..?.3 60 B1 1E 08 81 DF 77 E1 39 C6 34 43 20 08 F1 A3 `.....w.9.4C ... 9E DA 11 4D 33 18 9F 98 B0 5C 20 C5 27 6D 0D 84 ...M3....\ .'m.. 37 66 C5 BD 45 19 A6 57 05 82 10 3E 41 55 88 A9 7f..E..W...>AU.. 42 C5 70 E3 02 A0 1A DF FA A8 91 EE 34 8B 07 70 B.p.........4..p 2F 01 A3 A7 6B 84 66 CC C9 E0 DB B5 8E 11 CB 6F /...k.f........o C3 87 C0 B0 AE FB 82 F9 F1 C5 BE 38 E5 2E D8 4B ...........8...K E1 8F 7B F4 F0 18 EB 82 9F 42 82 8D 28 98 7D 0A ..{......B..(.}. B0 9E 3D 85 CA E7 B4 DB 8E 7B 3C 28 BC 6F E9 1C ..=......{<(.o.. 04 B3 87 68 A1 53 70 F3 19 38 B8 A9 1B 5C AF BD ...h.Sp..8...\.. 67 DE B1 CC 47 3D 2A 0B 55 59 25 77 62 45 2C ED g...G=*.UY%wbE,. 8B CD 05 D7 B7 99 DD 55 22 32 91 BB 32 32 4E D7 .......U"2..22N. 17 B6 ED 0F 5B F0 61 A4 AD 86 6F 56 E8 77 04 F8 ....[.a...oV.w.. AB BD A7 34 94 E5 1C 2A 0E B0 B1 BF 0F 83 1C 96 ...4...*........ 40 15 A5 C6 3B D3 E3 29 4D 45 46 92 FC 9A D1 CF @...;..)MEF..... D1 94 FB 94 C5 AA 77 25 52 1F D6 B6 D1 DD F2 56 ......w%R......V CF F1 E5 72 E2 2C 33 9A 59 B7 65 55 8D AD A0 4D ...r.,3.Y.eU...M 49 61 2E 62 4F AF 48 A6 1A 5B 5D 61 FD 12 62 32 Ia.bO.H..[]a..b2 A8 93 36 5D 22 79 AB 7F 79 30 5E FD F3 DE 03 14 ..6]"y..y0^..... 6D 32 8D AF EC 2E A9 AF CE BB FA 6B CB 36 A0 74 m2.........k.6.t 6A F5 E0 DD 3B C4 E5 31 97 DD 4A 4C A9 C3 91 F6 j...;..1..JL.... 86 B5 9F CF E8 FA 8F EC 2C 94 95 CA 17 5D 59 EF ........,....]Y. 3B B4 65 95 92 1F 67 BF F7 F8 50 81 68 0B 85 48 ;.e...g...P.h..H 06 F5 63 0F 3F 4A 00 E8 0E A3 88 1C 80 17 B4 5F ..c.?J ........_ FE 6E 3F 15 .n?. t= 94140 [st= 6087] SSL_SOCKET_BYTES_RECEIVED --> byte_count = 647 --> hex_encoded_bytes = 00 00 36 01 04 00 00 00 03 48 03 34 30 35 76 89 6.. .H.405v. AA 63 55 E5 80 AE FA E1 6F 61 96 E4 59 3E 94 0B .cU.....oa..Y>.. 2A 43 5D 8A 08 01 71 40 B3 71 B7 6E 09 A5 31 68 *C]...q at .q.n..1h DF 5F 87 49 7C A5 89 D3 4D 1F 5C 03 35 37 35 00 ._.I|...M.\.575 02 3F 00 01 00 00 00 03 3C 68 74 6D 6C 3E 0D 0A .? . ... 3C 68 65 61 64 3E 3C 74 69 74 6C 65 3E 34 30 35 405 20 4E 6F 74 20 41 6C 6C 6F 77 65 64 3C 2F 74 69 Not Allowed</ti 74 6C 65 3E 3C 2F 68 65 61 64 3E 0D 0A 3C 62 6F tle></head>..<bo 64 79 20 62 67 63 6F 6C 6F 72 3D 22 77 68 69 74 dy bgcolor="whit 65 22 3E 0D 0A 3C 63 65 6E 74 65 72 3E 3C 68 31 e">..<center><h1 3E 34 30 35 20 4E 6F 74 20 41 6C 6C 6F 77 65 64 >405 Not Allowed 3C 2F 68 31 3E 3C 2F 63 65 6E 74 65 72 3E 0D 0A </h1></center>.. 3C 68 72 3E 3C 63 65 6E 74 65 72 3E 6E 67 69 6E <hr><center>ngin 78 2F 31 2E 39 2E 31 35 3C 2F 63 65 6E 74 65 72 x/1.9.15</center 3E 0D 0A 3C 2F 62 6F 64 79 3E 0D 0A 3C 2F 68 74 >..</body>..</ht 6D 6C 3E 0D 0A 3C 21 2D 2D 20 61 20 70 61 64 64 ml>..<!-- a padd 69 6E 67 20 74 6F 20 64 69 73 61 62 6C 65 20 4D ing to disable M 53 49 45 20 61 6E 64 20 43 68 72 6F 6D 65 20 66 SIE and Chrome f 72 69 65 6E 64 6C 79 20 65 72 72 6F 72 20 70 61 riendly error pa 67 65 20 2D 2D 3E 0D 0A 3C 21 2D 2D 20 61 20 70 ge -->..<!-- a p 61 64 64 69 6E 67 20 74 6F 20 64 69 73 61 62 6C adding to disabl 65 20 4D 53 49 45 20 61 6E 64 20 43 68 72 6F 6D e MSIE and Chrom 65 20 66 72 69 65 6E 64 6C 79 20 65 72 72 6F 72 e friendly error 20 70 61 67 65 20 2D 2D 3E 0D 0A 3C 21 2D 2D 20 page -->..<!-- 61 20 70 61 64 64 69 6E 67 20 74 6F 20 64 69 73 a padding to dis 61 62 6C 65 20 4D 53 49 45 20 61 6E 64 20 43 68 able MSIE and Ch 72 6F 6D 65 20 66 72 69 65 6E 64 6C 79 20 65 72 rome friendly er 72 6F 72 20 70 61 67 65 20 2D 2D 3E 0D 0A 3C 21 ror page -->..<! 2D 2D 20 61 20 70 61 64 64 69 6E 67 20 74 6F 20 -- a padding to 64 69 73 61 62 6C 65 20 4D 53 49 45 20 61 6E 64 disable MSIE and 20 43 68 72 6F 6D 65 20 66 72 69 65 6E 64 6C 79 Chrome friendly 20 65 72 72 6F 72 20 70 61 67 65 20 2D 2D 3E 0D error page -->. 0A 3C 21 2D 2D 20 61 20 70 61 64 64 69 6E 67 20 .<!-- a padding 74 6F 20 64 69 73 61 62 6C 65 20 4D 53 49 45 20 to disable MSIE 61 6E 64 20 43 68 72 6F 6D 65 20 66 72 69 65 6E and Chrome frien 64 6C 79 20 65 72 72 6F 72 20 70 61 67 65 20 2D dly error page - 2D 3E 0D 0A 3C 21 2D 2D 20 61 20 70 61 64 64 69 ->..<!-- a paddi 6E 67 20 74 6F 20 64 69 73 61 62 6C 65 20 4D 53 ng to disable MS 49 45 20 61 6E 64 20 43 68 72 6F 6D 65 20 66 72 IE and Chrome fr 69 65 6E 64 6C 79 20 65 72 72 6F 72 20 70 61 67 iendly error pag 65 20 2D 2D 3E 0D 0A e -->.. t= 94140 [st= 6087] SOCKET_BYTES_RECEIVED --> byte_count = 42 --> hex_encoded_bytes = 17 03 03 00 25 A0 35 17 C1 DD 34 B4 52 F8 1E F3 ... %.5...4.R... 82 4C 1B B3 D2 EC 8F 4C 9B B2 C0 E1 B8 3E BB 99 .L.....L.....>.. F5 E6 D9 28 AC FC 31 4E 7E E2 ...(..1N~. t= 94141 [st= 6088] SSL_SOCKET_BYTES_RECEIVED --> byte_count = 13 --> hex_encoded_bytes = 00 00 04 03 00 00 00 00 03 00 00 00 00 .. . t=104980 [st=16927] SOCKET_BYTES_RECEIVED --> byte_count = 0 t=104980 [st=16927] SSL_SOCKET_BYTES_RECEIVED --> byte_count = 0 t=104980 [st=16927] -SOCKET_IN_USE t=104980 [st=16927] -SOCKET_IN_USE t=104980 [st=16927] -SOCKET_ALIVE 12282: HTTP2_SESSION localhost:4433 (DIRECT) Start Time: 2016-04-13 16:57:18.768 t= 88056 [st= 0] +HTTP2_SESSION [dt=16924] --> host = "localhost:4433" --> proxy = "DIRECT" t= 88056 [st= 0] HTTP2_SESSION_INITIALIZED --> protocol = "h2" --> source_dependency = 12281 (SOCKET) t= 88056 [st= 0] HTTP2_SESSION_SEND_SETTINGS --> settings = ["[id:3 flags:0 value:1000]","[id:4 flags:0 value:6291456]"] t= 88056 [st= 0] HTTP2_STREAM_UPDATE_RECV_WINDOW --> delta = 15663105 --> window_size = 15728640 t= 88056 [st= 0] HTTP2_SESSION_SENT_WINDOW_UPDATE_FRAME --> delta = 15663105 --> stream_id = 0 t= 88056 [st= 0] HTTP2_SESSION_RECV_SETTINGS --> clear_persisted = false --> host = "localhost:4433" t= 88056 [st= 0] HTTP2_SESSION_RECV_SETTING --> flags = 0 --> id = 3 --> value = 128 t= 88056 [st= 0] HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE --> delta_window_size = -65535 t= 88057 [st= 1] HTTP2_SESSION_RECV_SETTING --> flags = 0 --> id = 4 --> value = 0 t= 88057 [st= 1] HTTP2_SESSION_RECV_SETTING --> flags = 0 --> id = 5 --> value = 16777215 t= 88057 [st= 1] HTTP2_SESSION_RECEIVED_WINDOW_UPDATE_FRAME --> delta = 2147418112 --> stream_id = 0 t= 88057 [st= 1] HTTP2_SESSION_UPDATE_SEND_WINDOW --> delta = 2147418112 --> window_size = 2147483647 t= 88057 [st= 1] HTTP2_SESSION_SEND_HEADERS --> exclusive = true --> fin = true --> has_priority = true --> :method: GET :authority: localhost:4433 :scheme: https :path: /post.html cache-control: max-age=0 accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 upgrade-insecure-requests: 1 user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.66 Safari/537.36 accept-encoding: gzip, deflate, sdch accept-language: en-US,en;q=0.8 --> parent_stream_id = 0 --> priority = 0 --> stream_id = 1 t= 88057 [st= 1] HTTP2_SESSION_RECV_HEADERS --> fin = false --> :status: 200 server: nginx/1.9.15 date: Wed, 13 Apr 2016 13:57:18 GMT content-type: text/html content-length: 414 last-modified: Tue, 12 Apr 2016 22:32:46 GMT etag: "570d778e-19e" accept-ranges: bytes --> stream_id = 1 t= 88057 [st= 1] HTTP2_SESSION_RECV_DATA --> fin = false --> size = 414 --> stream_id = 1 t= 88057 [st= 1] HTTP2_SESSION_UPDATE_RECV_WINDOW --> delta = -414 --> window_size = 15728226 t= 88057 [st= 1] HTTP2_SESSION_RECV_DATA --> fin = true --> size = 0 --> stream_id = 1 t= 88058 [st= 2] HTTP2_STREAM_UPDATE_RECV_WINDOW --> delta = 414 --> window_size = 15728640 t= 94138 [st= 6082] HTTP2_SESSION_SEND_HEADERS --> exclusive = true --> fin = false --> has_priority = true --> :method: POST :authority: localhost:4433 :scheme: https :path: /upload content-length: 187596 cache-control: max-age=0 accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 origin: https://localhost:4433 upgrade-insecure-requests: 1 user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.66 Safari/537.36 content-type: multipart/form-data; boundary=----WebKitFormBoundaryQnbh18sYFuB890SB referer: https://localhost:4433/post.html accept-encoding: gzip, deflate accept-language: en-US,en;q=0.8 --> parent_stream_id = 0 --> priority = 0 --> stream_id = 3 t= 94140 [st= 6084] HTTP2_SESSION_RECV_HEADERS --> fin = false --> :status: 405 server: nginx/1.9.15 date: Wed, 13 Apr 2016 13:57:24 GMT content-type: text/html content-length: 575 --> stream_id = 3 t= 94141 [st= 6085] HTTP2_SESSION_RECV_DATA --> fin = false --> size = 575 --> stream_id = 3 t= 94141 [st= 6085] HTTP2_SESSION_UPDATE_RECV_WINDOW --> delta = -575 --> window_size = 15728065 t= 94141 [st= 6085] HTTP2_SESSION_RECV_DATA --> fin = true --> size = 0 --> stream_id = 3 t= 94141 [st= 6085] HTTP2_SESSION_RST_STREAM --> description = "" --> status = 6 --> stream_id = 3 t= 94141 [st= 6085] HTTP2_STREAM_UPDATE_RECV_WINDOW --> delta = 575 --> window_size = 15728640 t=104980 [st=16924] HTTP2_SESSION_CLOSE --> description = "Connection closed" --> net_error = -100 (ERR_CONNECTION_CLOSED) t=104980 [st=16924] HTTP2_SESSION_POOL_REMOVE_SESSION --> source_dependency = 12282 (HTTP2_SESSION) t=104980 [st=16924] -HTTP2_SESSION From vbart at nginx.com Wed Apr 13 16:35:25 2016 From: vbart at nginx.com (=?utf-8?B?0JLQsNC70LXQvdGC0LjQvSDQkdCw0YDRgtC10L3QtdCy?=) Date: Wed, 13 Apr 2016 19:35:25 +0300 Subject: 1.9.14 - http2 protocol violations In-Reply-To: <2066226.e0z408FIE7@vbart-laptop> References: <CAHqmWiNxpj8zBtXEXp8aDa9-nMXtX_408HN+3AwptxtjuMaKqQ@mail.gmail.com> <CAHqmWiNfM49NBtT-nWXkxGUMLsNY-xZiac6zcPXDaoYTWxzoxQ@mail.gmail.com> <2066226.e0z408FIE7@vbart-laptop> Message-ID: <25631723.3VOtH9GG3y@vbart-laptop> On Wednesday 13 April 2016 18:00:26 ???????? ???????? wrote: > On Wednesday 13 April 2016 15:08:29 Otto van der Schaaf wrote: > > I'm sorry to say that the patch does not make a difference. > > > > I collected Chrome's http/2 trace for a post to a non-existant url: > > https://gist.github.com/oschaaf/da273f96fad5e22890981fcd4a1a4376 > > > > I'm wondering about that last HTTP2_SESSION_RST_STREAM entry.. it looks > > like > > the httpv2 mod wants to cancel the incoming post data stream at an odd > > point in time? > > But I'm no expert, so I'm not sure at all. > > > [..] > > I was able to capture quite the same Chrome trace with the actual bytes > sent/received and this last RST_STREAM entry with status 6 (which is > FRAME_SIZE_ERROR) looks really strange. > > > It isn't presented in nginx debug log (nginx hasn't sent, nor has received > it). Moreover, the actual bytes sent/received trace, that you can get from > Chrome if you set the "Include the actual bytes sent/received." flag in > chrome://net-internals/#capture), doesn't contain it either. > > The trace (and nginx log) contains RST_STREAM sent by nginx with status 0 > (NO_ERROR), which is correct: > > t= 94141 [st= 6088] SSL_SOCKET_BYTES_RECEIVED > --> byte_count = 13 > --> hex_encoded_bytes = > 00 00 04 03 00 00 00 00 03 00 00 00 00 > > As you can see it has 4 bytes length, type 3, flags 0, stream id 3 > and error code 0. > > +-----------------------------------------------+ > | Length (24) | > +---------------+---------------+---------------+ > | Type (8) | Flags (8) | > +-+-------------+---------------+-------------------------------+ > |R| Stream Identifier (31) | > +=+=============================================================+ > | Frame Payload (0...) ... > +---------------------------------------------------------------+ > > Figure 1: Frame Layout > > > https://tools.ietf.org/html/rfc7540#section-4.1 > > > +---------------------------------------------------------------+ > | Error Code (32) | > +---------------------------------------------------------------+ > > Figure 9: RST_STREAM Frame Payload > > https://tools.ietf.org/html/rfc7540#section-6.4 > > I've attached the full trace. > > Maybe I missed something, but after manual decoding bytes I don't see any > problems with the frame sizes received from nginx. > > However, that can be a result of this change: > http://hg.nginx.org/nginx/rev/92464ebace8e > > Firefox perfectly fine with it. It looks like the problem in Chrome. > Well, I've found the key how to interpret these statuses in Chromium sources: // Status codes for RST_STREAM frames. enum SpdyRstStreamStatus { RST_STREAM_INVALID = 0, RST_STREAM_PROTOCOL_ERROR = 1, RST_STREAM_INVALID_STREAM = 2, RST_STREAM_STREAM_CLOSED = 2, // Equivalent to INVALID_STREAM RST_STREAM_REFUSED_STREAM = 3, RST_STREAM_UNSUPPORTED_VERSION = 4, RST_STREAM_CANCEL = 5, RST_STREAM_INTERNAL_ERROR = 6, RST_STREAM_FLOW_CONTROL_ERROR = 7, RST_STREAM_STREAM_IN_USE = 8, RST_STREAM_STREAM_ALREADY_CLOSED = 9, RST_STREAM_INVALID_CREDENTIALS = 10, // FRAME_TOO_LARGE (defined by SPDY versions 3.1 and below), and // FRAME_SIZE_ERROR (defined by HTTP/2) are mapped to the same internal // reset status. RST_STREAM_FRAME_TOO_LARGE = 11, RST_STREAM_FRAME_SIZE_ERROR = 11, RST_STREAM_SETTINGS_TIMEOUT = 12, RST_STREAM_CONNECT_ERROR = 13, RST_STREAM_ENHANCE_YOUR_CALM = 14, RST_STREAM_NUM_STATUS_CODES = 15 }; looks like NO_ERROR is handled as internal error, which is obviously wrong. wbr, Valentin V. Bartenev From vbart at nginx.com Wed Apr 13 17:36:44 2016 From: vbart at nginx.com (=?utf-8?B?0JLQsNC70LXQvdGC0LjQvSDQkdCw0YDRgtC10L3QtdCy?=) Date: Wed, 13 Apr 2016 20:36:44 +0300 Subject: 1.9.14 - http2 protocol violations In-Reply-To: <25631723.3VOtH9GG3y@vbart-laptop> References: <CAHqmWiNxpj8zBtXEXp8aDa9-nMXtX_408HN+3AwptxtjuMaKqQ@mail.gmail.com> <2066226.e0z408FIE7@vbart-laptop> <25631723.3VOtH9GG3y@vbart-laptop> Message-ID: <3388716.rnsO59aBFA@vbart-laptop> On Wednesday 13 April 2016 19:35:25 ???????? ???????? wrote: > On Wednesday 13 April 2016 18:00:26 ???????? ???????? wrote: > > On Wednesday 13 April 2016 15:08:29 Otto van der Schaaf wrote: > > > I'm sorry to say that the patch does not make a difference. > > > > > > I collected Chrome's http/2 trace for a post to a non-existant url: > > > https://gist.github.com/oschaaf/da273f96fad5e22890981fcd4a1a4376 > > > > > > I'm wondering about that last HTTP2_SESSION_RST_STREAM entry.. it looks > > > like > > > the httpv2 mod wants to cancel the incoming post data stream at an odd > > > point in time? > > > But I'm no expert, so I'm not sure at all. > > > > > [..] > > > > I was able to capture quite the same Chrome trace with the actual bytes > > sent/received and this last RST_STREAM entry with status 6 (which is > > FRAME_SIZE_ERROR) looks really strange. > > > > > > It isn't presented in nginx debug log (nginx hasn't sent, nor has received > > it). Moreover, the actual bytes sent/received trace, that you can get from > > Chrome if you set the "Include the actual bytes sent/received." flag in > > chrome://net-internals/#capture), doesn't contain it either. > > > > The trace (and nginx log) contains RST_STREAM sent by nginx with status 0 > > (NO_ERROR), which is correct: > > > > t= 94141 [st= 6088] SSL_SOCKET_BYTES_RECEIVED > > --> byte_count = 13 > > --> hex_encoded_bytes = > > 00 00 04 03 00 00 00 00 03 00 00 00 00 > > > > As you can see it has 4 bytes length, type 3, flags 0, stream id 3 > > and error code 0. > > > > +-----------------------------------------------+ > > | Length (24) | > > +---------------+---------------+---------------+ > > | Type (8) | Flags (8) | > > +-+-------------+---------------+-------------------------------+ > > |R| Stream Identifier (31) | > > +=+=============================================================+ > > | Frame Payload (0...) ... > > +---------------------------------------------------------------+ > > > > Figure 1: Frame Layout > > > > > > https://tools.ietf.org/html/rfc7540#section-4.1 > > > > > > +---------------------------------------------------------------+ > > | Error Code (32) | > > +---------------------------------------------------------------+ > > > > Figure 9: RST_STREAM Frame Payload > > > > https://tools.ietf.org/html/rfc7540#section-6.4 > > > > I've attached the full trace. > > > > Maybe I missed something, but after manual decoding bytes I don't see any > > problems with the frame sizes received from nginx. > > > > However, that can be a result of this change: > > http://hg.nginx.org/nginx/rev/92464ebace8e > > > > Firefox perfectly fine with it. It looks like the problem in Chrome. > > > > Well, I've found the key how to interpret these statuses in Chromium sources: > > // Status codes for RST_STREAM frames. > enum SpdyRstStreamStatus { > RST_STREAM_INVALID = 0, > RST_STREAM_PROTOCOL_ERROR = 1, > RST_STREAM_INVALID_STREAM = 2, > RST_STREAM_STREAM_CLOSED = 2, // Equivalent to INVALID_STREAM > RST_STREAM_REFUSED_STREAM = 3, > RST_STREAM_UNSUPPORTED_VERSION = 4, > RST_STREAM_CANCEL = 5, > RST_STREAM_INTERNAL_ERROR = 6, > RST_STREAM_FLOW_CONTROL_ERROR = 7, > RST_STREAM_STREAM_IN_USE = 8, > RST_STREAM_STREAM_ALREADY_CLOSED = 9, > RST_STREAM_INVALID_CREDENTIALS = 10, > // FRAME_TOO_LARGE (defined by SPDY versions 3.1 and below), and > // FRAME_SIZE_ERROR (defined by HTTP/2) are mapped to the same internal > // reset status. > RST_STREAM_FRAME_TOO_LARGE = 11, > RST_STREAM_FRAME_SIZE_ERROR = 11, > RST_STREAM_SETTINGS_TIMEOUT = 12, > RST_STREAM_CONNECT_ERROR = 13, > RST_STREAM_ENHANCE_YOUR_CALM = 14, > RST_STREAM_NUM_STATUS_CODES = 15 > }; > > looks like NO_ERROR is handled as internal error, which is obviously wrong. > I've opened a ticket for this: https://bugs.chromium.org/p/chromium/issues/detail?id=603182 wbr, Valentin V. Bartenev From vbart at nginx.com Thu Apr 14 12:25:29 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 14 Apr 2016 12:25:29 +0000 Subject: [nginx] FastCGI: skip special bufs in buffered request body chain. Message-ID: <hg.b5734248d5e7.1460636729.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/b5734248d5e7 branches: changeset: 6512:b5734248d5e7 user: Valentin Bartenev <vbart at nginx.com> date: Mon Apr 11 18:42:34 2016 +0300 description: FastCGI: skip special bufs in buffered request body chain. This prevents forming empty records out of such buffers. Particularly it fixes double end-of-stream records with chunked transfer encoding, or when HTTP/2 is used and the END_STREAM flag has been sent without data. In both cases there is an empty buffer at the end of the request body chain with the "last_buf" flag set. The canonical libfcgi, as well as php implementation, tolerates such records, while the HHVM parser is more strict and drops the connection (ticket #950). diffstat: src/http/modules/ngx_http_fastcgi_module.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r 640288d0e1bc -r b5734248d5e7 src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c Tue Apr 12 19:01:56 2016 +0300 +++ b/src/http/modules/ngx_http_fastcgi_module.c Mon Apr 11 18:42:34 2016 +0300 @@ -1177,6 +1177,11 @@ ngx_http_fastcgi_create_request(ngx_http while (body) { + if (ngx_buf_special(body->buf)) { + body = body->next; + continue; + } + if (body->buf->in_file) { file_pos = body->buf->file_pos; From vbart at nginx.com Thu Apr 14 12:25:32 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 14 Apr 2016 12:25:32 +0000 Subject: [nginx] HTTP/2: deduplicated some code in ngx_http_v2_state_headers(). Message-ID: <hg.80ba811112ed.1460636732.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/80ba811112ed branches: changeset: 6513:80ba811112ed user: Valentin Bartenev <vbart at nginx.com> date: Thu Apr 14 15:14:15 2016 +0300 description: HTTP/2: deduplicated some code in ngx_http_v2_state_headers(). No functional changes. diffstat: src/http/v2/ngx_http_v2.c | 31 +++++++++++++------------------ 1 files changed, 13 insertions(+), 18 deletions(-) diffs (62 lines): diff -r b5734248d5e7 -r 80ba811112ed src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Mon Apr 11 18:42:34 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Thu Apr 14 15:14:15 2016 +0300 @@ -948,6 +948,7 @@ ngx_http_v2_state_headers(ngx_http_v2_co { size_t size; ngx_uint_t padded, priority, depend, dependency, excl, weight; + ngx_uint_t status; ngx_http_v2_node_t *node; ngx_http_v2_stream_t *stream; ngx_http_v2_srv_conf_t *h2scf; @@ -1040,15 +1041,8 @@ ngx_http_v2_state_headers(ngx_http_v2_co "client sent HEADERS frame for stream %ui " "with incorrect dependency", h2c->state.sid); - if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, - NGX_HTTP_V2_PROTOCOL_ERROR) - != NGX_OK) - { - return ngx_http_v2_connection_error(h2c, - NGX_HTTP_V2_INTERNAL_ERROR); - } - - return ngx_http_v2_state_header_block(h2c, pos, end); + status = NGX_HTTP_V2_PROTOCOL_ERROR; + goto rst_stream; } h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, @@ -1060,15 +1054,8 @@ ngx_http_v2_state_headers(ngx_http_v2_co ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, "concurrent streams exceeded %ui", h2c->processing); - if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, - NGX_HTTP_V2_REFUSED_STREAM) - != NGX_OK) - { - return ngx_http_v2_connection_error(h2c, - NGX_HTTP_V2_INTERNAL_ERROR); - } - - return ngx_http_v2_state_header_block(h2c, pos, end); + status = NGX_HTTP_V2_REFUSED_STREAM; + goto rst_stream; } node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1); @@ -1105,6 +1092,14 @@ ngx_http_v2_state_headers(ngx_http_v2_co } return ngx_http_v2_state_header_block(h2c, pos, end); + +rst_stream: + + if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, status) != NGX_OK) { + return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); + } + + return ngx_http_v2_state_header_block(h2c, pos, end); } From vbart at nginx.com Thu Apr 14 12:25:34 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 14 Apr 2016 12:25:34 +0000 Subject: [nginx] HTTP/2: refuse streams with data until SETTINGS is acknowledged. Message-ID: <hg.0aa07850922f.1460636734.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/0aa07850922f branches: changeset: 6514:0aa07850922f user: Valentin Bartenev <vbart at nginx.com> date: Thu Apr 14 15:14:15 2016 +0300 description: HTTP/2: refuse streams with data until SETTINGS is acknowledged. A client is allowed to send requests before receiving and acknowledging the SETTINGS frame. Such a client having a wrong idea about the stream's could send the request body that nginx isn't ready to process. The previous behavior was to send RST_STREAM with FLOW_CONTROL_ERROR in such case, but it didn't allow retrying requests that have been rejected. diffstat: src/http/v2/ngx_http_v2.c | 8 +++++++- src/http/v2/ngx_http_v2.h | 1 + 2 files changed, 8 insertions(+), 1 deletions(-) diffs (36 lines): diff -r 80ba811112ed -r 0aa07850922f src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Thu Apr 14 15:14:15 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Thu Apr 14 15:14:15 2016 +0300 @@ -1058,6 +1058,12 @@ ngx_http_v2_state_headers(ngx_http_v2_co goto rst_stream; } + if (!h2c->settings_ack && !(h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG)) + { + status = NGX_HTTP_V2_REFUSED_STREAM; + goto rst_stream; + } + node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1); if (node == NULL) { @@ -1878,7 +1884,7 @@ ngx_http_v2_state_settings(ngx_http_v2_c return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); } - /* TODO settings acknowledged */ + h2c->settings_ack = 1; return ngx_http_v2_state_complete(h2c, pos, end); } diff -r 80ba811112ed -r 0aa07850922f src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Thu Apr 14 15:14:15 2016 +0300 +++ b/src/http/v2/ngx_http_v2.h Thu Apr 14 15:14:15 2016 +0300 @@ -141,6 +141,7 @@ struct ngx_http_v2_connection_s { ngx_uint_t last_sid; unsigned closed_nodes:8; + unsigned settings_ack:1; unsigned blocked:1; }; From vbart at nginx.com Thu Apr 14 12:25:37 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 14 Apr 2016 12:25:37 +0000 Subject: [nginx] HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR. Message-ID: <hg.8df664ebe037.1460636737.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/8df664ebe037 branches: changeset: 6515:8df664ebe037 user: Valentin Bartenev <vbart at nginx.com> date: Thu Apr 14 15:14:15 2016 +0300 description: HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR. After the 92464ebace8e change, it has been discovered that not all clients follow the RFC and handle RST_STREAM with NO_ERROR properly. Notably, Chrome currently interprets it as INTERNAL_ERROR and discards the response. As a workaround, instead of RST_STREAM the maximum stream window update will be sent, which will let client to send up to 2 GB of a request body data before getting stuck on flow control. All the received data will be silently discarded. See for details: http://mailman.nginx.org/pipermail/nginx-devel/2016-April/008143.html https://bugs.chromium.org/p/chromium/issues/detail?id=603182 diffstat: src/http/v2/ngx_http_v2.c | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-) diffs (37 lines): diff -r 0aa07850922f -r 8df664ebe037 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Thu Apr 14 15:14:15 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Thu Apr 14 15:14:15 2016 +0300 @@ -3860,11 +3860,33 @@ ngx_http_v2_close_stream(ngx_http_v2_str } } else if (!stream->in_closed) { +#if 0 if (ngx_http_v2_send_rst_stream(h2c, node->id, NGX_HTTP_V2_NO_ERROR) != NGX_OK) { h2c->connection->error = 1; } +#else + /* + * At the time of writing at least the latest versions of Chrome + * do not properly handle RST_STREAM with NO_ERROR status. + * + * See: https://bugs.chromium.org/p/chromium/issues/detail?id=603182 + * + * As a workaround, the stream window is maximized before closing + * the stream. This allows a client to send up to 2 GB of data + * before getting blocked on flow control. + */ + + if (stream->recv_window < NGX_HTTP_V2_MAX_WINDOW + && ngx_http_v2_send_window_update(h2c, node->id, + NGX_HTTP_V2_MAX_WINDOW + - stream->recv_window) + != NGX_OK) + { + h2c->connection->error = 1; + } +#endif } } From igor at sysoev.ru Fri Apr 15 14:21:23 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 15 Apr 2016 14:21:23 +0000 Subject: [njs] String.fromCharCode() and String.fromCodePoint(). Message-ID: <hg.51009da8e3d0.1460730083.5965299922797593991@dev.nginx.com> details: http://hg.nginx.org/njs/rev/51009da8e3d0 branches: changeset: 98:51009da8e3d0 user: Igor Sysoev <igor at sysoev.ru> date: Mon Apr 11 14:39:59 2016 +0300 description: String.fromCharCode() and String.fromCodePoint(). diffstat: njs/njs_string.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 21 ++++++++++++++ 2 files changed, 90 insertions(+), 0 deletions(-) diffs (124 lines): diff -r 24544f647802 -r 51009da8e3d0 njs/njs_string.c --- a/njs/njs_string.c Sat Apr 09 12:21:31 2016 +0300 +++ b/njs/njs_string.c Mon Apr 11 14:39:59 2016 +0300 @@ -35,6 +35,8 @@ static nxt_noinline void njs_string_slic njs_slice_prop_t *slice, njs_value_t *args, nxt_uint_t nargs); static nxt_noinline void njs_string_slice_args(njs_slice_prop_t *slice, njs_value_t *args, nxt_uint_t nargs); +static njs_ret_t njs_string_prototype_from_char_code(njs_vm_t *vm, + njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); static nxt_noinline ssize_t njs_string_index_of(njs_vm_t *vm, njs_value_t *src, njs_value_t *search_string, size_t index); @@ -305,6 +307,20 @@ static const njs_object_prop_t njs_stri .name = njs_string("prototype"), .value = njs_native_getter(njs_object_prototype_create), }, + + { + .type = NJS_METHOD, + .name = njs_string("fromCharCode"), + .value = njs_native_function(njs_string_prototype_from_char_code, 0, 0), + }, + + + /* ECMAScript 6, fromCodePoint(). */ + { + .type = NJS_METHOD, + .name = njs_string("fromCodePoint"), + .value = njs_native_function(njs_string_prototype_from_char_code, 0, 0), + }, }; @@ -1045,6 +1061,59 @@ done: static njs_ret_t +njs_string_prototype_from_char_code(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) +{ + u_char *p; + double num; + size_t size; + int32_t code; + nxt_uint_t i; + + for (i = 1; i < nargs; i++) { + if (!njs_is_numeric(&args[i])) { + vm->frame->trap_scratch.data.u.value = &args[i]; + return NJS_TRAP_NUMBER_ARG; + } + } + + size = 0; + + for (i = 1; i < nargs; i++) { + num = args[i].data.u.number; + if (njs_is_nan(num)) { + goto range_error; + } + + code = num; + + if (code != num || code < 0 || code >= 0x110000) { + goto range_error; + } + + size += nxt_utf8_size(code); + } + + p = njs_string_alloc(vm, &vm->retval, size, nargs - 1); + if (nxt_slow_path(p == NULL)) { + return NXT_ERROR; + } + + for (i = 1; i < nargs; i++) { + p = nxt_utf8_encode(p, args[i].data.u.number); + } + + return NXT_OK; + +range_error: + + vm->exception = &njs_exception_range_error; + + return NXT_ERROR; +} + + +static njs_ret_t njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { diff -r 24544f647802 -r 51009da8e3d0 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sat Apr 09 12:21:31 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Apr 11 14:39:59 2016 +0300 @@ -2681,6 +2681,27 @@ static njs_unit_test_t njs_test[] = " .length"), nxt_string("5") }, + { nxt_string("String.fromCharCode('_')"), + nxt_string("RangeError") }, + + { nxt_string("String.fromCharCode(3.14)"), + nxt_string("RangeError") }, + + { nxt_string("String.fromCharCode(65, 90)"), + nxt_string("AZ") }, + + { nxt_string("String.fromCharCode(945, 946, 947)"), + nxt_string("???") }, + + { nxt_string("(function() {" + " for (n = 0; n <= 1114111; n++) {" + " if (String.fromCharCode(n).charCodeAt(0) !== n)" + " return n;" + " }" + " return -1" + "})()"), + nxt_string("-1") }, + { nxt_string("a = 'abcdef'; function f(a) {" "return a.slice(a.indexOf('cd')) } f(a)"), nxt_string("cdef") }, From igor at sysoev.ru Fri Apr 15 14:21:24 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 15 Apr 2016 14:21:24 +0000 Subject: [njs] "new Date()" incorrectly returned always Jan 1, 1970. Message-ID: <hg.1c50334fbea6.1460730084.5965299922797593991@dev.nginx.com> details: http://hg.nginx.org/njs/rev/1c50334fbea6 branches: changeset: 99:1c50334fbea6 user: Igor Sysoev <igor at sysoev.ru> date: Thu Apr 14 18:23:09 2016 +0300 description: "new Date()" incorrectly returned always Jan 1, 1970. diffstat: njs/njs_date.c | 2 +- njs/test/njs_unit_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (24 lines): diff -r 51009da8e3d0 -r 1c50334fbea6 njs/njs_date.c --- a/njs/njs_date.c Mon Apr 11 14:39:59 2016 +0300 +++ b/njs/njs_date.c Thu Apr 14 18:23:09 2016 +0300 @@ -88,7 +88,7 @@ njs_date_constructor(njs_vm_t *vm, njs_v if (vm->frame->ctor) { - if (nargs == 0) { + if (nargs == 1) { time = njs_gettime(); } else if (nargs == 2 && njs_is_string(&args[1])) { diff -r 51009da8e3d0 -r 1c50334fbea6 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Apr 11 14:39:59 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Apr 14 18:23:09 2016 +0300 @@ -4025,7 +4025,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("Date.parse('-000001-01-01T00:00:00.000Z')"), nxt_string("-62198755200000") }, - { nxt_string("var d = new Date(); d == Date.parse(d.toString())"), + { nxt_string("var d = new Date(); d == Date.parse(d.toISOString())"), nxt_string("true") }, { nxt_string("var s = Date(); s === Date(Date.parse(s))"), From junpei.yoshino at gmail.com Mon Apr 18 15:47:36 2016 From: junpei.yoshino at gmail.com (junpei yoshino) Date: Tue, 19 Apr 2016 00:47:36 +0900 Subject: [PATCH]add proxy_protocol_port variable for rfc6302 In-Reply-To: <CAP_hEECZQecDugj3wWmBssTMBrO2Q+u-PsWRJkZNMQaRMgMOCg@mail.gmail.com> References: <CAP_hEEBbkd8vG+stGxk6TdoNUKwZSfqra9Ns_ceAUFuWm0kF5A@mail.gmail.com> <20151203190316.GG74233@mdounin.ru> <CAP_hEEAFZZvg+5XnvjfN6KJ8COVqVfQE22UWYuNnBG_XOs9TyA@mail.gmail.com> <20151207025141.GT74233@mdounin.ru> <CAP_hEEDb99nsuAu0m3-gAHpJb+HeUrEY1f5BDhBESx20H8xR1g@mail.gmail.com> <CAP_hEEBByrey3KToDarnST=Jk8hwhfXjxRWoi3jdhB=0JgZ-+w@mail.gmail.com> <CANgqiG=ZEeRDdSe5gbBPTpq9byW9d_yLKjZaWap6VfJ60ai4VA@mail.gmail.com> <CAP_hEECHmU1mS2YRXSoPRO7RwYpFitMkr7g885jRZtC=V7cZ=A@mail.gmail.com> <20160404153057.GH36620@mdounin.ru> <CAP_hEEA=GOxdCi_pOK_RCGjTRokZZa76ovRmjYKjhK_nw9HFiQ@mail.gmail.com> <20160404175633.GL36620@mdounin.ru> <CAP_hEECZQecDugj3wWmBssTMBrO2Q+u-PsWRJkZNMQaRMgMOCg@mail.gmail.com> Message-ID: <CAP_hEEAFjf0RcjBuQZ9MHP_kmat--wTyhM1-MX5miZ8fmVFk6A@mail.gmail.com> Hello, Is there any problem or comment? Best Regards, Junpei Yoshino On Tue, Apr 5, 2016 at 9:50 AM, junpei yoshino <junpei.yoshino at gmail.com> wrote: > Hello! > > Thank you for your comment. > > I rewrote patch in way 3. > > Best Regards, > Junpei Yoshino > > # HG changeset patch > # User Junpei Yoshino <junpei.yoshino at gmail.com> > # Date 1459816952 -32400 > # Tue Apr 05 09:42:32 2016 +0900 > # Node ID cdaf19070ed1687a4f942936a0e7339355b98bfa > # Parent 8426275a13fdfac6dfe6955b7b3e999430eb373d > Http: add proxy_protocol_port variable for rfc6302 & support in realip module > > > real_port_header is not needed if "real_ip_header proxy_protocol" configured. > replace remote_port with request header if you set real_port_header. > > diff -r 8426275a13fd -r cdaf19070ed1 src/core/ngx_connection.h > --- a/src/core/ngx_connection.h Fri Apr 01 16:38:31 2016 +0300 > +++ b/src/core/ngx_connection.h Tue Apr 05 09:42:32 2016 +0900 > @@ -147,8 +147,10 @@ > struct sockaddr *sockaddr; > socklen_t socklen; > ngx_str_t addr_text; > + ngx_uint_t port; > > ngx_str_t proxy_protocol_addr; > + ngx_int_t proxy_protocol_port; > > #if (NGX_SSL) > ngx_ssl_connection_t *ssl; > diff -r 8426275a13fd -r cdaf19070ed1 src/core/ngx_inet.c > --- a/src/core/ngx_inet.c Fri Apr 01 16:38:31 2016 +0300 > +++ b/src/core/ngx_inet.c Tue Apr 05 09:42:32 2016 +0900 > @@ -256,6 +256,38 @@ > } > > > +ngx_uint_t > +ngx_sock_get_port(struct sockaddr *sa, socklen_t socklen) > +{ > + struct sockaddr_in *sin; > +#if (NGX_HAVE_INET6) > + struct sockaddr_in6 *sin6; > +#endif > + > + switch (sa->sa_family) { > + > + case AF_INET: > + sin = (struct sockaddr_in *) sa; > + return ntohs(sin->sin_port); > + break; > + > +#if (NGX_HAVE_INET6) > + > + case AF_INET6: > + > + sin6 = (struct sockaddr_in6 *) sa; > + > + return ntohs(sin6->sin6_port); > + > + break; > +#endif > + > + default: > + return 0; > + } > +} > + > + > size_t > ngx_inet_ntop(int family, void *addr, u_char *text, size_t len) > { > diff -r 8426275a13fd -r cdaf19070ed1 src/core/ngx_inet.h > --- a/src/core/ngx_inet.h Fri Apr 01 16:38:31 2016 +0300 > +++ b/src/core/ngx_inet.h Tue Apr 05 09:42:32 2016 +0900 > @@ -109,6 +109,7 @@ > #endif > size_t ngx_sock_ntop(struct sockaddr *sa, socklen_t socklen, u_char *text, > size_t len, ngx_uint_t port); > +ngx_uint_t ngx_sock_get_port(struct sockaddr *sa, socklen_t socklen); > size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len); > ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr); > ngx_int_t ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, > diff -r 8426275a13fd -r cdaf19070ed1 src/core/ngx_proxy_protocol.c > --- a/src/core/ngx_proxy_protocol.c Fri Apr 01 16:38:31 2016 +0300 > +++ b/src/core/ngx_proxy_protocol.c Tue Apr 05 09:42:32 2016 +0900 > @@ -13,7 +13,7 @@ > ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) > { > size_t len; > - u_char ch, *p, *addr; > + u_char ch, *p, *addr, *port; > > p = buf; > len = last - buf; > @@ -71,8 +71,40 @@ > ngx_memcpy(c->proxy_protocol_addr.data, addr, len); > c->proxy_protocol_addr.len = len; > > - ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, > - "PROXY protocol address: \"%V\"", &c->proxy_protocol_addr); > + for ( ;; ) { > + if (p == last) { > + goto invalid; > + } > + > + ch = *p++; > + > + if (ch == ' ') { > + break; > + } > + } > + port = p; > + for ( ;; ) { > + if (p == last) { > + goto invalid; > + } > + > + ch = *p++; > + > + if (ch == ' ') { > + break; > + } > + > + if (ch < '0' || ch > '9') > + { > + goto invalid; > + } > + } > + len = p - port - 1; > + c->proxy_protocol_port = ngx_atoi(port,len); > + > + ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0, > + "PROXY protocol address: \"%V\", PROXY protocol > port: \"%d\"", > + &c->proxy_protocol_addr, c->proxy_protocol_port); > > skip: > > diff -r 8426275a13fd -r cdaf19070ed1 src/event/ngx_event_accept.c > --- a/src/event/ngx_event_accept.c Fri Apr 01 16:38:31 2016 +0300 > +++ b/src/event/ngx_event_accept.c Tue Apr 05 09:42:32 2016 +0900 > @@ -278,6 +278,7 @@ > ngx_close_accepted_connection(c); > return; > } > + c->port = ngx_sock_get_port(c->sockaddr, c->socklen); > } > > #if (NGX_DEBUG) > diff -r 8426275a13fd -r cdaf19070ed1 src/http/modules/ngx_http_realip_module.c > --- a/src/http/modules/ngx_http_realip_module.c Fri Apr 01 16:38:31 2016 +0300 > +++ b/src/http/modules/ngx_http_realip_module.c Tue Apr 05 09:42:32 2016 +0900 > @@ -15,6 +15,8 @@ > #define NGX_HTTP_REALIP_HEADER 2 > #define NGX_HTTP_REALIP_PROXY 3 > > +#define NGX_HTTP_REALPORT_PROXY 1 > +#define NGX_HTTP_REALPORT_HEADER 2 > > typedef struct { > ngx_array_t *from; /* array of ngx_cidr_t */ > @@ -22,6 +24,9 @@ > ngx_uint_t hash; > ngx_str_t header; > ngx_flag_t recursive; > + ngx_uint_t porttype; > + ngx_uint_t porthash; > + ngx_str_t portheader; > } ngx_http_realip_loc_conf_t; > > > @@ -30,16 +35,18 @@ > struct sockaddr *sockaddr; > socklen_t socklen; > ngx_str_t addr_text; > + ngx_uint_t port; > } ngx_http_realip_ctx_t; > > > static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r); > static ngx_int_t ngx_http_realip_set_addr(ngx_http_request_t *r, > - ngx_addr_t *addr); > + ngx_addr_t *addr, ngx_uint_t port); > static void ngx_http_realip_cleanup(void *data); > static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, > void *conf); > static char *ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); > +static char *ngx_http_real_port(ngx_conf_t *cf, ngx_command_t *cmd, > void *conf); > static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf); > static char *ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, > void *parent, void *child); > @@ -49,6 +56,8 @@ > > static ngx_int_t ngx_http_realip_remote_addr_variable(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data); > +static ngx_int_t ngx_http_realip_remote_port_variable(ngx_http_request_t *r, > + ngx_http_variable_value_t *v, uintptr_t data); > > > static ngx_command_t ngx_http_realip_commands[] = { > @@ -67,6 +76,13 @@ > 0, > NULL }, > > + { ngx_string("real_port_header"), > + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, > + ngx_http_real_port, > + NGX_HTTP_LOC_CONF_OFFSET, > + 0, > + NULL }, > + > { ngx_string("real_ip_recursive"), > NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, > ngx_conf_set_flag_slot, > @@ -115,6 +131,9 @@ > { ngx_string("realip_remote_addr"), NULL, > ngx_http_realip_remote_addr_variable, 0, 0, 0 }, > > + { ngx_string("realip_remote_port"), NULL, > + ngx_http_realip_remote_port_variable, 0, 0, 0 }, > + > { ngx_null_string, NULL, NULL, 0, 0, 0 } > }; > > @@ -127,6 +146,7 @@ > ngx_str_t *value; > ngx_uint_t i, hash; > ngx_addr_t addr; > + ngx_uint_t port; > ngx_array_t *xfwd; > ngx_list_part_t *part; > ngx_table_elt_t *header; > @@ -146,6 +166,8 @@ > return NGX_DECLINED; > } > > + port = r->connection->port; > + > switch (rlcf->type) { > > case NGX_HTTP_REALIP_XREALIP: > @@ -172,8 +194,8 @@ > break; > > case NGX_HTTP_REALIP_PROXY: > - > value = &r->connection->proxy_protocol_addr; > + port = r->connection->proxy_protocol_port; > > if (value->len == 0) { > return NGX_DECLINED; > @@ -211,14 +233,52 @@ > value = &header[i].value; > xfwd = NULL; > > - goto found; > + goto portphase; > } > } > > return NGX_DECLINED; > } > > -found: > +portphase: > + > + > + switch (rlcf->porttype) { > + > + case NGX_CONF_UNSET_UINT: > + break; > + > + default: /* NGX_HTTP_REALPORT_HEADER */ > + > + part = &r->headers_in.headers.part; > + header = part->elts; > + > + hash = rlcf->porthash; > + len = rlcf->portheader.len; > + p = rlcf->portheader.data; > + > + for (i = 0; /* void */ ; i++) { > + > + if (i >= part->nelts) { > + if (part->next == NULL) { > + break; > + } > + > + part = part->next; > + header = part->elts; > + i = 0; > + } > + > + if (hash == header[i].hash > + && len == header[i].key.len > + && ngx_strncmp(p, header[i].lowcase_key, len) == 0) > + { > + port=ngx_atoi(header[i].value.data, header[i].value.len); > + > + break; > + } > + } > + } > > c = r->connection; > > @@ -230,7 +290,7 @@ > rlcf->recursive) > != NGX_DECLINED) > { > - return ngx_http_realip_set_addr(r, &addr); > + return ngx_http_realip_set_addr(r, &addr, port); > } > > return NGX_DECLINED; > @@ -238,7 +298,7 @@ > > > static ngx_int_t > -ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr) > +ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr, > ngx_uint_t port) > { > size_t len; > u_char *p; > @@ -276,11 +336,13 @@ > ctx->sockaddr = c->sockaddr; > ctx->socklen = c->socklen; > ctx->addr_text = c->addr_text; > + ctx->port = c->port; > > c->sockaddr = addr->sockaddr; > c->socklen = addr->socklen; > c->addr_text.len = len; > c->addr_text.data = p; > + c->port = port; > > return NGX_DECLINED; > } > @@ -298,6 +360,7 @@ > c->sockaddr = ctx->sockaddr; > c->socklen = ctx->socklen; > c->addr_text = ctx->addr_text; > + c->port = ctx->port; > } > > > @@ -383,6 +446,28 @@ > } > > > +static char * > +ngx_http_real_port(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) > +{ > + ngx_http_realip_loc_conf_t *rlcf = conf; > + > + ngx_str_t *value; > + > + value = cf->args->elts; > + > + if (ngx_strcmp(value[1].data, "proxy_protocol") == 0) { > + rlcf->porttype = NGX_HTTP_REALPORT_PROXY; > + return NGX_CONF_OK; > + } > + > + rlcf->porttype = NGX_HTTP_REALPORT_HEADER; > + rlcf->porthash = ngx_hash_strlow(value[1].data, value[1].data, > value[1].len); > + rlcf->portheader = value[1]; > + > + return NGX_CONF_OK; > +} > + > + > static void * > ngx_http_realip_create_loc_conf(ngx_conf_t *cf) > { > @@ -399,9 +484,12 @@ > * conf->from = NULL; > * conf->hash = 0; > * conf->header = { 0, NULL }; > + * conf->porthash = 0 > + * conf->portheader = { 0, NULL }; > */ > > conf->type = NGX_CONF_UNSET_UINT; > + conf->porttype = NGX_CONF_UNSET_UINT; > conf->recursive = NGX_CONF_UNSET; > > return conf; > @@ -510,3 +598,50 @@ > > return NGX_OK; > } > + > + > +static ngx_int_t > +ngx_http_realip_remote_port_variable(ngx_http_request_t *r, > + ngx_http_variable_value_t *v, uintptr_t data) > +{ > + ngx_uint_t port; > + ngx_pool_cleanup_t *cln; > + ngx_http_realip_ctx_t *ctx; > + > + ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module); > + > + if (ctx == NULL && (r->internal || r->filter_finalize)) { > + > + /* > + * if module context was reset, the original port > + * can still be found in the cleanup handler > + */ > + > + for (cln = r->pool->cleanup; cln; cln = cln->next) { > + if (cln->handler == ngx_http_realip_cleanup) { > + ctx = cln->data; > + break; > + } > + } > + } > + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, > + "piyo %ui %ui",ctx->port,r->connection->port); > + > + > + port = ctx ? ctx->port : r->connection->port; > + > + v->len = 0; > + v->valid = 1; > + v->no_cacheable = 0; > + v->not_found = 0; > + v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1); > + > + if (v->data == NULL) { > + return NGX_ERROR; > + } > + if (port > 0 && port < 65536) { > + v->len = ngx_sprintf(v->data, "%ui", port) - v->data; > + } > + > + return NGX_OK; > +} > diff -r 8426275a13fd -r cdaf19070ed1 src/http/ngx_http_variables.c > --- a/src/http/ngx_http_variables.c Fri Apr 01 16:38:31 2016 +0300 > +++ b/src/http/ngx_http_variables.c Tue Apr 05 09:42:32 2016 +0900 > @@ -58,6 +58,8 @@ > ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data); > +static ngx_int_t ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, > + ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r, > @@ -192,6 +194,9 @@ > { ngx_string("proxy_protocol_addr"), NULL, > ngx_http_variable_proxy_protocol_addr, 0, 0, 0 }, > > + { ngx_string("proxy_protocol_port"), NULL, > + ngx_http_variable_proxy_protocol_port, 0, 0, 0 }, > + > { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, > 0, 0, 0 }, > > { ngx_string("server_port"), NULL, ngx_http_variable_server_port, > 0, 0, 0 }, > @@ -1190,12 +1195,7 @@ > ngx_http_variable_remote_port(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data) > { > - ngx_uint_t port; > - struct sockaddr_in *sin; > -#if (NGX_HAVE_INET6) > - struct sockaddr_in6 *sin6; > -#endif > - > + ngx_uint_t port; > v->len = 0; > v->valid = 1; > v->no_cacheable = 0; > @@ -1205,27 +1205,8 @@ > if (v->data == NULL) { > return NGX_ERROR; > } > - > - switch (r->connection->sockaddr->sa_family) { > - > -#if (NGX_HAVE_INET6) > - case AF_INET6: > - sin6 = (struct sockaddr_in6 *) r->connection->sockaddr; > - port = ntohs(sin6->sin6_port); > - break; > -#endif > - > -#if (NGX_HAVE_UNIX_DOMAIN) > - case AF_UNIX: > - port = 0; > - break; > -#endif > - > - default: /* AF_INET */ > - sin = (struct sockaddr_in *) r->connection->sockaddr; > - port = ntohs(sin->sin_port); > - break; > - } > + > + port = r->connection->port; > > if (port > 0 && port < 65536) { > v->len = ngx_sprintf(v->data, "%ui", port) - v->data; > @@ -1250,6 +1231,29 @@ > > > static ngx_int_t > +ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, > + ngx_http_variable_value_t *v, uintptr_t data) > +{ > + ngx_int_t port = r->connection->proxy_protocol_port; > + > + v->len = 0; > + v->valid = 1; > + v->no_cacheable = 0; > + v->not_found = 0; > + v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1); > + > + if (v->data == NULL) { > + return NGX_ERROR; > + } > + if (port > 0 && port < 65536) { > + v->len = ngx_sprintf(v->data, "%ui", port) - v->data; > + } > + > + return NGX_OK; > +} > + > + > +static ngx_int_t > ngx_http_variable_server_addr(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data) > { > > > On Tue, Apr 5, 2016 at 2:56 AM, Maxim Dounin <mdounin at mdounin.ru> wrote: >> Hello! >> >> On Tue, Apr 05, 2016 at 02:12:21AM +0900, junpei yoshino wrote: >> >>> which is better way ? >>> 1. >>> "real_ip_from Forwarded" replace remote_addr and remote_port. >>> And proxy_protocol also replace remote_addr and remote_port, too. >> >> While support for Forwarded is a good thing to have, it looks like >> a separate and big work, so I wouldn't recommend trying to do this >> now. >> >>> 2. >>> "real_port_from Forwarded" replace port only. >>> ip and port is independent. >>> Also proxy protocol must configure real_ip_from and real_port_from. >> >> This approach looks wrong. If we know client port it should be >> used. But see above about Forwarded. >> >>> 3. >>> At first, not care Forwarded header. >>> delete code related x-forwarded-port. >>> support only custom http header including port number. >> >> This option looks most appropriate for now. >> >> (Assuming this also includes "proxy_protocol also replace >> remote_addr and remote_port" as in 1.) >> >> -- >> Maxim Dounin >> http://nginx.org/ >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > -- > junpei.yoshino at gmail.com -- junpei.yoshino at gmail.com From rmind at noxt.eu Mon Apr 18 21:40:59 2016 From: rmind at noxt.eu (Mindaugas Rasiukevicius) Date: Mon, 18 Apr 2016 22:40:59 +0100 Subject: Fix for ngx_unlock() and thus race conditions in AIO mechanism Message-ID: <20160418224059.91a93254e685d1d0b0558da9@noxt.eu> Hi, Some background: enabling AIO threads can result in "stuck" connections, permanently waiting for handler callback (in the system these connections appear in a CLOSE_WAIT state). This happens due to race condition(s) in the AIO thread pool code. Since the window is tiny, it may take hundreds of thousands of requests on a many-core machine to trigger a single race, but it is present in the real world: on some systems we accumulate over a hundred of them a day. Fix: add a compiler barrier to ngx_unlock(); since it is a macro, it is subject to the compiler reordering optimisations. Consider the following fragment of the ngx_thread_pool_cycle() function: ngx_spinlock(&ngx_thread_pool_done_lock, 1, 2048); *ngx_thread_pool_done.last = task; ngx_thread_pool_done.last = &task->next; ngx_unlock(&ngx_thread_pool_done_lock); (void) ngx_notify(ngx_thread_pool_handler); On nginx 1.9.14 RHEL 6 build (nginx-1.9.14-1.el6.ngx.x86_64.rpm), you can see the following assembly code: 438a05: bf 78 f6 70 00 mov $0x70f678,%edi ... 438a1c: e8 df a6 fe ff callq 423100 <ngx_spinlock> 438a21: 48 8b 05 60 6c 2d 00 mov 0x2d6c60(%rip),%rax 438a28: 48 c7 05 45 6c 2d 00 movq $0x0,0x2d6c45(%rip) # <-- 438a2f: 00 00 00 00 438a33: bf b0 8a 43 00 mov $0x438ab0,%edi 438a38: 48 89 2d 49 6c 2d 00 mov %rbp,0x2d6c49(%rip) 438a3f: 48 89 28 mov %rbp,(%rax) 438a42: ff 15 08 72 2d 00 callq *0x2d7208(%rip) You can see that at 0x438a28 it performs "*lock = 0" before inserting the task into the queue. This can race with ngx_thread_pool_handler(), where ngx_thread_pool_done list is reset before the "task" is inserted (that is, tasks just get lost). On x86/amd64, the unlock operation only needs a *compiler* barrier, it does not need a *memory* barrier. I used ngx_memory_barrier() in the patch, but you can optimise x86/amd64 to use __asm __volatile("":::"memory"). The patch is attached. Even better fix would be to use pthread_spin_lock or just pthread_mutex_lock. Why roll out your own one? -- Mindaugas -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ngx_unlock.patch URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160418/fbabe82f/attachment.ksh> From mdounin at mdounin.ru Tue Apr 19 14:00:10 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 19 Apr 2016 17:00:10 +0300 Subject: Fix for ngx_unlock() and thus race conditions in AIO mechanism In-Reply-To: <20160418224059.91a93254e685d1d0b0558da9@noxt.eu> References: <20160418224059.91a93254e685d1d0b0558da9@noxt.eu> Message-ID: <20160419140009.GX36620@mdounin.ru> Hello! On Mon, Apr 18, 2016 at 10:40:59PM +0100, Mindaugas Rasiukevicius wrote: > Some background: enabling AIO threads can result in "stuck" connections, > permanently waiting for handler callback (in the system these connections > appear in a CLOSE_WAIT state). This happens due to race condition(s) in > the AIO thread pool code. Since the window is tiny, it may take hundreds > of thousands of requests on a many-core machine to trigger a single race, > but it is present in the real world: on some systems we accumulate over > a hundred of them a day. > > Fix: add a compiler barrier to ngx_unlock(); since it is a macro, it is > subject to the compiler reordering optimisations. Consider the following > fragment of the ngx_thread_pool_cycle() function: > > ngx_spinlock(&ngx_thread_pool_done_lock, 1, 2048); > *ngx_thread_pool_done.last = task; > ngx_thread_pool_done.last = &task->next; > ngx_unlock(&ngx_thread_pool_done_lock); > (void) ngx_notify(ngx_thread_pool_handler); Thanks for catching. Patch that follows the same logic as used in ngx_update_time(), that is, with an explicit ngx_memory_barrier() call before ngx_unlock(), and no barrier semantics in ngx_unlock() itself: # HG changeset patch # User Maxim Dounin <mdounin at mdounin.ru> # Date 1461074302 -10800 # Tue Apr 19 16:58:22 2016 +0300 # Node ID 2bd8671356581d351a07c871bf57676b23605109 # Parent 2fe71825c99a3e7442c2f96899379675148a83f7 Thread pools: memory barriers in thread task notifications. The ngx_thread_pool_done object isn't volatile, and at least some compilers assume that it is permitted to reorder modifications of volatile and non-volatile objects. Added appropriate ngx_memory_barrier() calls to make sure all modifications will happen before the lock is released. Reported by Mindaugas Rasiukevicius, http://mailman.nginx.org/pipermail/nginx-devel/2016-April/008160.html. diff --git a/src/core/ngx_thread_pool.c b/src/core/ngx_thread_pool.c --- a/src/core/ngx_thread_pool.c +++ b/src/core/ngx_thread_pool.c @@ -345,6 +345,8 @@ ngx_thread_pool_cycle(void *data) *ngx_thread_pool_done.last = task; ngx_thread_pool_done.last = &task->next; + ngx_memory_barrier(); + ngx_unlock(&ngx_thread_pool_done_lock); (void) ngx_notify(ngx_thread_pool_handler); @@ -366,6 +368,8 @@ ngx_thread_pool_handler(ngx_event_t *ev) ngx_thread_pool_done.first = NULL; ngx_thread_pool_done.last = &ngx_thread_pool_done.first; + ngx_memory_barrier(); + ngx_unlock(&ngx_thread_pool_done_lock); while (task) { -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Tue Apr 19 14:09:33 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 19 Apr 2016 14:09:33 +0000 Subject: [nginx] HTTP/2: write logs when refusing streams with data. Message-ID: <hg.ab16126a06a0.1461074973.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/ab16126a06a0 branches: changeset: 6516:ab16126a06a0 user: Maxim Dounin <mdounin at mdounin.ru> date: Mon Apr 18 21:18:24 2016 +0300 description: HTTP/2: write logs when refusing streams with data. Refusing streams is known to be incorrectly handled at least by IE, Edge and Safari. Make sure to provide appropriate logging to simplify fixing this in the affected browsers. diffstat: src/http/v2/ngx_http_v2.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -1060,6 +1060,10 @@ ngx_http_v2_state_headers(ngx_http_v2_co if (!h2c->settings_ack && !(h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG)) { + ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, + "client sent stream with data " + "before settings were acknowledged"); + status = NGX_HTTP_V2_REFUSED_STREAM; goto rst_stream; } From mdounin at mdounin.ru Tue Apr 19 14:20:42 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 19 Apr 2016 14:20:42 +0000 Subject: [nginx] Thread pools: memory barriers in task completion notifications. Message-ID: <hg.657e029bac28.1461075642.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/657e029bac28 branches: changeset: 6517:657e029bac28 user: Maxim Dounin <mdounin at mdounin.ru> date: Tue Apr 19 17:18:28 2016 +0300 description: Thread pools: memory barriers in task completion notifications. The ngx_thread_pool_done object isn't volatile, and at least some compilers assume that it is permitted to reorder modifications of volatile and non-volatile objects. Added appropriate ngx_memory_barrier() calls to make sure all modifications will happen before the lock is released. Reported by Mindaugas Rasiukevicius, http://mailman.nginx.org/pipermail/nginx-devel/2016-April/008160.html. diffstat: src/core/ngx_thread_pool.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (21 lines): diff --git a/src/core/ngx_thread_pool.c b/src/core/ngx_thread_pool.c --- a/src/core/ngx_thread_pool.c +++ b/src/core/ngx_thread_pool.c @@ -345,6 +345,8 @@ ngx_thread_pool_cycle(void *data) *ngx_thread_pool_done.last = task; ngx_thread_pool_done.last = &task->next; + ngx_memory_barrier(); + ngx_unlock(&ngx_thread_pool_done_lock); (void) ngx_notify(ngx_thread_pool_handler); @@ -366,6 +368,8 @@ ngx_thread_pool_handler(ngx_event_t *ev) ngx_thread_pool_done.first = NULL; ngx_thread_pool_done.last = &ngx_thread_pool_done.first; + ngx_memory_barrier(); + ngx_unlock(&ngx_thread_pool_done_lock); while (task) { From vbart at nginx.com Tue Apr 19 14:39:55 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 19 Apr 2016 14:39:55 +0000 Subject: [nginx] HTTP/2: don't send WINDOW_UPDATE for an empty request body. Message-ID: <hg.7760b54d5458.1461076795.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/7760b54d5458 branches: changeset: 6518:7760b54d5458 user: Valentin Bartenev <vbart at nginx.com> date: Tue Apr 19 17:38:49 2016 +0300 description: HTTP/2: don't send WINDOW_UPDATE for an empty request body. Particularly this prevents sending WINDOW_UPDATE with zero delta which can result in PROTOCOL_ERROR. Also removed surplus setting of no_flow_control to 0. diffstat: src/http/v2/ngx_http_v2.c | 29 +++++++++++++++-------------- 1 files changed, 15 insertions(+), 14 deletions(-) diffs (39 lines): diff -r 657e029bac28 -r 7760b54d5458 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Tue Apr 19 17:18:28 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Tue Apr 19 17:38:49 2016 +0300 @@ -3481,20 +3481,21 @@ ngx_http_v2_read_request_body(ngx_http_r return ngx_http_v2_process_request_body(r, NULL, 0, 1); } - if (r->request_body_no_buffering) { - stream->no_flow_control = 0; - stream->recv_window = (size_t) len; - - } else { - stream->no_flow_control = 1; - stream->recv_window = NGX_HTTP_V2_MAX_WINDOW; - } - - if (ngx_http_v2_send_window_update(stream->connection, stream->node->id, - stream->recv_window) - == NGX_ERROR) - { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + if (len) { + if (r->request_body_no_buffering) { + stream->recv_window = (size_t) len; + + } else { + stream->no_flow_control = 1; + stream->recv_window = NGX_HTTP_V2_MAX_WINDOW; + } + + if (ngx_http_v2_send_window_update(stream->connection, stream->node->id, + stream->recv_window) + == NGX_ERROR) + { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } } ngx_add_timer(r->connection->read, clcf->client_body_timeout); From vbart at nginx.com Tue Apr 19 14:39:58 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 19 Apr 2016 14:39:58 +0000 Subject: [nginx] HTTP/2: skip data frames in case of internal errors. Message-ID: <hg.9ac934dd5dd8.1461076798.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/9ac934dd5dd8 branches: changeset: 6519:9ac934dd5dd8 user: Valentin Bartenev <vbart at nginx.com> date: Tue Apr 19 17:38:49 2016 +0300 description: HTTP/2: skip data frames in case of internal errors. This prevents possible processing of such frames and triggering rb->post_handler if an error occurred during r->request_body initialization. diffstat: src/http/v2/ngx_http_v2.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (19 lines): diff -r 7760b54d5458 -r 9ac934dd5dd8 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Tue Apr 19 17:38:49 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Tue Apr 19 17:38:49 2016 +0300 @@ -3473,6 +3473,7 @@ ngx_http_v2_read_request_body(ngx_http_r } if (rb->buf == NULL) { + stream->skip_data = 1; return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -3494,6 +3495,7 @@ ngx_http_v2_read_request_body(ngx_http_r stream->recv_window) == NGX_ERROR) { + stream->skip_data = 1; return NGX_HTTP_INTERNAL_SERVER_ERROR; } } From vbart at nginx.com Tue Apr 19 14:40:01 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 19 Apr 2016 14:40:01 +0000 Subject: [nginx] HTTP/2: send the output queue after emitting WINDOW_UPDATE. Message-ID: <hg.9070ba416284.1461076801.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/9070ba416284 branches: changeset: 6520:9070ba416284 user: Valentin Bartenev <vbart at nginx.com> date: Tue Apr 19 17:38:49 2016 +0300 description: HTTP/2: send the output queue after emitting WINDOW_UPDATE. The WINDOW_UPDATE frame could be left in the output queue for an indefinite period of time resulting in the request timeout. This might happen if reading of the body was triggered by an event unrelated to client connection, e.g. by the limit_req timer. diffstat: src/http/v2/ngx_http_v2.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diffs (27 lines): diff -r 9ac934dd5dd8 -r 9070ba416284 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Tue Apr 19 17:38:49 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Tue Apr 19 17:38:49 2016 +0300 @@ -3414,6 +3414,7 @@ ngx_http_v2_read_request_body(ngx_http_r ngx_http_v2_stream_t *stream; ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; + ngx_http_v2_connection_t *h2c; stream = r->stream; @@ -3498,6 +3499,15 @@ ngx_http_v2_read_request_body(ngx_http_r stream->skip_data = 1; return NGX_HTTP_INTERNAL_SERVER_ERROR; } + + h2c = stream->connection; + + if (!h2c->blocked) { + if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) { + stream->skip_data = 1; + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + } } ngx_add_timer(r->connection->read, clcf->client_body_timeout); From mdounin at mdounin.ru Tue Apr 19 16:04:47 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 19 Apr 2016 16:04:47 +0000 Subject: [nginx] nginx-1.9.15-RELEASE Message-ID: <hg.13070ecfda67.1461081887.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/13070ecfda67 branches: changeset: 6521:13070ecfda67 user: Maxim Dounin <mdounin at mdounin.ru> date: Tue Apr 19 19:02:37 2016 +0300 description: nginx-1.9.15-RELEASE diffstat: docs/xml/nginx/changes.xml | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 55 insertions(+), 0 deletions(-) diffs (65 lines): diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,61 @@ <change_log title="nginx"> +<changes ver="1.9.15" date="19.04.2016"> + +<change type="bugfix"> +<para lang="ru"> +??? ????????????? HHVM ? ???????? FastCGI-??????? +????? ????????? ?????? "recv() failed". +</para> +<para lang="en"> +"recv() failed" errors might occur +when using HHVM as a FastCGI server. +</para> +</change> + +<change type="bugfix"> +<para lang="ru"> +??? ????????????? HTTP/2 ? ???????? limit_req ??? auth_request +??? ?????? ???? ??????? ??? ????????? ??????? +??? ?????? "client violated flow control"; +?????? ????????? ? 1.9.14. +</para> +<para lang="en"> +when using HTTP/2 and the "limit_req" or "auth_request" directives +a timeout or a "client violated flow control" error +might occur while reading client request body; +the bug had appeared in 1.9.14. +</para> +</change> + +<change type="workaround"> +<para lang="ru"> +??? ????????????? HTTP/2 ????? ??? ?? ???????????? ?????????? ??????????, +???? ???? ??????? ???? ????????? ?? ???????; +?????? ????????? ? 1.9.14. +</para> +<para lang="en"> +a response might not be shown by some browsers +if HTTP/2 was used and client request body was not fully read; +the bug had appeared in 1.9.14. +</para> +</change> + +<change type="bugfix"> +<para lang="ru"> +??? ????????????? ????????? "aio threads" ?????????? ????? ????????.<br/> +??????? Mindaugas Rasiukevicius. +</para> +<para lang="en"> +connections might hang when using the "aio threads" directive.<br/> +Thanks to Mindaugas Rasiukevicius. +</para> +</change> + +</changes> + + <changes ver="1.9.14" date="05.04.2016"> <change type="feature"> From mdounin at mdounin.ru Tue Apr 19 16:04:50 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 19 Apr 2016 16:04:50 +0000 Subject: [nginx] release-1.9.15 tag Message-ID: <hg.5b5a2d8d4d97.1461081890.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/5b5a2d8d4d97 branches: changeset: 6522:5b5a2d8d4d97 user: Maxim Dounin <mdounin at mdounin.ru> date: Tue Apr 19 19:02:37 2016 +0300 description: release-1.9.15 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -397,3 +397,4 @@ fe66cff450a95beed36a2515210eb2d7ef62c9d3 ead3907d74f90a14d1646f1b2b56ba01d3d11702 release-1.9.12 5936b7ed929237f1a73b467f662611cdc0309e51 release-1.9.13 4106db71cbcb9c8274700199ac17e520902c6c0f release-1.9.14 +13070ecfda67397985f0e986eb9c42ecb46d05b5 release-1.9.15 From rmind at noxt.eu Tue Apr 19 16:09:55 2016 From: rmind at noxt.eu (Mindaugas Rasiukevicius) Date: Tue, 19 Apr 2016 17:09:55 +0100 Subject: Fix for ngx_unlock() and thus race conditions in AIO mechanism In-Reply-To: <20160419140009.GX36620@mdounin.ru> References: <20160418224059.91a93254e685d1d0b0558da9@noxt.eu> <20160419140009.GX36620@mdounin.ru> Message-ID: <20160419170955.99b45df8cbd4ec8c6b7d2b52@noxt.eu> Maxim Dounin <mdounin at mdounin.ru> wrote: > Patch that follows the same logic as used in ngx_update_time(), that is, > with an explicit ngx_memory_barrier() call before ngx_unlock(), and no > barrier semantics in ngx_unlock() itself: I can just point out that pretty much all spin-lock implementations provide memory ordering guarantees; this is 1990s discussion which has been settled by now with a consensus that certain ordering guarantees should be provided by the synchronisation primitives. If you will look into the kernels (be it Linux, BSD or Solaris -- it was Sun who de facto set the standard back in the day), libraries (say libpthread) or other projects, (e.g. PostgreSQL) -- you will find the right barrier in the unlock operation. If you do not provide these guarantees, then you provide something what is different from a textbook implementation of a spin-lock. It is rather dangerous and unlikely to prevent from bugs. -- Mindaugas From mdounin at mdounin.ru Tue Apr 19 16:47:08 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 19 Apr 2016 19:47:08 +0300 Subject: Fix for ngx_unlock() and thus race conditions in AIO mechanism In-Reply-To: <20160419170955.99b45df8cbd4ec8c6b7d2b52@noxt.eu> References: <20160418224059.91a93254e685d1d0b0558da9@noxt.eu> <20160419140009.GX36620@mdounin.ru> <20160419170955.99b45df8cbd4ec8c6b7d2b52@noxt.eu> Message-ID: <20160419164708.GH36620@mdounin.ru> Hello! On Tue, Apr 19, 2016 at 05:09:55PM +0100, Mindaugas Rasiukevicius wrote: > Maxim Dounin <mdounin at mdounin.ru> wrote: > > Patch that follows the same logic as used in ngx_update_time(), that is, > > with an explicit ngx_memory_barrier() call before ngx_unlock(), and no > > barrier semantics in ngx_unlock() itself: > > I can just point out that pretty much all spin-lock implementations > provide memory ordering guarantees; this is 1990s discussion which has > been settled by now with a consensus that certain ordering guarantees > should be provided by the synchronisation primitives. If you will look > into the kernels (be it Linux, BSD or Solaris -- it was Sun who de facto > set the standard back in the day), libraries (say libpthread) or other > projects, (e.g. PostgreSQL) -- you will find the right barrier in the > unlock operation. > > If you do not provide these guarantees, then you provide something what > is different from a textbook implementation of a spin-lock. It is rather > dangerous and unlikely to prevent from bugs. Sure, current behaviour of ngx_unlock() is different from a textbook one, and we may consider changing it to something more common, even if it means additional unneeded barriers in ngx_update_time(). But changing semantics and fixing bugs are distinct things and shouldn't be mixed whenever possible. -- Maxim Dounin http://nginx.org/ From anthonyryan1 at gmail.com Wed Apr 20 04:33:17 2016 From: anthonyryan1 at gmail.com (Anthony Ryan) Date: Wed, 20 Apr 2016 00:33:17 -0400 Subject: 3rd party modules requiring ngx_http_postpone_filter_module Message-ID: <CACqULmNs80FAG8D7wE=+Kcxzc-WP9kA9FkVS-kCU5=RmSUQGXw@mail.gmail.com> Hello, I'm currently looking for ideas to resolve a 3rd party module regression[1][2] that I keep running into, and figured it would be best to consult the experts. The ngx_http_postpone_filter_module is a critical helper for many modules to ensure subrequests are properly ordered. But I can't seem to find a proper way to ensure it's included for a 3rd party module. All of the internal modules which use it have a special declaration in the auto/modules file enabling postpone, but among the 3rd party modules there has only ever been crappy workarounds (documentation saying to enable the SSI module or another which pulls in postpone) or hacks to add HTTP_POSTPONE_FILTER_SRCS to HTTP_SRCS. With the new build system introduced in 1.9.11 though, HTTP_POSTPONE_FILTER_SRCS is no longer exposed to the config file 3rd party modules use, and we've hit a bit of an impasse. We either need to pile on increasingly desperate hacks, or we need a better way to express to the build system when a 3rd party module depends on postpone. One possible solution is to patch the build process to have a "preconfig" file where modules could override the options specified in auto/options but it would also give 3rd party modules more room to mess up variables and break nginx in unexpected ways. Another option could be to modify the build process to check for inter-module dependencies being satisfied. So that a module could specify that it depends on ngx_http_postpone_filter_module and after all modules were configured, if any dependencies were not enabled, they would then be configured as well. So I pose the question: How can we ensure 3rd party modules can pull in postpone in a future proof way? Is there an obvious solution I'm overlooking? Or how can the build process be modified to address this? Kind regards, Anthony Ryan [1] https://github.com/evanmiller/mod_zip/issues/52 [2] https://github.com/openresty/echo-nginx-module/pull/42 From mdounin at mdounin.ru Wed Apr 20 14:16:06 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 20 Apr 2016 17:16:06 +0300 Subject: 3rd party modules requiring ngx_http_postpone_filter_module In-Reply-To: <CACqULmNs80FAG8D7wE=+Kcxzc-WP9kA9FkVS-kCU5=RmSUQGXw@mail.gmail.com> References: <CACqULmNs80FAG8D7wE=+Kcxzc-WP9kA9FkVS-kCU5=RmSUQGXw@mail.gmail.com> Message-ID: <20160420141605.GJ36620@mdounin.ru> Hello! On Wed, Apr 20, 2016 at 12:33:17AM -0400, Anthony Ryan wrote: > Hello, > > I'm currently looking for ideas to resolve a 3rd party module > regression[1][2] that I keep running into, and figured it would be > best to consult the experts. > > The ngx_http_postpone_filter_module is a critical helper for many > modules to ensure subrequests are properly ordered. But I can't seem > to find a proper way to ensure it's included for a 3rd party module. > > All of the internal modules which use it have a special declaration in > the auto/modules file enabling postpone, but among the 3rd party > modules there has only ever been crappy workarounds (documentation > saying to enable the SSI module or another which pulls in postpone) or > hacks to add HTTP_POSTPONE_FILTER_SRCS to HTTP_SRCS. I personally think that documenting that SSI module should not be excluded from a build is good enough approach for all practical reasons. Hacks that use HTTP_POSTPONE_FILTER_SRCS are certainly hacks and they were expected to fail sooner or later. [...] -- Maxim Dounin http://nginx.org/ From robinmonjo at gmail.com Thu Apr 21 22:32:00 2016 From: robinmonjo at gmail.com (Robin Monjo) Date: Fri, 22 Apr 2016 00:32:00 +0200 Subject: Module development: Stuck in "access phase: 6" when calling a function from a shared library (written in Go) Message-ID: <DC5CC0D7-D003-445D-9055-C8CE779E9E42@gmail.com> Hello all, I?m trying to build a nginx module both with C code and Go code. The idea is to create a Go code that is compiled into a shared library and then call function of this lib from a basic nginx module C code. Here is my handler (in C), taken from this guide: https://www.airpair.com/nginx/extending-nginx-tutorial <https://www.airpair.com/nginx/extending-nginx-tutorial> ???????????????????????????????????????? static ngx_int_t ngx_http_l_handler(ngx_http_request_t *r) { if (r->main->internal) { //already processed return NGX_DECLINED; } r->main->internal = 1; // mark as processed ngx_table_elt_t *h; h = ngx_list_push(&r->headers_out.headers); h->hash = 1; ngx_str_set(&h->key, "X-NGINX-Tutorial"); ngx_str_set(&h->value, "Hello World!"); HandleRequest(); // calling go code here :) return NGX_DECLINED; } ???????????????????????????????????????? It just inject a HTTP header. It works fine, without the ?HandleRequest()? call. ?HandleRequest()? is a function coming from the Go code. This function is empty and does nothing. With this call, nginx just never finishes the response and is stuck. Here are the logs: ???????????????????????????????????????? 2016/04/21 21:57:01 [debug] 33#0: epoll: fd:6 ev:0001 d:00007FC064EA9010 2016/04/21 21:57:01 [debug] 33#0: accept on 0.0.0.0:8888, ready: 0 2016/04/21 21:57:01 [debug] 33#0: posix_memalign: 00000000007426F0:512 @16 2016/04/21 21:57:01 [debug] 33#0: *1 accept: 127.0.0.1:43842 fd:3 2016/04/21 21:57:01 [debug] 33#0: *1 event timer add: 3: 60000:1461275881230 2016/04/21 21:57:01 [debug] 33#0: *1 reusable connection: 1 2016/04/21 21:57:01 [debug] 33#0: *1 epoll add event: fd:3 op:1 ev:80002001 2016/04/21 21:57:01 [debug] 33#0: timer delta: 17268 2016/04/21 21:57:01 [debug] 33#0: worker cycle 2016/04/21 21:57:01 [debug] 33#0: epoll timer: 60000 2016/04/21 21:57:01 [debug] 33#0: epoll: fd:3 ev:0001 d:00007FC064EA91B0 2016/04/21 21:57:01 [debug] 33#0: *1 http wait request handler 2016/04/21 21:57:01 [debug] 33#0: *1 malloc: 0000000000742900:1024 2016/04/21 21:57:01 [debug] 33#0: *1 recv: fd:3 78 of 1024 2016/04/21 21:57:01 [debug] 33#0: *1 reusable connection: 0 2016/04/21 21:57:01 [debug] 33#0: *1 posix_memalign: 0000000000742D10:4096 @16 2016/04/21 21:57:01 [debug] 33#0: *1 http process request line 2016/04/21 21:57:01 [debug] 33#0: *1 http request line: "GET / HTTP/1.1" 2016/04/21 21:57:01 [debug] 33#0: *1 http uri: "/" 2016/04/21 21:57:01 [debug] 33#0: *1 http args: "" 2016/04/21 21:57:01 [debug] 33#0: *1 http exten: "" 2016/04/21 21:57:01 [debug] 33#0: *1 http process request header line 2016/04/21 21:57:01 [debug] 33#0: *1 http header: "User-Agent: curl/7.35.0" 2016/04/21 21:57:01 [debug] 33#0: *1 http header: "Host: 127.0.0.1:8888" 2016/04/21 21:57:01 [debug] 33#0: *1 http header: "Accept: */*" 2016/04/21 21:57:01 [debug] 33#0: *1 http header done 2016/04/21 21:57:01 [debug] 33#0: *1 event timer del: 3: 1461275881230 2016/04/21 21:57:01 [debug] 33#0: *1 rewrite phase: 0 2016/04/21 21:57:01 [debug] 33#0: *1 test location: "/" 2016/04/21 21:57:01 [debug] 33#0: *1 using configuration "/" 2016/04/21 21:57:01 [debug] 33#0: *1 http cl:-1 max:1048576 2016/04/21 21:57:01 [debug] 33#0: *1 rewrite phase: 2 2016/04/21 21:57:01 [debug] 33#0: *1 post rewrite phase: 3 2016/04/21 21:57:01 [debug] 33#0: *1 generic phase: 4 2016/04/21 21:57:01 [debug] 33#0: *1 generic phase: 5 2016/04/21 21:57:01 [debug] 33#0: *1 access phase: 6 // stuck here nothing will happen next ... ???????????????????????????????????????? I have no warning or error during the compilation of my module. Any idea of where this behaviour could come from ? Regards, Robin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160422/834cfcd6/attachment.html> From agentzh at gmail.com Fri Apr 22 19:27:13 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Fri, 22 Apr 2016 12:27:13 -0700 Subject: 3rd party modules requiring ngx_http_postpone_filter_module In-Reply-To: <20160420141605.GJ36620@mdounin.ru> References: <CACqULmNs80FAG8D7wE=+Kcxzc-WP9kA9FkVS-kCU5=RmSUQGXw@mail.gmail.com> <20160420141605.GJ36620@mdounin.ru> Message-ID: <CAB4Tn6OQgjdLGkhdt6Gp_+zcuT1oeoCei9Nj2M=o6=zBKA8ZYA@mail.gmail.com> Hello! On Wed, Apr 20, 2016 at 7:16 AM, Maxim Dounin wrote: > I personally think that documenting that SSI module should not be > excluded from a build is good enough approach for all practical > reasons. > As the author of the ngx_echo and ngx_srcache modules that require the http postpone module, I must say I disagree with you here. There is just no reason to include unrelated standard modules like SSI or Addition when they are not really required. Regards, -agentzh From vbart at nginx.com Mon Apr 25 11:57:06 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Mon, 25 Apr 2016 14:57:06 +0300 Subject: 3rd party modules requiring ngx_http_postpone_filter_module In-Reply-To: <CAB4Tn6OQgjdLGkhdt6Gp_+zcuT1oeoCei9Nj2M=o6=zBKA8ZYA@mail.gmail.com> References: <CACqULmNs80FAG8D7wE=+Kcxzc-WP9kA9FkVS-kCU5=RmSUQGXw@mail.gmail.com> <20160420141605.GJ36620@mdounin.ru> <CAB4Tn6OQgjdLGkhdt6Gp_+zcuT1oeoCei9Nj2M=o6=zBKA8ZYA@mail.gmail.com> Message-ID: <1886793.mySUlOVymV@vbart-workstation> On Friday 22 April 2016 12:27:13 Yichun Zhang wrote: > Hello! > > On Wed, Apr 20, 2016 at 7:16 AM, Maxim Dounin wrote: > > I personally think that documenting that SSI module should not be > > excluded from a build is good enough approach for all practical > > reasons. > > > > As the author of the ngx_echo and ngx_srcache modules that require the > http postpone module, I must say I disagree with you here. There is > just no reason to include unrelated standard modules like SSI or > Addition when they are not really required. > +1 wbr, Valentin V. Bartenev From pankajitbhu at gmail.com Tue Apr 26 11:37:19 2016 From: pankajitbhu at gmail.com (Pankaj Chaudhary) Date: Tue, 26 Apr 2016 17:07:19 +0530 Subject: reading cookie value issue Message-ID: <CAAePTQq5mozKbt1dhrNwLfgTDJdG59FDyrnBmyFTAdTeFtUdKA@mail.gmail.com> Hi, I have requirement to create own cookie based on input and wirte the that cookie in header. whenever i need that i can read from header and use it. for example:- I have created my own cookie "thissomevalue" worte in header and later the same read from header. Please check my code and let me know why i am not able to read the value from header. Below code snippet to set header value in request header:- ngx_table_elt_t *cookie; cookie = ngx_list_push(&r->headers_in.headers); cookie->lowcase_key = (u_char*) "cookie"; ngx_str_set(&cookie->key, "Cookie"); ngx_str_set(&cookie->value, "somevalue"); cookie->hash = ngx_crc32_long(cookie->lowcase_key, cookie->key.len); Below code snippet to read set value from header:- ngx_http_core_main_conf_t *clcf; ngx_str_t *type; ngx_uint_t key; ngx_str_t val = ngx_string("cookie"); clcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); key= ngx_hash_key_lc(val.data, val.len); type = ngx_hash_find(&clcf->headers_in_hash, key, val.data, val.len); if (type != NULL) { ngx_table_elt_t *test_val; test_val= ngx_list_push(&r->headers_out.headers); test_val->lowcase_key = (u_char*) "test_val"; ngx_str_set(&test_val->key, "Test_Val"); ngx_str_set(&test_val->value, type->data); test_val->hash = ngx_crc32_long(test_val->lowcase_key, test_val->key.len); } curl response:-Test_val was accepting "somevalue" HTTP/1.1 200 OK Server: nginx/1.9.12 Date: Tue, 26 Apr 2016 19:13:40 GMT Content-Type: text/plain Content-Length: 34 Connection: keep-alive Test_Val: Cookie Hello, This is Nginx test Module! Thanks & Regards, Pankaj Chaudhary -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160426/af20a22f/attachment.html> From mdounin at mdounin.ru Tue Apr 26 13:08:25 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 26 Apr 2016 16:08:25 +0300 Subject: reading cookie value issue In-Reply-To: <CAAePTQq5mozKbt1dhrNwLfgTDJdG59FDyrnBmyFTAdTeFtUdKA@mail.gmail.com> References: <CAAePTQq5mozKbt1dhrNwLfgTDJdG59FDyrnBmyFTAdTeFtUdKA@mail.gmail.com> Message-ID: <20160426130825.GZ36620@mdounin.ru> Hello! On Tue, Apr 26, 2016 at 05:07:19PM +0530, Pankaj Chaudhary wrote: > Hi, > > I have requirement to create own cookie based on input and wirte the that > cookie in header. > whenever i need that i can read from header and use it. > > > for example:- > > I have created my own cookie "thissomevalue" worte in header and later the > same read from header. > > Please check my code and let me know why i am not able to read the value > from header. > > Below code snippet to set header value in request header:- > > ngx_table_elt_t *cookie; > cookie = ngx_list_push(&r->headers_in.headers); > cookie->lowcase_key = (u_char*) "cookie"; > ngx_str_set(&cookie->key, "Cookie"); > ngx_str_set(&cookie->value, "somevalue"); > cookie->hash = ngx_crc32_long(cookie->lowcase_key, cookie->key.len); Note: you are not expected to modify request headers (r->headers_in). Doing so will likely lead to segmentation faults. If you want to provide your own cookie for a backend server, consider using proxy_set_header instead, see http://nginx.org/r/proxy_set_header. > Below code snippet to read set value from header:- > > ngx_http_core_main_conf_t *clcf; > ngx_str_t *type; > ngx_uint_t key; > ngx_str_t val = ngx_string("cookie"); > clcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); > key= ngx_hash_key_lc(val.data, val.len); > type = ngx_hash_find(&clcf->headers_in_hash, key, val.data, val.len); > > if (type != NULL) > { > ngx_table_elt_t *test_val; > test_val= ngx_list_push(&r->headers_out.headers); > test_val->lowcase_key = (u_char*) "test_val"; > ngx_str_set(&test_val->key, "Test_Val"); > ngx_str_set(&test_val->value, type->data); > test_val->hash = ngx_crc32_long(test_val->lowcase_key, test_val->key.len); > } Structures stored in cmcf->headers_in_hash are ngx_http_header_t, see ngx_http_headers_in[] array in src/http/ngx_http_request.c. It is not expected to contain header value. In case of the Cookie header, it's expected to contain the header name, function to handle the header during reading request headers from a client, and an offset of r->headers_in.cookie. If you want to find out how to read a cookie as got from client, consider looking at the ngx_http_variable_cookie() function in src/http/ngx_http_variables.c. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Tue Apr 26 13:47:12 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 26 Apr 2016 13:47:12 +0000 Subject: [nginx] Stable branch. Message-ID: <hg.9fc87d93c4ed.1461678432.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/9fc87d93c4ed branches: stable-1.10 changeset: 6523:9fc87d93c4ed user: Maxim Dounin <mdounin at mdounin.ru> date: Tue Apr 26 16:30:30 2016 +0300 description: Stable branch. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1009015 -#define NGINX_VERSION "1.9.15" +#define nginx_version 1010000 +#define NGINX_VERSION "1.10.0" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From mdounin at mdounin.ru Tue Apr 26 13:47:14 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 26 Apr 2016 13:47:14 +0000 Subject: [nginx] nginx-1.10.0-RELEASE Message-ID: <hg.d4b7edd7fa81.1461678434.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/d4b7edd7fa81 branches: stable-1.10 changeset: 6524:d4b7edd7fa81 user: Maxim Dounin <mdounin at mdounin.ru> date: Tue Apr 26 16:31:18 2016 +0300 description: nginx-1.10.0-RELEASE diffstat: docs/xml/nginx/changes.xml | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diffs (24 lines): diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,20 @@ <change_log title="nginx"> +<changes ver="1.10.0" date="26.04.2016"> + +<change> +<para lang="ru"> +?????????? ????? 1.10.x. +</para> +<para lang="en"> +1.10.x stable branch. +</para> +</change> + +</changes> + + <changes ver="1.9.15" date="19.04.2016"> <change type="bugfix"> From mdounin at mdounin.ru Tue Apr 26 13:47:17 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 26 Apr 2016 13:47:17 +0000 Subject: [nginx] release-1.10.0 tag Message-ID: <hg.efbdc2f66901.1461678437.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/efbdc2f66901 branches: stable-1.10 changeset: 6525:efbdc2f66901 user: Maxim Dounin <mdounin at mdounin.ru> date: Tue Apr 26 16:31:18 2016 +0300 description: release-1.10.0 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -398,3 +398,4 @@ ead3907d74f90a14d1646f1b2b56ba01d3d11702 5936b7ed929237f1a73b467f662611cdc0309e51 release-1.9.13 4106db71cbcb9c8274700199ac17e520902c6c0f release-1.9.14 13070ecfda67397985f0e986eb9c42ecb46d05b5 release-1.9.15 +d4b7edd7fa81cbf554ee3dcfe9de53ad6d1dbc69 release-1.10.0 From ru at nginx.com Tue Apr 26 15:59:47 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 26 Apr 2016 15:59:47 +0000 Subject: [nginx] Version bump. Message-ID: <hg.be44757637dd.1461686387.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/be44757637dd branches: changeset: 6526:be44757637dd user: Ruslan Ermilov <ru at nginx.com> date: Tue Apr 26 18:26:18 2016 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r 5b5a2d8d4d97 -r be44757637dd src/core/nginx.h --- a/src/core/nginx.h Tue Apr 19 19:02:37 2016 +0300 +++ b/src/core/nginx.h Tue Apr 26 18:26:18 2016 +0300 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1009015 -#define NGINX_VERSION "1.9.15" +#define nginx_version 1011000 +#define NGINX_VERSION "1.11.0" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From ru at nginx.com Tue Apr 26 15:59:50 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 26 Apr 2016 15:59:50 +0000 Subject: [nginx] Removed some bitrot. Message-ID: <hg.6d3a60a909c8.1461686390.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/6d3a60a909c8 branches: changeset: 6527:6d3a60a909c8 user: Ruslan Ermilov <ru at nginx.com> date: Tue Apr 26 18:26:43 2016 +0300 description: Removed some bitrot. Removed NGX_CONF_MULTI unused since 1.3.4. Removed ngx_url_t.one_addr unused since 1.3.10. diffstat: src/core/ngx_conf_file.h | 1 - src/core/ngx_inet.h | 1 - 2 files changed, 0 insertions(+), 2 deletions(-) diffs (22 lines): diff -r be44757637dd -r 6d3a60a909c8 src/core/ngx_conf_file.h --- a/src/core/ngx_conf_file.h Tue Apr 26 18:26:18 2016 +0300 +++ b/src/core/ngx_conf_file.h Tue Apr 26 18:26:43 2016 +0300 @@ -45,7 +45,6 @@ #define NGX_CONF_ANY 0x00000400 #define NGX_CONF_1MORE 0x00000800 #define NGX_CONF_2MORE 0x00001000 -#define NGX_CONF_MULTI 0x00000000 /* compatibility */ #define NGX_DIRECT_CONF 0x00010000 diff -r be44757637dd -r 6d3a60a909c8 src/core/ngx_inet.h --- a/src/core/ngx_inet.h Tue Apr 26 18:26:18 2016 +0300 +++ b/src/core/ngx_inet.h Tue Apr 26 18:26:43 2016 +0300 @@ -87,7 +87,6 @@ typedef struct { unsigned listen:1; unsigned uri_part:1; unsigned no_resolve:1; - unsigned one_addr:1; /* compatibility */ unsigned no_port:1; unsigned wildcard:1; From ru at nginx.com Tue Apr 26 15:59:52 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 26 Apr 2016 15:59:52 +0000 Subject: [nginx] Upstream: prepared proxy_bind to accept parameters. Message-ID: <hg.88f012eee7d8.1461686392.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/88f012eee7d8 branches: changeset: 6528:88f012eee7d8 user: Roman Arutyunyan <arut at nginx.com> date: Wed Apr 13 15:42:46 2016 +0300 description: Upstream: prepared proxy_bind to accept parameters. In addition, errors occurred while setting bind address are no longer ignored. diffstat: src/http/ngx_http_upstream.c | 96 +++++++++++++++++++++++-------------------- 1 files changed, 51 insertions(+), 45 deletions(-) diffs (148 lines): diff -r 6d3a60a909c8 -r 88f012eee7d8 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Tue Apr 26 18:26:43 2016 +0300 +++ b/src/http/ngx_http_upstream.c Wed Apr 13 15:42:46 2016 +0300 @@ -165,8 +165,8 @@ static char *ngx_http_upstream(ngx_conf_ static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static ngx_addr_t *ngx_http_upstream_get_local(ngx_http_request_t *r, - ngx_http_upstream_local_t *local); +static ngx_int_t ngx_http_upstream_set_local(ngx_http_request_t *r, + ngx_http_upstream_t *u, ngx_http_upstream_local_t *local); static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf); static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf); @@ -588,7 +588,10 @@ ngx_http_upstream_init_request(ngx_http_ return; } - u->peer.local = ngx_http_upstream_get_local(r, u->conf->local); + if (ngx_http_upstream_set_local(r, u, u->conf->local) != NGX_OK) { + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); @@ -5815,34 +5818,35 @@ ngx_http_upstream_bind_set_slot(ngx_conf *local->value = cv; - return NGX_CONF_OK; - } - - local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); - if (local->addr == NULL) { - return NGX_CONF_ERROR; - } - - rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len); - - switch (rc) { - case NGX_OK: - local->addr->name = value[1]; - return NGX_CONF_OK; - - case NGX_DECLINED: - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid address \"%V\"", &value[1]); - /* fall through */ - - default: - return NGX_CONF_ERROR; - } + } else { + local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); + if (local->addr == NULL) { + return NGX_CONF_ERROR; + } + + rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len); + + switch (rc) { + case NGX_OK: + local->addr->name = value[1]; + break; + + case NGX_DECLINED: + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid address \"%V\"", &value[1]); + /* fall through */ + + default: + return NGX_CONF_ERROR; + } + } + + return NGX_CONF_OK; } -static ngx_addr_t * -ngx_http_upstream_get_local(ngx_http_request_t *r, +static ngx_int_t +ngx_http_upstream_set_local(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_http_upstream_local_t *local) { ngx_int_t rc; @@ -5850,41 +5854,43 @@ ngx_http_upstream_get_local(ngx_http_req ngx_addr_t *addr; if (local == NULL) { - return NULL; + u->peer.local = NULL; + return NGX_OK; } if (local->value == NULL) { - return local->addr; + u->peer.local = local->addr; + return NGX_OK; } if (ngx_http_complex_value(r, local->value, &val) != NGX_OK) { - return NULL; + return NGX_ERROR; } if (val.len == 0) { - return NULL; + return NGX_OK; } addr = ngx_palloc(r->pool, sizeof(ngx_addr_t)); if (addr == NULL) { - return NULL; + return NGX_ERROR; } rc = ngx_parse_addr(r->pool, addr, val.data, val.len); - - switch (rc) { - case NGX_OK: - addr->name = val; - return addr; - - case NGX_DECLINED: + if (rc == NGX_ERROR) { + return NGX_ERROR; + } + + if (rc != NGX_OK) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "invalid local address \"%V\"", &val); - /* fall through */ - - default: - return NULL; - } + return NGX_OK; + } + + addr->name = val; + u->peer.local = addr; + + return NGX_OK; } From ru at nginx.com Tue Apr 26 15:59:54 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 26 Apr 2016 15:59:54 +0000 Subject: [nginx] Stream: prepared proxy_bind to accept parameters. Message-ID: <hg.cb8177ca0990.1461686394.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/cb8177ca0990 branches: changeset: 6529:cb8177ca0990 user: Roman Arutyunyan <arut at nginx.com> date: Wed Apr 13 15:42:47 2016 +0300 description: Stream: prepared proxy_bind to accept parameters. diffstat: src/stream/ngx_stream_proxy_module.c | 57 ++++++++++++++++++++++++++++++----- 1 files changed, 48 insertions(+), 9 deletions(-) diffs (120 lines): diff -r 88f012eee7d8 -r cb8177ca0990 src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Wed Apr 13 15:42:46 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Wed Apr 13 15:42:47 2016 +0300 @@ -11,6 +11,11 @@ typedef struct { + ngx_addr_t *addr; +} ngx_stream_upstream_local_t; + + +typedef struct { ngx_msec_t connect_timeout; ngx_msec_t timeout; ngx_msec_t next_upstream_timeout; @@ -21,7 +26,7 @@ typedef struct { ngx_uint_t next_upstream_tries; ngx_flag_t next_upstream; ngx_flag_t proxy_protocol; - ngx_addr_t *local; + ngx_stream_upstream_local_t *local; #if (NGX_STREAM_SSL) ngx_flag_t ssl_enable; @@ -47,6 +52,8 @@ typedef struct { static void ngx_stream_proxy_handler(ngx_stream_session_t *s); +static ngx_int_t ngx_stream_proxy_set_local(ngx_stream_session_t *s, + ngx_stream_upstream_t *u, ngx_stream_upstream_local_t *local); static void ngx_stream_proxy_connect(ngx_stream_session_t *s); static void ngx_stream_proxy_init_upstream(ngx_stream_session_t *s); static void ngx_stream_proxy_upstream_handler(ngx_event_t *ev); @@ -358,7 +365,11 @@ ngx_stream_proxy_handler(ngx_stream_sess u->peer.log = c->log; u->peer.log_error = NGX_ERROR_ERR; - u->peer.local = pscf->local; + if (ngx_stream_proxy_set_local(s, u, pscf->local) != NGX_OK) { + ngx_stream_proxy_finalize(s, NGX_ERROR); + return; + } + u->peer.type = c->type; uscf = pscf->upstream; @@ -428,6 +439,24 @@ ngx_stream_proxy_handler(ngx_stream_sess } +static ngx_int_t +ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u, + ngx_stream_upstream_local_t *local) +{ + if (local == NULL) { + u->peer.local = NULL; + return NGX_OK; + } + + if (local->addr) { + u->peer.local = local->addr; + return NGX_OK; + } + + return NGX_OK; +} + + static void ngx_stream_proxy_connect(ngx_stream_session_t *s) { @@ -1637,8 +1666,9 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng { ngx_stream_proxy_srv_conf_t *pscf = conf; - ngx_int_t rc; - ngx_str_t *value; + ngx_int_t rc; + ngx_str_t *value; + ngx_stream_upstream_local_t *local; if (pscf->local != NGX_CONF_UNSET_PTR) { return "is duplicate"; @@ -1651,17 +1681,24 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng return NGX_CONF_OK; } - pscf->local = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); - if (pscf->local == NULL) { + local = ngx_palloc(cf->pool, sizeof(ngx_stream_upstream_local_t)); + if (local == NULL) { return NGX_CONF_ERROR; } - rc = ngx_parse_addr(cf->pool, pscf->local, value[1].data, value[1].len); + pscf->local = local; + + local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); + if (local->addr == NULL) { + return NGX_CONF_ERROR; + } + + rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len); switch (rc) { case NGX_OK: - pscf->local->name = value[1]; - return NGX_CONF_OK; + local->addr->name = value[1]; + break; case NGX_DECLINED: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -1671,4 +1708,6 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng default: return NGX_CONF_ERROR; } + + return NGX_CONF_OK; } From ru at nginx.com Tue Apr 26 15:59:57 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 26 Apr 2016 15:59:57 +0000 Subject: [nginx] Upstream: the "transparent" parameter of proxy_bind and friends. Message-ID: <hg.1d0e03db9f8e.1461686397.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/1d0e03db9f8e branches: changeset: 6530:1d0e03db9f8e user: Roman Arutyunyan <arut at nginx.com> date: Fri Dec 18 19:05:27 2015 +0300 description: Upstream: the "transparent" parameter of proxy_bind and friends. This parameter lets binding the proxy connection to a non-local address. Upstream will see the connection as coming from that address. When used with $remote_addr, upstream will accept the connection from real client address. Example: proxy_bind $remote_addr transparent; diffstat: auto/unix | 38 +++++++++ src/event/ngx_event_connect.c | 103 ++++++++++++++++++++++++++ src/event/ngx_event_connect.h | 3 + src/http/modules/ngx_http_fastcgi_module.c | 2 +- src/http/modules/ngx_http_memcached_module.c | 2 +- src/http/modules/ngx_http_proxy_module.c | 2 +- src/http/modules/ngx_http_scgi_module.c | 2 +- src/http/modules/ngx_http_uwsgi_module.c | 2 +- src/http/ngx_http_upstream.c | 22 +++++- src/http/ngx_http_upstream.h | 3 + src/stream/ngx_stream_proxy_module.c | 105 ++++++++++++++++++++++---- 11 files changed, 260 insertions(+), 24 deletions(-) diffs (463 lines): diff -r cb8177ca0990 -r 1d0e03db9f8e auto/unix --- a/auto/unix Wed Apr 13 15:42:47 2016 +0300 +++ b/auto/unix Fri Dec 18 19:05:27 2015 +0300 @@ -329,6 +329,44 @@ ngx_feature_test="setsockopt(0, SOL_SOCK . auto/feature +# NetBSD bind to any address for transparent proxying + +ngx_feature="SO_BINDANY" +ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" +ngx_feature_run=no +ngx_feature_incs="#include <sys/socket.h>" +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_BINDANY, NULL, 0)" +. auto/feature + + +# Linux transparent proxying + +ngx_feature="IP_TRANSPARENT" +ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" +ngx_feature_run=no +ngx_feature_incs="#include <sys/socket.h> + #include <netinet/in.h>" +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" +. auto/feature + + +# FreeBSD bind to any address for transparent proxying + +ngx_feature="IP_BINDANY" +ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" +ngx_feature_run=no +ngx_feature_incs="#include <sys/socket.h> + #include <netinet/in.h>" +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" +. auto/feature + + # BSD way to get IPv4 datagram destination address ngx_feature="IP_RECVDSTADDR" diff -r cb8177ca0990 -r 1d0e03db9f8e src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c Wed Apr 13 15:42:47 2016 +0300 +++ b/src/event/ngx_event_connect.c Fri Dec 18 19:05:27 2015 +0300 @@ -11,6 +11,12 @@ #include <ngx_event_connect.h> +#if (NGX_HAVE_TRANSPARENT_PROXY) +static ngx_int_t ngx_event_connect_set_transparent(ngx_peer_connection_t *pc, + ngx_socket_t s); +#endif + + ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc) { @@ -72,6 +78,15 @@ ngx_event_connect_peer(ngx_peer_connecti } if (pc->local) { + +#if (NGX_HAVE_TRANSPARENT_PROXY) + if (pc->transparent) { + if (ngx_event_connect_set_transparent(pc, s) != NGX_OK) { + goto failed; + } + } +#endif + if (bind(s, pc->local->sockaddr, pc->local->socklen) == -1) { ngx_log_error(NGX_LOG_CRIT, pc->log, ngx_socket_errno, "bind(%V) failed", &pc->local->name); @@ -249,6 +264,94 @@ failed: } +#if (NGX_HAVE_TRANSPARENT_PROXY) + +static ngx_int_t +ngx_event_connect_set_transparent(ngx_peer_connection_t *pc, ngx_socket_t s) +{ + int value; + + value = 1; + +#if defined(SO_BINDANY) + + if (setsockopt(s, SOL_SOCKET, SO_BINDANY, + (const void *) &value, sizeof(int)) == -1) + { + ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, + "setsockopt(SO_BINDANY) failed"); + return NGX_ERROR; + } + +#else + + switch (pc->local->sockaddr->sa_family) { + + case AF_INET: + +#if defined(IP_TRANSPARENT) + + if (setsockopt(s, IPPROTO_IP, IP_TRANSPARENT, + (const void *) &value, sizeof(int)) == -1) + { + ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, + "setsockopt(IP_TRANSPARENT) failed"); + return NGX_ERROR; + } + +#elif defined(IP_BINDANY) + + if (setsockopt(s, IPPROTO_IP, IP_BINDANY, + (const void *) &value, sizeof(int)) == -1) + { + ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, + "setsockopt(IP_BINDANY) failed"); + return NGX_ERROR; + } + +#endif + + break; + +#if (NGX_HAVE_INET6) + + case AF_INET6: + +#if defined(IPV6_TRANSPARENT) + + if (setsockopt(s, IPPROTO_IPV6, IPV6_TRANSPARENT, + (const void *) &value, sizeof(int)) == -1) + { + ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, + "setsockopt(IPV6_TRANSPARENT) failed"); + return NGX_ERROR; + } + +#elif defined(IPV6_BINDANY) + + if (setsockopt(s, IPPROTO_IPV6, IPV6_BINDANY, + (const void *) &value, sizeof(int)) == -1) + { + ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, + "setsockopt(IPV6_BINDANY) failed"); + return NGX_ERROR; + } + +#endif + break; + +#endif /* NGX_HAVE_INET6 */ + + } + +#endif /* SO_BINDANY */ + + return NGX_OK; +} + +#endif + + ngx_int_t ngx_event_get_peer(ngx_peer_connection_t *pc, void *data) { diff -r cb8177ca0990 -r 1d0e03db9f8e src/event/ngx_event_connect.h --- a/src/event/ngx_event_connect.h Wed Apr 13 15:42:47 2016 +0300 +++ b/src/event/ngx_event_connect.h Fri Dec 18 19:05:27 2015 +0300 @@ -61,6 +61,9 @@ struct ngx_peer_connection_s { ngx_log_t *log; unsigned cached:1; +#if (NGX_HAVE_TRANSPARENT_PROXY) + unsigned transparent:1; +#endif /* ngx_connection_log_error_e */ unsigned log_error:2; diff -r cb8177ca0990 -r 1d0e03db9f8e src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c Wed Apr 13 15:42:47 2016 +0300 +++ b/src/http/modules/ngx_http_fastcgi_module.c Fri Dec 18 19:05:27 2015 +0300 @@ -279,7 +279,7 @@ static ngx_command_t ngx_http_fastcgi_c NULL }, { ngx_string("fastcgi_bind"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, ngx_http_upstream_bind_set_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_fastcgi_loc_conf_t, upstream.local), diff -r cb8177ca0990 -r 1d0e03db9f8e src/http/modules/ngx_http_memcached_module.c --- a/src/http/modules/ngx_http_memcached_module.c Wed Apr 13 15:42:47 2016 +0300 +++ b/src/http/modules/ngx_http_memcached_module.c Fri Dec 18 19:05:27 2015 +0300 @@ -61,7 +61,7 @@ static ngx_command_t ngx_http_memcached NULL }, { ngx_string("memcached_bind"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, ngx_http_upstream_bind_set_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_memcached_loc_conf_t, upstream.local), diff -r cb8177ca0990 -r 1d0e03db9f8e src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Wed Apr 13 15:42:47 2016 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Fri Dec 18 19:05:27 2015 +0300 @@ -316,7 +316,7 @@ static ngx_command_t ngx_http_proxy_com NULL }, { ngx_string("proxy_bind"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, ngx_http_upstream_bind_set_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, upstream.local), diff -r cb8177ca0990 -r 1d0e03db9f8e src/http/modules/ngx_http_scgi_module.c --- a/src/http/modules/ngx_http_scgi_module.c Wed Apr 13 15:42:47 2016 +0300 +++ b/src/http/modules/ngx_http_scgi_module.c Fri Dec 18 19:05:27 2015 +0300 @@ -136,7 +136,7 @@ static ngx_command_t ngx_http_scgi_comma NULL }, { ngx_string("scgi_bind"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, ngx_http_upstream_bind_set_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_scgi_loc_conf_t, upstream.local), diff -r cb8177ca0990 -r 1d0e03db9f8e src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c Wed Apr 13 15:42:47 2016 +0300 +++ b/src/http/modules/ngx_http_uwsgi_module.c Fri Dec 18 19:05:27 2015 +0300 @@ -196,7 +196,7 @@ static ngx_command_t ngx_http_uwsgi_comm NULL }, { ngx_string("uwsgi_bind"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, ngx_http_upstream_bind_set_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_uwsgi_loc_conf_t, upstream.local), diff -r cb8177ca0990 -r 1d0e03db9f8e src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Wed Apr 13 15:42:47 2016 +0300 +++ b/src/http/ngx_http_upstream.c Fri Dec 18 19:05:27 2015 +0300 @@ -5788,7 +5788,7 @@ ngx_http_upstream_bind_set_slot(ngx_conf value = cf->args->elts; - if (ngx_strcmp(value[1].data, "off") == 0) { + if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "off") == 0) { *plocal = NULL; return NGX_CONF_OK; } @@ -5841,6 +5841,22 @@ ngx_http_upstream_bind_set_slot(ngx_conf } } + if (cf->args->nelts > 2) { + if (ngx_strcmp(value[2].data, "transparent") == 0) { +#if (NGX_HAVE_TRANSPARENT_PROXY) + local->transparent = 1; +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "transparent proxying is not supported " + "on this platform, ignored"); +#endif + } else { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%V\"", &value[2]); + return NGX_CONF_ERROR; + } + } + return NGX_CONF_OK; } @@ -5858,6 +5874,10 @@ ngx_http_upstream_set_local(ngx_http_req return NGX_OK; } +#if (NGX_HAVE_TRANSPARENT_PROXY) + u->peer.transparent = local->transparent; +#endif + if (local->value == NULL) { u->peer.local = local->addr; return NGX_OK; diff -r cb8177ca0990 -r 1d0e03db9f8e src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h Wed Apr 13 15:42:47 2016 +0300 +++ b/src/http/ngx_http_upstream.h Fri Dec 18 19:05:27 2015 +0300 @@ -133,6 +133,9 @@ struct ngx_http_upstream_srv_conf_s { typedef struct { ngx_addr_t *addr; ngx_http_complex_value_t *value; +#if (NGX_HAVE_TRANSPARENT_PROXY) + ngx_uint_t transparent; /* unsigned transparent:1; */ +#endif } ngx_http_upstream_local_t; diff -r cb8177ca0990 -r 1d0e03db9f8e src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Wed Apr 13 15:42:47 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Fri Dec 18 19:05:27 2015 +0300 @@ -12,6 +12,9 @@ typedef struct { ngx_addr_t *addr; +#if (NGX_HAVE_TRANSPARENT_PROXY) + ngx_uint_t transparent; /* unsigned transparent:1; */ +#endif } ngx_stream_upstream_local_t; @@ -120,7 +123,7 @@ static ngx_command_t ngx_stream_proxy_c NULL }, { ngx_string("proxy_bind"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12, ngx_stream_proxy_bind, NGX_STREAM_SRV_CONF_OFFSET, 0, @@ -443,16 +446,63 @@ static ngx_int_t ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u, ngx_stream_upstream_local_t *local) { + ngx_addr_t *addr; + ngx_connection_t *c; + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif + if (local == NULL) { u->peer.local = NULL; return NGX_OK; } +#if (NGX_HAVE_TRANSPARENT_PROXY) + u->peer.transparent = local->transparent; +#endif + if (local->addr) { u->peer.local = local->addr; return NGX_OK; } + /* $remote_addr */ + + c = s->connection; + + addr = ngx_palloc(c->pool, sizeof(ngx_addr_t)); + if (addr == NULL) { + return NGX_ERROR; + } + + addr->socklen = c->socklen; + + addr->sockaddr = ngx_palloc(c->pool, addr->socklen); + if (addr->sockaddr == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(addr->sockaddr, c->sockaddr, c->socklen); + + switch (addr->sockaddr->sa_family) { + + case AF_INET: + sin = (struct sockaddr_in *) addr->sockaddr; + sin->sin_port = 0; + break; + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) addr->sockaddr; + sin6->sin6_port = 0; + break; +#endif + } + + addr->name = c->addr_text; + u->peer.local = addr; + return NGX_OK; } @@ -1676,7 +1726,7 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng value = cf->args->elts; - if (ngx_strcmp(value[1].data, "off") == 0) { + if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "off") == 0) { pscf->local = NULL; return NGX_CONF_OK; } @@ -1688,25 +1738,44 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng pscf->local = local; - local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); - if (local->addr == NULL) { - return NGX_CONF_ERROR; + if (ngx_strcmp(value[1].data, "$remote_addr") != 0) { + local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); + if (local->addr == NULL) { + return NGX_CONF_ERROR; + } + + rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len); + + switch (rc) { + case NGX_OK: + local->addr->name = value[1]; + break; + + case NGX_DECLINED: + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid address \"%V\"", &value[1]); + /* fall through */ + + default: + return NGX_CONF_ERROR; + } } - rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len); + if (cf->args->nelts > 2) { + if (ngx_strcmp(value[2].data, "transparent") == 0) { +#if (NGX_HAVE_TRANSPARENT_PROXY) + local->transparent = 1; - switch (rc) { - case NGX_OK: - local->addr->name = value[1]; - break; - - case NGX_DECLINED: - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid address \"%V\"", &value[1]); - /* fall through */ - - default: - return NGX_CONF_ERROR; +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "transparent proxying is not supported " + "on this platform, ignored"); +#endif + } else { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%V\"", &value[2]); + return NGX_CONF_ERROR; + } } return NGX_CONF_OK; From vl at nginx.com Tue Apr 26 16:38:09 2016 From: vl at nginx.com (Vladimir Homutov) Date: Tue, 26 Apr 2016 16:38:09 +0000 Subject: [nginx] Variable $request_id. Message-ID: <hg.59f8f2dd8b31.1461688689.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/59f8f2dd8b31 branches: changeset: 6531:59f8f2dd8b31 user: Vladimir Homutov <vl at nginx.com> date: Tue Apr 26 19:31:46 2016 +0300 description: Variable $request_id. The variable contains text representation based on random data, usable as a unique request identifier. diffstat: src/http/ngx_http_variables.c | 47 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 47 insertions(+), 0 deletions(-) diffs (71 lines): diff -r 1d0e03db9f8e -r 59f8f2dd8b31 src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c Fri Dec 18 19:05:27 2015 +0300 +++ b/src/http/ngx_http_variables.c Tue Apr 26 19:31:46 2016 +0300 @@ -98,6 +98,8 @@ static ngx_int_t ngx_http_variable_reque ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_request_time(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_request_id(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); @@ -274,6 +276,10 @@ static ngx_http_variable_t ngx_http_cor { ngx_string("request_time"), NULL, ngx_http_variable_request_time, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, + { ngx_string("request_id"), NULL, + ngx_http_variable_request_id, + 0, 0, 0 }, + { ngx_string("status"), NULL, ngx_http_variable_status, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, @@ -2068,6 +2074,47 @@ ngx_http_variable_request_time(ngx_http_ static ngx_int_t +ngx_http_variable_request_id(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *id; + +#if (NGX_OPENSSL) + u_char random_bytes[16]; +#endif + + id = ngx_pnalloc(r->pool, 32); + if (id == NULL) { + return NGX_ERROR; + } + + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + + v->len = 32; + v->data = id; + +#if (NGX_OPENSSL) + + if (RAND_bytes(random_bytes, 16) == 1) { + ngx_hex_dump(id, random_bytes, 16); + return NGX_OK; + } + + ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, "RAND_bytes() failed"); + +#endif + + ngx_sprintf(id, "%08xD%08xD%08xD%08xD", + (uint32_t) ngx_random(), (uint32_t) ngx_random(), + (uint32_t) ngx_random(), (uint32_t) ngx_random()); + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_connection(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { From toshic.toshic at gmail.com Tue Apr 26 16:51:49 2016 From: toshic.toshic at gmail.com (ToSHiC) Date: Tue, 26 Apr 2016 19:51:49 +0300 Subject: [nginx] Variable $request_id. In-Reply-To: <hg.59f8f2dd8b31.1461688689.6026610855610030274@dev.nginx.com> References: <hg.59f8f2dd8b31.1461688689.6026610855610030274@dev.nginx.com> Message-ID: <CAB73Exp85FvWnyK1Ww0j2T2Xa7U+qYqvu2KZgAKVOcynn=U+aQ@mail.gmail.com> Hello, We are using such variable for more than a year, and I suggest to add ability to extract request_id from header. It's very usefull for systems with frontend and backend installed on different servers. On Tue, Apr 26, 2016 at 7:38 PM, Vladimir Homutov <vl at nginx.com> wrote: > details: http://hg.nginx.org/nginx/rev/59f8f2dd8b31 > branches: > changeset: 6531:59f8f2dd8b31 > user: Vladimir Homutov <vl at nginx.com> > date: Tue Apr 26 19:31:46 2016 +0300 > description: > Variable $request_id. > > The variable contains text representation based on random data, usable as > a unique request identifier. > > diffstat: > > src/http/ngx_http_variables.c | 47 > +++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 47 insertions(+), 0 deletions(-) > > diffs (71 lines): > > diff -r 1d0e03db9f8e -r 59f8f2dd8b31 src/http/ngx_http_variables.c > --- a/src/http/ngx_http_variables.c Fri Dec 18 19:05:27 2015 +0300 > +++ b/src/http/ngx_http_variables.c Tue Apr 26 19:31:46 2016 +0300 > @@ -98,6 +98,8 @@ static ngx_int_t ngx_http_variable_reque > ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_variable_request_time(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data); > +static ngx_int_t ngx_http_variable_request_id(ngx_http_request_t *r, > + ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data); > > @@ -274,6 +276,10 @@ static ngx_http_variable_t ngx_http_cor > { ngx_string("request_time"), NULL, ngx_http_variable_request_time, > 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, > > + { ngx_string("request_id"), NULL, > + ngx_http_variable_request_id, > + 0, 0, 0 }, > + > { ngx_string("status"), NULL, > ngx_http_variable_status, 0, > NGX_HTTP_VAR_NOCACHEABLE, 0 }, > @@ -2068,6 +2074,47 @@ ngx_http_variable_request_time(ngx_http_ > > > static ngx_int_t > +ngx_http_variable_request_id(ngx_http_request_t *r, > + ngx_http_variable_value_t *v, uintptr_t data) > +{ > + u_char *id; > + > +#if (NGX_OPENSSL) > + u_char random_bytes[16]; > +#endif > + > + id = ngx_pnalloc(r->pool, 32); > + if (id == NULL) { > + return NGX_ERROR; > + } > + > + v->valid = 1; > + v->no_cacheable = 0; > + v->not_found = 0; > + > + v->len = 32; > + v->data = id; > + > +#if (NGX_OPENSSL) > + > + if (RAND_bytes(random_bytes, 16) == 1) { > + ngx_hex_dump(id, random_bytes, 16); > + return NGX_OK; > + } > + > + ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, "RAND_bytes() > failed"); > + > +#endif > + > + ngx_sprintf(id, "%08xD%08xD%08xD%08xD", > + (uint32_t) ngx_random(), (uint32_t) ngx_random(), > + (uint32_t) ngx_random(), (uint32_t) ngx_random()); > + > + return NGX_OK; > +} > + > + > +static ngx_int_t > ngx_http_variable_connection(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data) > { > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160426/c802ba15/attachment.html> From savetherbtz at gmail.com Wed Apr 27 02:14:12 2016 From: savetherbtz at gmail.com (Alexey Ivanov) Date: Tue, 26 Apr 2016 19:14:12 -0700 Subject: [nginx] Variable $request_id. In-Reply-To: <CAB73Exp85FvWnyK1Ww0j2T2Xa7U+qYqvu2KZgAKVOcynn=U+aQ@mail.gmail.com> References: <hg.59f8f2dd8b31.1461688689.6026610855610030274@dev.nginx.com> <CAB73Exp85FvWnyK1Ww0j2T2Xa7U+qYqvu2KZgAKVOcynn=U+aQ@mail.gmail.com> Message-ID: <5BB56607-F266-4303-84B9-14577E88E651@gmail.com> Same here, in our environment we: * get current request id from a header * validate it against our guidelines * if not already present or does not pass validation: * re-generate using `RAND_bytes()` * propagate it to the upstream * echo it back to the downstream * log it to the access.log It would be nice if new nginx code can be used more or less drop-in replacement for our homegrown lua-stuff. We currently use following pseudo-code to validate/generate/propagate/echo-back request_ids: ``` set_by_lua $request_id ' local success, req_id = pcall(request_id.get_hex_or_generate, ngx.var.http_x_dropbox_request_id) if not success then return "-" end return req_id '; more_set_headers "X-Dropbox-Request-Id: $request_id"; proxy_set_header X-Dropbox-Request-Id $request_id ; ``` ``` --[[ Helper function that verifies request_id or generates new one in case validation fails. @req_id: current request id --]] function request_id.get_hex_or_generate(req_id) ... end ``` > On Apr 26, 2016, at 9:51 AM, ToSHiC <toshic.toshic at gmail.com> wrote: > > Hello, > > We are using such variable for more than a year, and I suggest to add ability to extract request_id from header. It's very usefull for systems with frontend and backend installed on different servers. > > On Tue, Apr 26, 2016 at 7:38 PM, Vladimir Homutov <vl at nginx.com> wrote: > details: http://hg.nginx.org/nginx/rev/59f8f2dd8b31 > branches: > changeset: 6531:59f8f2dd8b31 > user: Vladimir Homutov <vl at nginx.com> > date: Tue Apr 26 19:31:46 2016 +0300 > description: > Variable $request_id. > > The variable contains text representation based on random data, usable as > a unique request identifier. > > diffstat: > > src/http/ngx_http_variables.c | 47 +++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 47 insertions(+), 0 deletions(-) > > diffs (71 lines): > > diff -r 1d0e03db9f8e -r 59f8f2dd8b31 src/http/ngx_http_variables.c > --- a/src/http/ngx_http_variables.c Fri Dec 18 19:05:27 2015 +0300 > +++ b/src/http/ngx_http_variables.c Tue Apr 26 19:31:46 2016 +0300 > @@ -98,6 +98,8 @@ static ngx_int_t ngx_http_variable_reque > ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_variable_request_time(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data); > +static ngx_int_t ngx_http_variable_request_id(ngx_http_request_t *r, > + ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data); > > @@ -274,6 +276,10 @@ static ngx_http_variable_t ngx_http_cor > { ngx_string("request_time"), NULL, ngx_http_variable_request_time, > 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, > > + { ngx_string("request_id"), NULL, > + ngx_http_variable_request_id, > + 0, 0, 0 }, > + > { ngx_string("status"), NULL, > ngx_http_variable_status, 0, > NGX_HTTP_VAR_NOCACHEABLE, 0 }, > @@ -2068,6 +2074,47 @@ ngx_http_variable_request_time(ngx_http_ > > > static ngx_int_t > +ngx_http_variable_request_id(ngx_http_request_t *r, > + ngx_http_variable_value_t *v, uintptr_t data) > +{ > + u_char *id; > + > +#if (NGX_OPENSSL) > + u_char random_bytes[16]; > +#endif > + > + id = ngx_pnalloc(r->pool, 32); > + if (id == NULL) { > + return NGX_ERROR; > + } > + > + v->valid = 1; > + v->no_cacheable = 0; > + v->not_found = 0; > + > + v->len = 32; > + v->data = id; > + > +#if (NGX_OPENSSL) > + > + if (RAND_bytes(random_bytes, 16) == 1) { > + ngx_hex_dump(id, random_bytes, 16); > + return NGX_OK; > + } > + > + ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, "RAND_bytes() failed"); > + > +#endif > + > + ngx_sprintf(id, "%08xD%08xD%08xD%08xD", > + (uint32_t) ngx_random(), (uint32_t) ngx_random(), > + (uint32_t) ngx_random(), (uint32_t) ngx_random()); > + > + return NGX_OK; > +} > + > + > +static ngx_int_t > ngx_http_variable_connection(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data) > { > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 842 bytes Desc: Message signed with OpenPGP using GPGMail URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160426/9d76146d/attachment.bin> From mat999 at gmail.com Wed Apr 27 05:23:51 2016 From: mat999 at gmail.com (SplitIce) Date: Wed, 27 Apr 2016 15:23:51 +1000 Subject: [nginx] Variable $request_id. In-Reply-To: <5BB56607-F266-4303-84B9-14577E88E651@gmail.com> References: <hg.59f8f2dd8b31.1461688689.6026610855610030274@dev.nginx.com> <CAB73Exp85FvWnyK1Ww0j2T2Xa7U+qYqvu2KZgAKVOcynn=U+aQ@mail.gmail.com> <5BB56607-F266-4303-84B9-14577E88E651@gmail.com> Message-ID: <CALFfGYY7COoYw-fUxYUrMgQRjBqW+1tDx_REn6=fE4iWJ-wzsQ@mail.gmail.com> Hi, We have been using something like this for ~2 years. For ours we used a random number to start and the Process ID & Process start time to try and increase uniqueness between reloads (ours is a 128bit ID). Then applying an increment, with future requests having a higher id. Perhaps that would be better than just 128bit of random data? On Wed, Apr 27, 2016 at 12:14 PM, Alexey Ivanov <savetherbtz at gmail.com> wrote: > Same here, in our environment we: > * get current request id from a header > * validate it against our guidelines > * if not already present or does not pass validation: > * re-generate using `RAND_bytes()` > * propagate it to the upstream > * echo it back to the downstream > * log it to the access.log > > It would be nice if new nginx code can be used more or less drop-in > replacement for our homegrown lua-stuff. > > We currently use following pseudo-code to > validate/generate/propagate/echo-back request_ids: > > ``` > set_by_lua $request_id ' > local success, req_id = pcall(request_id.get_hex_or_generate, > ngx.var.http_x_dropbox_request_id) > if not success then > return "-" > end > return req_id > '; > more_set_headers "X-Dropbox-Request-Id: $request_id"; > proxy_set_header X-Dropbox-Request-Id $request_id ; > ``` > > ``` > --[[ > Helper function that verifies request_id or generates new one in case > validation fails. > > @req_id: current request id > --]] > function request_id.get_hex_or_generate(req_id) > ... > end > ``` > > > > On Apr 26, 2016, at 9:51 AM, ToSHiC <toshic.toshic at gmail.com> wrote: > > > > Hello, > > > > We are using such variable for more than a year, and I suggest to add > ability to extract request_id from header. It's very usefull for systems > with frontend and backend installed on different servers. > > > > On Tue, Apr 26, 2016 at 7:38 PM, Vladimir Homutov <vl at nginx.com> wrote: > > details: http://hg.nginx.org/nginx/rev/59f8f2dd8b31 > > branches: > > changeset: 6531:59f8f2dd8b31 > > user: Vladimir Homutov <vl at nginx.com> > > date: Tue Apr 26 19:31:46 2016 +0300 > > description: > > Variable $request_id. > > > > The variable contains text representation based on random data, usable as > > a unique request identifier. > > > > diffstat: > > > > src/http/ngx_http_variables.c | 47 > +++++++++++++++++++++++++++++++++++++++++++ > > 1 files changed, 47 insertions(+), 0 deletions(-) > > > > diffs (71 lines): > > > > diff -r 1d0e03db9f8e -r 59f8f2dd8b31 src/http/ngx_http_variables.c > > --- a/src/http/ngx_http_variables.c Fri Dec 18 19:05:27 2015 +0300 > > +++ b/src/http/ngx_http_variables.c Tue Apr 26 19:31:46 2016 +0300 > > @@ -98,6 +98,8 @@ static ngx_int_t ngx_http_variable_reque > > ngx_http_variable_value_t *v, uintptr_t data); > > static ngx_int_t ngx_http_variable_request_time(ngx_http_request_t *r, > > ngx_http_variable_value_t *v, uintptr_t data); > > +static ngx_int_t ngx_http_variable_request_id(ngx_http_request_t *r, > > + ngx_http_variable_value_t *v, uintptr_t data); > > static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r, > > ngx_http_variable_value_t *v, uintptr_t data); > > > > @@ -274,6 +276,10 @@ static ngx_http_variable_t ngx_http_cor > > { ngx_string("request_time"), NULL, ngx_http_variable_request_time, > > 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, > > > > + { ngx_string("request_id"), NULL, > > + ngx_http_variable_request_id, > > + 0, 0, 0 }, > > + > > { ngx_string("status"), NULL, > > ngx_http_variable_status, 0, > > NGX_HTTP_VAR_NOCACHEABLE, 0 }, > > @@ -2068,6 +2074,47 @@ ngx_http_variable_request_time(ngx_http_ > > > > > > static ngx_int_t > > +ngx_http_variable_request_id(ngx_http_request_t *r, > > + ngx_http_variable_value_t *v, uintptr_t data) > > +{ > > + u_char *id; > > + > > +#if (NGX_OPENSSL) > > + u_char random_bytes[16]; > > +#endif > > + > > + id = ngx_pnalloc(r->pool, 32); > > + if (id == NULL) { > > + return NGX_ERROR; > > + } > > + > > + v->valid = 1; > > + v->no_cacheable = 0; > > + v->not_found = 0; > > + > > + v->len = 32; > > + v->data = id; > > + > > +#if (NGX_OPENSSL) > > + > > + if (RAND_bytes(random_bytes, 16) == 1) { > > + ngx_hex_dump(id, random_bytes, 16); > > + return NGX_OK; > > + } > > + > > + ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, "RAND_bytes() > failed"); > > + > > +#endif > > + > > + ngx_sprintf(id, "%08xD%08xD%08xD%08xD", > > + (uint32_t) ngx_random(), (uint32_t) ngx_random(), > > + (uint32_t) ngx_random(), (uint32_t) ngx_random()); > > + > > + return NGX_OK; > > +} > > + > > + > > +static ngx_int_t > > ngx_http_variable_connection(ngx_http_request_t *r, > > ngx_http_variable_value_t *v, uintptr_t data) > > { > > > > _______________________________________________ > > nginx-devel mailing list > > nginx-devel at nginx.org > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > _______________________________________________ > > nginx-devel mailing list > > nginx-devel at nginx.org > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160427/f3aa7586/attachment.html> From ahutchings at nginx.com Wed Apr 27 08:41:31 2016 From: ahutchings at nginx.com (Andrew Hutchings) Date: Wed, 27 Apr 2016 09:41:31 +0100 Subject: [nginx] Variable $request_id. In-Reply-To: <CALFfGYY7COoYw-fUxYUrMgQRjBqW+1tDx_REn6=fE4iWJ-wzsQ@mail.gmail.com> References: <hg.59f8f2dd8b31.1461688689.6026610855610030274@dev.nginx.com> <CAB73Exp85FvWnyK1Ww0j2T2Xa7U+qYqvu2KZgAKVOcynn=U+aQ@mail.gmail.com> <5BB56607-F266-4303-84B9-14577E88E651@gmail.com> <CALFfGYY7COoYw-fUxYUrMgQRjBqW+1tDx_REn6=fE4iWJ-wzsQ@mail.gmail.com> Message-ID: <45d6b988-68e3-9c4f-c9df-a4aee8c7e3ca@nginx.com> Hi, Or you could use UUIDv1 and then it would also give you uniqueness and the ability to have some debugging of IDs if required. Kind Regards Andrew On 27/04/16 06:23, SplitIce wrote: > Hi, > > We have been using something like this for ~2 years. > > For ours we used a random number to start and the Process ID & Process > start time to try and increase uniqueness between reloads (ours is a > 128bit ID). Then applying an increment, with future requests having a > higher id. > > Perhaps that would be better than just 128bit of random data? > > On Wed, Apr 27, 2016 at 12:14 PM, Alexey Ivanov <savetherbtz at gmail.com > <mailto:savetherbtz at gmail.com>> wrote: > > Same here, in our environment we: > * get current request id from a header > * validate it against our guidelines > * if not already present or does not pass validation: > * re-generate using `RAND_bytes()` > * propagate it to the upstream > * echo it back to the downstream > * log it to the access.log > > It would be nice if new nginx code can be used more or less drop-in > replacement for our homegrown lua-stuff. > > We currently use following pseudo-code to > validate/generate/propagate/echo-back request_ids: > > ``` > set_by_lua $request_id ' > local success, req_id = pcall(request_id.get_hex_or_generate, > ngx.var.http_x_dropbox_request_id) > if not success then > return "-" > end > return req_id > '; > more_set_headers "X-Dropbox-Request-Id: $request_id"; > proxy_set_header X-Dropbox-Request-Id $request_id ; > ``` > > ``` > --[[ > Helper function that verifies request_id or generates new one in > case > validation fails. > > @req_id: current request id > --]] > function request_id.get_hex_or_generate(req_id) > ... > end > ``` > > > > On Apr 26, 2016, at 9:51 AM, ToSHiC <toshic.toshic at gmail.com > <mailto:toshic.toshic at gmail.com>> wrote: > > > > Hello, > > > > We are using such variable for more than a year, and I suggest to > add ability to extract request_id from header. It's very usefull for > systems with frontend and backend installed on different servers. > > > > On Tue, Apr 26, 2016 at 7:38 PM, Vladimir Homutov <vl at nginx.com > <mailto:vl at nginx.com>> wrote: > > details: http://hg.nginx.org/nginx/rev/59f8f2dd8b31 > > branches: > > changeset: 6531:59f8f2dd8b31 > > user: Vladimir Homutov <vl at nginx.com <mailto:vl at nginx.com>> > > date: Tue Apr 26 19:31:46 2016 +0300 > > description: > > Variable $request_id. > > > > The variable contains text representation based on random data, > usable as > > a unique request identifier. > > > > diffstat: > > > > src/http/ngx_http_variables.c | 47 > +++++++++++++++++++++++++++++++++++++++++++ > > 1 files changed, 47 insertions(+), 0 deletions(-) > > > > diffs (71 lines): > > > > diff -r 1d0e03db9f8e -r 59f8f2dd8b31 src/http/ngx_http_variables.c > > --- a/src/http/ngx_http_variables.c Fri Dec 18 19:05:27 2015 +0300 > > +++ b/src/http/ngx_http_variables.c Tue Apr 26 19:31:46 2016 +0300 > > @@ -98,6 +98,8 @@ static ngx_int_t ngx_http_variable_reque > > ngx_http_variable_value_t *v, uintptr_t data); > > static ngx_int_t > ngx_http_variable_request_time(ngx_http_request_t *r, > > ngx_http_variable_value_t *v, uintptr_t data); > > +static ngx_int_t ngx_http_variable_request_id(ngx_http_request_t *r, > > + ngx_http_variable_value_t *v, uintptr_t data); > > static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r, > > ngx_http_variable_value_t *v, uintptr_t data); > > > > @@ -274,6 +276,10 @@ static ngx_http_variable_t ngx_http_cor > > { ngx_string("request_time"), NULL, > ngx_http_variable_request_time, > > 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, > > > > + { ngx_string("request_id"), NULL, > > + ngx_http_variable_request_id, > > + 0, 0, 0 }, > > + > > { ngx_string("status"), NULL, > > ngx_http_variable_status, 0, > > NGX_HTTP_VAR_NOCACHEABLE, 0 }, > > @@ -2068,6 +2074,47 @@ ngx_http_variable_request_time(ngx_http_ > > > > > > static ngx_int_t > > +ngx_http_variable_request_id(ngx_http_request_t *r, > > + ngx_http_variable_value_t *v, uintptr_t data) > > +{ > > + u_char *id; > > + > > +#if (NGX_OPENSSL) > > + u_char random_bytes[16]; > > +#endif > > + > > + id = ngx_pnalloc(r->pool, 32); > > + if (id == NULL) { > > + return NGX_ERROR; > > + } > > + > > + v->valid = 1; > > + v->no_cacheable = 0; > > + v->not_found = 0; > > + > > + v->len = 32; > > + v->data = id; > > + > > +#if (NGX_OPENSSL) > > + > > + if (RAND_bytes(random_bytes, 16) == 1) { > > + ngx_hex_dump(id, random_bytes, 16); > > + return NGX_OK; > > + } > > + > > + ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, > "RAND_bytes() failed"); > > + > > +#endif > > + > > + ngx_sprintf(id, "%08xD%08xD%08xD%08xD", > > + (uint32_t) ngx_random(), (uint32_t) ngx_random(), > > + (uint32_t) ngx_random(), (uint32_t) ngx_random()); > > + > > + return NGX_OK; > > +} > > + > > + > > +static ngx_int_t > > ngx_http_variable_connection(ngx_http_request_t *r, > > ngx_http_variable_value_t *v, uintptr_t data) > > { > > > > _______________________________________________ > > nginx-devel mailing list > > nginx-devel at nginx.org <mailto:nginx-devel at nginx.org> > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > _______________________________________________ > > nginx-devel mailing list > > nginx-devel at nginx.org <mailto:nginx-devel at nginx.org> > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org <mailto:nginx-devel at nginx.org> > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Andrew Hutchings (LinuxJedi) Technical Product Manager, NGINX Inc. From toshic.toshic at gmail.com Wed Apr 27 08:50:43 2016 From: toshic.toshic at gmail.com (ToSHiC) Date: Wed, 27 Apr 2016 11:50:43 +0300 Subject: [nginx] Variable $request_id. In-Reply-To: <45d6b988-68e3-9c4f-c9df-a4aee8c7e3ca@nginx.com> References: <hg.59f8f2dd8b31.1461688689.6026610855610030274@dev.nginx.com> <CAB73Exp85FvWnyK1Ww0j2T2Xa7U+qYqvu2KZgAKVOcynn=U+aQ@mail.gmail.com> <5BB56607-F266-4303-84B9-14577E88E651@gmail.com> <CALFfGYY7COoYw-fUxYUrMgQRjBqW+1tDx_REn6=fE4iWJ-wzsQ@mail.gmail.com> <45d6b988-68e3-9c4f-c9df-a4aee8c7e3ca@nginx.com> Message-ID: <CAB73ExrsaOcsFbGaYZh7igX9b4n9FFH1d4uT3mn2hz1+TOfkHA@mail.gmail.com> Random data string is good: you can easily cut it twice to decrease length and it will still be useful and pretty random. For example, twitter zipkin works with 64 bit request id. Uuid doesn't have this property. 27 ??? 2016 ?. 11:41 ???????????? "Andrew Hutchings" <ahutchings at nginx.com> ???????: > Hi, > > Or you could use UUIDv1 and then it would also give you uniqueness and the > ability to have some debugging of IDs if required. > > Kind Regards > Andrew > > On 27/04/16 06:23, SplitIce wrote: > >> Hi, >> >> We have been using something like this for ~2 years. >> >> For ours we used a random number to start and the Process ID & Process >> start time to try and increase uniqueness between reloads (ours is a >> 128bit ID). Then applying an increment, with future requests having a >> higher id. >> >> Perhaps that would be better than just 128bit of random data? >> >> On Wed, Apr 27, 2016 at 12:14 PM, Alexey Ivanov <savetherbtz at gmail.com >> <mailto:savetherbtz at gmail.com>> wrote: >> >> Same here, in our environment we: >> * get current request id from a header >> * validate it against our guidelines >> * if not already present or does not pass validation: >> * re-generate using `RAND_bytes()` >> * propagate it to the upstream >> * echo it back to the downstream >> * log it to the access.log >> >> It would be nice if new nginx code can be used more or less drop-in >> replacement for our homegrown lua-stuff. >> >> We currently use following pseudo-code to >> validate/generate/propagate/echo-back request_ids: >> >> ``` >> set_by_lua $request_id ' >> local success, req_id = pcall(request_id.get_hex_or_generate, >> ngx.var.http_x_dropbox_request_id) >> if not success then >> return "-" >> end >> return req_id >> '; >> more_set_headers "X-Dropbox-Request-Id: $request_id"; >> proxy_set_header X-Dropbox-Request-Id $request_id ; >> ``` >> >> ``` >> --[[ >> Helper function that verifies request_id or generates new one in >> case >> validation fails. >> >> @req_id: current request id >> --]] >> function request_id.get_hex_or_generate(req_id) >> ... >> end >> ``` >> >> >> > On Apr 26, 2016, at 9:51 AM, ToSHiC <toshic.toshic at gmail.com >> <mailto:toshic.toshic at gmail.com>> wrote: >> > >> > Hello, >> > >> > We are using such variable for more than a year, and I suggest to >> add ability to extract request_id from header. It's very usefull for >> systems with frontend and backend installed on different servers. >> > >> > On Tue, Apr 26, 2016 at 7:38 PM, Vladimir Homutov <vl at nginx.com >> <mailto:vl at nginx.com>> wrote: >> > details: http://hg.nginx.org/nginx/rev/59f8f2dd8b31 >> > branches: >> > changeset: 6531:59f8f2dd8b31 >> > user: Vladimir Homutov <vl at nginx.com <mailto:vl at nginx.com>> >> > date: Tue Apr 26 19:31:46 2016 +0300 >> > description: >> > Variable $request_id. >> > >> > The variable contains text representation based on random data, >> usable as >> > a unique request identifier. >> > >> > diffstat: >> > >> > src/http/ngx_http_variables.c | 47 >> +++++++++++++++++++++++++++++++++++++++++++ >> > 1 files changed, 47 insertions(+), 0 deletions(-) >> > >> > diffs (71 lines): >> > >> > diff -r 1d0e03db9f8e -r 59f8f2dd8b31 src/http/ngx_http_variables.c >> > --- a/src/http/ngx_http_variables.c Fri Dec 18 19:05:27 2015 >> +0300 >> > +++ b/src/http/ngx_http_variables.c Tue Apr 26 19:31:46 2016 >> +0300 >> > @@ -98,6 +98,8 @@ static ngx_int_t ngx_http_variable_reque >> > ngx_http_variable_value_t *v, uintptr_t data); >> > static ngx_int_t >> ngx_http_variable_request_time(ngx_http_request_t *r, >> > ngx_http_variable_value_t *v, uintptr_t data); >> > +static ngx_int_t ngx_http_variable_request_id(ngx_http_request_t >> *r, >> > + ngx_http_variable_value_t *v, uintptr_t data); >> > static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r, >> > ngx_http_variable_value_t *v, uintptr_t data); >> > >> > @@ -274,6 +276,10 @@ static ngx_http_variable_t ngx_http_cor >> > { ngx_string("request_time"), NULL, >> ngx_http_variable_request_time, >> > 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, >> > >> > + { ngx_string("request_id"), NULL, >> > + ngx_http_variable_request_id, >> > + 0, 0, 0 }, >> > + >> > { ngx_string("status"), NULL, >> > ngx_http_variable_status, 0, >> > NGX_HTTP_VAR_NOCACHEABLE, 0 }, >> > @@ -2068,6 +2074,47 @@ ngx_http_variable_request_time(ngx_http_ >> > >> > >> > static ngx_int_t >> > +ngx_http_variable_request_id(ngx_http_request_t *r, >> > + ngx_http_variable_value_t *v, uintptr_t data) >> > +{ >> > + u_char *id; >> > + >> > +#if (NGX_OPENSSL) >> > + u_char random_bytes[16]; >> > +#endif >> > + >> > + id = ngx_pnalloc(r->pool, 32); >> > + if (id == NULL) { >> > + return NGX_ERROR; >> > + } >> > + >> > + v->valid = 1; >> > + v->no_cacheable = 0; >> > + v->not_found = 0; >> > + >> > + v->len = 32; >> > + v->data = id; >> > + >> > +#if (NGX_OPENSSL) >> > + >> > + if (RAND_bytes(random_bytes, 16) == 1) { >> > + ngx_hex_dump(id, random_bytes, 16); >> > + return NGX_OK; >> > + } >> > + >> > + ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, >> "RAND_bytes() failed"); >> > + >> > +#endif >> > + >> > + ngx_sprintf(id, "%08xD%08xD%08xD%08xD", >> > + (uint32_t) ngx_random(), (uint32_t) ngx_random(), >> > + (uint32_t) ngx_random(), (uint32_t) ngx_random()); >> > + >> > + return NGX_OK; >> > +} >> > + >> > + >> > +static ngx_int_t >> > ngx_http_variable_connection(ngx_http_request_t *r, >> > ngx_http_variable_value_t *v, uintptr_t data) >> > { >> > >> > _______________________________________________ >> > nginx-devel mailing list >> > nginx-devel at nginx.org <mailto:nginx-devel at nginx.org> >> > http://mailman.nginx.org/mailman/listinfo/nginx-devel >> > >> > _______________________________________________ >> > nginx-devel mailing list >> > nginx-devel at nginx.org <mailto:nginx-devel at nginx.org> >> > http://mailman.nginx.org/mailman/listinfo/nginx-devel >> >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org <mailto:nginx-devel at nginx.org> >> http://mailman.nginx.org/mailman/listinfo/nginx-devel >> >> >> >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel >> >> > -- > Andrew Hutchings (LinuxJedi) > Technical Product Manager, NGINX Inc. > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160427/f2d30487/attachment.html> From hongzhidao at gmail.com Wed Apr 27 09:10:47 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Wed, 27 Apr 2016 17:10:47 +0800 Subject: [nginx] dso Message-ID: <CAJuLd0hwtnd0F86ZEYjVsjpxs4ZNS77qePR=x6HayKP9TanTHg@mail.gmail.com> Hi, for example following config: daemon on; ... load_module modules/ngx_http_test_module.so; ... > start nginx > change ngx_http_test_module.c, then regenerate so file > kill -HUP pid I found nginx still run the old so file (load first time), and how to work with new so file? I tried .../sbin/nginx -s reload, It works as I expected. It seems there is some differences in 'kill -HUP' and 'sbin/nginx -s reload'; Thanks and Regards -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160427/e1e474d8/attachment.html> From mat999 at gmail.com Wed Apr 27 09:53:38 2016 From: mat999 at gmail.com (SplitIce) Date: Wed, 27 Apr 2016 19:53:38 +1000 Subject: [nginx] Variable $request_id. In-Reply-To: <CAB73ExrsaOcsFbGaYZh7igX9b4n9FFH1d4uT3mn2hz1+TOfkHA@mail.gmail.com> References: <hg.59f8f2dd8b31.1461688689.6026610855610030274@dev.nginx.com> <CAB73Exp85FvWnyK1Ww0j2T2Xa7U+qYqvu2KZgAKVOcynn=U+aQ@mail.gmail.com> <5BB56607-F266-4303-84B9-14577E88E651@gmail.com> <CALFfGYY7COoYw-fUxYUrMgQRjBqW+1tDx_REn6=fE4iWJ-wzsQ@mail.gmail.com> <45d6b988-68e3-9c4f-c9df-a4aee8c7e3ca@nginx.com> <CAB73ExrsaOcsFbGaYZh7igX9b4n9FFH1d4uT3mn2hz1+TOfkHA@mail.gmail.com> Message-ID: <CALFfGYZPGu2PZujuXO0kfXUv9P1x=EFwG2jytsf=QJ0-JJJGPw@mail.gmail.com> I am sure there are many different uses for a variable like this, and many different properties desired and available. If we switch to using this variable down the line, I would probably combine it with something that increments for each request as thats a property that aids in tracing issues. On Wed, Apr 27, 2016 at 6:50 PM, ToSHiC <toshic.toshic at gmail.com> wrote: > Random data string is good: you can easily cut it twice to decrease length > and it will still be useful and pretty random. For example, twitter zipkin > works with 64 bit request id. Uuid doesn't have this property. > 27 ??? 2016 ?. 11:41 ???????????? "Andrew Hutchings" <ahutchings at nginx.com> > ???????: > > Hi, >> >> Or you could use UUIDv1 and then it would also give you uniqueness and >> the ability to have some debugging of IDs if required. >> >> Kind Regards >> Andrew >> >> On 27/04/16 06:23, SplitIce wrote: >> >>> Hi, >>> >>> We have been using something like this for ~2 years. >>> >>> For ours we used a random number to start and the Process ID & Process >>> start time to try and increase uniqueness between reloads (ours is a >>> 128bit ID). Then applying an increment, with future requests having a >>> higher id. >>> >>> Perhaps that would be better than just 128bit of random data? >>> >>> On Wed, Apr 27, 2016 at 12:14 PM, Alexey Ivanov <savetherbtz at gmail.com >>> <mailto:savetherbtz at gmail.com>> wrote: >>> >>> Same here, in our environment we: >>> * get current request id from a header >>> * validate it against our guidelines >>> * if not already present or does not pass validation: >>> * re-generate using `RAND_bytes()` >>> * propagate it to the upstream >>> * echo it back to the downstream >>> * log it to the access.log >>> >>> It would be nice if new nginx code can be used more or less drop-in >>> replacement for our homegrown lua-stuff. >>> >>> We currently use following pseudo-code to >>> validate/generate/propagate/echo-back request_ids: >>> >>> ``` >>> set_by_lua $request_id ' >>> local success, req_id = pcall(request_id.get_hex_or_generate, >>> ngx.var.http_x_dropbox_request_id) >>> if not success then >>> return "-" >>> end >>> return req_id >>> '; >>> more_set_headers "X-Dropbox-Request-Id: $request_id"; >>> proxy_set_header X-Dropbox-Request-Id $request_id ; >>> ``` >>> >>> ``` >>> --[[ >>> Helper function that verifies request_id or generates new one in >>> case >>> validation fails. >>> >>> @req_id: current request id >>> --]] >>> function request_id.get_hex_or_generate(req_id) >>> ... >>> end >>> ``` >>> >>> >>> > On Apr 26, 2016, at 9:51 AM, ToSHiC <toshic.toshic at gmail.com >>> <mailto:toshic.toshic at gmail.com>> wrote: >>> > >>> > Hello, >>> > >>> > We are using such variable for more than a year, and I suggest to >>> add ability to extract request_id from header. It's very usefull for >>> systems with frontend and backend installed on different servers. >>> > >>> > On Tue, Apr 26, 2016 at 7:38 PM, Vladimir Homutov <vl at nginx.com >>> <mailto:vl at nginx.com>> wrote: >>> > details: http://hg.nginx.org/nginx/rev/59f8f2dd8b31 >>> > branches: >>> > changeset: 6531:59f8f2dd8b31 >>> > user: Vladimir Homutov <vl at nginx.com <mailto:vl at nginx.com>> >>> > date: Tue Apr 26 19:31:46 2016 +0300 >>> > description: >>> > Variable $request_id. >>> > >>> > The variable contains text representation based on random data, >>> usable as >>> > a unique request identifier. >>> > >>> > diffstat: >>> > >>> > src/http/ngx_http_variables.c | 47 >>> +++++++++++++++++++++++++++++++++++++++++++ >>> > 1 files changed, 47 insertions(+), 0 deletions(-) >>> > >>> > diffs (71 lines): >>> > >>> > diff -r 1d0e03db9f8e -r 59f8f2dd8b31 src/http/ngx_http_variables.c >>> > --- a/src/http/ngx_http_variables.c Fri Dec 18 19:05:27 2015 >>> +0300 >>> > +++ b/src/http/ngx_http_variables.c Tue Apr 26 19:31:46 2016 >>> +0300 >>> > @@ -98,6 +98,8 @@ static ngx_int_t ngx_http_variable_reque >>> > ngx_http_variable_value_t *v, uintptr_t data); >>> > static ngx_int_t >>> ngx_http_variable_request_time(ngx_http_request_t *r, >>> > ngx_http_variable_value_t *v, uintptr_t data); >>> > +static ngx_int_t ngx_http_variable_request_id(ngx_http_request_t >>> *r, >>> > + ngx_http_variable_value_t *v, uintptr_t data); >>> > static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r, >>> > ngx_http_variable_value_t *v, uintptr_t data); >>> > >>> > @@ -274,6 +276,10 @@ static ngx_http_variable_t ngx_http_cor >>> > { ngx_string("request_time"), NULL, >>> ngx_http_variable_request_time, >>> > 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, >>> > >>> > + { ngx_string("request_id"), NULL, >>> > + ngx_http_variable_request_id, >>> > + 0, 0, 0 }, >>> > + >>> > { ngx_string("status"), NULL, >>> > ngx_http_variable_status, 0, >>> > NGX_HTTP_VAR_NOCACHEABLE, 0 }, >>> > @@ -2068,6 +2074,47 @@ ngx_http_variable_request_time(ngx_http_ >>> > >>> > >>> > static ngx_int_t >>> > +ngx_http_variable_request_id(ngx_http_request_t *r, >>> > + ngx_http_variable_value_t *v, uintptr_t data) >>> > +{ >>> > + u_char *id; >>> > + >>> > +#if (NGX_OPENSSL) >>> > + u_char random_bytes[16]; >>> > +#endif >>> > + >>> > + id = ngx_pnalloc(r->pool, 32); >>> > + if (id == NULL) { >>> > + return NGX_ERROR; >>> > + } >>> > + >>> > + v->valid = 1; >>> > + v->no_cacheable = 0; >>> > + v->not_found = 0; >>> > + >>> > + v->len = 32; >>> > + v->data = id; >>> > + >>> > +#if (NGX_OPENSSL) >>> > + >>> > + if (RAND_bytes(random_bytes, 16) == 1) { >>> > + ngx_hex_dump(id, random_bytes, 16); >>> > + return NGX_OK; >>> > + } >>> > + >>> > + ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, >>> "RAND_bytes() failed"); >>> > + >>> > +#endif >>> > + >>> > + ngx_sprintf(id, "%08xD%08xD%08xD%08xD", >>> > + (uint32_t) ngx_random(), (uint32_t) ngx_random(), >>> > + (uint32_t) ngx_random(), (uint32_t) ngx_random()); >>> > + >>> > + return NGX_OK; >>> > +} >>> > + >>> > + >>> > +static ngx_int_t >>> > ngx_http_variable_connection(ngx_http_request_t *r, >>> > ngx_http_variable_value_t *v, uintptr_t data) >>> > { >>> > >>> > _______________________________________________ >>> > nginx-devel mailing list >>> > nginx-devel at nginx.org <mailto:nginx-devel at nginx.org> >>> > http://mailman.nginx.org/mailman/listinfo/nginx-devel >>> > >>> > _______________________________________________ >>> > nginx-devel mailing list >>> > nginx-devel at nginx.org <mailto:nginx-devel at nginx.org> >>> > http://mailman.nginx.org/mailman/listinfo/nginx-devel >>> >>> >>> _______________________________________________ >>> nginx-devel mailing list >>> nginx-devel at nginx.org <mailto:nginx-devel at nginx.org> >>> http://mailman.nginx.org/mailman/listinfo/nginx-devel >>> >>> >>> >>> >>> _______________________________________________ >>> nginx-devel mailing list >>> nginx-devel at nginx.org >>> http://mailman.nginx.org/mailman/listinfo/nginx-devel >>> >>> >> -- >> Andrew Hutchings (LinuxJedi) >> Technical Product Manager, NGINX Inc. >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel >> > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160427/fb1e2399/attachment.html> From igor at sysoev.ru Wed Apr 27 11:22:46 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 27 Apr 2016 14:22:46 +0300 Subject: [nginx] dso In-Reply-To: <CAJuLd0hwtnd0F86ZEYjVsjpxs4ZNS77qePR=x6HayKP9TanTHg@mail.gmail.com> References: <CAJuLd0hwtnd0F86ZEYjVsjpxs4ZNS77qePR=x6HayKP9TanTHg@mail.gmail.com> Message-ID: <951F36D8-94DC-43E5-85D3-30AAA4EAA538@sysoev.ru> On 27 Apr 2016, at 12:10, ??? <hongzhidao at gmail.com> wrote: > Hi, > > for example following config: > > daemon on; > ... > load_module modules/ngx_http_test_module.so; > ... > > > start nginx > > change ngx_http_test_module.c, then regenerate so file > > kill -HUP pid > > I found nginx still run the old so file (load first time), and how to work with new so file? > > I tried .../sbin/nginx -s reload, It works as I expected. It seems there is some differences in 'kill -HUP' and 'sbin/nginx -s reload?; kill -USR2 `cat nginx.pid`; sleep 2; kill -QUIT `cat nginx.pid.oldbin` -- Igor Sysoev http://nginx.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160427/47494d20/attachment.html> From mdounin at mdounin.ru Wed Apr 27 14:30:07 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 27 Apr 2016 17:30:07 +0300 Subject: [nginx] Variable $request_id. In-Reply-To: <CALFfGYY7COoYw-fUxYUrMgQRjBqW+1tDx_REn6=fE4iWJ-wzsQ@mail.gmail.com> References: <hg.59f8f2dd8b31.1461688689.6026610855610030274@dev.nginx.com> <CAB73Exp85FvWnyK1Ww0j2T2Xa7U+qYqvu2KZgAKVOcynn=U+aQ@mail.gmail.com> <5BB56607-F266-4303-84B9-14577E88E651@gmail.com> <CALFfGYY7COoYw-fUxYUrMgQRjBqW+1tDx_REn6=fE4iWJ-wzsQ@mail.gmail.com> Message-ID: <20160427143007.GI36620@mdounin.ru> Hello! On Wed, Apr 27, 2016 at 03:23:51PM +1000, SplitIce wrote: > For ours we used a random number to start and the Process ID & Process > start time to try and increase uniqueness between reloads (ours is a 128bit > ID). Then applying an increment, with future requests having a higher id. > > Perhaps that would be better than just 128bit of random data? Using process id & start time is believed to be particularly bad approach in virtualized environments where multiple identical virtual machines and/or containers can start at the same time. -- Maxim Dounin http://nginx.org/ From albertcasademont at gmail.com Wed Apr 27 14:40:47 2016 From: albertcasademont at gmail.com (Albert Casademont) Date: Wed, 27 Apr 2016 17:40:47 +0300 Subject: [nginx] Variable $request_id. In-Reply-To: <20160427143007.GI36620@mdounin.ru> References: <hg.59f8f2dd8b31.1461688689.6026610855610030274@dev.nginx.com> <CAB73Exp85FvWnyK1Ww0j2T2Xa7U+qYqvu2KZgAKVOcynn=U+aQ@mail.gmail.com> <5BB56607-F266-4303-84B9-14577E88E651@gmail.com> <CALFfGYY7COoYw-fUxYUrMgQRjBqW+1tDx_REn6=fE4iWJ-wzsQ@mail.gmail.com> <20160427143007.GI36620@mdounin.ru> Message-ID: <CAMA5aFaCCayFu3ni1Kn7skzmQP7ZKgspMwrcLD-686MPtcSEuA@mail.gmail.com> Hi all, We've been using this extension for quite a long time now, it's based on UUIDs and it works flawlessly, no need to reinvent the wheel here! https://github.com/newobj/nginx-x-rid-header/ Best, Albert On Wed, Apr 27, 2016 at 5:30 PM, Maxim Dounin <mdounin at mdounin.ru> wrote: > Hello! > > On Wed, Apr 27, 2016 at 03:23:51PM +1000, SplitIce wrote: > > > For ours we used a random number to start and the Process ID & Process > > start time to try and increase uniqueness between reloads (ours is a > 128bit > > ID). Then applying an increment, with future requests having a higher id. > > > > Perhaps that would be better than just 128bit of random data? > > Using process id & start time is believed to be particularly bad > approach in virtualized environments where multiple identical > virtual machines and/or containers can start at the same time. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160427/5666938b/attachment.html> From albertcasademont at gmail.com Wed Apr 27 14:42:28 2016 From: albertcasademont at gmail.com (Albert Casademont) Date: Wed, 27 Apr 2016 17:42:28 +0300 Subject: [nginx] Variable $request_id. In-Reply-To: <CAMA5aFaCCayFu3ni1Kn7skzmQP7ZKgspMwrcLD-686MPtcSEuA@mail.gmail.com> References: <hg.59f8f2dd8b31.1461688689.6026610855610030274@dev.nginx.com> <CAB73Exp85FvWnyK1Ww0j2T2Xa7U+qYqvu2KZgAKVOcynn=U+aQ@mail.gmail.com> <5BB56607-F266-4303-84B9-14577E88E651@gmail.com> <CALFfGYY7COoYw-fUxYUrMgQRjBqW+1tDx_REn6=fE4iWJ-wzsQ@mail.gmail.com> <20160427143007.GI36620@mdounin.ru> <CAMA5aFaCCayFu3ni1Kn7skzmQP7ZKgspMwrcLD-686MPtcSEuA@mail.gmail.com> Message-ID: <CAMA5aFYOXSv1CrtwkRRC0=PrDv2OArBC4d85kg9F-xyvBNJu7g@mail.gmail.com> To be clear, that extension also uses a "request_id" variable, accepting this patch would effectively break that extension, which I believe quite a lof of people also use. On Wed, Apr 27, 2016 at 5:40 PM, Albert Casademont < albertcasademont at gmail.com> wrote: > Hi all, > > We've been using this extension for quite a long time now, it's based on > UUIDs and it works flawlessly, no need to reinvent the wheel here! > > https://github.com/newobj/nginx-x-rid-header/ > > Best, > > Albert > > On Wed, Apr 27, 2016 at 5:30 PM, Maxim Dounin <mdounin at mdounin.ru> wrote: > >> Hello! >> >> On Wed, Apr 27, 2016 at 03:23:51PM +1000, SplitIce wrote: >> >> > For ours we used a random number to start and the Process ID & Process >> > start time to try and increase uniqueness between reloads (ours is a >> 128bit >> > ID). Then applying an increment, with future requests having a higher >> id. >> > >> > Perhaps that would be better than just 128bit of random data? >> >> Using process id & start time is believed to be particularly bad >> approach in virtualized environments where multiple identical >> virtual machines and/or containers can start at the same time. >> >> -- >> Maxim Dounin >> http://nginx.org/ >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160427/566a1449/attachment.html> From hongzhidao at gmail.com Wed Apr 27 15:51:18 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Wed, 27 Apr 2016 23:51:18 +0800 Subject: [nginx] dso In-Reply-To: <951F36D8-94DC-43E5-85D3-30AAA4EAA538@sysoev.ru> References: <CAJuLd0hwtnd0F86ZEYjVsjpxs4ZNS77qePR=x6HayKP9TanTHg@mail.gmail.com> <951F36D8-94DC-43E5-85D3-30AAA4EAA538@sysoev.ru> Message-ID: <CAJuLd0gc3bitK_Ey4vL56uoJmFQmYNVExU0sZfn15dXe+rSSVg@mail.gmail.com> Thanks for your reply. Is it the only way to solve the problem? I think it will be common that developers try to use dso instead of static module. Nginx offical site points out we could load in so modules using reload or restart, but it seems forget to instruct the details about reload. And it's a great design, thanks again. 2016-04-27 19:22 GMT+08:00 Igor Sysoev <igor at sysoev.ru>: > On 27 Apr 2016, at 12:10, ??? <hongzhidao at gmail.com> wrote: > > Hi, > > for example following config: > > daemon on; > ... > load_module modules/ngx_http_test_module.so; > ... > > > start nginx > > change ngx_http_test_module.c, then regenerate so file > > kill -HUP pid > > I found nginx still run the old so file (load first time), and how to work > with new so file? > > I tried .../sbin/nginx -s reload, It works as I expected. It seems there > is some differences in 'kill -HUP' and 'sbin/nginx -s reload?; > > > kill -USR2 `cat nginx.pid`; sleep 2; kill -QUIT `cat nginx.pid.oldbin` > > > -- > Igor Sysoev > http://nginx.com > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160427/6a309ef9/attachment.html> From igor at sysoev.ru Wed Apr 27 16:08:32 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 27 Apr 2016 19:08:32 +0300 Subject: [nginx] dso In-Reply-To: <CAJuLd0gc3bitK_Ey4vL56uoJmFQmYNVExU0sZfn15dXe+rSSVg@mail.gmail.com> References: <CAJuLd0hwtnd0F86ZEYjVsjpxs4ZNS77qePR=x6HayKP9TanTHg@mail.gmail.com> <951F36D8-94DC-43E5-85D3-30AAA4EAA538@sysoev.ru> <CAJuLd0gc3bitK_Ey4vL56uoJmFQmYNVExU0sZfn15dXe+rSSVg@mail.gmail.com> Message-ID: <05EE205C-457A-466C-A286-22EA54B15A3D@sysoev.ru> On 27 Apr 2016, at 18:51, ??? <hongzhidao at gmail.com> wrote: > Thanks for your reply. > > Is it the only way to solve the problem? This is a way to reload a module in production without service interruption. > I think it will be common that developers try to use dso instead of static module. Developers can simply stop and start nginx again. -- Igor Sysoev http://nginx.com > Nginx offical site points out we could load in so modules using reload or restart, but it seems forget to instruct the details about reload. > And it's a great design, thanks again. > > 2016-04-27 19:22 GMT+08:00 Igor Sysoev <igor at sysoev.ru>: > On 27 Apr 2016, at 12:10, ??? <hongzhidao at gmail.com> wrote: > >> Hi, >> >> for example following config: >> >> daemon on; >> ... >> load_module modules/ngx_http_test_module.so; >> ... >> >> > start nginx >> > change ngx_http_test_module.c, then regenerate so file >> > kill -HUP pid >> >> I found nginx still run the old so file (load first time), and how to work with new so file? >> >> I tried .../sbin/nginx -s reload, It works as I expected. It seems there is some differences in 'kill -HUP' and 'sbin/nginx -s reload?; > > kill -USR2 `cat nginx.pid`; sleep 2; kill -QUIT `cat nginx.pid.oldbin` > > > -- > Igor Sysoev > http://nginx.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160427/5f0c429a/attachment.html> From hongzhidao at gmail.com Wed Apr 27 16:32:30 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Thu, 28 Apr 2016 00:32:30 +0800 Subject: [nginx] dso In-Reply-To: <05EE205C-457A-466C-A286-22EA54B15A3D@sysoev.ru> References: <CAJuLd0hwtnd0F86ZEYjVsjpxs4ZNS77qePR=x6HayKP9TanTHg@mail.gmail.com> <951F36D8-94DC-43E5-85D3-30AAA4EAA538@sysoev.ru> <CAJuLd0gc3bitK_Ey4vL56uoJmFQmYNVExU0sZfn15dXe+rSSVg@mail.gmail.com> <05EE205C-457A-466C-A286-22EA54B15A3D@sysoev.ru> Message-ID: <CAJuLd0gF0SR_cQJmM0BfM8EQjPbULrzUEPy0mwMr9X5TWDGfhA@mail.gmail.com> Get. In production, there may be some possibility with load_module directive. 1. add new module: load_module modules/some_module.so; [?] 2. remove exist load_module directive, just comment out. [?] 3. directive not changed but the so file changed. [kill -USR2 `cat nginx.pid`; sleep 2; kill -QUIT `cat nginx.pid.oldbin`] And how to deal with? 2016-04-28 0:08 GMT+08:00 Igor Sysoev <igor at sysoev.ru>: > On 27 Apr 2016, at 18:51, ??? <hongzhidao at gmail.com> wrote: > > Thanks for your reply. > > Is it the only way to solve the problem? > > > This is a way to reload a module in production without > service interruption. > > I think it will be common that developers try to use dso instead of static > module. > > > Developers can simply stop and start nginx again. > > -- > Igor Sysoev > http://nginx.com > > Nginx offical site points out we could load in so modules using reload or > restart, but it seems forget to instruct the details about reload. > And it's a great design, thanks again. > > 2016-04-27 19:22 GMT+08:00 Igor Sysoev <igor at sysoev.ru>: > >> On 27 Apr 2016, at 12:10, ??? <hongzhidao at gmail.com> wrote: >> >> Hi, >> >> for example following config: >> >> daemon on; >> ... >> load_module modules/ngx_http_test_module.so; >> ... >> >> > start nginx >> > change ngx_http_test_module.c, then regenerate so file >> > kill -HUP pid >> >> I found nginx still run the old so file (load first time), and how to >> work with new so file? >> >> I tried .../sbin/nginx -s reload, It works as I expected. It seems there >> is some differences in 'kill -HUP' and 'sbin/nginx -s reload?; >> >> >> kill -USR2 `cat nginx.pid`; sleep 2; kill -QUIT `cat nginx.pid.oldbin` >> >> >> -- >> Igor Sysoev >> http://nginx.com >> > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160428/2ecc98d5/attachment.html> From igor at sysoev.ru Wed Apr 27 19:02:02 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 27 Apr 2016 22:02:02 +0300 Subject: [nginx] dso In-Reply-To: <CAJuLd0gF0SR_cQJmM0BfM8EQjPbULrzUEPy0mwMr9X5TWDGfhA@mail.gmail.com> References: <CAJuLd0hwtnd0F86ZEYjVsjpxs4ZNS77qePR=x6HayKP9TanTHg@mail.gmail.com> <951F36D8-94DC-43E5-85D3-30AAA4EAA538@sysoev.ru> <CAJuLd0gc3bitK_Ey4vL56uoJmFQmYNVExU0sZfn15dXe+rSSVg@mail.gmail.com> <05EE205C-457A-466C-A286-22EA54B15A3D@sysoev.ru> <CAJuLd0gF0SR_cQJmM0BfM8EQjPbULrzUEPy0mwMr9X5TWDGfhA@mail.gmail.com> Message-ID: <6BEEE0A6-BBB6-4F7D-A65E-99C1D7406F31@sysoev.ru> On 27 Apr 2016, at 19:32, ??? <hongzhidao at gmail.com> wrote: > Get. > In production, there may be some possibility with load_module directive. > 1. add new module: load_module modules/some_module.so; [?] > 2. remove exist load_module directive, just comment out. [?] > 3. directive not changed but the so file changed. [kill -USR2 `cat nginx.pid`; sleep 2; kill -QUIT `cat nginx.pid.oldbin`] > And how to deal with? USR2/QUIT is online binary upgrade procedure: http://nginx.org/en/docs/control.html#upgrade And this procedure should be used to change and to unload modules. -- Igor Sysoev http://nginx.com > 2016-04-28 0:08 GMT+08:00 Igor Sysoev <igor at sysoev.ru>: > On 27 Apr 2016, at 18:51, ??? <hongzhidao at gmail.com> wrote: > >> Thanks for your reply. >> >> Is it the only way to solve the problem? > > This is a way to reload a module in production without service interruption. > >> I think it will be common that developers try to use dso instead of static module. > > Developers can simply stop and start nginx again. > > -- > Igor Sysoev > http://nginx.com > >> Nginx offical site points out we could load in so modules using reload or restart, but it seems forget to instruct the details about reload. >> And it's a great design, thanks again. >> >> 2016-04-27 19:22 GMT+08:00 Igor Sysoev <igor at sysoev.ru>: >> On 27 Apr 2016, at 12:10, ??? <hongzhidao at gmail.com> wrote: >> >>> Hi, >>> >>> for example following config: >>> >>> daemon on; >>> ... >>> load_module modules/ngx_http_test_module.so; >>> ... >>> >>> > start nginx >>> > change ngx_http_test_module.c, then regenerate so file >>> > kill -HUP pid >>> >>> I found nginx still run the old so file (load first time), and how to work with new so file? >>> >>> I tried .../sbin/nginx -s reload, It works as I expected. It seems there is some differences in 'kill -HUP' and 'sbin/nginx -s reload?; >> >> kill -USR2 `cat nginx.pid`; sleep 2; kill -QUIT `cat nginx.pid.oldbin` >> >> >> -- >> Igor Sysoev >> http://nginx.com > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160427/629f6b08/attachment.html> From ru at nginx.com Thu Apr 28 13:31:26 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 28 Apr 2016 13:31:26 +0000 Subject: [nginx] Removed unused flag unexpected_eof from ngx_connection_t. Message-ID: <hg.2f98b5709d79.1461850286.6026610855610030274@dev.nginx.com> details: http://hg.nginx.org/nginx/rev/2f98b5709d79 branches: changeset: 6532:2f98b5709d79 user: Ruslan Ermilov <ru at nginx.com> date: Thu Apr 28 16:30:19 2016 +0300 description: Removed unused flag unexpected_eof from ngx_connection_t. diffstat: src/core/ngx_connection.h | 1 - src/event/ngx_event_accept.c | 2 -- src/event/ngx_event_acceptex.c | 2 -- src/http/ngx_http_core_module.c | 2 -- 4 files changed, 0 insertions(+), 7 deletions(-) diffs (47 lines): diff -r 59f8f2dd8b31 -r 2f98b5709d79 src/core/ngx_connection.h --- a/src/core/ngx_connection.h Tue Apr 26 19:31:46 2016 +0300 +++ b/src/core/ngx_connection.h Thu Apr 28 16:30:19 2016 +0300 @@ -169,7 +169,6 @@ struct ngx_connection_s { unsigned log_error:3; /* ngx_connection_log_error_e */ - unsigned unexpected_eof:1; unsigned timedout:1; unsigned error:1; unsigned destroyed:1; diff -r 59f8f2dd8b31 -r 2f98b5709d79 src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c Tue Apr 26 19:31:46 2016 +0300 +++ b/src/event/ngx_event_accept.c Thu Apr 28 16:30:19 2016 +0300 @@ -217,8 +217,6 @@ ngx_event_accept(ngx_event_t *ev) c->local_sockaddr = ls->sockaddr; c->local_socklen = ls->socklen; - c->unexpected_eof = 1; - #if (NGX_HAVE_UNIX_DOMAIN) if (c->sockaddr->sa_family == AF_UNIX) { c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; diff -r 59f8f2dd8b31 -r 2f98b5709d79 src/event/ngx_event_acceptex.c --- a/src/event/ngx_event_acceptex.c Tue Apr 26 19:31:46 2016 +0300 +++ b/src/event/ngx_event_acceptex.c Thu Apr 28 16:30:19 2016 +0300 @@ -159,8 +159,6 @@ ngx_event_post_acceptex(ngx_listening_t c->recv_chain = ngx_recv_chain; c->send_chain = ngx_send_chain; - c->unexpected_eof = 1; - c->listening = ls; rev = c->read; diff -r 59f8f2dd8b31 -r 2f98b5709d79 src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Tue Apr 26 19:31:46 2016 +0300 +++ b/src/http/ngx_http_core_module.c Thu Apr 28 16:30:19 2016 +0300 @@ -793,8 +793,6 @@ ngx_http_handler(ngx_http_request_t *r) r->connection->log->action = NULL; - r->connection->unexpected_eof = 0; - if (!r->internal) { switch (r->headers_in.connection_type) { case 0: From danibento at overdestiny.com Thu Apr 28 23:43:18 2016 From: danibento at overdestiny.com (Dani Bento) Date: Fri, 29 Apr 2016 00:43:18 +0100 Subject: Add support for Log ZMQ 3rd Party Module on vim syntax Message-ID: <CADcaCQxQ4vaQTKYoR+dKxogBhXeiZnQbqvyQ2-dYezYOmQzYuA@mail.gmail.com> # HG changeset patch # User Daniela Bento <danibento at overdestiny.com> # Date 1461886571 -3600 # Fri Apr 29 00:36:11 2016 +0100 # Node ID 6a1f953371d22ab082f05b5249d29ec72f934411 # Parent 2f98b5709d7965e7c97cb74b8380014179c7bf0d Contrib: add support for Log ZMQ on Vim Syntax Add support for the 3rd party module Log ZMQ to the Vim Syntax diff -r 2f98b5709d79 -r 6a1f953371d2 contrib/vim/syntax/nginx.vim --- a/contrib/vim/syntax/nginx.vim Thu Apr 28 16:30:19 2016 +0300 +++ b/contrib/vim/syntax/nginx.vim Fri Apr 29 00:36:11 2016 +0100 @@ -669,6 +669,13 @@ syn keyword ngxDirectiveThirdParty log_request_speed_filter syn keyword ngxDirectiveThirdParty log_request_speed_filter_timeout +" Log ZMQ http://https://www.nginx.com/resources/wiki/modules/log_zmq/> +" ZeroMQ logger module for nginx +syn keyword ngxDirectiveThirdParty log_zmq_server +syn keyword ngxDirectiveThirdParty log_zmq_format +syn keyword ngxDirectiveThirdParty log_zmq_endpoint +syn keyword ngxDirectiveThirdParty log_zmq_off + " Memc Module <http://wiki.nginx.org/NginxHttpMemcModule> " An extended version of the standard memcached module that supports set, add, delete, and many more memcached commands. syn keyword ngxDirectiveThirdParty memc_buffer_size -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160429/3315af77/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: log_zmq_vim.patch Type: text/x-patch Size: 1243 bytes Desc: not available URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160429/3315af77/attachment.bin> From al-nginx at none.at Fri Apr 29 10:47:22 2016 From: al-nginx at none.at (Aleksandar Lazic) Date: Fri, 29 Apr 2016 12:47:22 +0200 Subject: Add support for Log ZMQ 3rd Party Module on vim syntax In-Reply-To: <CADcaCQxQ4vaQTKYoR+dKxogBhXeiZnQbqvyQ2-dYezYOmQzYuA@mail.gmail.com> References: <CADcaCQxQ4vaQTKYoR+dKxogBhXeiZnQbqvyQ2-dYezYOmQzYuA@mail.gmail.com> Message-ID: <2e8f6260d518572763e56e9bf8d4e8a8@none.at> Hi Dani. Am 29-04-2016 01:43, schrieb Dani Bento: > # HG changeset patch > # User Daniela Bento <danibento at overdestiny.com> > # Date 1461886571 -3600 > # Fri Apr 29 00:36:11 2016 +0100 > # Node ID 6a1f953371d22ab082f05b5249d29ec72f934411 > # Parent 2f98b5709d7965e7c97cb74b8380014179c7bf0d > Contrib: add support for Log ZMQ on Vim Syntax > > Add support for the 3rd party module Log ZMQ to the Vim Syntax [snipp] > +" Log ZMQ > http://https://www.nginx.com/resources/wiki/modules/log_zmq/> > +" ZeroMQ logger module for nginx That's cool ;-) Do you think to make this module loadable and provide the SO file ?! Best regards Aleks From danibento at overdestiny.com Sat Apr 30 17:20:43 2016 From: danibento at overdestiny.com (Dani Bento) Date: Sat, 30 Apr 2016 18:20:43 +0100 Subject: Add support for Log ZMQ 3rd Party Module on vim syntax In-Reply-To: <2e8f6260d518572763e56e9bf8d4e8a8@none.at> References: <CADcaCQxQ4vaQTKYoR+dKxogBhXeiZnQbqvyQ2-dYezYOmQzYuA@mail.gmail.com> <2e8f6260d518572763e56e9bf8d4e8a8@none.at> Message-ID: <CADcaCQxCafPqaN+g3Dn1kK488PNvK5pdigj9a_iY=rizMR99mw@mail.gmail.com> Hey, Thanks! The module's config file was already updated to have support for dynamic modules. It was tested locally, but it was not yet automated in travis-cli or it has tests in a running environment. And I want to test the support with 0MQ 4 table too. Best regards, Dani On Fri, Apr 29, 2016 at 11:47 AM, Aleksandar Lazic <al-nginx at none.at> wrote: > Hi Dani. > > Am 29-04-2016 01:43, schrieb Dani Bento: > >> # HG changeset patch >> # User Daniela Bento <danibento at overdestiny.com> >> # Date 1461886571 -3600 >> # Fri Apr 29 00:36:11 2016 +0100 >> # Node ID 6a1f953371d22ab082f05b5249d29ec72f934411 >> # Parent 2f98b5709d7965e7c97cb74b8380014179c7bf0d >> Contrib: add support for Log ZMQ on Vim Syntax >> >> Add support for the 3rd party module Log ZMQ to the Vim Syntax >> > > [snipp] > > +" Log ZMQ http://https://www.nginx.com/resources/wiki/modules/log_zmq/> >> +" ZeroMQ logger module for nginx >> > > That's cool ;-) > > Do you think to make this module loadable and provide the SO file ?! > > Best regards > Aleks > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160430/1aa072d1/attachment.html>