From datong at cloudflare.com Thu Dec 1 09:16:37 2016 From: datong at cloudflare.com (Datong Sun) Date: Thu, 1 Dec 2016 01:16:37 -0800 Subject: Why not remove UNIX domain socket before bind In-Reply-To: <20161130145719.GA8196@mdounin.ru> References: <423e461b-75fc-70a6-8f22-65681e54a7fa@gmail.com> <20161130145719.GA8196@mdounin.ru> Message-ID: Hi Maxim, Thanks for the explanation. Regarding a), what about checking and making sure the type of file is actually a socket before removing? Obviously it does not prevent NGINX from deleting sockets created by other processes but it's a much smaller issue compared to deleting arbitrary file. Thanks, On Wed, Nov 30, 2016 at 6:57 AM, Maxim Dounin wrote: > Hello! > > On Tue, Nov 29, 2016 at 01:30:25PM -0800, Shuxin Yang wrote: > > > Is there any reason not to delete UNIX domain socket before bind? > > To name a few, deleting a socket implies that: > > a) any file can be accidentally deleted due to a typo in the > listen directive; > > b) attempts to do duplicate listen are not detected and silently > break service, e.g., if you start duplicate instance of nginx. > > Instead we delete the socket after closing it. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- *Datong Sun* | Systems Engineer datong at cloudflare.com 1 888 99 FLARE | www.cloudflare.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From savetherbtz at gmail.com Thu Dec 1 09:20:43 2016 From: savetherbtz at gmail.com (Alexey Ivanov) Date: Thu, 1 Dec 2016 01:20:43 -0800 Subject: Why not remove UNIX domain socket before bind In-Reply-To: <20161130145719.GA8196@mdounin.ru> References: <423e461b-75fc-70a6-8f22-65681e54a7fa@gmail.com> <20161130145719.GA8196@mdounin.ru> Message-ID: <7F9FF625-4A3F-467A-A6F9-D107A4567453@gmail.com> Why not just use `flock(2)` there? > On Nov 30, 2016, at 6:57 AM, Maxim Dounin wrote: > > Hello! > > On Tue, Nov 29, 2016 at 01:30:25PM -0800, Shuxin Yang wrote: > >> Is there any reason not to delete UNIX domain socket before bind? > > To name a few, deleting a socket implies that: > > a) any file can be accidentally deleted due to a typo in the > listen directive; > > b) attempts to do duplicate listen are not detected and silently > break service, e.g., if you start duplicate instance of nginx. > > Instead we delete the socket after closing it. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > 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: From xeioex at nginx.com Thu Dec 1 12:12:21 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Thu, 01 Dec 2016 12:12:21 +0000 Subject: [nginx] Events: improved error event handling for UDP sockets. Message-ID: details: http://hg.nginx.org/nginx/rev/75dbab4ea930 branches: changeset: 6806:75dbab4ea930 user: Dmitry Volyntsev date: Mon Nov 21 16:03:42 2016 +0300 description: Events: improved error event handling for UDP sockets. Normally, the epoll module calls the read and write handlers depending on whether EPOLLIN and EPOLLOUT are reported by epoll_wait(). No error processing is done in the module, the handlers are expected to get an error when doing I/O. If an error event is reported without EPOLLIN and EPOLLOUT, the module set both EPOLLIN and EPOLLOUT to ensure the error event is handled at least in one active handler. This works well unless the error is delivered along with only one of EPOLLIN or EPOLLOUT, and the corresponding handler does not do any I/O. For example, it happened when getting EPOLLERR|EPOLLOUT from epoll_wait() upon receiving "ICMP port unreachable" while proxying UDP. As the write handler had nothing to send it was not able to detect and log an error, and did not switch to the next upstream. The fix is to unconditionally set EPOLLIN and EPOLLOUT in case of an error event. In the aforementioned case, this causes the read handler to be called which does recv() and detects an error. In addition to the epoll module, analogous changes were made in devpoll/eventport/poll. diffstat: src/event/modules/ngx_devpoll_module.c | 10 ++++------ src/event/modules/ngx_epoll_module.c | 19 +++++++------------ src/event/modules/ngx_eventport_module.c | 10 ++++------ src/event/modules/ngx_poll_module.c | 10 ++++------ 4 files changed, 19 insertions(+), 30 deletions(-) diffs (99 lines): diff -r 52bd8cc17f34 -r 75dbab4ea930 src/event/modules/ngx_devpoll_module.c --- a/src/event/modules/ngx_devpoll_module.c Mon Nov 28 19:19:21 2016 +0300 +++ b/src/event/modules/ngx_devpoll_module.c Mon Nov 21 16:03:42 2016 +0300 @@ -481,13 +481,11 @@ ngx_devpoll_process_events(ngx_cycle_t * fd, event_list[i].events, revents); } - if ((revents & (POLLERR|POLLHUP|POLLNVAL)) - && (revents & (POLLIN|POLLOUT)) == 0) - { + if (revents & (POLLERR|POLLHUP|POLLNVAL)) { + /* - * if the error events were returned without POLLIN or POLLOUT, - * then add these flags to handle the events at least in one - * active handler + * if the error events were returned, add POLLIN and POLLOUT + * to handle the events at least in one active handler */ revents |= POLLIN|POLLOUT; diff -r 52bd8cc17f34 -r 75dbab4ea930 src/event/modules/ngx_epoll_module.c --- a/src/event/modules/ngx_epoll_module.c Mon Nov 28 19:19:21 2016 +0300 +++ b/src/event/modules/ngx_epoll_module.c Mon Nov 21 16:03:42 2016 +0300 @@ -863,6 +863,13 @@ ngx_epoll_process_events(ngx_cycle_t *cy ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "epoll_wait() error on fd:%d ev:%04XD", c->fd, revents); + + /* + * if the error events were returned, add EPOLLIN and EPOLLOUT + * to handle the events at least in one active handler + */ + + revents |= EPOLLIN|EPOLLOUT; } #if 0 @@ -873,18 +880,6 @@ ngx_epoll_process_events(ngx_cycle_t *cy } #endif - if ((revents & (EPOLLERR|EPOLLHUP)) - && (revents & (EPOLLIN|EPOLLOUT)) == 0) - { - /* - * if the error events were returned without EPOLLIN or EPOLLOUT, - * then add these flags to handle the events at least in one - * active handler - */ - - revents |= EPOLLIN|EPOLLOUT; - } - if ((revents & EPOLLIN) && rev->active) { #if (NGX_HAVE_EPOLLRDHUP) diff -r 52bd8cc17f34 -r 75dbab4ea930 src/event/modules/ngx_eventport_module.c --- a/src/event/modules/ngx_eventport_module.c Mon Nov 28 19:19:21 2016 +0300 +++ b/src/event/modules/ngx_eventport_module.c Mon Nov 21 16:03:42 2016 +0300 @@ -540,13 +540,11 @@ ngx_eventport_process_events(ngx_cycle_t (int) event_list[i].portev_object, revents); } - if ((revents & (POLLERR|POLLHUP|POLLNVAL)) - && (revents & (POLLIN|POLLOUT)) == 0) - { + if (revents & (POLLERR|POLLHUP|POLLNVAL)) { + /* - * if the error events were returned without POLLIN or POLLOUT, - * then add these flags to handle the events at least in one - * active handler + * if the error events were returned, add POLLIN and POLLOUT + * to handle the events at least in one active handler */ revents |= POLLIN|POLLOUT; diff -r 52bd8cc17f34 -r 75dbab4ea930 src/event/modules/ngx_poll_module.c --- a/src/event/modules/ngx_poll_module.c Mon Nov 28 19:19:21 2016 +0300 +++ b/src/event/modules/ngx_poll_module.c Mon Nov 21 16:03:42 2016 +0300 @@ -353,13 +353,11 @@ ngx_poll_process_events(ngx_cycle_t *cyc continue; } - if ((revents & (POLLERR|POLLHUP|POLLNVAL)) - && (revents & (POLLIN|POLLOUT)) == 0) - { + if (revents & (POLLERR|POLLHUP|POLLNVAL)) { + /* - * if the error events were returned without POLLIN or POLLOUT, - * then add these flags to handle the events at least in one - * active handler + * if the error events were returned, add POLLIN and POLLOUT + * to handle the events at least in one active handler */ revents |= POLLIN|POLLOUT; From mdounin at mdounin.ru Thu Dec 1 13:46:59 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 1 Dec 2016 16:46:59 +0300 Subject: Why not remove UNIX domain socket before bind In-Reply-To: <7F9FF625-4A3F-467A-A6F9-D107A4567453@gmail.com> References: <423e461b-75fc-70a6-8f22-65681e54a7fa@gmail.com> <20161130145719.GA8196@mdounin.ru> <7F9FF625-4A3F-467A-A6F9-D107A4567453@gmail.com> Message-ID: <20161201134659.GE8196@mdounin.ru> Hello! On Thu, Dec 01, 2016 at 01:20:43AM -0800, Alexey Ivanov wrote: > Why not just use `flock(2)` there? It won't work if the socket is used by a different server. -- Maxim Dounin http://nginx.org/ From igor at sysoev.ru Thu Dec 1 16:49:23 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 01 Dec 2016 16:49:23 +0000 Subject: [njs] Maximum call stack size is limited by 16M. Message-ID: details: http://hg.nginx.org/njs/rev/6d0d4a92fa02 branches: changeset: 269:6d0d4a92fa02 user: Igor Sysoev date: Thu Dec 01 18:56:35 2016 +0300 description: Maximum call stack size is limited by 16M. diffstat: njs/njs_function.c | 20 +++++++++++++++----- njs/njs_function.h | 14 ++++---------- njs/njs_vm.c | 6 ++++-- njs/njs_vm.h | 3 +++ njs/njscript.c | 2 +- njs/test/njs_unit_test.c | 3 +++ 6 files changed, 30 insertions(+), 18 deletions(-) diffs (172 lines): diff -r 86c35adbd3f9 -r 6d0d4a92fa02 njs/njs_function.c --- a/njs/njs_function.c Wed Nov 30 14:53:15 2016 +0300 +++ b/njs/njs_function.c Thu Dec 01 18:56:35 2016 +0300 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -199,35 +200,44 @@ njs_function_frame(njs_vm_t *vm, njs_fun } +static const njs_value_t njs_exception_stack_size_exceeded = + njs_long_string("RangeError: Maximum call stack size exceeded"); + + nxt_noinline njs_native_frame_t * njs_function_frame_alloc(njs_vm_t *vm, size_t size) { - size_t spare_size; - uint8_t first; + size_t spare_size, chunk_size; njs_native_frame_t *frame; spare_size = vm->frame->free_size; if (nxt_fast_path(size <= spare_size)) { frame = (njs_native_frame_t *) vm->frame->free; - first = 0; + chunk_size = 0; } else { spare_size = size + NJS_FRAME_SPARE_SIZE; spare_size = nxt_align_size(spare_size, NJS_FRAME_SPARE_SIZE); + if (vm->stack_size + spare_size > NJS_MAX_STACK_SIZE) { + vm->exception = &njs_exception_stack_size_exceeded; + return NULL; + } + frame = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t), spare_size); if (nxt_slow_path(frame == NULL)) { return NULL; } - first = 1; + chunk_size = spare_size; + vm->stack_size += spare_size; } memset(frame, 0, sizeof(njs_native_frame_t)); - frame->first = first; + frame->size = chunk_size; frame->free_size = spare_size - size; frame->free = (u_char *) frame + size; diff -r 86c35adbd3f9 -r 6d0d4a92fa02 njs/njs_function.h --- a/njs/njs_function.h Wed Nov 30 14:53:15 2016 +0300 +++ b/njs/njs_function.h Thu Dec 01 18:56:35 2016 +0300 @@ -89,30 +89,24 @@ struct njs_native_frame_s { njs_exception_t exception; + uint32_t size; uint32_t free_size; uint32_t nargs; /* Function is called as constructor with "new" keyword. */ uint8_t ctor; /* 1 bit */ - /* - * The first frame in chunk. - * 7 bits are just to possibly initialize first and skip - * fields with one operation. - */ - uint8_t first:7; /* 1 bit */ - /* Skip the Function.call() and Function.apply() methods frames. */ - uint8_t skip:1; /* 1 bit */ + uint8_t skip; /* 1 bit */ /* A number of trap tries, it can be no more than three. */ - uint8_t trap_tries:2; /* 2 bits */ + uint8_t trap_tries; /* 2 bits */ /* * The first operand in trap is reference to original value, * it is used to increment or decrement this value. */ - uint8_t trap_reference:1; /* 1 bit */ + uint8_t trap_reference; /* 1 bit */ }; diff -r 86c35adbd3f9 -r 6d0d4a92fa02 njs/njs_vm.c --- a/njs/njs_vm.c Wed Nov 30 14:53:15 2016 +0300 +++ b/njs/njs_vm.c Thu Dec 01 18:56:35 2016 +0300 @@ -277,7 +277,8 @@ start: vm->scopes[NJS_SCOPE_LOCAL] = frame->prev_local; vm->scopes[NJS_SCOPE_ARGUMENTS] = frame->prev_arguments; - if (frame->native.first) { + if (frame->native.size != 0) { + vm->stack_size -= frame->native.size; nxt_mem_cache_free(vm->mem_cache_pool, frame); } } @@ -2673,7 +2674,8 @@ njs_function_frame_free(njs_vm_t *vm, nj /* GC: free frame->local, etc. */ - if (frame->first) { + if (frame->size != 0) { + vm->stack_size -= frame->size; nxt_mem_cache_free(vm->mem_cache_pool, frame); } diff -r 86c35adbd3f9 -r 6d0d4a92fa02 njs/njs_vm.h --- a/njs/njs_vm.h Wed Nov 30 14:53:15 2016 +0300 +++ b/njs/njs_vm.h Thu Dec 01 18:56:35 2016 +0300 @@ -12,6 +12,8 @@ #include +#define NJS_MAX_STACK_SIZE (16 * 1024 * 1024) + /* * Negative return values handled by nJSVM interpreter as special events. * The values must be in range from -1 to -11, because -12 is minimal jump @@ -829,6 +831,7 @@ struct njs_vm_s { njs_value_t *global_scope; size_t scope_size; + size_t stack_size; njs_vm_shared_t *shared; njs_parser_t *parser; diff -r 86c35adbd3f9 -r 6d0d4a92fa02 njs/njscript.c --- a/njs/njscript.c Wed Nov 30 14:53:15 2016 +0300 +++ b/njs/njscript.c Thu Dec 01 18:56:35 2016 +0300 @@ -324,12 +324,12 @@ njs_vm_clone(njs_vm_t *vm, nxt_mem_cache nvm->frame = &frame->native; + frame->native.size = size; frame->native.free_size = size - (NJS_GLOBAL_FRAME_SIZE + scope_size); values = (u_char *) frame + NJS_GLOBAL_FRAME_SIZE; frame->native.free = values + scope_size; - frame->native.first = 1; nvm->scopes[NJS_SCOPE_GLOBAL] = (njs_value_t *) values; memcpy(values + NJS_INDEX_GLOBAL_OFFSET, vm->global_scope, diff -r 86c35adbd3f9 -r 6d0d4a92fa02 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Nov 30 14:53:15 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Dec 01 18:56:35 2016 +0300 @@ -3759,6 +3759,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("return"), nxt_string("SyntaxError: Illegal return statement in 1") }, + { nxt_string("function f() { return f() } f()"), + nxt_string("RangeError: Maximum call stack size exceeded") }, + { nxt_string("function () { } f()"), nxt_string("SyntaxError: Unexpected token \"(\" in 1") }, From igor at sysoev.ru Thu Dec 1 16:49:25 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 01 Dec 2016 16:49:25 +0000 Subject: [njs] Using short string values where they are enough. Message-ID: details: http://hg.nginx.org/njs/rev/f8f20b27724e branches: changeset: 270:f8f20b27724e user: Igor Sysoev date: Thu Dec 01 19:45:19 2016 +0300 description: Using short string values where they are enough. diffstat: njs/njs_date.c | 28 ++++++++++++++-------------- njs/njs_object.c | 3 +-- 2 files changed, 15 insertions(+), 16 deletions(-) diffs (136 lines): diff -r 6d0d4a92fa02 -r f8f20b27724e njs/njs_date.c --- a/njs/njs_date.c Thu Dec 01 18:56:35 2016 +0300 +++ b/njs/njs_date.c Thu Dec 01 19:45:19 2016 +0300 @@ -2097,7 +2097,7 @@ static const njs_object_prop_t njs_date { .type = NJS_METHOD, - .name = njs_long_string("setTime"), + .name = njs_string("setTime"), .value = njs_native_function(njs_date_prototype_set_time, 0, NJS_DATE_ARG, NJS_NUMBER_ARG), }, @@ -2118,21 +2118,21 @@ static const njs_object_prop_t njs_date { .type = NJS_METHOD, - .name = njs_long_string("setSeconds"), + .name = njs_string("setSeconds"), .value = njs_native_function(njs_date_prototype_set_seconds, 0, NJS_DATE_ARG, NJS_NUMBER_ARG), }, { .type = NJS_METHOD, - .name = njs_long_string("setUTCSeconds"), + .name = njs_string("setUTCSeconds"), .value = njs_native_function(njs_date_prototype_set_seconds, 0, NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), }, { .type = NJS_METHOD, - .name = njs_long_string("setMinutes"), + .name = njs_string("setMinutes"), .value = njs_native_function(njs_date_prototype_set_minutes, 0, NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), @@ -2140,7 +2140,7 @@ static const njs_object_prop_t njs_date { .type = NJS_METHOD, - .name = njs_long_string("setUTCMinutes"), + .name = njs_string("setUTCMinutes"), .value = njs_native_function(njs_date_prototype_set_utc_minutes, 0, NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), @@ -2148,7 +2148,7 @@ static const njs_object_prop_t njs_date { .type = NJS_METHOD, - .name = njs_long_string("setHours"), + .name = njs_string("setHours"), .value = njs_native_function(njs_date_prototype_set_hours, 0, NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), @@ -2156,7 +2156,7 @@ static const njs_object_prop_t njs_date { .type = NJS_METHOD, - .name = njs_long_string("setUTCHours"), + .name = njs_string("setUTCHours"), .value = njs_native_function(njs_date_prototype_set_utc_hours, 0, NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), @@ -2164,35 +2164,35 @@ static const njs_object_prop_t njs_date { .type = NJS_METHOD, - .name = njs_long_string("setDate"), + .name = njs_string("setDate"), .value = njs_native_function(njs_date_prototype_set_date, 0, NJS_DATE_ARG, NJS_NUMBER_ARG), }, { .type = NJS_METHOD, - .name = njs_long_string("setUTCDate"), + .name = njs_string("setUTCDate"), .value = njs_native_function(njs_date_prototype_set_utc_date, 0, NJS_DATE_ARG, NJS_NUMBER_ARG), }, { .type = NJS_METHOD, - .name = njs_long_string("setMonth"), + .name = njs_string("setMonth"), .value = njs_native_function(njs_date_prototype_set_month, 0, NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), }, { .type = NJS_METHOD, - .name = njs_long_string("setUTCMonth"), + .name = njs_string("setUTCMonth"), .value = njs_native_function(njs_date_prototype_set_utc_month, 0, NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), }, { .type = NJS_METHOD, - .name = njs_long_string("setFullYear"), + .name = njs_string("setFullYear"), .value = njs_native_function(njs_date_prototype_set_full_year, 0, NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), @@ -2200,7 +2200,7 @@ static const njs_object_prop_t njs_date { .type = NJS_METHOD, - .name = njs_long_string("setUTCFullYear"), + .name = njs_string("setUTCFullYear"), .value = njs_native_function(njs_date_prototype_set_utc_full_year, 0, NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), @@ -2208,7 +2208,7 @@ static const njs_object_prop_t njs_date { .type = NJS_METHOD, - .name = njs_long_string("toJSON"), + .name = njs_string("toJSON"), .value = njs_native_function(njs_date_prototype_to_json, NJS_CONTINUATION_SIZE, 0), }, diff -r 6d0d4a92fa02 -r f8f20b27724e njs/njs_object.c --- a/njs/njs_object.c Thu Dec 01 18:56:35 2016 +0300 +++ b/njs/njs_object.c Thu Dec 01 19:45:19 2016 +0300 @@ -603,8 +603,7 @@ static const njs_value_t njs_object_fun njs_long_string("[object Function]"); static const njs_value_t njs_object_regexp_string = njs_long_string("[object RegExp]"); -static const njs_value_t njs_object_date_string = - njs_long_string("[object Date]"); +static const njs_value_t njs_object_date_string = njs_string("[object Date]"); njs_ret_t From dndx at idndx.com Fri Dec 2 09:20:25 2016 From: dndx at idndx.com (Datong Sun) Date: Fri, 2 Dec 2016 01:20:25 -0800 Subject: [nginx] Master process: make sure unix domain sockets are removed from disk when performing graceful shutdown. Message-ID: # HG changeset patch # User Datong Sun # Date 1480669608 21600 # Fri Dec 02 03:06:48 2016 -0600 # Node ID 1b7a6785d1f3c76f436a9dea5cb0fc86e1db5f2b # Parent 75dbab4ea930bc73cca98d183c2f556eb5125462 Master process: make sure unix domain sockets are removed from disk when performing graceful shutdown by using ngx_close_listening_sockets() to close them. This fixes https://trac.nginx.org/nginx/ticket/753 diff -r 75dbab4ea930 -r 1b7a6785d1f3 src/os/unix/ngx_process_cycle.c --- a/src/os/unix/ngx_process_cycle.c Mon Nov 21 16:03:42 2016 +0300 +++ b/src/os/unix/ngx_process_cycle.c Fri Dec 02 03:06:48 2016 -0600 @@ -76,12 +76,11 @@ u_char *p; size_t size; ngx_int_t i; - ngx_uint_t n, sigio; + ngx_uint_t sigio; sigset_t set; struct itimerval itv; ngx_uint_t live; ngx_msec_t delay; - ngx_listening_t *ls; ngx_core_conf_t *ccf; sigemptyset(&set); @@ -203,16 +202,7 @@ if (ngx_quit) { ngx_signal_worker_processes(cycle, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); - - ls = cycle->listening.elts; - for (n = 0; n < cycle->listening.nelts; n++) { - if (ngx_close_socket(ls[n].fd) == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno, - ngx_close_socket_n " %V failed", - &ls[n].addr_text); - } - } - cycle->listening.nelts = 0; + ngx_close_listening_sockets(cycle); continue; } -- Datong Sun dndx at idndx.com From dndx at idndx.com Fri Dec 2 09:23:36 2016 From: dndx at idndx.com (Datong Sun) Date: Fri, 2 Dec 2016 01:23:36 -0800 Subject: [nginx] Core: when changing binary, newly forked master process should not remove unix domain socket unless old master has quit. Message-ID: # HG changeset patch # User Datong Sun # Date 1480669905 21600 # Fri Dec 02 03:11:45 2016 -0600 # Node ID 92a7853a439708584bbc45b416df464c64ec446e # Parent 1b7a6785d1f3c76f436a9dea5cb0fc86e1db5f2b Core: when changing binary, newly forked master process should not remove unix domain socket unless old master has quit. This commit fixes a bug that during a binary change, when both old and new master processes are running, sending TERM to the new master process will accidently remove unix domain socket from disk while old master is still listening on it. diff -r 1b7a6785d1f3 -r 92a7853a4397 src/core/ngx_connection.c --- a/src/core/ngx_connection.c Fri Dec 02 03:06:48 2016 -0600 +++ b/src/core/ngx_connection.c Fri Dec 02 03:11:45 2016 -0600 @@ -1007,7 +1007,8 @@ if (ls[i].sockaddr->sa_family == AF_UNIX && ngx_process <= NGX_PROCESS_MASTER - && ngx_new_binary == 0) + && ngx_new_binary == 0 + && getppid() == 1) { u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1; -- Datong Sun dndx at idndx.com From vbart at nginx.com Fri Dec 2 14:12:14 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 02 Dec 2016 14:12:14 +0000 Subject: [njs] Fixed a unit test for Math.acosh(). Message-ID: details: http://hg.nginx.org/njs/rev/7275165c3832 branches: changeset: 271:7275165c3832 user: Valentin Bartenev date: Fri Dec 02 17:11:57 2016 +0300 description: Fixed a unit test for Math.acosh(). diffstat: njs/test/njs_unit_test.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (18 lines): diff -r f8f20b27724e -r 7275165c3832 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Dec 01 19:45:19 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Dec 02 17:11:57 2016 +0300 @@ -5568,11 +5568,11 @@ static njs_unit_test_t njs_test[] = nxt_string("Infinity") }, /* - * The difference is 2 * Number.EPSILON on FreeBSD + * The difference is Number.EPSILON on Linux/i686 * and zero on other platforms. */ - { nxt_string("Math.abs(Math.cosh(1) - (1/Math.E + Math.E)/2)" - " <= 2 * Number.EPSILON"), + { nxt_string("Math.abs(Math.acosh((1/Math.E + Math.E)/2) - 1)" + " <= Number.EPSILON"), nxt_string("true") }, { nxt_string("Math.asin()"), From ru at nginx.com Sat Dec 3 07:06:29 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Sat, 03 Dec 2016 07:06:29 +0000 Subject: [nginx] Slab: style. Message-ID: details: http://hg.nginx.org/nginx/rev/ea76a3aa18ae branches: changeset: 6807:ea76a3aa18ae user: Ruslan Ermilov date: Sat Dec 03 09:55:40 2016 +0300 description: Slab: style. Removed redundant parentheses. No functional changes. diffstat: src/core/ngx_slab.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (30 lines): diff -r 75dbab4ea930 -r ea76a3aa18ae src/core/ngx_slab.c --- a/src/core/ngx_slab.c Mon Nov 21 16:03:42 2016 +0300 +++ b/src/core/ngx_slab.c Sat Dec 03 09:55:40 2016 +0300 @@ -211,7 +211,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p if (bitmap[n] != NGX_SLAB_BUSY) { for (m = 1, i = 0; m; m <<= 1, i++) { - if ((bitmap[n] & m)) { + if (bitmap[n] & m) { continue; } @@ -255,7 +255,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p if (page->slab != NGX_SLAB_BUSY) { for (m = 1, i = 0; m; m <<= 1, i++) { - if ((page->slab & m)) { + if (page->slab & m) { continue; } @@ -297,7 +297,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p m & mask; m <<= 1, i++) { - if ((page->slab & m)) { + if (page->slab & m) { continue; } From ru at nginx.com Sat Dec 3 07:06:32 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Sat, 03 Dec 2016 07:06:32 +0000 Subject: [nginx] Slab: always show the requested allocation size in debug messages. Message-ID: details: http://hg.nginx.org/nginx/rev/2af776c22aec branches: changeset: 6808:2af776c22aec user: Ruslan Ermilov date: Sat Dec 03 10:01:03 2016 +0300 description: Slab: always show the requested allocation size in debug messages. Previously, allocations smaller than min_size were shown as min_size. diffstat: src/core/ngx_slab.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r ea76a3aa18ae -r 2af776c22aec src/core/ngx_slab.c --- a/src/core/ngx_slab.c Sat Dec 03 09:55:40 2016 +0300 +++ b/src/core/ngx_slab.c Sat Dec 03 10:01:03 2016 +0300 @@ -184,7 +184,6 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p slot = shift - pool->min_shift; } else { - size = pool->min_size; shift = pool->min_shift; slot = 0; } From ru at nginx.com Sat Dec 3 07:06:35 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Sat, 03 Dec 2016 07:06:35 +0000 Subject: [nginx] Slab: improved double free detection. Message-ID: details: http://hg.nginx.org/nginx/rev/87d7e640b45d branches: changeset: 6809:87d7e640b45d user: Ruslan Ermilov date: Sat Dec 03 10:01:39 2016 +0300 description: Slab: improved double free detection. Previously, an attempt to double free the starting page of the free range was not detected. diffstat: src/core/ngx_slab.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 2af776c22aec -r 87d7e640b45d src/core/ngx_slab.c --- a/src/core/ngx_slab.c Sat Dec 03 10:01:03 2016 +0300 +++ b/src/core/ngx_slab.c Sat Dec 03 10:01:39 2016 +0300 @@ -597,7 +597,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *po goto wrong_chunk; } - if (slab == NGX_SLAB_PAGE_FREE) { + if (!(slab & NGX_SLAB_PAGE_START)) { ngx_slab_error(pool, NGX_LOG_ALERT, "ngx_slab_free(): page is already free"); goto fail; From eran.kornblau at kaltura.com Sat Dec 3 21:06:16 2016 From: eran.kornblau at kaltura.com (Eran Kornblau) Date: Sat, 3 Dec 2016 21:06:16 +0000 Subject: Add support for 'nocache' flag to map directive In-Reply-To: References: Message-ID: As I got no objections... :) patch attached Thank you, Eran -------------- next part -------------- A non-text attachment was scrubbed... Name: nocacheable-map.patch Type: application/octet-stream Size: 1693 bytes Desc: nocacheable-map.patch URL: From igor at sysoev.ru Mon Dec 5 15:17:44 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 05 Dec 2016 15:17:44 +0000 Subject: [njs] Native methods called by iterators should run via continuation Message-ID: details: http://hg.nginx.org/njs/rev/eba4f3a30bb4 branches: changeset: 272:eba4f3a30bb4 user: Igor Sysoev date: Mon Dec 05 17:35:33 2016 +0300 description: Native methods called by iterators should run via continuation to normilize arguments. diffstat: njs/njs_function.c | 12 ++---------- njs/njs_function.h | 1 + njs/njs_vm.c | 8 ++++++++ njs/test/njs_unit_test.c | 3 +++ 4 files changed, 14 insertions(+), 10 deletions(-) diffs (83 lines): diff -r 7275165c3832 -r eba4f3a30bb4 njs/njs_function.c --- a/njs/njs_function.c Fri Dec 02 17:11:57 2016 +0300 +++ b/njs/njs_function.c Mon Dec 05 17:35:33 2016 +0300 @@ -252,21 +252,12 @@ nxt_noinline njs_ret_t njs_function_apply(njs_vm_t *vm, njs_function_t *function, njs_value_t *args, nxt_uint_t nargs, njs_index_t retval) { - size_t reserve; njs_ret_t ret; njs_continuation_t *cont; if (function->native) { - - if (function->continuation_size == 0 && function->bound == NULL) { - return function->u.native(vm, args, nargs, retval); - } - - reserve = nxt_align_size(sizeof(njs_continuation_t), - sizeof(njs_value_t)), - ret = njs_function_native_frame(vm, function, &args[0], &args[1], - nargs - 1, reserve, 0); + nargs - 1, NJS_CONTINUATION_SIZE, 0); if (ret != NJS_OK) { return ret; } @@ -274,6 +265,7 @@ njs_function_apply(njs_vm_t *vm, njs_fun cont = njs_continuation(vm->frame); cont->function = function->u.native; + cont->args_types = function->args_types; cont->retval = retval; cont->return_address = vm->current; diff -r 7275165c3832 -r eba4f3a30bb4 njs/njs_function.h --- a/njs/njs_function.h Fri Dec 02 17:11:57 2016 +0300 +++ b/njs/njs_function.h Mon Dec 05 17:35:33 2016 +0300 @@ -50,6 +50,7 @@ struct njs_function_lambda_s { typedef struct { njs_function_native_t function; + uint8_t *args_types; u_char *return_address; njs_index_t retval; } njs_continuation_t; diff -r 7275165c3832 -r eba4f3a30bb4 njs/njs_vm.c --- a/njs/njs_vm.c Fri Dec 02 17:11:57 2016 +0300 +++ b/njs/njs_vm.c Mon Dec 05 17:35:33 2016 +0300 @@ -2358,6 +2358,7 @@ njs_vmcode_function_call(njs_vm_t *vm, n cont = njs_continuation(vm->frame); cont->function = function->u.native; + cont->args_types = function->args_types; cont->retval = (njs_index_t) retval; cont->return_address = vm->current + sizeof(njs_vmcode_function_call_t); @@ -2609,6 +2610,13 @@ njs_vmcode_continuation(njs_vm_t *vm, nj cont = njs_continuation(frame); args = frame->arguments - frame->function->args_offset; + if (cont->args_types != NULL) { + ret = njs_normalize_args(vm, args, cont->args_types, frame->nargs); + if (ret != NJS_OK) { + return ret; + } + } + ret = cont->function(vm, args, frame->nargs, cont->retval); switch (ret) { diff -r 7275165c3832 -r eba4f3a30bb4 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Dec 02 17:11:57 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Dec 05 17:35:33 2016 +0300 @@ -5461,6 +5461,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("var d = new Date(); d.__proto__ === Date.prototype"), nxt_string("true") }, + { nxt_string("[0].map(new Date().getDate)"), + nxt_string("TypeError") }, + { nxt_string("new Date(eval)"), nxt_string("Invalid Date") }, From igor at sysoev.ru Mon Dec 5 15:17:46 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 05 Dec 2016 15:17:46 +0000 Subject: [njs] Native methods called with Function.prototype.call() and Message-ID: details: http://hg.nginx.org/njs/rev/15ec6a09cece branches: changeset: 273:15ec6a09cece user: Igor Sysoev date: Mon Dec 05 17:45:02 2016 +0300 description: Native methods called with Function.prototype.call() and Functon.prototype.apply() should run via continuation to normilize arguments. diffstat: njs/njs_function.c | 21 ++++++++++++++++----- 1 files changed, 16 insertions(+), 5 deletions(-) diffs (46 lines): diff -r eba4f3a30bb4 -r 15ec6a09cece njs/njs_function.c --- a/njs/njs_function.c Mon Dec 05 17:35:33 2016 +0300 +++ b/njs/njs_function.c Mon Dec 05 17:45:02 2016 +0300 @@ -484,18 +484,29 @@ static njs_ret_t njs_function_activate(njs_vm_t *vm, njs_function_t *function, njs_value_t *this, njs_value_t *args, nxt_uint_t nargs, njs_index_t retval) { - njs_ret_t ret; + njs_ret_t ret; + njs_continuation_t *cont; if (function->native) { - ret = njs_function_native_frame(vm, function, this, args, - nargs, 0, 0); + ret = njs_function_native_frame(vm, function, this, args, nargs, + NJS_CONTINUATION_SIZE, 0); if (nxt_slow_path(ret != NXT_OK)) { return ret; } - /* Skip the "apply" method frame. */ + /* Skip the "call/apply" method frame. */ vm->frame->previous->skip = 1; + cont = njs_continuation(vm->frame); + + cont->function = function->u.native; + cont->args_types = function->args_types; + cont->retval = retval; + + cont->return_address = vm->current + + sizeof(njs_vmcode_function_call_t);; + vm->current = (u_char *) njs_continuation_nexus; + return NJS_APPLIED; } @@ -505,7 +516,7 @@ njs_function_activate(njs_vm_t *vm, njs_ return ret; } - /* Skip the "apply" method frame. */ + /* Skip the "call/apply" method frame. */ vm->frame->previous->skip = 1; return njs_function_call(vm, retval, sizeof(njs_vmcode_function_call_t)); From igor at sysoev.ru Mon Dec 5 15:17:47 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 05 Dec 2016 15:17:47 +0000 Subject: [njs] RegExp.prototype.toString() should be applied only to RegExp. Message-ID: details: http://hg.nginx.org/njs/rev/709ac03a4bfd branches: changeset: 274:709ac03a4bfd user: Igor Sysoev date: Mon Dec 05 17:47:00 2016 +0300 description: RegExp.prototype.toString() should be applied only to RegExp. diffstat: njs/njs_regexp.c | 19 ++++++++++++++----- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 17 insertions(+), 5 deletions(-) diffs (46 lines): diff -r 15ec6a09cece -r 709ac03a4bfd njs/njs_regexp.c --- a/njs/njs_regexp.c Mon Dec 05 17:45:02 2016 +0300 +++ b/njs/njs_regexp.c Mon Dec 05 17:47:00 2016 +0300 @@ -560,15 +560,24 @@ njs_regexp_prototype_to_string(njs_vm_t u_char *source; int32_t length; uint32_t size; + njs_value_t *value; njs_regexp_pattern_t *pattern; - pattern = args[0].data.u.regexp->pattern; - source = pattern->source; + value = &args[0]; - size = strlen((char *) source); - length = nxt_utf8_length(source, size); + if (value->type == NJS_REGEXP) { + pattern = value->data.u.regexp->pattern; + source = pattern->source; - return njs_regexp_string_create(vm, &vm->retval, source, size, length); + size = strlen((char *) source); + length = nxt_utf8_length(source, size); + + return njs_regexp_string_create(vm, &vm->retval, source, size, length); + } + + vm->exception = &njs_exception_type_error; + + return NXT_ERROR; } diff -r 15ec6a09cece -r 709ac03a4bfd njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Dec 05 17:45:02 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Dec 05 17:47:00 2016 +0300 @@ -4410,6 +4410,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("var r = new RegExp('abc', 'i'); r.test('00ABC11')"), nxt_string("true") }, + { nxt_string("[0].map(RegExp().toString)"), + nxt_string("TypeError") }, + /* Non-standard ECMA-262 features. */ /* 0x10400 is not a surrogate pair of 0xD801 and 0xDC00. */ From igor at sysoev.ru Mon Dec 5 15:26:59 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 5 Dec 2016 18:26:59 +0300 Subject: nginScript documentation Message-ID: Hi! We have made recently documentation for nginScript: http://nginx.org/en/docs/http/ngx_http_js_module.html http://nginx.org/en/docs/stream/ngx_stream_js_module.html http://nginx.org/en/docs/njs_about.html -- Igor Sysoev http://nginx.com From steven.hartland at multiplay.co.uk Mon Dec 5 15:32:41 2016 From: steven.hartland at multiplay.co.uk (Steven Hartland) Date: Mon, 5 Dec 2016 15:32:41 +0000 Subject: nginScript documentation In-Reply-To: References: Message-ID: <938ab1e4-f240-d0a0-7c3d-f3c6910f9494@multiplay.co.uk> Cool thanks for this. Looks like on http://nginx.org/en/docs/njs_about.html you have a typo on the second line "nignScript" I assume you meant nginScript ;-) On 05/12/2016 15:26, Igor Sysoev wrote: > Hi! > > We have made recently documentation for nginScript: > > http://nginx.org/en/docs/http/ngx_http_js_module.html > http://nginx.org/en/docs/stream/ngx_stream_js_module.html > http://nginx.org/en/docs/njs_about.html > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From maxim at nginx.com Mon Dec 5 15:37:02 2016 From: maxim at nginx.com (Maxim Konovalov) Date: Mon, 5 Dec 2016 18:37:02 +0300 Subject: nginScript documentation In-Reply-To: <938ab1e4-f240-d0a0-7c3d-f3c6910f9494@multiplay.co.uk> References: <938ab1e4-f240-d0a0-7c3d-f3c6910f9494@multiplay.co.uk> Message-ID: <91633a91-31e0-39cf-7d3b-4e0237017592@nginx.com> On 12/5/16 6:32 PM, Steven Hartland wrote: > Cool thanks for this. > > Looks like on http://nginx.org/en/docs/njs_about.html you have a > typo on the second line "nignScript" I assume you meant nginScript ;-) > Fixed. Thanks! -- Maxim Konovalov From mdounin at mdounin.ru Mon Dec 5 19:54:04 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 5 Dec 2016 22:54:04 +0300 Subject: [PATCH 1 of 6] SSL: define NGX_SSL_VERIFY constants In-Reply-To: References: <653b04653271346c63ab.1471480162@piotrsikora.sfo.corp.google.com> <20161018231800.GT73038@mdounin.ru> Message-ID: <20161205195404.GM18639@mdounin.ru> Hello! On Tue, Nov 29, 2016 at 05:08:04PM -0800, Piotr Sikora via nginx-devel wrote: > Hey Maxim, > > > How is that related to the commit in question? > > > > Please note that I pinged you on 3 out of 6 commits, which I'm > > interested in getting in, regardless of ngx_ssl_verify_client() & > > friends. > > Ping. Suggested patches move things specific to a configuration of particular modules into the code which is intended to provide a generic SSL API. This doesn't looks like a good change for me. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Mon Dec 5 20:01:47 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 05 Dec 2016 20:01:47 +0000 Subject: [nginx] OCSP stapling: style. Message-ID: details: http://hg.nginx.org/nginx/rev/64f5bfba5d96 branches: changeset: 6810:64f5bfba5d96 user: Maxim Dounin date: Mon Dec 05 22:23:22 2016 +0300 description: OCSP stapling: style. diffstat: src/event/ngx_event_openssl_stapling.c | 22 ++++++++++++---------- 1 files changed, 12 insertions(+), 10 deletions(-) diffs (88 lines): diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c +++ b/src/event/ngx_event_openssl_stapling.c @@ -57,14 +57,14 @@ struct ngx_ssl_ocsp_ctx_s { ngx_msec_t timeout; - void (*handler)(ngx_ssl_ocsp_ctx_t *r); + void (*handler)(ngx_ssl_ocsp_ctx_t *ctx); void *data; ngx_buf_t *request; ngx_buf_t *response; ngx_peer_connection_t peer; - ngx_int_t (*process)(ngx_ssl_ocsp_ctx_t *r); + ngx_int_t (*process)(ngx_ssl_ocsp_ctx_t *ctx); ngx_uint_t state; @@ -374,9 +374,9 @@ static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_ssl_stapling_t *staple, ngx_str_t *responder) { - ngx_url_t u; char *s; ngx_str_t rsp; + ngx_url_t u; STACK_OF(OPENSSL_STRING) *aia; if (responder->len == 0) { @@ -757,10 +757,10 @@ error: static time_t ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time) { + BIO *bio; u_char *value; size_t len; time_t time; - BIO *bio; /* * OpenSSL doesn't provide a way to convert ASN1_GENERALIZEDTIME @@ -1005,7 +1005,7 @@ failed: static void ngx_ssl_ocsp_connect(ngx_ssl_ocsp_ctx_t *ctx) { - ngx_int_t rc; + ngx_int_t rc; ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, "ssl ocsp connect"); @@ -1103,10 +1103,10 @@ ngx_ssl_ocsp_write_handler(ngx_event_t * static void ngx_ssl_ocsp_read_handler(ngx_event_t *rev) { - ssize_t n, size; - ngx_int_t rc; - ngx_ssl_ocsp_ctx_t *ctx; - ngx_connection_t *c; + ssize_t n, size; + ngx_int_t rc; + ngx_connection_t *c; + ngx_ssl_ocsp_ctx_t *ctx; c = rev->data; ctx = c->data; @@ -1608,10 +1608,11 @@ ngx_ssl_ocsp_process_headers(ngx_ssl_ocs return ctx->process(ctx); } + static ngx_int_t ngx_ssl_ocsp_parse_header_line(ngx_ssl_ocsp_ctx_t *ctx) { - u_char c, ch, *p; + u_char c, ch, *p; enum { sw_start = 0, sw_name, @@ -1846,6 +1847,7 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl return NGX_OK; } + ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_resolver_t *resolver, ngx_msec_t resolver_timeout) From mdounin at mdounin.ru Mon Dec 5 20:01:49 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 05 Dec 2016 20:01:49 +0000 Subject: [nginx] OCSP stapling: added http response status logging. Message-ID: details: http://hg.nginx.org/nginx/rev/5eb3309d0b9e branches: changeset: 6811:5eb3309d0b9e user: Maxim Dounin date: Mon Dec 05 22:23:22 2016 +0300 description: OCSP stapling: added http response status logging. diffstat: src/event/ngx_event_openssl_stapling.c | 15 +++++++++------ 1 files changed, 9 insertions(+), 6 deletions(-) diffs (53 lines): diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c +++ b/src/event/ngx_event_openssl_stapling.c @@ -1310,12 +1310,11 @@ ngx_ssl_ocsp_process_status_line(ngx_ssl rc = ngx_ssl_ocsp_parse_status_line(ctx); if (rc == NGX_OK) { -#if 0 - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp status line \"%*s\"", - ctx->response->pos - ctx->response->start, - ctx->response->start); -#endif + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->log, 0, + "ssl ocsp status %ui \"%*s\"", + ctx->code, + ctx->header_end - ctx->header_start, + ctx->header_start); ctx->process = ngx_ssl_ocsp_process_headers; return ctx->process(ctx); @@ -1476,6 +1475,7 @@ ngx_ssl_ocsp_parse_status_line(ngx_ssl_o if (++ctx->count == 3) { state = sw_space_after_status; + ctx->header_start = p - 2; } break; @@ -1493,6 +1493,7 @@ ngx_ssl_ocsp_parse_status_line(ngx_ssl_o state = sw_almost_done; break; case LF: + ctx->header_end = p; goto done; default: return NGX_ERROR; @@ -1506,6 +1507,7 @@ ngx_ssl_ocsp_parse_status_line(ngx_ssl_o state = sw_almost_done; break; case LF: + ctx->header_end = p; goto done; } break; @@ -1514,6 +1516,7 @@ ngx_ssl_ocsp_parse_status_line(ngx_ssl_o case sw_almost_done: switch (ch) { case LF: + ctx->header_end = p - 1; goto done; default: return NGX_ERROR; From mdounin at mdounin.ru Mon Dec 5 20:01:52 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 05 Dec 2016 20:01:52 +0000 Subject: [nginx] OCSP stapling: added certificate name to warnings. Message-ID: details: http://hg.nginx.org/nginx/rev/a7ec59df0c4d branches: changeset: 6812:a7ec59df0c4d user: Maxim Dounin date: Mon Dec 05 22:23:22 2016 +0300 description: OCSP stapling: added certificate name to warnings. diffstat: src/event/ngx_event_openssl.c | 18 ++++++++++++++++++ src/event/ngx_event_openssl.h | 1 + src/event/ngx_event_openssl_stapling.c | 22 +++++++++++++++++----- 3 files changed, 36 insertions(+), 5 deletions(-) diffs (127 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -106,6 +106,7 @@ int ngx_ssl_session_cache_index; int ngx_ssl_session_ticket_keys_index; int ngx_ssl_certificate_index; int ngx_ssl_next_certificate_index; +int ngx_ssl_certificate_name_index; int ngx_ssl_stapling_index; @@ -193,6 +194,14 @@ ngx_ssl_init(ngx_log_t *log) return NGX_ERROR; } + ngx_ssl_certificate_name_index = X509_get_ex_new_index(0, NULL, NULL, NULL, + NULL); + + if (ngx_ssl_certificate_name_index == -1) { + ngx_ssl_error(NGX_LOG_ALERT, log, 0, "X509_get_ex_new_index() failed"); + return NGX_ERROR; + } + ngx_ssl_stapling_index = X509_get_ex_new_index(0, NULL, NULL, NULL, NULL); if (ngx_ssl_stapling_index == -1) { @@ -385,6 +394,15 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ return NGX_ERROR; } + if (X509_set_ex_data(x509, ngx_ssl_certificate_name_index, cert->data) + == 0) + { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_set_ex_data() failed"); + X509_free(x509); + BIO_free(bio); + return NGX_ERROR; + } + if (X509_set_ex_data(x509, ngx_ssl_next_certificate_index, SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index)) == 0) diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -236,6 +236,7 @@ extern int ngx_ssl_session_cache_index; extern int ngx_ssl_session_ticket_keys_index; extern int ngx_ssl_certificate_index; extern int ngx_ssl_next_certificate_index; +extern int ngx_ssl_certificate_name_index; extern int ngx_ssl_stapling_index; diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c +++ b/src/event/ngx_event_openssl_stapling.c @@ -31,6 +31,8 @@ typedef struct { X509 *cert; X509 *issuer; + u_char *name; + time_t valid; time_t refresh; @@ -173,6 +175,8 @@ ngx_ssl_stapling_certificate(ngx_conf_t staple->timeout = 60000; staple->verify = verify; staple->cert = cert; + staple->name = X509_get_ex_data(staple->cert, + ngx_ssl_certificate_name_index); if (file->len) { /* use OCSP response from the file */ @@ -354,7 +358,9 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, if (rc == 0) { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, - "\"ssl_stapling\" ignored, issuer certificate not found"); + "\"ssl_stapling\" ignored, " + "issuer certificate not found for certificate \"%s\"", + staple->name); X509_STORE_CTX_free(store_ctx); return NGX_DECLINED; } @@ -387,7 +393,8 @@ ngx_ssl_stapling_responder(ngx_conf_t *c if (aia == NULL) { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, " - "no OCSP responder URL in the certificate"); + "no OCSP responder URL in the certificate \"%s\"", + staple->name); return NGX_DECLINED; } @@ -399,7 +406,8 @@ ngx_ssl_stapling_responder(ngx_conf_t *c if (s == NULL) { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, " - "no OCSP responder URL in the certificate"); + "no OCSP responder URL in the certificate \"%s\"", + staple->name); X509_email_free(aia); return NGX_DECLINED; } @@ -432,7 +440,9 @@ ngx_ssl_stapling_responder(ngx_conf_t *c } else { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, " - "invalid URL prefix in OCSP responder \"%V\"", &u.url); + "invalid URL prefix in OCSP responder \"%V\" " + "in the certificate \"%s\"", + &u.url, staple->name); return NGX_DECLINED; } @@ -440,7 +450,9 @@ ngx_ssl_stapling_responder(ngx_conf_t *c if (u.err) { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, " - "%s in OCSP responder \"%V\"", u.err, &u.url); + "%s in OCSP responder \"%V\" " + "in the certificate \"%s\"", + u.err, &u.url, staple->name); return NGX_DECLINED; } From mdounin at mdounin.ru Mon Dec 5 20:01:54 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 05 Dec 2016 20:01:54 +0000 Subject: [nginx] OCSP stapling: improved error logging context. Message-ID: details: http://hg.nginx.org/nginx/rev/94586180fb41 branches: changeset: 6813:94586180fb41 user: Maxim Dounin date: Mon Dec 05 22:23:22 2016 +0300 description: OCSP stapling: improved error logging context. It now logs the IP address of the responder used (if it's already known), as well as the certificate name. diffstat: src/event/ngx_event_openssl_stapling.c | 20 +++++++++++++++++++- 1 files changed, 19 insertions(+), 1 deletions(-) diffs (49 lines): diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c +++ b/src/event/ngx_event_openssl_stapling.c @@ -47,6 +47,8 @@ struct ngx_ssl_ocsp_ctx_s { X509 *cert; X509 *issuer; + u_char *name; + ngx_uint_t naddrs; ngx_addr_t *addrs; @@ -559,6 +561,7 @@ ngx_ssl_stapling_update(ngx_ssl_stapling ctx->cert = staple->cert; ctx->issuer = staple->issuer; + ctx->name = staple->name; ctx->addrs = staple->addrs; ctx->host = staple->host; @@ -1837,12 +1840,27 @@ ngx_ssl_ocsp_log_error(ngx_log_t *log, u if (log->action) { p = ngx_snprintf(buf, len, " while %s", log->action); len -= p - buf; + buf = p; } ctx = log->data; if (ctx) { - p = ngx_snprintf(p, len, ", responder: %V", &ctx->host); + p = ngx_snprintf(buf, len, ", responder: %V", &ctx->host); + len -= p - buf; + buf = p; + } + + if (ctx && ctx->peer.name) { + p = ngx_snprintf(buf, len, ", peer: %V", ctx->peer.name); + len -= p - buf; + buf = p; + } + + if (ctx && ctx->name) { + p = ngx_snprintf(buf, len, ", certificate: \"%s\"", ctx->name); + len -= p - buf; + buf = p; } return p; From mdounin at mdounin.ru Mon Dec 5 20:01:56 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 05 Dec 2016 20:01:56 +0000 Subject: [nginx] SSL: $ssl_client_verify extended with a failure reason. Message-ID: details: http://hg.nginx.org/nginx/rev/379139020d36 branches: changeset: 6814:379139020d36 user: Maxim Dounin date: Mon Dec 05 22:23:22 2016 +0300 description: SSL: $ssl_client_verify extended with a failure reason. Now in case of a verification failure $ssl_client_verify contains "FAILED:", similar to Apache's SSL_CLIENT_VERIFY, e.g., "FAILED:certificate has expired". Detailed description of possible errors can be found in the verify(1) manual page as provided by OpenSSL. diffstat: src/event/ngx_event_openssl.c | 32 +++++++++++++++++++++----------- 1 files changed, 21 insertions(+), 11 deletions(-) diffs (48 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -3717,23 +3717,33 @@ ngx_ssl_get_fingerprint(ngx_connection_t ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { - X509 *cert; - - if (SSL_get_verify_result(c->ssl->connection) != X509_V_OK) { - ngx_str_set(s, "FAILED"); + X509 *cert; + long rc; + const char *str; + + cert = SSL_get_peer_certificate(c->ssl->connection); + if (cert == NULL) { + ngx_str_set(s, "NONE"); return NGX_OK; } - cert = SSL_get_peer_certificate(c->ssl->connection); - - if (cert) { + X509_free(cert); + + rc = SSL_get_verify_result(c->ssl->connection); + + if (rc == X509_V_OK) { ngx_str_set(s, "SUCCESS"); - - } else { - ngx_str_set(s, "NONE"); + return NGX_OK; } - X509_free(cert); + str = X509_verify_cert_error_string(rc); + + s->data = ngx_pnalloc(pool, sizeof("FAILED:") - 1 + ngx_strlen(str)); + if (s->data == NULL) { + return NGX_ERROR; + } + + s->len = ngx_sprintf(s->data, "FAILED:%s", str) - s->data; return NGX_OK; } From mdounin at mdounin.ru Mon Dec 5 20:01:59 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 05 Dec 2016 20:01:59 +0000 Subject: [nginx] SSL: $ssl_client_v_start, $ssl_client_v_end, $ssl_client_v_remain. Message-ID: details: http://hg.nginx.org/nginx/rev/2d15fff64e3c branches: changeset: 6815:2d15fff64e3c user: Maxim Dounin date: Mon Dec 05 22:23:23 2016 +0300 description: SSL: $ssl_client_v_start, $ssl_client_v_end, $ssl_client_v_remain. diffstat: src/event/ngx_event_openssl.c | 178 +++++++++++++++++++++++++++++++++ src/event/ngx_event_openssl.h | 6 + src/http/modules/ngx_http_ssl_module.c | 9 + 3 files changed, 193 insertions(+), 0 deletions(-) diffs (230 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -59,6 +59,12 @@ static int ngx_ssl_session_ticket_key_ca static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *str); #endif +static time_t ngx_ssl_parse_time( +#if OPENSSL_VERSION_NUMBER > 0x10100000L + const +#endif + ASN1_TIME *asn1time); + static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static void ngx_openssl_exit(ngx_cycle_t *cycle); @@ -3749,6 +3755,178 @@ ngx_ssl_get_client_verify(ngx_connection } +ngx_int_t +ngx_ssl_get_client_v_start(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + BIO *bio; + X509 *cert; + size_t len; + + s->len = 0; + + cert = SSL_get_peer_certificate(c->ssl->connection); + if (cert == NULL) { + return NGX_OK; + } + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) { + X509_free(cert); + return NGX_ERROR; + } + +#if OPENSSL_VERSION_NUMBER > 0x10100000L + ASN1_TIME_print(bio, X509_get0_notBefore(cert)); +#else + ASN1_TIME_print(bio, X509_get_notBefore(cert)); +#endif + + len = BIO_pending(bio); + + s->len = len; + s->data = ngx_pnalloc(pool, len); + if (s->data == NULL) { + BIO_free(bio); + X509_free(cert); + return NGX_ERROR; + } + + BIO_read(bio, s->data, len); + BIO_free(bio); + X509_free(cert); + + return NGX_OK; +} + + +ngx_int_t +ngx_ssl_get_client_v_end(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + BIO *bio; + X509 *cert; + size_t len; + + s->len = 0; + + cert = SSL_get_peer_certificate(c->ssl->connection); + if (cert == NULL) { + return NGX_OK; + } + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) { + X509_free(cert); + return NGX_ERROR; + } + +#if OPENSSL_VERSION_NUMBER > 0x10100000L + ASN1_TIME_print(bio, X509_get0_notAfter(cert)); +#else + ASN1_TIME_print(bio, X509_get_notAfter(cert)); +#endif + + len = BIO_pending(bio); + + s->len = len; + s->data = ngx_pnalloc(pool, len); + if (s->data == NULL) { + BIO_free(bio); + X509_free(cert); + return NGX_ERROR; + } + + BIO_read(bio, s->data, len); + BIO_free(bio); + X509_free(cert); + + return NGX_OK; +} + + +ngx_int_t +ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + X509 *cert; + time_t now, end; + + s->len = 0; + + cert = SSL_get_peer_certificate(c->ssl->connection); + if (cert == NULL) { + return NGX_OK; + } + +#if OPENSSL_VERSION_NUMBER > 0x10100000L + end = ngx_ssl_parse_time(X509_get0_notAfter(cert)); +#else + end = ngx_ssl_parse_time(X509_get_notAfter(cert)); +#endif + + if (end == (time_t) NGX_ERROR) { + X509_free(cert); + return NGX_OK; + } + + now = ngx_time(); + + if (end < now + 86400) { + ngx_str_set(s, "0"); + X509_free(cert); + return NGX_OK; + } + + s->data = ngx_pnalloc(pool, NGX_TIME_T_LEN); + if (s->data == NULL) { + X509_free(cert); + return NGX_ERROR; + } + + s->len = ngx_sprintf(s->data, "%T", (end - now) / 86400) - s->data; + + X509_free(cert); + + return NGX_OK; +} + + +static time_t +ngx_ssl_parse_time( +#if OPENSSL_VERSION_NUMBER > 0x10100000L + const +#endif + ASN1_TIME *asn1time) +{ + BIO *bio; + u_char *value; + size_t len; + time_t time; + + /* + * OpenSSL doesn't provide a way to convert ASN1_TIME + * into time_t. To do this, we use ASN1_TIME_print(), + * which uses the "MMM DD HH:MM:SS YYYY [GMT]" format (e.g., + * "Feb 3 00:55:52 2015 GMT"), and parse the result. + */ + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) { + return NGX_ERROR; + } + + /* fake weekday prepended to match C asctime() format */ + + BIO_write(bio, "Tue ", sizeof("Tue ") - 1); + ASN1_TIME_print(bio, asn1time); + len = BIO_get_mem_data(bio, &value); + + time = ngx_parse_http_time(value, len); + + BIO_free(bio); + + return time; +} + + static void * ngx_openssl_create_conf(ngx_cycle_t *cycle) { diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -215,6 +215,12 @@ ngx_int_t ngx_ssl_get_fingerprint(ngx_co ngx_str_t *s); ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_client_v_start(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); +ngx_int_t ngx_ssl_get_client_v_end(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); +ngx_int_t ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_handshake(ngx_connection_t *c); diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -313,6 +313,15 @@ static ngx_http_variable_t ngx_http_ssl { ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_v_start"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_client_v_start, NGX_HTTP_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_v_end"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_client_v_end, NGX_HTTP_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_v_remain"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_client_v_remain, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; From mdounin at mdounin.ru Mon Dec 5 20:02:01 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 05 Dec 2016 20:02:01 +0000 Subject: [nginx] SSL: $ssl_ciphers (ticket #870). Message-ID: details: http://hg.nginx.org/nginx/rev/ea93c7d8752a branches: changeset: 6816:ea93c7d8752a user: Maxim Dounin date: Mon Dec 05 22:23:23 2016 +0300 description: SSL: $ssl_ciphers (ticket #870). The variable contains list of ciphers as supported by the client. Known ciphers are listed by their names, unknown ones are shown in hex, e.g., ""AES128-SHA:AES256-SHA:0x00ff". The variable is fully supported only when using OpenSSL 1.0.2 and above. With older version there is an attempt to provide some information using SSL_get_shared_ciphers(). It only lists known ciphers though. Moreover, as OpenSSL uses session data for SSL_get_shared_ciphers(), and it doesn't store relevant data when serializing a session. As a result $ssl_ciphers is only available for new sessions (and not available for reused ones) when using OpenSSL older than 1.0.2. diffstat: src/event/ngx_event_openssl.c | 84 ++++++++++++++++++++++++++++++++++ src/event/ngx_event_openssl.h | 2 + src/http/modules/ngx_http_ssl_module.c | 3 + src/stream/ngx_stream_ssl_module.c | 3 + 4 files changed, 92 insertions(+), 0 deletions(-) diffs (132 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -3294,6 +3294,90 @@ ngx_ssl_get_cipher_name(ngx_connection_t ngx_int_t +ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ +#ifdef SSL_CTRL_GET_RAW_CIPHERLIST + + int n, i, bytes; + size_t len; + u_char *ciphers, *p; + const SSL_CIPHER *cipher; + + bytes = SSL_get0_raw_cipherlist(c->ssl->connection, NULL); + n = SSL_get0_raw_cipherlist(c->ssl->connection, &ciphers); + + if (n <= 0) { + s->len = 0; + return NGX_OK; + } + + len = 0; + n /= bytes; + + for (i = 0; i < n; i++) { + cipher = SSL_CIPHER_find(c->ssl->connection, ciphers + i * bytes); + + if (cipher) { + len += ngx_strlen(SSL_CIPHER_get_name(cipher)); + + } else { + len += sizeof("0x") - 1 + bytes * (sizeof("00") - 1); + } + + len += sizeof(":") - 1; + } + + s->data = ngx_pnalloc(pool, len); + if (s->data == NULL) { + return NGX_ERROR; + } + + p = s->data; + + for (i = 0; i < n; i++) { + cipher = SSL_CIPHER_find(c->ssl->connection, ciphers + i * bytes); + + if (cipher) { + p = ngx_sprintf(p, "%s", SSL_CIPHER_get_name(cipher)); + + } else { + p = ngx_sprintf(p, "0x"); + p = ngx_hex_dump(p, ciphers + i * bytes, bytes); + } + + *p++ = ':'; + } + + p--; + + s->len = p - s->data; + +#else + + u_char buf[4096]; + + if (SSL_get_shared_ciphers(c->ssl->connection, (char *) buf, 4096) + == NULL) + { + s->len = 0; + return NGX_OK; + } + + s->len = ngx_strlen(buf); + s->data = ngx_pnalloc(pool, s->len); + if (s->data == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(s->data, buf, s->len); + +#endif + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { u_char *buf; diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -191,6 +191,8 @@ ngx_int_t ngx_ssl_get_protocol(ngx_conne ngx_str_t *s); ngx_int_t ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -276,6 +276,9 @@ static ngx_http_variable_t ngx_http_ssl { ngx_string("ssl_cipher"), NULL, ngx_http_ssl_static_variable, (uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_ciphers"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_ciphers, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 }, diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -182,6 +182,9 @@ static ngx_stream_variable_t ngx_stream { ngx_string("ssl_cipher"), NULL, ngx_stream_ssl_static_variable, (uintptr_t) ngx_ssl_get_cipher_name, NGX_STREAM_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_ciphers"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_ciphers, NGX_STREAM_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable, (uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 }, From mdounin at mdounin.ru Mon Dec 5 20:02:04 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 05 Dec 2016 20:02:04 +0000 Subject: [nginx] SSL: $ssl_curves (ticket #1088). Message-ID: details: http://hg.nginx.org/nginx/rev/e75e854657ba branches: changeset: 6817:e75e854657ba user: Maxim Dounin date: Mon Dec 05 22:23:23 2016 +0300 description: SSL: $ssl_curves (ticket #1088). The variable contains a list of curves as supported by the client. Known curves are listed by their names, unknown ones are shown in hex, e.g., "0x001d:prime256v1:secp521r1:secp384r1". Note that OpenSSL uses session data for SSL_get1_curves(), and it doesn't store full list of curves supported by the client when serializing a session. As a result $ssl_curves is only available for new sessions (and will be empty for reused ones). The variable is only meaningful when using OpenSSL 1.0.2 and above. With older versions the variable is empty. diffstat: src/event/ngx_event_openssl.c | 68 ++++++++++++++++++++++++++++++++++ src/event/ngx_event_openssl.h | 2 + src/http/modules/ngx_http_ssl_module.c | 3 + src/stream/ngx_stream_ssl_module.c | 3 + 4 files changed, 76 insertions(+), 0 deletions(-) diffs (116 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -3378,6 +3378,74 @@ ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_int_t +ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ +#ifdef SSL_CTRL_GET_CURVES + + int *curves, n, i, nid; + u_char *p; + size_t len; + + n = SSL_get1_curves(c->ssl->connection, NULL); + + if (n <= 0) { + s->len = 0; + return NGX_OK; + } + + curves = ngx_palloc(pool, n * sizeof(int)); + + n = SSL_get1_curves(c->ssl->connection, curves); + len = 0; + + for (i = 0; i < n; i++) { + nid = curves[i]; + + if (nid & TLSEXT_nid_unknown) { + len += sizeof("0x0000") - 1; + + } else { + len += ngx_strlen(OBJ_nid2sn(nid)); + } + + len += sizeof(":") - 1; + } + + s->data = ngx_pnalloc(pool, len); + if (s->data == NULL) { + return NGX_ERROR; + } + + p = s->data; + + for (i = 0; i < n; i++) { + nid = curves[i]; + + if (nid & TLSEXT_nid_unknown) { + p = ngx_sprintf(p, "0x%04xd", nid & 0xffff); + + } else { + p = ngx_sprintf(p, "%s", OBJ_nid2sn(nid)); + } + + *p++ = ':'; + } + + p--; + + s->len = p - s->data; + +#else + + s->len = 0; + +#endif + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { u_char *buf; diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -193,6 +193,8 @@ ngx_int_t ngx_ssl_get_cipher_name(ngx_co ngx_str_t *s); ngx_int_t ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -279,6 +279,9 @@ static ngx_http_variable_t ngx_http_ssl { ngx_string("ssl_ciphers"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_ciphers, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_curves"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_curves, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 }, diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -185,6 +185,9 @@ static ngx_stream_variable_t ngx_stream { ngx_string("ssl_ciphers"), NULL, ngx_stream_ssl_variable, (uintptr_t) ngx_ssl_get_ciphers, NGX_STREAM_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_curves"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_curves, NGX_STREAM_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable, (uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 }, From mdounin at mdounin.ru Mon Dec 5 20:45:11 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 05 Dec 2016 20:45:11 +0000 Subject: [nginx] Mp4: fixed setting wrong mdat atom size in very rare cases. Message-ID: details: http://hg.nginx.org/nginx/rev/2b2239a1e0d4 branches: changeset: 6818:2b2239a1e0d4 user: hucongcong date: Tue Nov 22 13:40:08 2016 +0800 description: Mp4: fixed setting wrong mdat atom size in very rare cases. Atom size is the sum of atom header size and atom data size. The specification says that the first 4 bytes are set to one when the atom size is greater than the maximum unsigned 32-bit value. Which means atom header size should be considered when the comparison takes place between atom data size and 0xffffffff. diffstat: src/http/modules/ngx_http_mp4_module.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c +++ b/src/http/modules/ngx_http_mp4_module.c @@ -1229,7 +1229,9 @@ ngx_http_mp4_update_mdat_atom(ngx_http_m atom_header = mp4->mdat_atom_header; - if ((uint64_t) atom_data_size > (uint64_t) 0xffffffff) { + if ((uint64_t) atom_data_size + > (uint64_t) 0xffffffff - sizeof(ngx_mp4_atom_header_t)) + { atom_size = 1; atom_header_size = sizeof(ngx_mp4_atom_header64_t); ngx_mp4_set_64value(atom_header + sizeof(ngx_mp4_atom_header_t), From mdounin at mdounin.ru Mon Dec 5 20:45:23 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 5 Dec 2016 23:45:23 +0300 Subject: [PATCH] Mp4: fixed setting wrong mdat atom size in very rarecases. In-Reply-To: References: <20161121142557.GI8196@mdounin.ru> <2766424.N7GUhy8r5P@vbart-laptop> Message-ID: <20161205204523.GN18639@mdounin.ru> Hello! On Tue, Nov 22, 2016 at 02:13:11PM +0800, ?? (hucc) wrote: > Hi, > > On Tue, Nov 22, 2016 at 4:37 AM +0300, Valentin V. Bartenev wrote: > > >On Monday 21 November 2016 23:10:25 ?? wrote: > > > >> - if ((uint64_t) atom_data_size > (uint64_t) 0xffffffff) { > >> + if ((uint64_t) atom_data_size + sizeof(ngx_mp4_atom_header_t) > >> + > (uint64_t) 0xffffffff) > >> + { > >> atom_size = 1; > > > >Maxim wrote the expression the way that almost all compilers should optimize > >it to comparison with one static constant. I'm not sure about your case. > > Yes, that is a matter. I checked that the above situation does not seem to be > optimized. > > # HG changeset patch > # User hucongcong > # Date 1479793208 -28800 > # Tue Nov 22 13:40:08 2016 +0800 > # Node ID 7a4d011601cefeda16c8de2630ae0cc7639edf84 > # Parent 2c7a2d75938a31044552b0a6cd6edaebdaf0bd69 > Mp4: fixed setting wrong mdat atom size in very rare cases. > > Atom size is the sum of atom header size and atom data size. The > specification says that the first 4 bytes are set to one when > the atom size is greater than the maximum unsigned 32-bit value. > Which means atom header size should be considered when the > comparison takes place between atom data size and 0xffffffff. > > diff -r 2c7a2d75938a -r 7a4d011601ce src/http/modules/ngx_http_mp4_module.c > --- a/src/http/modules/ngx_http_mp4_module.c Mon Nov 21 16:49:19 2016 +0300 > +++ b/src/http/modules/ngx_http_mp4_module.c Tue Nov 22 13:40:08 2016 +0800 > @@ -1229,7 +1229,9 @@ ngx_http_mp4_update_mdat_atom(ngx_http_m > > atom_header = mp4->mdat_atom_header; > > - if ((uint64_t) atom_data_size > (uint64_t) 0xffffffff) { > + if ((uint64_t) atom_data_size > + > (uint64_t) 0xffffffff - sizeof(ngx_mp4_atom_header_t)) > + { > atom_size = 1; > atom_header_size = sizeof(ngx_mp4_atom_header64_t); > ngx_mp4_set_64value(atom_header + sizeof(ngx_mp4_atom_header_t), Committed, thanks. -- Maxim Dounin http://nginx.org/ From ru at nginx.com Tue Dec 6 19:13:06 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 6 Dec 2016 22:13:06 +0300 Subject: Add support for 'nocache' flag to map directive In-Reply-To: References: Message-ID: <20161206191306.GA41460@lo0.su> On Sat, Dec 03, 2016 at 09:06:16PM +0000, Eran Kornblau wrote: > As I got no objections... :) patch attached There was a similar patch circulating locally circa 2013. I've updated it today. Please give it a try. # HG changeset patch # User Ruslan Ermilov # Date 1481040301 -10800 # Tue Dec 06 19:05:01 2016 +0300 # Node ID a68b9457f36bc0f4bfdf44722e966e790c7fd7f0 # Parent b5ba6cf04d0aa69260f58d5416532c3edc7feb56 Map: simplified "map" block parser. No functional changes. diff --git a/src/http/modules/ngx_http_map_module.c b/src/http/modules/ngx_http_map_module.c --- a/src/http/modules/ngx_http_map_module.c +++ b/src/http/modules/ngx_http_map_module.c @@ -393,8 +393,9 @@ ngx_http_map(ngx_conf_t *cf, ngx_command { ctx->hostnames = 1; return NGX_CONF_OK; + } - } else if (cf->args->nelts != 2) { + if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of the map parameters"); return NGX_CONF_ERROR; diff --git a/src/stream/ngx_stream_map_module.c b/src/stream/ngx_stream_map_module.c --- a/src/stream/ngx_stream_map_module.c +++ b/src/stream/ngx_stream_map_module.c @@ -392,8 +392,9 @@ ngx_stream_map(ngx_conf_t *cf, ngx_comma { ctx->hostnames = 1; return NGX_CONF_OK; + } - } else if (cf->args->nelts != 2) { + if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of the map parameters"); return NGX_CONF_ERROR; # HG changeset patch # User Ruslan Ermilov # Date 1481040307 -10800 # Tue Dec 06 19:05:07 2016 +0300 # Node ID 414e7061c1b6fa89003e1c5600921cb48d6d977f # Parent a68b9457f36bc0f4bfdf44722e966e790c7fd7f0 Map: the "volatile" parameter. diff --git a/src/http/modules/ngx_http_map_module.c b/src/http/modules/ngx_http_map_module.c --- a/src/http/modules/ngx_http_map_module.c +++ b/src/http/modules/ngx_http_map_module.c @@ -26,7 +26,8 @@ typedef struct { ngx_http_variable_value_t *default_value; ngx_conf_t *cf; - ngx_uint_t hostnames; /* unsigned hostnames:1 */ + unsigned hostnames:1; + unsigned no_cacheable:1; } ngx_http_map_conf_ctx_t; @@ -265,6 +266,7 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_c ctx.default_value = NULL; ctx.cf = &save; ctx.hostnames = 0; + ctx.no_cacheable = 0; save = *cf; cf->pool = pool; @@ -281,6 +283,10 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_c return rv; } + if (ctx.no_cacheable) { + var->flags |= NGX_HTTP_VAR_NOCACHEABLE; + } + map->default_value = ctx.default_value ? ctx.default_value: &ngx_http_variable_null_value; @@ -395,6 +401,13 @@ ngx_http_map(ngx_conf_t *cf, ngx_command return NGX_CONF_OK; } + if (cf->args->nelts == 1 + && ngx_strcmp(value[0].data, "volatile") == 0) + { + ctx->no_cacheable = 1; + return NGX_CONF_OK; + } + if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of the map parameters"); diff --git a/src/stream/ngx_stream_map_module.c b/src/stream/ngx_stream_map_module.c --- a/src/stream/ngx_stream_map_module.c +++ b/src/stream/ngx_stream_map_module.c @@ -26,7 +26,8 @@ typedef struct { ngx_stream_variable_value_t *default_value; ngx_conf_t *cf; - ngx_uint_t hostnames; /* unsigned hostnames:1 */ + unsigned hostnames:1; + unsigned no_cacheable:1; } ngx_stream_map_conf_ctx_t; @@ -264,6 +265,7 @@ ngx_stream_map_block(ngx_conf_t *cf, ngx ctx.default_value = NULL; ctx.cf = &save; ctx.hostnames = 0; + ctx.no_cacheable = 0; save = *cf; cf->pool = pool; @@ -280,6 +282,10 @@ ngx_stream_map_block(ngx_conf_t *cf, ngx return rv; } + if (ctx.no_cacheable) { + var->flags |= NGX_STREAM_VAR_NOCACHEABLE; + } + map->default_value = ctx.default_value ? ctx.default_value: &ngx_stream_variable_null_value; @@ -394,6 +400,13 @@ ngx_stream_map(ngx_conf_t *cf, ngx_comma return NGX_CONF_OK; } + if (cf->args->nelts == 1 + && ngx_strcmp(value[0].data, "volatile") == 0) + { + ctx->no_cacheable = 1; + return NGX_CONF_OK; + } + if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of the map parameters"); From eran.kornblau at kaltura.com Tue Dec 6 19:42:36 2016 From: eran.kornblau at kaltura.com (Eran Kornblau) Date: Tue, 6 Dec 2016 19:42:36 +0000 Subject: Add support for 'nocache' flag to map directive In-Reply-To: <20161206191306.GA41460@lo0.su> References: <20161206191306.GA41460@lo0.su> Message-ID: > > -----Original Message----- > From: nginx-devel [mailto:nginx-devel-bounces at nginx.org] On Behalf Of Ruslan Ermilov > Sent: Tuesday, December 6, 2016 9:13 PM > To: nginx-devel at nginx.org > Subject: Re: Add support for 'nocache' flag to map directive > > There was a similar patch circulating locally circa 2013. > I've updated it today. Please give it a try. > I merged these changes manually (I'm still on an old version of nginx that doesn't have the stream module) and it's working great. Is this going to be merged? Thank you! Eran > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > From mdounin at mdounin.ru Tue Dec 6 20:06:46 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 6 Dec 2016 23:06:46 +0300 Subject: [PATCH] Fix MinGW64 compilation In-Reply-To: References: Message-ID: <20161206200645.GX18639@mdounin.ru> Hello! On Tue, Nov 29, 2016 at 01:13:27PM +0200, Orgad Shaneh wrote: > # HG changeset patch > # User Orgad Shaneh > # Date 1480405065 -7200 > # Tue Nov 29 09:37:45 2016 +0200 > # Node ID e036a4628d9cc8803579d7d41848d528488eca6d > # Parent 52bd8cc17f34bbebcb4d2ce3651b40af7d572d55 > Fix MinGW64 compilation Style, should use "Configure: ..." prefix and trailing dot, e.g.: Configure: fix MinGW64 compilation. It may also be more specific about what "MinGW64 compilation" means, see below. > > diff -r 52bd8cc17f34 -r e036a4628d9c auto/configure > --- a/auto/configure Mon Nov 28 19:19:21 2016 +0300 > +++ b/auto/configure Tue Nov 29 09:37:45 2016 +0200 > @@ -36,7 +36,7 @@ > NGX_PLATFORM="$NGX_SYSTEM:$NGX_RELEASE:$NGX_MACHINE"; > > case "$NGX_SYSTEM" in > - MINGW32_*) > + MINGW32_*|MINGW64_*) Style, should be spaces around "|". > NGX_PLATFORM=win32 > ;; > esac AFAIK, MinGW-w64 project doesn't provide any compilation environment by itself. We do support compiling with mingw-w64 gcc under MSYS, similar to how it's documented for MSVC at [1], but it only returns MINGW32_* in "uname -s". Do you mean compiling under some different environment? MSYS2? [1] http://nginx.org/en/docs/howto_build_on_win32.html -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Tue Dec 6 20:14:26 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 6 Dec 2016 23:14:26 +0300 Subject: [PATCH] Use .exe for binaries for all win32 compilers In-Reply-To: References: Message-ID: <20161206201426.GY18639@mdounin.ru> Hello! On Tue, Nov 29, 2016 at 11:32:03AM +0200, Orgad Shaneh wrote: > Hi, > > I'm not sure if this is the right place to do this. Please review and comment. > > # HG changeset patch > # User Orgad Shaneh > # Date 1480411801 -7200 > # Tue Nov 29 11:30:01 2016 +0200 > # Node ID 017b0c3afbbf960b9f29a892a82a77e9f17b6774 > # Parent e036a4628d9cc8803579d7d41848d528488eca6d > Use .exe for binaries for all win32 compilers > > diff -r e036a4628d9c -r 017b0c3afbbf auto/cc/conf > --- a/auto/cc/conf Tue Nov 29 09:37:45 2016 +0200 > +++ b/auto/cc/conf Tue Nov 29 11:30:01 2016 +0200 > @@ -144,7 +144,9 @@ > CFLAGS="$CFLAGS $NGX_CC_OPT" > NGX_TEST_LD_OPT="$NGX_LD_OPT" > > -if [ "$NGX_PLATFORM" != win32 ]; then > +if [ "$NGX_PLATFORM" = win32 ]; then > + ngx_binext=".exe" > +else > > if test -n "$NGX_LD_OPT"; then > ngx_feature=--with-ld-opt=\"$NGX_LD_OPT\" > Not sure it's at all needed. But if it is, it should be somewhere before per-compiler calls instead, e.g.: diff --git a/auto/cc/conf b/auto/cc/conf --- a/auto/cc/conf +++ b/auto/cc/conf @@ -17,6 +17,10 @@ ngx_objext="o" ngx_binext= ngx_modext=".so" +if [ "$NGX_PLATFORM" = win32 ]; then + ngx_binext=".exe" +fi + ngx_long_start= ngx_long_end= And also should imply removing ngx_binext from particular compilers. -- Maxim Dounin http://nginx.org/ From ru at nginx.com Wed Dec 7 09:20:27 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 7 Dec 2016 12:20:27 +0300 Subject: Add support for 'nocache' flag to map directive In-Reply-To: References: <20161206191306.GA41460@lo0.su> Message-ID: <20161207092027.GH41460@lo0.su> On Tue, Dec 06, 2016 at 07:42:36PM +0000, Eran Kornblau wrote: > > > > -----Original Message----- > > From: nginx-devel [mailto:nginx-devel-bounces at nginx.org] On Behalf Of Ruslan Ermilov > > Sent: Tuesday, December 6, 2016 9:13 PM > > To: nginx-devel at nginx.org > > Subject: Re: Add support for 'nocache' flag to map directive > > > > There was a similar patch circulating locally circa 2013. > > I've updated it today. Please give it a try. > > > > I merged these changes manually (I'm still on an old version of nginx that doesn't have the stream module) > and it's working great. > Is this going to be merged? Yes, if the review process succeeds. From eran.kornblau at kaltura.com Wed Dec 7 09:22:06 2016 From: eran.kornblau at kaltura.com (Eran Kornblau) Date: Wed, 7 Dec 2016 09:22:06 +0000 Subject: Add support for 'nocache' flag to map directive In-Reply-To: <20161207092027.GH41460@lo0.su> References: <20161206191306.GA41460@lo0.su> <20161207092027.GH41460@lo0.su> Message-ID: > > > -----Original Message----- > From: nginx-devel [mailto:nginx-devel-bounces at nginx.org] On Behalf Of Ruslan Ermilov > Sent: Wednesday, December 7, 2016 11:20 AM > To: nginx-devel at nginx.org > Subject: Re: Add support for 'nocache' flag to map directive > > On Tue, Dec 06, 2016 at 07:42:36PM +0000, Eran Kornblau wrote: > > > > > > -----Original Message----- > > > From: nginx-devel [mailto:nginx-devel-bounces at nginx.org] On Behalf > > > Of Ruslan Ermilov > > > Sent: Tuesday, December 6, 2016 9:13 PM > > > To: nginx-devel at nginx.org > > > Subject: Re: Add support for 'nocache' flag to map directive > > > > > > There was a similar patch circulating locally circa 2013. > > > I've updated it today. Please give it a try. > > > > > > > I merged these changes manually (I'm still on an old version of nginx > > that doesn't have the stream module) and it's working great. > > Is this going to be merged? > > Yes, if the review process succeeds. Awesome! Thank you! > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > From pluknet at nginx.com Wed Dec 7 10:55:53 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Wed, 07 Dec 2016 10:55:53 +0000 Subject: [nginx] Fixed spelling of logical AND operator, no functional changes. Message-ID: details: http://hg.nginx.org/nginx/rev/4395758d08e6 branches: changeset: 6819:4395758d08e6 user: Sergey Kandaurov date: Wed Dec 07 13:54:30 2016 +0300 description: Fixed spelling of logical AND operator, no functional changes. Found by PVS-Studio. diffstat: src/core/ngx_output_chain.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 2b2239a1e0d4 -r 4395758d08e6 src/core/ngx_output_chain.c --- a/src/core/ngx_output_chain.c Tue Nov 22 13:40:08 2016 +0800 +++ b/src/core/ngx_output_chain.c Wed Dec 07 13:54:30 2016 +0300 @@ -512,7 +512,7 @@ ngx_output_chain_copy_buf(ngx_output_cha size = ngx_buf_size(src); size = ngx_min(size, dst->end - dst->pos); - sendfile = ctx->sendfile & !ctx->directio; + sendfile = ctx->sendfile && !ctx->directio; #if (NGX_SENDFILE_LIMIT) From igor at sysoev.ru Wed Dec 7 12:18:02 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 07 Dec 2016 12:18:02 +0000 Subject: [njs] Fixed "return" usage in a true branch of an "if" statement. Message-ID: details: http://hg.nginx.org/njs/rev/56d6fc12dc31 branches: changeset: 275:56d6fc12dc31 user: Igor Sysoev date: Wed Dec 07 15:02:00 2016 +0300 description: Fixed "return" usage in a true branch of an "if" statement. diffstat: njs/njs_parser.c | 4 ++++ njs/test/njs_unit_test.c | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 0 deletions(-) diffs (39 lines): diff -r 709ac03a4bfd -r 56d6fc12dc31 njs/njs_parser.c --- a/njs/njs_parser.c Mon Dec 05 17:47:00 2016 +0300 +++ b/njs/njs_parser.c Wed Dec 07 15:02:00 2016 +0300 @@ -629,6 +629,10 @@ njs_parser_return_statement(njs_vm_t *vm node->right = parser->node; parser->node = node; + if (token == NJS_TOKEN_SEMICOLON) { + return njs_parser_token(parser); + } + return token; } } diff -r 709ac03a4bfd -r 56d6fc12dc31 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Dec 05 17:47:00 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Dec 07 15:02:00 2016 +0300 @@ -1514,6 +1514,21 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = [3], b; if (1==1||2==2) { b = '1'+'2'+a[0] }; b }"), nxt_string("123") }, + { nxt_string("(function(){ if(true) return 1 else return 0; })()"), + nxt_string("1") }, + + { nxt_string("(function(){ if(true) return 1; else return 0; })()"), + nxt_string("1") }, + + { nxt_string("(function(){ if(true) return 1;; else return 0; })()"), + nxt_string("SyntaxError: Unexpected token \"else\" in 1") }, + + { nxt_string("(function(){ if(true) return 1\n else return 0; })()"), + nxt_string("1") }, + + { nxt_string("(function(){ if(true) return 1\n;\n else return 0; })()"), + nxt_string("1") }, + /* do while. */ { nxt_string("do { break } if (false)"), From mdounin at mdounin.ru Wed Dec 7 15:47:39 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 7 Dec 2016 18:47:39 +0300 Subject: [nginx] Core: when changing binary, newly forked master process should not remove unix domain socket unless old master has quit. In-Reply-To: References: Message-ID: <20161207154739.GB18639@mdounin.ru> Hello! On Fri, Dec 02, 2016 at 01:23:36AM -0800, Datong Sun via nginx-devel wrote: > # HG changeset patch > # User Datong Sun > # Date 1480669905 21600 > # Fri Dec 02 03:11:45 2016 -0600 > # Node ID 92a7853a439708584bbc45b416df464c64ec446e > # Parent 1b7a6785d1f3c76f436a9dea5cb0fc86e1db5f2b > Core: when changing binary, newly forked master process should > not remove unix domain socket unless old master has quit. Style, please keep summary line under 67 symbols. See http://nginx.org/en/docs/contributing_changes.html for more details. > > This commit fixes a bug that during a binary change, when both > old and new master processes are running, sending TERM to the > new master process will accidently remove unix domain socket > from disk while old master is still listening on it. > > diff -r 1b7a6785d1f3 -r 92a7853a4397 src/core/ngx_connection.c > --- a/src/core/ngx_connection.c Fri Dec 02 03:06:48 2016 -0600 > +++ b/src/core/ngx_connection.c Fri Dec 02 03:11:45 2016 -0600 > @@ -1007,7 +1007,8 @@ > > if (ls[i].sockaddr->sa_family == AF_UNIX > && ngx_process <= NGX_PROCESS_MASTER > - && ngx_new_binary == 0) > + && ngx_new_binary == 0 > + && getppid() == 1) > { > u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1; The getppid() call doesn't look right in platform-independent code. Especially keeping in mind that the test in question known to produce incorrect results in some cases - at least in Solaris zones, and AFAIR somehow with systemd. Also note that with your previous patch this problem starts to affect not only TERM, but also QUIT. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Dec 7 15:58:25 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 7 Dec 2016 18:58:25 +0300 Subject: [PATCH] Http gunzip: additional configuration In-Reply-To: References: Message-ID: <20161207155825.GC18639@mdounin.ru> Hello! On Sun, Nov 27, 2016 at 02:27:56PM +0200, Alon Blayer-Gat wrote: > Hi, > > 1) 'gunzip always' option will gunzip even if the client supports it. > 2) 'gunzip types', like 'always' but only for file types specified > with 'gunzip_types ' > 3) Allow gunzip and gunzip_types directives within "if in location" > block (rewrite phase condition). > > The suggested changes are needed, mainly, to allow dynamic > modification of compressed response (e.g. with the 'sub_filter' > module) > 'types' and 'if in location' may allow a more selective operation. No, thanks. "If in location" is evil, don't even try to suggest patches to allow directives in the "if in location" context. As for other changes - I can't say I like them as well. We may consider something as simple as "gunzip always", but additional types filter certainly looks like an overkill. Rather it should be some more generic mechanism to require gunzipping, may be useable by modules directly. [...] -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Dec 7 17:48:55 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 07 Dec 2016 17:48:55 +0000 Subject: [nginx] Perl: added PERL_SET_INTERP(). Message-ID: details: http://hg.nginx.org/nginx/rev/eada22643e8b branches: changeset: 6820:eada22643e8b user: Maxim Dounin date: Wed Dec 07 19:03:19 2016 +0300 description: Perl: added PERL_SET_INTERP(). For Perl compiled with threads, without PERL_SET_INTERP() the PL_curinterp remains set to the first interpreter created (that is, one created at original start). As a result after a reload Perl thinks that operations are done withing a thread, and, most notably, denies to change environment. For example, the following code properly works on original start, but fails after a reload: perl 'sub { my $r = shift; $r->send_http_header("text/plain"); $ENV{TZ} = "UTC"; $r->print("tz: " . $ENV{TZ} . " (localtime " . (localtime()) . ")\n"); $ENV{TZ} = "Europe/Moscow"; $r->print("tz: " . $ENV{TZ} . " (localtime " . (localtime()) . ")\n"); return OK; }'; To fix this, PERL_SET_INTERP() added anywhere where PERL_SET_CONTEXT() was previously used. Note that PERL_SET_INTERP() doesn't seem to be documented anywhere. Yet it is used in some other software, and also seems to be the only solution possible. diffstat: src/http/modules/perl/ngx_http_perl_module.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diffs (67 lines): diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -207,6 +207,7 @@ ngx_http_perl_handle_request(ngx_http_re dTHXa(pmcf->perl); PERL_SET_CONTEXT(pmcf->perl); + PERL_SET_INTERP(pmcf->perl); if (ctx->next == NULL) { plcf = ngx_http_get_module_loc_conf(r, ngx_http_perl_module); @@ -322,6 +323,7 @@ ngx_http_perl_variable(ngx_http_request_ dTHXa(pmcf->perl); PERL_SET_CONTEXT(pmcf->perl); + PERL_SET_INTERP(pmcf->perl); rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, pv->sub, NULL, &pv->handler, &value); @@ -387,6 +389,7 @@ ngx_http_perl_ssi(ngx_http_request_t *r, dTHXa(pmcf->perl); PERL_SET_CONTEXT(pmcf->perl); + PERL_SET_INTERP(pmcf->perl); #if 0 @@ -568,6 +571,7 @@ ngx_http_perl_create_interpreter(ngx_con dTHXa(perl); PERL_SET_CONTEXT(perl); + PERL_SET_INTERP(perl); perl_construct(perl); @@ -828,6 +832,7 @@ ngx_http_perl_cleanup_perl(void *data) PerlInterpreter *perl = data; PERL_SET_CONTEXT(perl); + PERL_SET_INTERP(perl); (void) perl_destruct(perl); @@ -936,6 +941,7 @@ ngx_http_perl(ngx_conf_t *cf, ngx_comman dTHXa(pmcf->perl); PERL_SET_CONTEXT(pmcf->perl); + PERL_SET_INTERP(pmcf->perl); ngx_http_perl_eval_anon_sub(aTHX_ &value[1], &plcf->sub); @@ -1007,6 +1013,7 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_co dTHXa(pmcf->perl); PERL_SET_CONTEXT(pmcf->perl); + PERL_SET_INTERP(pmcf->perl); ngx_http_perl_eval_anon_sub(aTHX_ &value[2], &pv->sub); @@ -1039,6 +1046,7 @@ ngx_http_perl_init_worker(ngx_cycle_t *c if (pmcf) { dTHXa(pmcf->perl); PERL_SET_CONTEXT(pmcf->perl); + PERL_SET_INTERP(pmcf->perl); /* set worker's $$ */ From mdounin at mdounin.ru Wed Dec 7 17:48:58 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 07 Dec 2016 17:48:58 +0000 Subject: [nginx] Perl: removed special environment handling for the perl module. Message-ID: details: http://hg.nginx.org/nginx/rev/30b6f1ff192b branches: changeset: 6821:30b6f1ff192b user: Maxim Dounin date: Wed Dec 07 19:03:26 2016 +0300 description: Perl: removed special environment handling for the perl module. In Perl 5.8.6 the default was switched to use putenv() when used as embedded library unless "PL_use_safe_putenv = 0" is explicitly used in the code. Therefore, for modern versions of Perl it is no longer necessary to restore previous environment when calling perl_destruct(). diffstat: auto/lib/perl/conf | 6 +++--- src/core/ngx_cycle.c | 13 +------------ 2 files changed, 4 insertions(+), 15 deletions(-) diffs (57 lines): diff --git a/auto/lib/perl/conf b/auto/lib/perl/conf --- a/auto/lib/perl/conf +++ b/auto/lib/perl/conf @@ -12,9 +12,9 @@ NGX_PERL_VER=`$NGX_PERL -v 2>&1 | grep ' if test -n "$NGX_PERL_VER"; then echo " + perl version: $NGX_PERL_VER" - if [ "`$NGX_PERL -e 'use 5.006001; print "OK"'`" != "OK" ]; then + if [ "`$NGX_PERL -e 'use 5.008006; print "OK"'`" != "OK" ]; then echo - echo "$0: error: perl 5.6.1 or higher is required" + echo "$0: error: perl 5.8.6 or higher is required" echo exit 1; @@ -76,7 +76,7 @@ if test -n "$NGX_PERL_VER"; then else echo - echo "$0: error: perl 5.6.1 or higher is required" + echo "$0: error: perl 5.8.6 or higher is required" echo exit 1; diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -37,7 +37,7 @@ ngx_cycle_t * ngx_init_cycle(ngx_cycle_t *old_cycle) { void *rv; - char **senv, **env; + char **senv; ngx_uint_t i, n; ngx_log_t *log; ngx_time_t *tp; @@ -750,20 +750,9 @@ old_shm_zone_done: if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) { - /* - * perl_destruct() frees environ, if it is not the same as it was at - * perl_construct() time, therefore we save the previous cycle - * environment before ngx_conf_parse() where it will be changed. - */ - - env = environ; - environ = senv; - ngx_destroy_pool(old_cycle->pool); cycle->old_cycle = NULL; - environ = env; - return cycle; } From mdounin at mdounin.ru Wed Dec 7 17:49:01 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 07 Dec 2016 17:49:01 +0000 Subject: [nginx] Core: fixed environment on exit. Message-ID: details: http://hg.nginx.org/nginx/rev/c045b4926b2c branches: changeset: 6822:c045b4926b2c user: Maxim Dounin date: Wed Dec 07 19:03:31 2016 +0300 description: Core: fixed environment on exit. On exit environment allocated from a pool is no longer available, leading to a segmentation fault if, for example, a library tries to use it from an atexit() handler. Fix is to allocate environment via ngx_alloc() instead, and explicitly free it using a pool cleanup handler if it's no longer used (e.g., on configuration reload). diffstat: src/core/nginx.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 40 insertions(+), 8 deletions(-) diffs (83 lines): diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -12,6 +12,7 @@ static void ngx_show_version_info(void); static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle); +static void ngx_cleanup_environment(void *data); static ngx_int_t ngx_get_options(int argc, char *const *argv); static ngx_int_t ngx_process_options(ngx_cycle_t *cycle); static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv); @@ -495,10 +496,11 @@ ngx_add_inherited_sockets(ngx_cycle_t *c char ** ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last) { - char **p, **env; - ngx_str_t *var; - ngx_uint_t i, n; - ngx_core_conf_t *ccf; + char **p, **env; + ngx_str_t *var; + ngx_uint_t i, n; + ngx_core_conf_t *ccf; + ngx_pool_cleanup_t *cln; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); @@ -550,14 +552,25 @@ tz_found: if (last) { env = ngx_alloc((*last + n + 1) * sizeof(char *), cycle->log); + if (env == NULL) { + return NULL; + } + *last = n; } else { - env = ngx_palloc(cycle->pool, (n + 1) * sizeof(char *)); - } + cln = ngx_pool_cleanup_add(cycle->pool, 0); + if (cln == NULL) { + return NULL; + } - if (env == NULL) { - return NULL; + env = ngx_alloc((n + 1) * sizeof(char *), cycle->log); + if (env == NULL) { + return NULL; + } + + cln->handler = ngx_cleanup_environment; + cln->data = env; } n = 0; @@ -591,6 +604,25 @@ tz_found: } +static void +ngx_cleanup_environment(void *data) +{ + char **env = data; + + if (environ == env) { + + /* + * if the environment is still used, as it happens on exit, + * the only option is to leak it + */ + + return; + } + + ngx_free(env); +} + + ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv) { From ru at nginx.com Wed Dec 7 19:27:29 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 07 Dec 2016 19:27:29 +0000 Subject: [nginx] Slab: improved code readability. Message-ID: details: http://hg.nginx.org/nginx/rev/88c8c3d65184 branches: changeset: 6823:88c8c3d65184 user: Ruslan Ermilov date: Wed Dec 07 22:25:37 2016 +0300 description: Slab: improved code readability. No functional changes. diffstat: src/core/ngx_slab.c | 103 ++++++++++++++++++++++++--------------------------- 1 files changed, 49 insertions(+), 54 deletions(-) diffs (302 lines): diff -r c045b4926b2c -r 88c8c3d65184 src/core/ngx_slab.c --- a/src/core/ngx_slab.c Wed Dec 07 19:03:31 2016 +0300 +++ b/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 @@ -41,6 +41,19 @@ #endif +#define ngx_slab_slots(pool) \ + (ngx_slab_page_t *) ((u_char *) (pool) + sizeof(ngx_slab_pool_t)) + +#define ngx_slab_page_type(page) ((page)->prev & NGX_SLAB_PAGE_MASK) + +#define ngx_slab_page_prev(page) \ + (ngx_slab_page_t *) ((page)->prev & ~NGX_SLAB_PAGE_MASK) + +#define ngx_slab_page_addr(pool, page) \ + ((((page) - (pool)->pages) << ngx_pagesize_shift) \ + + (uintptr_t) (pool)->start) + + #if (NGX_DEBUG_MALLOC) #define ngx_slab_junk(p, size) ngx_memset(p, 0xA5, size) @@ -76,7 +89,7 @@ ngx_slab_init(ngx_slab_pool_t *pool) size_t size; ngx_int_t m; ngx_uint_t i, n, pages; - ngx_slab_page_t *slots; + ngx_slab_page_t *slots, *page; /* STUB */ if (ngx_slab_max_size == 0) { @@ -90,12 +103,13 @@ ngx_slab_init(ngx_slab_pool_t *pool) pool->min_size = 1 << pool->min_shift; - p = (u_char *) pool + sizeof(ngx_slab_pool_t); + slots = ngx_slab_slots(pool); + + p = (u_char *) slots; size = pool->end - p; ngx_slab_junk(p, size); - slots = (ngx_slab_page_t *) p; n = ngx_pagesize_shift - pool->min_shift; for (i = 0; i < n; i++) { @@ -108,25 +122,25 @@ ngx_slab_init(ngx_slab_pool_t *pool) pages = (ngx_uint_t) (size / (ngx_pagesize + sizeof(ngx_slab_page_t))); - ngx_memzero(p, pages * sizeof(ngx_slab_page_t)); + pool->pages = (ngx_slab_page_t *) p; + ngx_memzero(pool->pages, pages * sizeof(ngx_slab_page_t)); - pool->pages = (ngx_slab_page_t *) p; + page = pool->pages; pool->free.prev = 0; - pool->free.next = (ngx_slab_page_t *) p; + pool->free.next = page; - pool->pages->slab = pages; - pool->pages->next = &pool->free; - pool->pages->prev = (uintptr_t) &pool->free; + page->slab = pages; + page->next = &pool->free; + page->prev = (uintptr_t) &pool->free; - pool->start = (u_char *) - ngx_align_ptr((uintptr_t) p + pages * sizeof(ngx_slab_page_t), - ngx_pagesize); + pool->start = ngx_align_ptr(p + pages * sizeof(ngx_slab_page_t), + ngx_pagesize); m = pages - (pool->end - pool->start) / ngx_pagesize; if (m > 0) { pages -= m; - pool->pages->slab = pages; + page->slab = pages; } pool->last = pool->pages + pages; @@ -168,8 +182,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p page = ngx_slab_alloc_pages(pool, (size >> ngx_pagesize_shift) + ((size % ngx_pagesize) ? 1 : 0)); if (page) { - p = (page - pool->pages) << ngx_pagesize_shift; - p += (uintptr_t) pool->start; + p = ngx_slab_page_addr(pool, page); } else { p = 0; @@ -191,7 +204,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab alloc: %uz slot: %ui", size, slot); - slots = (ngx_slab_page_t *) ((u_char *) pool + sizeof(ngx_slab_pool_t)); + slots = ngx_slab_slots(pool); page = slots[slot].next; if (page->next != page) { @@ -199,8 +212,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p if (shift < ngx_slab_exact_shift) { do { - p = (page - pool->pages) << ngx_pagesize_shift; - bitmap = (uintptr_t *) (pool->start + p); + bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page); map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8); @@ -228,8 +240,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p } } - prev = (ngx_slab_page_t *) - (page->prev & ~NGX_SLAB_PAGE_MASK); + prev = ngx_slab_page_prev(page); prev->next = page->next; page->next->prev = page->prev; @@ -261,8 +272,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p page->slab |= m; if (page->slab == NGX_SLAB_BUSY) { - prev = (ngx_slab_page_t *) - (page->prev & ~NGX_SLAB_PAGE_MASK); + prev = ngx_slab_page_prev(page); prev->next = page->next; page->next->prev = page->prev; @@ -270,9 +280,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p page->prev = NGX_SLAB_EXACT; } - p = (page - pool->pages) << ngx_pagesize_shift; - p += i << shift; - p += (uintptr_t) pool->start; + p = ngx_slab_page_addr(pool, page) + (i << shift); goto done; } @@ -303,8 +311,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p page->slab |= m; if ((page->slab & NGX_SLAB_MAP_MASK) == mask) { - prev = (ngx_slab_page_t *) - (page->prev & ~NGX_SLAB_PAGE_MASK); + prev = ngx_slab_page_prev(page); prev->next = page->next; page->next->prev = page->prev; @@ -312,9 +319,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p page->prev = NGX_SLAB_BIG; } - p = (page - pool->pages) << ngx_pagesize_shift; - p += i << shift; - p += (uintptr_t) pool->start; + p = ngx_slab_page_addr(pool, page) + (i << shift); goto done; } @@ -330,8 +335,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p if (page) { if (shift < ngx_slab_exact_shift) { - p = (page - pool->pages) << ngx_pagesize_shift; - bitmap = (uintptr_t *) (pool->start + p); + bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page); s = 1 << shift; n = (1 << (ngx_pagesize_shift - shift)) / 8 / s; @@ -354,8 +358,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p slots[slot].next = page; - p = ((page - pool->pages) << ngx_pagesize_shift) + s * n; - p += (uintptr_t) pool->start; + p = ngx_slab_page_addr(pool, page) + s * n; goto done; @@ -367,8 +370,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p slots[slot].next = page; - p = (page - pool->pages) << ngx_pagesize_shift; - p += (uintptr_t) pool->start; + p = ngx_slab_page_addr(pool, page); goto done; @@ -380,8 +382,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p slots[slot].next = page; - p = (page - pool->pages) << ngx_pagesize_shift; - p += (uintptr_t) pool->start; + p = ngx_slab_page_addr(pool, page); goto done; } @@ -456,7 +457,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *po n = ((u_char *) p - pool->start) >> ngx_pagesize_shift; page = &pool->pages[n]; slab = page->slab; - type = page->prev & NGX_SLAB_PAGE_MASK; + type = ngx_slab_page_type(page); switch (type) { @@ -478,8 +479,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *po if (bitmap[n] & m) { if (page->next == NULL) { - slots = (ngx_slab_page_t *) - ((u_char *) pool + sizeof(ngx_slab_pool_t)); + slots = ngx_slab_slots(pool); slot = shift - pool->min_shift; page->next = slots[slot].next; @@ -528,8 +528,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *po if (slab & m) { if (slab == NGX_SLAB_BUSY) { - slots = (ngx_slab_page_t *) - ((u_char *) pool + sizeof(ngx_slab_pool_t)); + slots = ngx_slab_slots(pool); slot = ngx_slab_exact_shift - pool->min_shift; page->next = slots[slot].next; @@ -567,8 +566,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *po if (slab & m) { if (page->next == NULL) { - slots = (ngx_slab_page_t *) - ((u_char *) pool + sizeof(ngx_slab_pool_t)); + slots = ngx_slab_slots(pool); slot = shift - pool->min_shift; page->next = slots[slot].next; @@ -705,7 +703,6 @@ static void ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page, ngx_uint_t pages) { - ngx_uint_t type; ngx_slab_page_t *prev, *join; page->slab = pages--; @@ -715,7 +712,7 @@ ngx_slab_free_pages(ngx_slab_pool_t *poo } if (page->next) { - prev = (ngx_slab_page_t *) (page->prev & ~NGX_SLAB_PAGE_MASK); + prev = ngx_slab_page_prev(page); prev->next = page->next; page->next->prev = page->prev; } @@ -723,15 +720,14 @@ ngx_slab_free_pages(ngx_slab_pool_t *poo join = page + page->slab; if (join < pool->last) { - type = join->prev & NGX_SLAB_PAGE_MASK; - if (type == NGX_SLAB_PAGE) { + if (ngx_slab_page_type(join) == NGX_SLAB_PAGE) { if (join->next != NULL) { pages += join->slab; page->slab += join->slab; - prev = (ngx_slab_page_t *) (join->prev & ~NGX_SLAB_PAGE_MASK); + prev = ngx_slab_page_prev(join); prev->next = join->next; join->next->prev = join->prev; @@ -744,19 +740,18 @@ ngx_slab_free_pages(ngx_slab_pool_t *poo if (page > pool->pages) { join = page - 1; - type = join->prev & NGX_SLAB_PAGE_MASK; - if (type == NGX_SLAB_PAGE) { + if (ngx_slab_page_type(join) == NGX_SLAB_PAGE) { if (join->slab == NGX_SLAB_PAGE_FREE) { - join = (ngx_slab_page_t *) (join->prev & ~NGX_SLAB_PAGE_MASK); + join = ngx_slab_page_prev(join); } if (join->next != NULL) { pages += join->slab; join->slab += page->slab; - prev = (ngx_slab_page_t *) (join->prev & ~NGX_SLAB_PAGE_MASK); + prev = ngx_slab_page_prev(join); prev->next = join->next; join->next->prev = join->prev; From ru at nginx.com Wed Dec 7 19:27:31 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 07 Dec 2016 19:27:31 +0000 Subject: [nginx] Slab: added comment about list heads. Message-ID: details: http://hg.nginx.org/nginx/rev/ea12328518dc branches: changeset: 6824:ea12328518dc user: Ruslan Ermilov date: Wed Dec 07 22:25:37 2016 +0300 description: Slab: added comment about list heads. diffstat: src/core/ngx_slab.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (23 lines): diff -r 88c8c3d65184 -r ea12328518dc src/core/ngx_slab.c --- a/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 +++ b/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 @@ -113,6 +113,7 @@ ngx_slab_init(ngx_slab_pool_t *pool) n = ngx_pagesize_shift - pool->min_shift; for (i = 0; i < n; i++) { + /* only "next" is used in list head */ slots[i].slab = 0; slots[i].next = &slots[i]; slots[i].prev = 0; @@ -127,8 +128,10 @@ ngx_slab_init(ngx_slab_pool_t *pool) page = pool->pages; + /* only "next" is used in list head */ + pool->free.slab = 0; + pool->free.next = page; pool->free.prev = 0; - pool->free.next = page; page->slab = pages; page->next = &pool->free; From ru at nginx.com Wed Dec 7 19:27:57 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 07 Dec 2016 19:27:57 +0000 Subject: [nginx] Slab: fixed the number of pages calculation. Message-ID: details: http://hg.nginx.org/nginx/rev/f6beb55792de branches: changeset: 6825:f6beb55792de user: Ruslan Ermilov date: Wed Dec 07 22:25:37 2016 +0300 description: Slab: fixed the number of pages calculation. When estimating the number of pages, do not count memory for slots. In some cases this gives one extra usable memory page. diffstat: src/core/ngx_slab.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r ea12328518dc -r f6beb55792de src/core/ngx_slab.c --- a/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 +++ b/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 @@ -120,6 +120,7 @@ ngx_slab_init(ngx_slab_pool_t *pool) } p += n * sizeof(ngx_slab_page_t); + size -= n * sizeof(ngx_slab_page_t); pages = (ngx_uint_t) (size / (ngx_pagesize + sizeof(ngx_slab_page_t))); From ru at nginx.com Wed Dec 7 19:28:00 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 07 Dec 2016 19:28:00 +0000 Subject: [nginx] Slab: simplified allocation from slots. Message-ID: details: http://hg.nginx.org/nginx/rev/d0404c9a7675 branches: changeset: 6826:d0404c9a7675 user: Ruslan Ermilov date: Wed Dec 07 22:25:37 2016 +0300 description: Slab: simplified allocation from slots. Removed code that would cause an endless loop, and removed condition check that is always false. The first page in the slot list is guaranteed to satisfy an allocation. diffstat: src/core/ngx_slab.c | 150 ++++++++++++++++++++++----------------------------- 1 files changed, 66 insertions(+), 84 deletions(-) diffs (193 lines): diff -r f6beb55792de -r d0404c9a7675 src/core/ngx_slab.c --- a/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 +++ b/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 @@ -215,84 +215,71 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p if (shift < ngx_slab_exact_shift) { - do { - bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page); - - map = (1 << (ngx_pagesize_shift - shift)) - / (sizeof(uintptr_t) * 8); - - for (n = 0; n < map; n++) { - - if (bitmap[n] != NGX_SLAB_BUSY) { - - for (m = 1, i = 0; m; m <<= 1, i++) { - if (bitmap[n] & m) { - continue; - } - - bitmap[n] |= m; - - i = ((n * sizeof(uintptr_t) * 8) << shift) - + (i << shift); - - if (bitmap[n] == NGX_SLAB_BUSY) { - for (n = n + 1; n < map; n++) { - if (bitmap[n] != NGX_SLAB_BUSY) { - p = (uintptr_t) bitmap + i; + bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page); - goto done; - } - } - - prev = ngx_slab_page_prev(page); - prev->next = page->next; - page->next->prev = page->prev; - - page->next = NULL; - page->prev = NGX_SLAB_SMALL; - } + map = (1 << (ngx_pagesize_shift - shift)) + / (sizeof(uintptr_t) * 8); - p = (uintptr_t) bitmap + i; - - goto done; - } - } - } + for (n = 0; n < map; n++) { - page = page->next; - - } while (page); - - } else if (shift == ngx_slab_exact_shift) { - - do { - if (page->slab != NGX_SLAB_BUSY) { + if (bitmap[n] != NGX_SLAB_BUSY) { for (m = 1, i = 0; m; m <<= 1, i++) { - if (page->slab & m) { + if (bitmap[n] & m) { continue; } - page->slab |= m; + bitmap[n] |= m; - if (page->slab == NGX_SLAB_BUSY) { + i = ((n * sizeof(uintptr_t) * 8) << shift) + + (i << shift); + + if (bitmap[n] == NGX_SLAB_BUSY) { + for (n = n + 1; n < map; n++) { + if (bitmap[n] != NGX_SLAB_BUSY) { + p = (uintptr_t) bitmap + i; + + goto done; + } + } + prev = ngx_slab_page_prev(page); prev->next = page->next; page->next->prev = page->prev; page->next = NULL; - page->prev = NGX_SLAB_EXACT; + page->prev = NGX_SLAB_SMALL; } - p = ngx_slab_page_addr(pool, page) + (i << shift); + p = (uintptr_t) bitmap + i; goto done; } } + } - page = page->next; + } else if (shift == ngx_slab_exact_shift) { - } while (page); + for (m = 1, i = 0; m; m <<= 1, i++) { + if (page->slab & m) { + continue; + } + + page->slab |= m; + + if (page->slab == NGX_SLAB_BUSY) { + prev = ngx_slab_page_prev(page); + prev->next = page->next; + page->next->prev = page->prev; + + page->next = NULL; + page->prev = NGX_SLAB_EXACT; + } + + p = ngx_slab_page_addr(pool, page) + (i << shift); + + goto done; + } } else { /* shift > ngx_slab_exact_shift */ @@ -301,38 +288,33 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p n = ((uintptr_t) 1 << n) - 1; mask = n << NGX_SLAB_MAP_SHIFT; - do { - if ((page->slab & NGX_SLAB_MAP_MASK) != mask) { - - for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0; - m & mask; - m <<= 1, i++) - { - if (page->slab & m) { - continue; - } - - page->slab |= m; - - if ((page->slab & NGX_SLAB_MAP_MASK) == mask) { - prev = ngx_slab_page_prev(page); - prev->next = page->next; - page->next->prev = page->prev; - - page->next = NULL; - page->prev = NGX_SLAB_BIG; - } - - p = ngx_slab_page_addr(pool, page) + (i << shift); - - goto done; - } + for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0; + m & mask; + m <<= 1, i++) + { + if (page->slab & m) { + continue; } - page = page->next; + page->slab |= m; - } while (page); + if ((page->slab & NGX_SLAB_MAP_MASK) == mask) { + prev = ngx_slab_page_prev(page); + prev->next = page->next; + page->next->prev = page->prev; + + page->next = NULL; + page->prev = NGX_SLAB_BIG; + } + + p = ngx_slab_page_addr(pool, page) + (i << shift); + + goto done; + } } + + ngx_slab_error(pool, NGX_LOG_ALERT, "ngx_slab_alloc(): page is busy"); + ngx_debug_point(); } page = ngx_slab_alloc_pages(pool, 1); From ru at nginx.com Wed Dec 7 19:28:07 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 07 Dec 2016 19:28:07 +0000 Subject: [nginx] Slab: simplified some math. Message-ID: details: http://hg.nginx.org/nginx/rev/0e61510c56c4 branches: changeset: 6827:0e61510c56c4 user: Ruslan Ermilov date: Wed Dec 07 22:25:37 2016 +0300 description: Slab: simplified some math. No functional changes. diffstat: src/core/ngx_slab.c | 29 ++++++++++++----------------- 1 files changed, 12 insertions(+), 17 deletions(-) diffs (94 lines): diff -r d0404c9a7675 -r 0e61510c56c4 src/core/ngx_slab.c --- a/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 +++ b/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 @@ -217,8 +217,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page); - map = (1 << (ngx_pagesize_shift - shift)) - / (sizeof(uintptr_t) * 8); + map = (ngx_pagesize >> shift) / (sizeof(uintptr_t) * 8); for (n = 0; n < map; n++) { @@ -231,8 +230,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p bitmap[n] |= m; - i = ((n * sizeof(uintptr_t) * 8) << shift) - + (i << shift); + i = (n * sizeof(uintptr_t) * 8 + i) << shift; if (bitmap[n] == NGX_SLAB_BUSY) { for (n = n + 1; n < map; n++) { @@ -283,10 +281,8 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p } else { /* shift > ngx_slab_exact_shift */ - n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK); - n = 1 << n; - n = ((uintptr_t) 1 << n) - 1; - mask = n << NGX_SLAB_MAP_SHIFT; + mask = ((uintptr_t) 1 << (ngx_pagesize >> shift)) - 1; + mask <<= NGX_SLAB_MAP_SHIFT; for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0; m & mask; @@ -323,16 +319,15 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p if (shift < ngx_slab_exact_shift) { bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page); - s = 1 << shift; - n = (1 << (ngx_pagesize_shift - shift)) / 8 / s; + n = (ngx_pagesize >> shift) / ((1 << shift) * 8); if (n == 0) { n = 1; } - bitmap[0] = (2 << n) - 1; + bitmap[0] = ((uintptr_t) 2 << n) - 1; - map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8); + map = (ngx_pagesize >> shift) / (sizeof(uintptr_t) * 8); for (i = 1; i < map; i++) { bitmap[i] = 0; @@ -344,7 +339,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p slots[slot].next = page; - p = ngx_slab_page_addr(pool, page) + s * n; + p = ngx_slab_page_addr(pool, page) + (n << shift); goto done; @@ -457,8 +452,8 @@ ngx_slab_free_locked(ngx_slab_pool_t *po } n = ((uintptr_t) p & (ngx_pagesize - 1)) >> shift; - m = (uintptr_t) 1 << (n & (sizeof(uintptr_t) * 8 - 1)); - n /= (sizeof(uintptr_t) * 8); + m = (uintptr_t) 1 << (n % (sizeof(uintptr_t) * 8)); + n /= sizeof(uintptr_t) * 8; bitmap = (uintptr_t *) ((uintptr_t) p & ~((uintptr_t) ngx_pagesize - 1)); @@ -477,7 +472,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *po bitmap[n] &= ~m; - n = (1 << (ngx_pagesize_shift - shift)) / 8 / (1 << shift); + n = (ngx_pagesize >> shift) / ((1 << shift) * 8); if (n == 0) { n = 1; @@ -487,7 +482,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *po goto done; } - map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8); + map = (ngx_pagesize >> shift) / (sizeof(uintptr_t) * 8); for (n = 1; n < map; n++) { if (bitmap[n]) { From ru at nginx.com Wed Dec 7 19:28:11 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 07 Dec 2016 19:28:11 +0000 Subject: [nginx] Slab: slots statistics. Message-ID: details: http://hg.nginx.org/nginx/rev/99770a5ea14f branches: changeset: 6828:99770a5ea14f user: Ruslan Ermilov date: Wed Dec 07 22:25:37 2016 +0300 description: Slab: slots statistics. For each slot, the number of total and used entries, as well as the number of allocation requests and failures, are tracked. diffstat: src/core/ngx_slab.c | 57 ++++++++++++++++++++++++++++++++++++++++++---------- src/core/ngx_slab.h | 11 ++++++++++ 2 files changed, 57 insertions(+), 11 deletions(-) diffs (236 lines): diff -r 0e61510c56c4 -r 99770a5ea14f src/core/ngx_slab.c --- a/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 +++ b/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 @@ -120,7 +120,13 @@ ngx_slab_init(ngx_slab_pool_t *pool) } p += n * sizeof(ngx_slab_page_t); - size -= n * sizeof(ngx_slab_page_t); + + pool->stats = (ngx_slab_stat_t *) p; + ngx_memzero(pool->stats, n * sizeof(ngx_slab_stat_t)); + + p += n * sizeof(ngx_slab_stat_t); + + size -= n * (sizeof(ngx_slab_page_t) + sizeof(ngx_slab_stat_t)); pages = (ngx_uint_t) (size / (ngx_pagesize + sizeof(ngx_slab_page_t))); @@ -205,6 +211,8 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p slot = 0; } + pool->stats[slot].reqs++; + ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab alloc: %uz slot: %ui", size, slot); @@ -232,11 +240,13 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p i = (n * sizeof(uintptr_t) * 8 + i) << shift; + p = (uintptr_t) bitmap + i; + + pool->stats[slot].used++; + if (bitmap[n] == NGX_SLAB_BUSY) { for (n = n + 1; n < map; n++) { if (bitmap[n] != NGX_SLAB_BUSY) { - p = (uintptr_t) bitmap + i; - goto done; } } @@ -249,8 +259,6 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p page->prev = NGX_SLAB_SMALL; } - p = (uintptr_t) bitmap + i; - goto done; } } @@ -276,6 +284,8 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p p = ngx_slab_page_addr(pool, page) + (i << shift); + pool->stats[slot].used++; + goto done; } @@ -305,6 +315,8 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p p = ngx_slab_page_addr(pool, page) + (i << shift); + pool->stats[slot].used++; + goto done; } } @@ -339,8 +351,12 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p slots[slot].next = page; + pool->stats[slot].total += (ngx_pagesize >> shift) - n; + p = ngx_slab_page_addr(pool, page) + (n << shift); + pool->stats[slot].used++; + goto done; } else if (shift == ngx_slab_exact_shift) { @@ -351,8 +367,12 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p slots[slot].next = page; + pool->stats[slot].total += sizeof(uintptr_t) * 8; + p = ngx_slab_page_addr(pool, page); + pool->stats[slot].used++; + goto done; } else { /* shift > ngx_slab_exact_shift */ @@ -363,14 +383,20 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p slots[slot].next = page; + pool->stats[slot].total += ngx_pagesize >> shift; + p = ngx_slab_page_addr(pool, page); + pool->stats[slot].used++; + goto done; } } p = 0; + pool->stats[slot].fails++; + done: ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, @@ -425,7 +451,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *po { size_t size; uintptr_t slab, m, *bitmap; - ngx_uint_t n, type, slot, shift, map; + ngx_uint_t i, n, type, slot, shift, map; ngx_slab_page_t *slots, *page; ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p); @@ -458,10 +484,10 @@ ngx_slab_free_locked(ngx_slab_pool_t *po ((uintptr_t) p & ~((uintptr_t) ngx_pagesize - 1)); if (bitmap[n] & m) { + slot = shift - pool->min_shift; if (page->next == NULL) { slots = ngx_slab_slots(pool); - slot = shift - pool->min_shift; page->next = slots[slot].next; slots[slot].next = page; @@ -484,14 +510,16 @@ ngx_slab_free_locked(ngx_slab_pool_t *po map = (ngx_pagesize >> shift) / (sizeof(uintptr_t) * 8); - for (n = 1; n < map; n++) { - if (bitmap[n]) { + for (i = 1; i < map; i++) { + if (bitmap[i]) { goto done; } } ngx_slab_free_pages(pool, page, 1); + pool->stats[slot].total -= (ngx_pagesize >> shift) - n; + goto done; } @@ -508,9 +536,10 @@ ngx_slab_free_locked(ngx_slab_pool_t *po } if (slab & m) { + slot = ngx_slab_exact_shift - pool->min_shift; + if (slab == NGX_SLAB_BUSY) { slots = ngx_slab_slots(pool); - slot = ngx_slab_exact_shift - pool->min_shift; page->next = slots[slot].next; slots[slot].next = page; @@ -527,6 +556,8 @@ ngx_slab_free_locked(ngx_slab_pool_t *po ngx_slab_free_pages(pool, page, 1); + pool->stats[slot].total -= sizeof(uintptr_t) * 8; + goto done; } @@ -545,10 +576,10 @@ ngx_slab_free_locked(ngx_slab_pool_t *po + NGX_SLAB_MAP_SHIFT); if (slab & m) { + slot = shift - pool->min_shift; if (page->next == NULL) { slots = ngx_slab_slots(pool); - slot = shift - pool->min_shift; page->next = slots[slot].next; slots[slot].next = page; @@ -565,6 +596,8 @@ ngx_slab_free_locked(ngx_slab_pool_t *po ngx_slab_free_pages(pool, page, 1); + pool->stats[slot].total -= ngx_pagesize >> shift; + goto done; } @@ -604,6 +637,8 @@ ngx_slab_free_locked(ngx_slab_pool_t *po done: + pool->stats[slot].used--; + ngx_slab_junk(p, size); return; diff -r 0e61510c56c4 -r 99770a5ea14f src/core/ngx_slab.h --- a/src/core/ngx_slab.h Wed Dec 07 22:25:37 2016 +0300 +++ b/src/core/ngx_slab.h Wed Dec 07 22:25:37 2016 +0300 @@ -23,6 +23,15 @@ struct ngx_slab_page_s { typedef struct { + ngx_uint_t total; + ngx_uint_t used; + + ngx_uint_t reqs; + ngx_uint_t fails; +} ngx_slab_stat_t; + + +typedef struct { ngx_shmtx_sh_t lock; size_t min_size; @@ -32,6 +41,8 @@ typedef struct { ngx_slab_page_t *last; ngx_slab_page_t free; + ngx_slab_stat_t *stats; + u_char *start; u_char *end; From ru at nginx.com Wed Dec 7 19:28:13 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 07 Dec 2016 19:28:13 +0000 Subject: [nginx] Slab: free pages statistics. Message-ID: details: http://hg.nginx.org/nginx/rev/6e757036e588 branches: changeset: 6829:6e757036e588 user: Ruslan Ermilov date: Wed Dec 07 22:25:37 2016 +0300 description: Slab: free pages statistics. diffstat: src/core/ngx_slab.c | 5 +++++ src/core/ngx_slab.h | 1 + 2 files changed, 6 insertions(+), 0 deletions(-) diffs (40 lines): diff -r 99770a5ea14f -r 6e757036e588 src/core/ngx_slab.c --- a/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 +++ b/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 @@ -154,6 +154,7 @@ ngx_slab_init(ngx_slab_pool_t *pool) } pool->last = pool->pages + pages; + pool->pfree = pages; pool->log_nomem = 1; pool->log_ctx = &pool->zero; @@ -691,6 +692,8 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *po page->next = NULL; page->prev = NGX_SLAB_PAGE; + pool->pfree -= pages; + if (--pages == 0) { return page; } @@ -721,6 +724,8 @@ ngx_slab_free_pages(ngx_slab_pool_t *poo { ngx_slab_page_t *prev, *join; + pool->pfree += pages; + page->slab = pages--; if (pages) { diff -r 99770a5ea14f -r 6e757036e588 src/core/ngx_slab.h --- a/src/core/ngx_slab.h Wed Dec 07 22:25:37 2016 +0300 +++ b/src/core/ngx_slab.h Wed Dec 07 22:25:37 2016 +0300 @@ -42,6 +42,7 @@ typedef struct { ngx_slab_page_t free; ngx_slab_stat_t *stats; + ngx_uint_t pfree; u_char *start; u_char *end; From igor at sysoev.ru Wed Dec 7 20:44:21 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 07 Dec 2016 20:44:21 +0000 Subject: [njs] A user defined object method called as constructor did not Message-ID: details: http://hg.nginx.org/njs/rev/2380d725ec7b branches: changeset: 276:2380d725ec7b user: Igor Sysoev date: Wed Dec 07 19:34:48 2016 +0300 description: A user defined object method called as constructor did not create correct prototype links in created objects. Thanks to ??? (Hong Zhi Dao). diffstat: njs/njs_function.c | 7 +- njs/njs_function.h | 3 +- njs/njs_vm.c | 177 ++++++++++++++++++---------------------------- njs/test/njs_unit_test.c | 4 + 4 files changed, 82 insertions(+), 109 deletions(-) diffs (298 lines): diff -r 56d6fc12dc31 -r 2380d725ec7b njs/njs_function.c --- a/njs/njs_function.c Wed Dec 07 15:02:00 2016 +0300 +++ b/njs/njs_function.c Wed Dec 07 19:34:48 2016 +0300 @@ -111,12 +111,14 @@ njs_function_native_frame(njs_vm_t *vm, bound = function->bound; if (bound == NULL) { + /* GC: njs_retain(this); */ *value++ = *this; } else { n = function->args_offset; do { + /* GC: njs_retain(bound); */ *value++ = *bound++; n--; } while (n != 0); @@ -134,8 +136,9 @@ njs_function_native_frame(njs_vm_t *vm, nxt_noinline njs_ret_t -njs_function_frame(njs_vm_t *vm, njs_function_t *function, njs_value_t *this, - njs_value_t *args, nxt_uint_t nargs, nxt_bool_t ctor) +njs_function_frame(njs_vm_t *vm, njs_function_t *function, + const njs_value_t *this, njs_value_t *args, nxt_uint_t nargs, + nxt_bool_t ctor) { size_t size; nxt_uint_t n, max_args; diff -r 56d6fc12dc31 -r 2380d725ec7b njs/njs_function.h --- a/njs/njs_function.h Wed Dec 07 15:02:00 2016 +0300 +++ b/njs/njs_function.h Wed Dec 07 19:34:48 2016 +0300 @@ -138,7 +138,8 @@ njs_ret_t njs_function_native_frame(njs_ const njs_value_t *this, njs_value_t *args, nxt_uint_t nargs, size_t reserve, nxt_bool_t ctor); njs_ret_t njs_function_frame(njs_vm_t *vm, njs_function_t *function, - njs_value_t *this, njs_value_t *args, nxt_uint_t nargs, nxt_bool_t ctor); + const njs_value_t *this, njs_value_t *args, nxt_uint_t nargs, + nxt_bool_t ctor); njs_ret_t njs_function_call(njs_vm_t *vm, njs_index_t retval, size_t advance); extern const njs_object_init_t njs_function_constructor_init; diff -r 56d6fc12dc31 -r 2380d725ec7b njs/njs_vm.c --- a/njs/njs_vm.c Wed Dec 07 15:02:00 2016 +0300 +++ b/njs/njs_vm.c Wed Dec 07 19:34:48 2016 +0300 @@ -82,9 +82,9 @@ static nxt_noinline njs_ret_t njs_values const njs_value_t *val2); static nxt_noinline njs_ret_t njs_values_compare(const njs_value_t *val1, const njs_value_t *val2); +static njs_ret_t njs_function_frame_create(njs_vm_t *vm, njs_value_t *value, + const njs_value_t *this, uintptr_t nargs, nxt_bool_t ctor); static njs_object_t *njs_function_new_object(njs_vm_t *vm, njs_value_t *value); -static njs_ret_t njs_vmcode_method_call(njs_vm_t *vm, njs_value_t *object, - njs_value_t *value); static njs_ret_t njs_vmcode_continuation(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2); static njs_native_frame_t * @@ -2127,61 +2127,58 @@ njs_ret_t njs_vmcode_function_frame(njs_vm_t *vm, njs_value_t *value, njs_value_t *nargs) { njs_ret_t ret; - nxt_bool_t ctor; - njs_value_t val, *this; - njs_object_t *object; - njs_function_t *function; - njs_vmcode_function_frame_t *func; + njs_vmcode_function_frame_t *function; + + function = (njs_vmcode_function_frame_t *) vm->current; + + /* TODO: external object instead of void this. */ + + ret = njs_function_frame_create(vm, value, &njs_value_void, + (uintptr_t) nargs, function->code.ctor); + + if (nxt_fast_path(ret == NXT_OK)) { + return sizeof(njs_vmcode_function_frame_t); + } + + return ret; +} + + +static njs_ret_t +njs_function_frame_create(njs_vm_t *vm, njs_value_t *value, + const njs_value_t *this, uintptr_t nargs, nxt_bool_t ctor) +{ + njs_value_t val; + njs_object_t *object; + njs_function_t *function; if (nxt_fast_path(njs_is_function(value))) { - func = (njs_vmcode_function_frame_t *) vm->current; - ctor = func->code.ctor; - function = value->data.u.function; - if (function->native) { - if (ctor && !function->ctor) { - goto fail; + if (!function->native) { + + if (ctor) { + object = njs_function_new_object(vm, value); + if (nxt_slow_path(object == NULL)) { + return NXT_ERROR; + } + + val.data.u.object = object; + val.type = NJS_OBJECT; + val.data.truth = 1; + this = &val; } - ret = njs_function_native_frame(vm, function, &njs_value_void, - NULL, (uintptr_t) nargs, 0, ctor); - - if (nxt_fast_path(ret == NXT_OK)) { - return sizeof(njs_vmcode_function_frame_t); - } - - return ret; + return njs_function_frame(vm, function, this, NULL, nargs, ctor); } - if (ctor) { - object = njs_function_new_object(vm, value); - if (nxt_slow_path(object == NULL)) { - return NXT_ERROR; - } - - val.data.u.object = object; - val.type = NJS_OBJECT; - val.data.truth = 1; - this = &val; - - } else { - this = (njs_value_t *) &njs_value_void; + if (!ctor || function->ctor) { + return njs_function_native_frame(vm, function, this, NULL, + nargs, 0, ctor); } - - ret = njs_function_frame(vm, function, this, NULL, (uintptr_t) nargs, - ctor); - - if (nxt_fast_path(ret == NXT_OK)) { - return sizeof(njs_vmcode_function_frame_t); - } - - return ret; } -fail: - vm->exception = &njs_exception_type_error; return NXT_ERROR; @@ -2237,6 +2234,8 @@ njs_vmcode_method_frame(njs_vm_t *vm, nj njs_property_query_t pq; njs_vmcode_method_frame_t *method; + method = (njs_vmcode_method_frame_t *) vm->current; + pq.query = NJS_PROPERTY_QUERY_GET; switch (njs_property_query(vm, &pq, object, name)) { @@ -2244,19 +2243,15 @@ njs_vmcode_method_frame(njs_vm_t *vm, nj case NXT_OK: prop = pq.lhq.value; - if (njs_is_function(&prop->value)) { - return njs_vmcode_method_call(vm, object, &prop->value); - } - + ret = njs_function_frame_create(vm, &prop->value, object, method->nargs, + method->code.ctor); break; case NJS_ARRAY_VALUE: value = pq.lhq.value; - if (njs_is_function(value)) { - return njs_vmcode_method_call(vm, object, value); - } - + ret = njs_function_frame_create(vm, value, object, method->nargs, + method->code.ctor); break; case NJS_EXTERNAL_VALUE: @@ -2264,67 +2259,37 @@ njs_vmcode_method_frame(njs_vm_t *vm, nj ret = nxt_lvlhsh_find(&ext->hash, &pq.lhq); - if (ret == NXT_OK) { - method = (njs_vmcode_method_frame_t *) vm->current; - ext = pq.lhq.value; - - if (ext->type == NJS_EXTERN_METHOD) { - this.data.u.data = vm->external[ext->object]; - - ret = njs_function_native_frame(vm, ext->function, &this, NULL, - method->nargs, 0, - method->code.ctor); - - if (nxt_fast_path(ret == NXT_OK)) { - return sizeof(njs_vmcode_method_frame_t); - } - - return ret; - } + if (nxt_slow_path(ret != NXT_OK)) { + goto type_error; } + + ext = pq.lhq.value; + + if (nxt_slow_path(ext->type != NJS_EXTERN_METHOD)) { + goto type_error; + } + + this.data.u.data = vm->external[ext->object]; + + ret = njs_function_native_frame(vm, ext->function, &this, NULL, + method->nargs, 0, method->code.ctor); + break; + + default: + goto type_error; } - vm->exception = &njs_exception_type_error; - - return NXT_ERROR; -} - - -static njs_ret_t -njs_vmcode_method_call(njs_vm_t *vm, njs_value_t *object, njs_value_t *value) -{ - njs_ret_t ret; - njs_function_t *function; - njs_vmcode_method_frame_t *method; - - method = (njs_vmcode_method_frame_t *) vm->current; - function = value->data.u.function; - - if (!function->native) { - ret = njs_function_frame(vm, function, object, NULL, method->nargs, - method->code.ctor); - - if (nxt_fast_path(ret == NXT_OK)) { - return sizeof(njs_vmcode_method_frame_t); - } - - return ret; - } - - if (method->code.ctor) { - vm->exception = &njs_exception_type_error; - return NXT_ERROR; - } - - ret = njs_function_native_frame(vm, function, object, NULL, method->nargs, - 0, 0); - if (nxt_fast_path(ret == NXT_OK)) { - njs_retain(object); return sizeof(njs_vmcode_method_frame_t); } return ret; + +type_error: + + vm->exception = &njs_exception_type_error; + + return NXT_ERROR; } diff -r 56d6fc12dc31 -r 2380d725ec7b njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Dec 07 15:02:00 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Dec 07 19:34:48 2016 +0300 @@ -4235,6 +4235,10 @@ static njs_unit_test_t njs_test[] = "o.__proto__ === F.prototype"), nxt_string("true") }, + { nxt_string("f = { F: function(){} }; o = new f.F();" + "o.__proto__ === f.F.prototype"), + nxt_string("true") }, + { nxt_string("function F(){}; typeof F.prototype"), nxt_string("object") }, From joel.cunningham at me.com Wed Dec 7 21:50:32 2016 From: joel.cunningham at me.com (Joel Cunningham) Date: Wed, 07 Dec 2016 15:50:32 -0600 Subject: [PATCH] Fix drain logic for small number of connections Message-ID: <691A2C9B-3561-4223-895B-EDBA1884743A@me.com> Hi, I run NGINX in an embedded environment with limited resources. We have NGINX configured with a small number of maximum connections (worker_connections is 16). I?ve found the ngx_drain_connection() logic uses a hard-coded value to limit the number of reaped reusable connections. This works fine with the default 512, but is too aggressive for small number of connections and ends up reaping all reusable connections. These include new connections just accepted on the previous event loop cycle (which had not yet had a chance to receive a request) at the head of the list. The below patch switches to the minimum of 32 or 1/4 of the number of connections. This should be less aggressive, even when the number of connections is slightly larger than 32, e.g. 48 or 64. Joel # HG changeset patch # User Joel Cunningham # Date 1481145862 21600 # Wed Dec 07 15:24:22 2016 -0600 # Node ID b103dddcee7322522651f9aca764d499d5822ac1 # Parent 75dbab4ea930bc73cca98d183c2f556eb5125462 Fix drain logic for small number of connections This commit fixes the ngx_drain_connections logic when maximum number of connections are small (16/32/64). Using a hardcoded value of 32 when the number of connections is small is overlly aggressive and will result in repeaing the entire (or large portion of) the reusable_connections_queue, which includes at the tail newly accepted connections that have not received a request yet The logic is updated to use the minimum of 1/4 the number of connections or 32, which ever is smaller diff -r 75dbab4ea930 -r b103dddcee73 src/core/ngx_connection.c --- a/src/core/ngx_connection.c Mon Nov 21 16:03:42 2016 +0300 +++ b/src/core/ngx_connection.c Wed Dec 07 15:24:22 2016 -0600 @@ -1232,7 +1232,7 @@ ngx_queue_t *q; ngx_connection_t *c; - for (i = 0; i < 32; i++) { + for (i = 0; i < ngx_min(32, ngx_cycle->connection_n / 4); i++) { if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) { break; } From ru at nginx.com Thu Dec 8 14:26:27 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 08 Dec 2016 14:26:27 +0000 Subject: [nginx] Slab: commented bitmap initialization for small allocations. Message-ID: details: http://hg.nginx.org/nginx/rev/6eed5ed31e22 branches: changeset: 6830:6eed5ed31e22 user: Ruslan Ermilov date: Thu Dec 08 17:22:07 2016 +0300 description: Slab: commented bitmap initialization for small allocations. diffstat: src/core/ngx_slab.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 6e757036e588 -r 6eed5ed31e22 src/core/ngx_slab.c --- a/src/core/ngx_slab.c Wed Dec 07 22:25:37 2016 +0300 +++ b/src/core/ngx_slab.c Thu Dec 08 17:22:07 2016 +0300 @@ -338,6 +338,7 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p n = 1; } + /* "n" elements for bitmap, plus one requested */ bitmap[0] = ((uintptr_t) 2 << n) - 1; map = (ngx_pagesize >> shift) / (sizeof(uintptr_t) * 8); From igor at sysoev.ru Thu Dec 8 14:46:34 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 08 Dec 2016 14:46:34 +0000 Subject: [njs] Array and object literals did not support assignment expressions. Message-ID: details: http://hg.nginx.org/njs/rev/0315d62a78c2 branches: changeset: 277:0315d62a78c2 user: Igor Sysoev date: Thu Dec 08 17:15:54 2016 +0300 description: Array and object literals did not support assignment expressions. Thanks to ??? (Hong Zhi Dao). diffstat: njs/njs_parser.c | 4 ++-- njs/njs_parser.h | 2 +- njs/njs_parser_expression.c | 24 +++++++++++++++++------- njs/test/njs_unit_test.c | 6 ++++++ 4 files changed, 26 insertions(+), 10 deletions(-) diffs (135 lines): diff -r 2380d725ec7b -r 0315d62a78c2 njs/njs_parser.c --- a/njs/njs_parser.c Wed Dec 07 19:34:48 2016 +0300 +++ b/njs/njs_parser.c Thu Dec 08 17:15:54 2016 +0300 @@ -1829,7 +1829,7 @@ njs_parser_object(njs_vm_t *vm, njs_pars return token; } - token = njs_parser_conditional_expression(vm, parser, token); + token = njs_parser_assignment_expression(vm, parser, token); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } @@ -1924,7 +1924,7 @@ njs_parser_array(njs_vm_t *vm, njs_parse propref->right = node; parser->code_size += sizeof(njs_vmcode_3addr_t); - token = njs_parser_conditional_expression(vm, parser, token); + token = njs_parser_assignment_expression(vm, parser, token); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } diff -r 2380d725ec7b -r 0315d62a78c2 njs/njs_parser.h --- a/njs/njs_parser.h Wed Dec 07 19:34:48 2016 +0300 +++ b/njs/njs_parser.h Thu Dec 08 17:15:54 2016 +0300 @@ -334,7 +334,7 @@ njs_token_t njs_parser_expression(njs_vm njs_token_t token); njs_token_t njs_parser_var_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); -njs_token_t njs_parser_conditional_expression(njs_vm_t *vm, +njs_token_t njs_parser_assignment_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); njs_token_t njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); diff -r 2380d725ec7b -r 0315d62a78c2 njs/njs_parser_expression.c --- a/njs/njs_parser_expression.c Wed Dec 07 19:34:48 2016 +0300 +++ b/njs/njs_parser_expression.c Thu Dec 08 17:15:54 2016 +0300 @@ -55,9 +55,11 @@ struct njs_parser_expression_s { }; -static njs_token_t njs_parser_assignment_expression(njs_vm_t *vm, +static njs_token_t njs_parser_any_expression(njs_vm_t *vm, njs_parser_t *parser, const njs_parser_expression_t *expr, njs_token_t token); +static njs_token_t njs_parser_conditional_expression(njs_vm_t *vm, + njs_parser_t *parser, njs_token_t token); static njs_token_t njs_parser_binary_expression(njs_vm_t *vm, njs_parser_t *parser, const njs_parser_expression_t *expr, njs_token_t token); @@ -227,7 +229,7 @@ static const njs_parser_expression_t static const njs_parser_expression_t njs_parser_comma_expression = { - njs_parser_assignment_expression, + njs_parser_any_expression, NULL, 1, { { NJS_TOKEN_COMMA, NULL, 0 }, @@ -346,8 +348,16 @@ njs_parser_var_expression(njs_vm_t *vm, static njs_token_t +njs_parser_any_expression(njs_vm_t *vm, njs_parser_t *parser, + const njs_parser_expression_t *expr, njs_token_t token) +{ + return njs_parser_assignment_expression(vm, parser, token); +} + + +njs_token_t njs_parser_assignment_expression(njs_vm_t *vm, njs_parser_t *parser, - const njs_parser_expression_t *expr, njs_token_t token) + njs_token_t token) { size_t size; njs_parser_node_t *node, *pending; @@ -475,7 +485,7 @@ njs_parser_assignment_expression(njs_vm_ return token; } - token = njs_parser_assignment_expression(vm, parser, NULL, token); + token = njs_parser_assignment_expression(vm, parser, token); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } @@ -568,7 +578,7 @@ njs_parser_conditional_expression(njs_vm cond->right = node; node->token = NJS_TOKEN_BRANCHING; - token = njs_parser_assignment_expression(vm, parser, NULL, token); + token = njs_parser_assignment_expression(vm, parser, token); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } @@ -585,7 +595,7 @@ njs_parser_conditional_expression(njs_vm return token; } - token = njs_parser_assignment_expression(vm, parser, NULL, token); + token = njs_parser_assignment_expression(vm, parser, token); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } @@ -1210,7 +1220,7 @@ njs_parser_arguments(njs_vm_t *vm, njs_p break; } - token = njs_parser_assignment_expression(vm, parser, NULL, token); + token = njs_parser_assignment_expression(vm, parser, token); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } diff -r 2380d725ec7b -r 0315d62a78c2 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Dec 07 19:34:48 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Dec 08 17:15:54 2016 +0300 @@ -1906,6 +1906,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("a = 1; a.b++; a.b"), nxt_string("TypeError") }, + { nxt_string("var n = 1, o = { p: n += 1 }; o.p"), + nxt_string("2") }, + { nxt_string("a = {}; a.b = {}; a.b.c = 1; a.b['c']"), nxt_string("1") }, @@ -2073,6 +2076,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("a = [ 1, 2, 3 ]; a[0] + a[1] + a[2]"), nxt_string("6") }, + { nxt_string("var n = 1, a = [ n += 1 ]; a"), + nxt_string("2") }, + { nxt_string("a = [ 1, 2; 3 ]; a[0] + a[1] + a[2]"), nxt_string("SyntaxError: Unexpected token \";\" in 1") }, From vbart at nginx.com Thu Dec 8 16:30:32 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 08 Dec 2016 16:30:32 +0000 Subject: [njs] NXT_DEBUG_MEMORY macro. Message-ID: details: http://hg.nginx.org/njs/rev/af66e460d7a0 branches: changeset: 278:af66e460d7a0 user: Valentin Bartenev date: Thu Dec 08 19:29:40 2016 +0300 description: NXT_DEBUG_MEMORY macro. It allows to turn off accumulation of small pool allocations into a big preallocated chunk of memory. This is useful for debugging memory access with sanitizer, since such accumulation can cover buffer overruns from being detected. diffstat: nxt/nxt_mem_cache_pool.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diffs (69 lines): diff -r 0315d62a78c2 -r af66e460d7a0 nxt/nxt_mem_cache_pool.c --- a/nxt/nxt_mem_cache_pool.c Thu Dec 08 17:15:54 2016 +0300 +++ b/nxt/nxt_mem_cache_pool.c Thu Dec 08 19:29:40 2016 +0300 @@ -124,12 +124,14 @@ struct nxt_mem_cache_pool_s { static nxt_uint_t nxt_mem_cache_shift(nxt_uint_t n); +#if !(NXT_DEBUG_MEMORY) static void *nxt_mem_cache_alloc_small(nxt_mem_cache_pool_t *pool, size_t size); static nxt_uint_t nxt_mem_cache_alloc_chunk(u_char *map, nxt_uint_t size); static nxt_mem_cache_page_t * nxt_mem_cache_alloc_page(nxt_mem_cache_pool_t *pool); static nxt_mem_cache_block_t * nxt_mem_cache_alloc_cluster(nxt_mem_cache_pool_t *pool); +#endif static void *nxt_mem_cache_alloc_large(nxt_mem_cache_pool_t *pool, size_t alignment, size_t size); static intptr_t nxt_mem_cache_rbtree_compare(nxt_rbtree_node_t *node1, @@ -302,10 +304,14 @@ nxt_mem_cache_alloc(nxt_mem_cache_pool_t pool->proto->trace(pool->trace, "mem cache alloc: %zd", size); } +#if !(NXT_DEBUG_MEMORY) + if (size <= pool->page_size) { return nxt_mem_cache_alloc_small(pool, size); } +#endif + return nxt_mem_cache_alloc_large(pool, NXT_MAX_ALIGNMENT, size); } @@ -337,6 +343,8 @@ nxt_mem_cache_align(nxt_mem_cache_pool_t if (nxt_fast_path((alignment - 1) & alignment) == 0) { +#if !(NXT_DEBUG_MEMORY) + if (size <= pool->page_size && alignment <= pool->page_alignment) { size = nxt_max(size, alignment); @@ -345,6 +353,8 @@ nxt_mem_cache_align(nxt_mem_cache_pool_t } } +#endif + return nxt_mem_cache_alloc_large(pool, alignment, size); } @@ -367,6 +377,8 @@ nxt_mem_cache_zalign(nxt_mem_cache_pool_ } +#if !(NXT_DEBUG_MEMORY) + static void * nxt_mem_cache_alloc_small(nxt_mem_cache_pool_t *pool, size_t size) { @@ -549,6 +561,8 @@ nxt_mem_cache_alloc_cluster(nxt_mem_cach return cluster; } +#endif + static void * nxt_mem_cache_alloc_large(nxt_mem_cache_pool_t *pool, size_t alignment, From igor at sysoev.ru Thu Dec 8 16:53:02 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 08 Dec 2016 16:53:02 +0000 Subject: [njs] Fixed building with CFLAGS=-DNXT_DEBUG_MEMORY=1 by some compilers. Message-ID: details: http://hg.nginx.org/njs/rev/6a60530c7b6b branches: changeset: 279:6a60530c7b6b user: Igor Sysoev date: Thu Dec 08 19:50:03 2016 +0300 description: Fixed building with CFLAGS=-DNXT_DEBUG_MEMORY=1 by some compilers. diffstat: nxt/nxt_mem_cache_pool.c | 26 +++++++++++++------------- 1 files changed, 13 insertions(+), 13 deletions(-) diffs (43 lines): diff -r af66e460d7a0 -r 6a60530c7b6b nxt/nxt_mem_cache_pool.c --- a/nxt/nxt_mem_cache_pool.c Thu Dec 08 19:29:40 2016 +0300 +++ b/nxt/nxt_mem_cache_pool.c Thu Dec 08 19:50:03 2016 +0300 @@ -284,19 +284,6 @@ nxt_mem_cache_pool_destroy(nxt_mem_cache } -nxt_inline u_char * -nxt_mem_cache_page_addr(nxt_mem_cache_pool_t *pool, nxt_mem_cache_page_t *page) -{ - nxt_mem_cache_block_t *block; - - block = (nxt_mem_cache_block_t *) - ((u_char *) page - page->number * sizeof(nxt_mem_cache_page_t) - - offsetof(nxt_mem_cache_block_t, pages)); - - return block->start + (page->number << pool->page_size_shift); -} - - void * nxt_mem_cache_alloc(nxt_mem_cache_pool_t *pool, size_t size) { @@ -379,6 +366,19 @@ nxt_mem_cache_zalign(nxt_mem_cache_pool_ #if !(NXT_DEBUG_MEMORY) +nxt_inline u_char * +nxt_mem_cache_page_addr(nxt_mem_cache_pool_t *pool, nxt_mem_cache_page_t *page) +{ + nxt_mem_cache_block_t *block; + + block = (nxt_mem_cache_block_t *) + ((u_char *) page - page->number * sizeof(nxt_mem_cache_page_t) + - offsetof(nxt_mem_cache_block_t, pages)); + + return block->start + (page->number << pool->page_size_shift); +} + + static void * nxt_mem_cache_alloc_small(nxt_mem_cache_pool_t *pool, size_t size) { From vbart at nginx.com Thu Dec 8 17:03:53 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 08 Dec 2016 17:03:53 +0000 Subject: [njs] Math.pow() method fix. Message-ID: details: http://hg.nginx.org/njs/rev/db0d8e2a4928 branches: changeset: 280:db0d8e2a4928 user: Valentin Bartenev date: Thu Dec 08 01:52:41 2016 +0300 description: Math.pow() method fix. diffstat: njs/njs_math.c | 12 ++++++++- njs/test/njs_unit_test.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletions(-) diffs (92 lines): diff -r 6a60530c7b6b -r db0d8e2a4928 njs/njs_math.c --- a/njs/njs_math.c Thu Dec 08 19:50:03 2016 +0300 +++ b/njs/njs_math.c Thu Dec 08 01:52:41 2016 +0300 @@ -578,7 +578,17 @@ njs_object_math_pow(njs_vm_t *vm, njs_va base = args[1].data.u.number; exponent = args[2].data.u.number; - num = pow(base, exponent); + /* + * Accordig to ECMA-262 the result of Math.pow(+/-1, +/-Infinity) + * should be NaN. + */ + + if (fabs(base) != 1 || !isinf(exponent)) { + num = pow(base, exponent); + + } else { + num = NAN; + } } else { num = NAN; diff -r 6a60530c7b6b -r db0d8e2a4928 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Dec 08 19:50:03 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Dec 08 01:52:41 2016 +0300 @@ -6215,6 +6215,66 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.pow()"), nxt_string("NaN") }, + { nxt_string("Math.pow('a', -0)"), + nxt_string("1") }, + + { nxt_string("Math.pow(1.1, Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.pow(-1.1, -Infinity)"), + nxt_string("0") }, + + { nxt_string("Math.pow(-1, Infinity)"), + nxt_string("NaN") }, + + { nxt_string("Math.pow(1, -Infinity)"), + nxt_string("NaN") }, + + { nxt_string("Math.pow(-0.9, Infinity)"), + nxt_string("0") }, + + { nxt_string("Math.pow(0.9, -Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.pow('Infinity', 0.1)"), + nxt_string("Infinity") }, + + { nxt_string("Math.pow(Infinity, '-0.1')"), + nxt_string("0") }, + + { nxt_string("Math.pow(-Infinity, 3)"), + nxt_string("-Infinity") }, + + { nxt_string("Math.pow('-Infinity', '3.1')"), + nxt_string("Infinity") }, + + { nxt_string("Math.pow(-Infinity, '-3')"), + nxt_string("-0") }, + + { nxt_string("Math.pow('-Infinity', -2)"), + nxt_string("0") }, + + { nxt_string("Math.pow('0', 0.1)"), + nxt_string("0") }, + + { nxt_string("Math.pow(0, '-0.1')"), + nxt_string("Infinity") }, + + { nxt_string("Math.pow(-0, 3)"), + nxt_string("-0") }, + + { nxt_string("Math.pow('-0', '3.1')"), + nxt_string("0") }, + + { nxt_string("Math.pow(-0, '-3')"), + nxt_string("-Infinity") }, + + { nxt_string("Math.pow('-0', -2)"), + nxt_string("Infinity") }, + + { nxt_string("Math.pow(-3, 0.1)"), + nxt_string("NaN") }, + { nxt_string("var a = Math.random(); a >= 0 && a < 1"), nxt_string("true") }, From ru at nginx.com Thu Dec 8 18:46:46 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 08 Dec 2016 18:46:46 +0000 Subject: [nginx] Map: simplified "map" block parser. Message-ID: details: http://hg.nginx.org/nginx/rev/014905eb7b3d branches: changeset: 6831:014905eb7b3d user: Ruslan Ermilov date: Thu Dec 08 17:29:01 2016 +0300 description: Map: simplified "map" block parser. No functional changes. diffstat: src/http/modules/ngx_http_map_module.c | 3 ++- src/stream/ngx_stream_map_module.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diffs (28 lines): diff -r 6eed5ed31e22 -r 014905eb7b3d src/http/modules/ngx_http_map_module.c --- a/src/http/modules/ngx_http_map_module.c Thu Dec 08 17:22:07 2016 +0300 +++ b/src/http/modules/ngx_http_map_module.c Thu Dec 08 17:29:01 2016 +0300 @@ -393,8 +393,9 @@ ngx_http_map(ngx_conf_t *cf, ngx_command { ctx->hostnames = 1; return NGX_CONF_OK; + } - } else if (cf->args->nelts != 2) { + if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of the map parameters"); return NGX_CONF_ERROR; diff -r 6eed5ed31e22 -r 014905eb7b3d src/stream/ngx_stream_map_module.c --- a/src/stream/ngx_stream_map_module.c Thu Dec 08 17:22:07 2016 +0300 +++ b/src/stream/ngx_stream_map_module.c Thu Dec 08 17:29:01 2016 +0300 @@ -392,8 +392,9 @@ ngx_stream_map(ngx_conf_t *cf, ngx_comma { ctx->hostnames = 1; return NGX_CONF_OK; + } - } else if (cf->args->nelts != 2) { + if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of the map parameters"); return NGX_CONF_ERROR; From ru at nginx.com Thu Dec 8 18:46:49 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 08 Dec 2016 18:46:49 +0000 Subject: [nginx] Map: the "volatile" parameter. Message-ID: details: http://hg.nginx.org/nginx/rev/ec10ce307dc0 branches: changeset: 6832:ec10ce307dc0 user: Ruslan Ermilov date: Thu Dec 08 17:51:49 2016 +0300 description: Map: the "volatile" parameter. By default, "map" creates cacheable variables [1]. With this parameter it creates a non-cacheable variable. An original idea was to deduce the cacheability of the "map" variable by checking the cacheability of variables specified in source and resulting values, but it turned to be too hard. For example, a cacheable variable can be overridden with the "set" directive or with the SSI "set" command. Also, keeping "map" variables cacheable by default is good for performance reasons. This required adding a new parameter. [1] Before db699978a33f (1.11.0), the cacheability of the "map" variable could vary depending on the cacheability of variables specified in resulting values (ticket #1090). This is believed to be a bug rather than a feature. diffstat: src/http/modules/ngx_http_map_module.c | 15 ++++++++++++++- src/stream/ngx_stream_map_module.c | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diffs (92 lines): diff -r 014905eb7b3d -r ec10ce307dc0 src/http/modules/ngx_http_map_module.c --- a/src/http/modules/ngx_http_map_module.c Thu Dec 08 17:29:01 2016 +0300 +++ b/src/http/modules/ngx_http_map_module.c Thu Dec 08 17:51:49 2016 +0300 @@ -26,7 +26,8 @@ typedef struct { ngx_http_variable_value_t *default_value; ngx_conf_t *cf; - ngx_uint_t hostnames; /* unsigned hostnames:1 */ + unsigned hostnames:1; + unsigned no_cacheable:1; } ngx_http_map_conf_ctx_t; @@ -265,6 +266,7 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_c ctx.default_value = NULL; ctx.cf = &save; ctx.hostnames = 0; + ctx.no_cacheable = 0; save = *cf; cf->pool = pool; @@ -281,6 +283,10 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_c return rv; } + if (ctx.no_cacheable) { + var->flags |= NGX_HTTP_VAR_NOCACHEABLE; + } + map->default_value = ctx.default_value ? ctx.default_value: &ngx_http_variable_null_value; @@ -395,6 +401,13 @@ ngx_http_map(ngx_conf_t *cf, ngx_command return NGX_CONF_OK; } + if (cf->args->nelts == 1 + && ngx_strcmp(value[0].data, "volatile") == 0) + { + ctx->no_cacheable = 1; + return NGX_CONF_OK; + } + if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of the map parameters"); diff -r 014905eb7b3d -r ec10ce307dc0 src/stream/ngx_stream_map_module.c --- a/src/stream/ngx_stream_map_module.c Thu Dec 08 17:29:01 2016 +0300 +++ b/src/stream/ngx_stream_map_module.c Thu Dec 08 17:51:49 2016 +0300 @@ -26,7 +26,8 @@ typedef struct { ngx_stream_variable_value_t *default_value; ngx_conf_t *cf; - ngx_uint_t hostnames; /* unsigned hostnames:1 */ + unsigned hostnames:1; + unsigned no_cacheable:1; } ngx_stream_map_conf_ctx_t; @@ -264,6 +265,7 @@ ngx_stream_map_block(ngx_conf_t *cf, ngx ctx.default_value = NULL; ctx.cf = &save; ctx.hostnames = 0; + ctx.no_cacheable = 0; save = *cf; cf->pool = pool; @@ -280,6 +282,10 @@ ngx_stream_map_block(ngx_conf_t *cf, ngx return rv; } + if (ctx.no_cacheable) { + var->flags |= NGX_STREAM_VAR_NOCACHEABLE; + } + map->default_value = ctx.default_value ? ctx.default_value: &ngx_stream_variable_null_value; @@ -394,6 +400,13 @@ ngx_stream_map(ngx_conf_t *cf, ngx_comma return NGX_CONF_OK; } + if (cf->args->nelts == 1 + && ngx_strcmp(value[0].data, "volatile") == 0) + { + ctx->no_cacheable = 1; + return NGX_CONF_OK; + } + if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of the map parameters"); From eran.kornblau at kaltura.com Thu Dec 8 20:02:53 2016 From: eran.kornblau at kaltura.com (Eran Kornblau) Date: Thu, 8 Dec 2016 20:02:53 +0000 Subject: [nginx] Map: the "volatile" parameter. In-Reply-To: References: Message-ID: Ruslan, thank you very much ! Eran -----Original Message----- From: nginx-devel [mailto:nginx-devel-bounces at nginx.org] On Behalf Of Ruslan Ermilov Sent: Thursday, December 8, 2016 8:47 PM To: nginx-devel at nginx.org Subject: [nginx] Map: the "volatile" parameter. details: http://hg.nginx.org/nginx/rev/ec10ce307dc0 branches: changeset: 6832:ec10ce307dc0 user: Ruslan Ermilov date: Thu Dec 08 17:51:49 2016 +0300 description: Map: the "volatile" parameter. By default, "map" creates cacheable variables [1]. With this parameter it creates a non-cacheable variable. An original idea was to deduce the cacheability of the "map" variable by checking the cacheability of variables specified in source and resulting values, but it turned to be too hard. For example, a cacheable variable can be overridden with the "set" directive or with the SSI "set" command. Also, keeping "map" variables cacheable by default is good for performance reasons. This required adding a new parameter. [1] Before db699978a33f (1.11.0), the cacheability of the "map" variable could vary depending on the cacheability of variables specified in resulting values (ticket #1090). This is believed to be a bug rather than a feature. diffstat: src/http/modules/ngx_http_map_module.c | 15 ++++++++++++++- src/stream/ngx_stream_map_module.c | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diffs (92 lines): diff -r 014905eb7b3d -r ec10ce307dc0 src/http/modules/ngx_http_map_module.c --- a/src/http/modules/ngx_http_map_module.c Thu Dec 08 17:29:01 2016 +0300 +++ b/src/http/modules/ngx_http_map_module.c Thu Dec 08 17:51:49 2016 +0300 @@ -26,7 +26,8 @@ typedef struct { ngx_http_variable_value_t *default_value; ngx_conf_t *cf; - ngx_uint_t hostnames; /* unsigned hostnames:1 */ + unsigned hostnames:1; + unsigned no_cacheable:1; } ngx_http_map_conf_ctx_t; @@ -265,6 +266,7 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_c ctx.default_value = NULL; ctx.cf = &save; ctx.hostnames = 0; + ctx.no_cacheable = 0; save = *cf; cf->pool = pool; @@ -281,6 +283,10 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_c return rv; } + if (ctx.no_cacheable) { + var->flags |= NGX_HTTP_VAR_NOCACHEABLE; + } + map->default_value = ctx.default_value ? ctx.default_value: &ngx_http_variable_null_value; @@ -395,6 +401,13 @@ ngx_http_map(ngx_conf_t *cf, ngx_command return NGX_CONF_OK; } + if (cf->args->nelts == 1 + && ngx_strcmp(value[0].data, "volatile") == 0) + { + ctx->no_cacheable = 1; + return NGX_CONF_OK; + } + if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of the map parameters"); diff -r 014905eb7b3d -r ec10ce307dc0 src/stream/ngx_stream_map_module.c --- a/src/stream/ngx_stream_map_module.c Thu Dec 08 17:29:01 2016 +0300 +++ b/src/stream/ngx_stream_map_module.c Thu Dec 08 17:51:49 2016 +0300 @@ -26,7 +26,8 @@ typedef struct { ngx_stream_variable_value_t *default_value; ngx_conf_t *cf; - ngx_uint_t hostnames; /* unsigned hostnames:1 */ + unsigned hostnames:1; + unsigned no_cacheable:1; } ngx_stream_map_conf_ctx_t; @@ -264,6 +265,7 @@ ngx_stream_map_block(ngx_conf_t *cf, ngx ctx.default_value = NULL; ctx.cf = &save; ctx.hostnames = 0; + ctx.no_cacheable = 0; save = *cf; cf->pool = pool; @@ -280,6 +282,10 @@ ngx_stream_map_block(ngx_conf_t *cf, ngx return rv; } + if (ctx.no_cacheable) { + var->flags |= NGX_STREAM_VAR_NOCACHEABLE; + } + map->default_value = ctx.default_value ? ctx.default_value: &ngx_stream_variable_null_value; @@ -394,6 +400,13 @@ ngx_stream_map(ngx_conf_t *cf, ngx_comma return NGX_CONF_OK; } + if (cf->args->nelts == 1 + && ngx_strcmp(value[0].data, "volatile") == 0) + { + ctx->no_cacheable = 1; + return NGX_CONF_OK; + } + if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of the map parameters"); _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel From hongzhidao at gmail.com Fri Dec 9 02:41:41 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Fri, 9 Dec 2016 10:41:41 +0800 Subject: [nginx] Map: the "volatile" parameter. In-Reply-To: References: Message-ID: Hi! It's still a problem when the variable generated by map and including itself. For example: map $host $abc { default $abc; } server { listen 80; location / { return 200 $abc; } } Thanks. B.R~ 2016-12-09 2:46 GMT+08:00 Ruslan Ermilov : > details: http://hg.nginx.org/nginx/rev/ec10ce307dc0 > branches: > changeset: 6832:ec10ce307dc0 > user: Ruslan Ermilov > date: Thu Dec 08 17:51:49 2016 +0300 > description: > Map: the "volatile" parameter. > > By default, "map" creates cacheable variables [1]. With this > parameter it creates a non-cacheable variable. > > An original idea was to deduce the cacheability of the "map" > variable by checking the cacheability of variables specified > in source and resulting values, but it turned to be too hard. > For example, a cacheable variable can be overridden with the > "set" directive or with the SSI "set" command. Also, keeping > "map" variables cacheable by default is good for performance > reasons. This required adding a new parameter. > > [1] Before db699978a33f (1.11.0), the cacheability of the > "map" variable could vary depending on the cacheability of > variables specified in resulting values (ticket #1090). > This is believed to be a bug rather than a feature. > > diffstat: > > src/http/modules/ngx_http_map_module.c | 15 ++++++++++++++- > src/stream/ngx_stream_map_module.c | 15 ++++++++++++++- > 2 files changed, 28 insertions(+), 2 deletions(-) > > diffs (92 lines): > > diff -r 014905eb7b3d -r ec10ce307dc0 src/http/modules/ngx_http_map_ > module.c > --- a/src/http/modules/ngx_http_map_module.c Thu Dec 08 17:29:01 2016 > +0300 > +++ b/src/http/modules/ngx_http_map_module.c Thu Dec 08 17:51:49 2016 > +0300 > @@ -26,7 +26,8 @@ typedef struct { > > ngx_http_variable_value_t *default_value; > ngx_conf_t *cf; > - ngx_uint_t hostnames; /* unsigned hostnames:1 > */ > + unsigned hostnames:1; > + unsigned no_cacheable:1; > } ngx_http_map_conf_ctx_t; > > > @@ -265,6 +266,7 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_c > ctx.default_value = NULL; > ctx.cf = &save; > ctx.hostnames = 0; > + ctx.no_cacheable = 0; > > save = *cf; > cf->pool = pool; > @@ -281,6 +283,10 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_c > return rv; > } > > + if (ctx.no_cacheable) { > + var->flags |= NGX_HTTP_VAR_NOCACHEABLE; > + } > + > map->default_value = ctx.default_value ? ctx.default_value: > > &ngx_http_variable_null_value; > > @@ -395,6 +401,13 @@ ngx_http_map(ngx_conf_t *cf, ngx_command > return NGX_CONF_OK; > } > > + if (cf->args->nelts == 1 > + && ngx_strcmp(value[0].data, "volatile") == 0) > + { > + ctx->no_cacheable = 1; > + return NGX_CONF_OK; > + } > + > if (cf->args->nelts != 2) { > ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, > "invalid number of the map parameters"); > diff -r 014905eb7b3d -r ec10ce307dc0 src/stream/ngx_stream_map_module.c > --- a/src/stream/ngx_stream_map_module.c Thu Dec 08 17:29:01 2016 > +0300 > +++ b/src/stream/ngx_stream_map_module.c Thu Dec 08 17:51:49 2016 > +0300 > @@ -26,7 +26,8 @@ typedef struct { > > ngx_stream_variable_value_t *default_value; > ngx_conf_t *cf; > - ngx_uint_t hostnames; /* unsigned > hostnames:1 */ > + unsigned hostnames:1; > + unsigned no_cacheable:1; > } ngx_stream_map_conf_ctx_t; > > > @@ -264,6 +265,7 @@ ngx_stream_map_block(ngx_conf_t *cf, ngx > ctx.default_value = NULL; > ctx.cf = &save; > ctx.hostnames = 0; > + ctx.no_cacheable = 0; > > save = *cf; > cf->pool = pool; > @@ -280,6 +282,10 @@ ngx_stream_map_block(ngx_conf_t *cf, ngx > return rv; > } > > + if (ctx.no_cacheable) { > + var->flags |= NGX_STREAM_VAR_NOCACHEABLE; > + } > + > map->default_value = ctx.default_value ? ctx.default_value: > &ngx_stream_variable_null_ > value; > > @@ -394,6 +400,13 @@ ngx_stream_map(ngx_conf_t *cf, ngx_comma > return NGX_CONF_OK; > } > > + if (cf->args->nelts == 1 > + && ngx_strcmp(value[0].data, "volatile") == 0) > + { > + ctx->no_cacheable = 1; > + return NGX_CONF_OK; > + } > + > if (cf->args->nelts != 2) { > ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, > "invalid number of the map parameters"); > _______________________________________________ > 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 Fri Dec 9 14:41:29 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 09 Dec 2016 14:41:29 +0000 Subject: [nginx] HTTP/2: fixed posted streams handling. Message-ID: details: http://hg.nginx.org/nginx/rev/3834951e32ab branches: changeset: 6833:3834951e32ab user: Valentin Bartenev date: Mon Nov 28 20:58:14 2016 +0300 description: HTTP/2: fixed posted streams handling. A bug was introduced by 82efcedb310b that could lead to timing out of responses or segmentation fault, when accept_mutex was enabled. The output queue in HTTP/2 can contain frames from different streams. When the queue is sent, all related write handlers need to be called. In order to do so, the streams were added to the h2c->posted queue after handling sent frames. Then this queue was processed in ngx_http_v2_write_handler(). If accept_mutex is enabled, the event's "ready" flag is set but its handler is not called immediately. Instead, the event is added to the ngx_posted_events queue. At the same time in this queue can be events from upstream connections. Such events can result in sending output queue before ngx_http_v2_write_handler() is triggered. And at the time ngx_http_v2_write_handler() is called, the output queue can be already empty with some streams added to h2c->posted. But after 82efcedb310b, these streams weren't processed if all frames have already been sent and the output queue was empty. This might lead to a situation when a number of streams were get stuck in h2c->posted queue for a long time. Eventually these streams might get closed by the send timeout. In the worst case this might also lead to a segmentation fault, if already freed stream was left in the h2c->posted queue. This could happen if one of the streams was terminated but wasn't closed, due to the HEADERS frame or a partially sent DATA frame left in the output queue. If this happened the ngx_http_v2_filter_cleanup() handler removed the stream from the h2c->waiting or h2c->posted queue on termination stage, before the frame has been sent, and the stream was again added to the h2c->posted queue after the frame was sent. In order to fix all these problems and simplify the code, write events of fake stream connections are now added to ngx_posted_events instead of using a custom h2c->posted queue. diffstat: src/http/v2/ngx_http_v2.c | 27 +---------------- src/http/v2/ngx_http_v2.h | 3 +- src/http/v2/ngx_http_v2_filter_module.c | 50 +++++++++++++++++++++++++------- 3 files changed, 42 insertions(+), 38 deletions(-) diffs (183 lines): diff -r ec10ce307dc0 -r 3834951e32ab src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Thu Dec 08 17:51:49 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Mon Nov 28 20:58:14 2016 +0300 @@ -286,7 +286,6 @@ ngx_http_v2_init(ngx_event_t *rev) : ngx_http_v2_state_preface; ngx_queue_init(&h2c->waiting); - ngx_queue_init(&h2c->posted); ngx_queue_init(&h2c->dependencies); ngx_queue_init(&h2c->closed); @@ -420,9 +419,7 @@ static void ngx_http_v2_write_handler(ngx_event_t *wev) { ngx_int_t rc; - ngx_queue_t *q; ngx_connection_t *c; - ngx_http_v2_stream_t *stream; ngx_http_v2_connection_t *h2c; c = wev->data; @@ -457,26 +454,6 @@ ngx_http_v2_write_handler(ngx_event_t *w return; } - while (!ngx_queue_empty(&h2c->posted)) { - q = ngx_queue_head(&h2c->posted); - - ngx_queue_remove(q); - - stream = ngx_queue_data(q, ngx_http_v2_stream_t, queue); - - stream->handled = 0; - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, - "run http2 stream %ui", stream->node->id); - - wev = stream->request->connection->write; - - wev->active = 0; - wev->ready = 1; - - wev->handler(wev); - } - h2c->blocked = 0; if (rc == NGX_AGAIN) { @@ -2254,7 +2231,7 @@ ngx_http_v2_state_window_update(ngx_http stream = ngx_queue_data(q, ngx_http_v2_stream_t, queue); - stream->handled = 0; + stream->waiting = 0; wev = stream->request->connection->write; @@ -4274,7 +4251,7 @@ ngx_http_v2_finalize_connection(ngx_http continue; } - stream->handled = 0; + stream->waiting = 0; r = stream->request; fc = r->connection; diff -r ec10ce307dc0 -r 3834951e32ab src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Thu Dec 08 17:51:49 2016 +0300 +++ b/src/http/v2/ngx_http_v2.h Mon Nov 28 20:58:14 2016 +0300 @@ -137,7 +137,6 @@ struct ngx_http_v2_connection_s { ngx_http_v2_out_frame_t *last_out; - ngx_queue_t posted; ngx_queue_t dependencies; ngx_queue_t closed; @@ -192,7 +191,7 @@ struct ngx_http_v2_stream_s { ngx_pool_t *pool; - unsigned handled:1; + unsigned waiting:1; unsigned blocked:1; unsigned exhausted:1; unsigned in_closed:1; diff -r ec10ce307dc0 -r 3834951e32ab src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Thu Dec 08 17:51:49 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Mon Nov 28 20:58:14 2016 +0300 @@ -1104,11 +1104,11 @@ ngx_http_v2_waiting_queue(ngx_http_v2_co ngx_queue_t *q; ngx_http_v2_stream_t *s; - if (stream->handled) { + if (stream->waiting) { return; } - stream->handled = 1; + stream->waiting = 1; for (q = ngx_queue_last(&h2c->waiting); q != ngx_queue_sentinel(&h2c->waiting); @@ -1298,20 +1298,29 @@ static ngx_inline void ngx_http_v2_handle_stream(ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream) { + ngx_event_t *wev; ngx_connection_t *fc; - if (stream->handled || stream->blocked) { + if (stream->waiting || stream->blocked) { return; } fc = stream->request->connection; - if (!fc->error && (stream->exhausted || fc->write->delayed)) { + if (!fc->error && stream->exhausted) { return; } - stream->handled = 1; - ngx_queue_insert_tail(&h2c->posted, &stream->queue); + wev = fc->write; + + wev->active = 0; + wev->ready = 1; + + if (!fc->error && wev->delayed) { + return; + } + + ngx_post_event(wev, &ngx_posted_events); } @@ -1321,11 +1330,13 @@ ngx_http_v2_filter_cleanup(void *data) ngx_http_v2_stream_t *stream = data; size_t window; + ngx_event_t *wev; + ngx_queue_t *q; ngx_http_v2_out_frame_t *frame, **fn; ngx_http_v2_connection_t *h2c; - if (stream->handled) { - stream->handled = 0; + if (stream->waiting) { + stream->waiting = 0; ngx_queue_remove(&stream->queue); } @@ -1359,9 +1370,26 @@ ngx_http_v2_filter_cleanup(void *data) fn = &frame->next; } - if (h2c->send_window == 0 && window && !ngx_queue_empty(&h2c->waiting)) { - ngx_queue_add(&h2c->posted, &h2c->waiting); - ngx_queue_init(&h2c->waiting); + if (h2c->send_window == 0 && window) { + + while (!ngx_queue_empty(&h2c->waiting)) { + q = ngx_queue_head(&h2c->waiting); + + ngx_queue_remove(q); + + stream = ngx_queue_data(q, ngx_http_v2_stream_t, queue); + + stream->waiting = 0; + + wev = stream->request->connection->write; + + wev->active = 0; + wev->ready = 1; + + if (!wev->delayed) { + ngx_post_event(wev, &ngx_posted_events); + } + } } h2c->send_window += window; From vbart at nginx.com Sat Dec 10 10:34:16 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Sat, 10 Dec 2016 10:34:16 +0000 Subject: [nginx] HTTP/2: prevented creating temp files for requests without body. Message-ID: details: http://hg.nginx.org/nginx/rev/e02f1977846b branches: changeset: 6834:e02f1977846b user: Valentin Bartenev date: Sat Dec 10 13:23:38 2016 +0300 description: HTTP/2: prevented creating temp files for requests without body. The problem was introduced by 52bd8cc17f34. diffstat: src/http/v2/ngx_http_v2.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (16 lines): diff -r 3834951e32ab -r e02f1977846b src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Mon Nov 28 20:58:14 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Sat Dec 10 13:23:38 2016 +0300 @@ -3552,8 +3552,10 @@ ngx_http_v2_read_request_body(ngx_http_r rb->buf = ngx_create_temp_buf(r->pool, (size_t) len); } else { - /* enforce writing body to file */ - r->request_body_in_file_only = 1; + if (stream->preread) { + /* enforce writing preread buffer to file */ + r->request_body_in_file_only = 1; + } rb->buf = ngx_calloc_buf(r->pool); From me at armingrodon.de Tue Dec 13 00:08:49 2016 From: me at armingrodon.de (Armin Grodon) Date: Tue, 13 Dec 2016 01:08:49 +0100 Subject: [nginx.vim][PATCH] add 'commentstring' for vim-commentary support Message-ID: <20161213000849.GA30641@armingrodon.de> Hi, this small path adds the correct comments for the widely used vim-plugin 'commentary.vim'. # HG changeset patch # User Armin Grodon # Date 1481586584 -3600 # Tue Dec 13 00:49:44 2016 +0100 # Node ID 21d59bd866499df91c0b3d8a9d4d81457db32dd5 # Parent e02f1977846b18fadc3e30e2ca97d35eb788cbf9 add 'commentstring' for vim-commentary support diff -r e02f1977846b -r 21d59bd86649 contrib/vim/ftplugin/nginx.vim --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/vim/ftplugin/nginx.vim Tue Dec 13 00:49:44 2016 +0100 @@ -0,0 +1,1 @@ +setlocal commentstring=#\ %s Best regards, Armin From arut at nginx.com Tue Dec 13 11:06:15 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 13 Dec 2016 11:06:15 +0000 Subject: [njs] Disabled js_set at server{} and location{} levels. Message-ID: details: http://hg.nginx.org/njs/rev/b54508367550 branches: changeset: 281:b54508367550 user: Roman Arutyunyan date: Tue Dec 13 14:04:46 2016 +0300 description: Disabled js_set at server{} and location{} levels. diffstat: nginx/ngx_http_js_module.c | 2 +- nginx/ngx_stream_js_module.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (24 lines): diff -r db0d8e2a4928 -r b54508367550 nginx/ngx_http_js_module.c --- a/nginx/ngx_http_js_module.c Thu Dec 08 01:52:41 2016 +0300 +++ b/nginx/ngx_http_js_module.c Tue Dec 13 14:04:46 2016 +0300 @@ -137,7 +137,7 @@ static ngx_command_t ngx_http_js_comman NULL }, { ngx_string("js_set"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, + NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2, ngx_http_js_set, NGX_HTTP_LOC_CONF_OFFSET, 0, diff -r db0d8e2a4928 -r b54508367550 nginx/ngx_stream_js_module.c --- a/nginx/ngx_stream_js_module.c Thu Dec 08 01:52:41 2016 +0300 +++ b/nginx/ngx_stream_js_module.c Tue Dec 13 14:04:46 2016 +0300 @@ -112,7 +112,7 @@ static ngx_command_t ngx_stream_js_comm NULL }, { ngx_string("js_set"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2, + NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE2, ngx_stream_js_set, NGX_STREAM_SRV_CONF_OFFSET, 0, From igor at sysoev.ru Tue Dec 13 11:19:06 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 13 Dec 2016 11:19:06 +0000 Subject: [njs] Version 0.1.6. Message-ID: details: http://hg.nginx.org/njs/rev/44b524f7e313 branches: changeset: 282:44b524f7e313 user: Igor Sysoev date: Tue Dec 13 14:18:11 2016 +0300 description: Version 0.1.6. diffstat: Makefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (10 lines): diff -r b54508367550 -r 44b524f7e313 Makefile --- a/Makefile Tue Dec 13 14:04:46 2016 +0300 +++ b/Makefile Tue Dec 13 14:18:11 2016 +0300 @@ -1,5 +1,5 @@ -NJS_VER = 0.1.5 +NJS_VER = 0.1.6 NXT_LIB = nxt From igor at sysoev.ru Tue Dec 13 11:19:08 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 13 Dec 2016 11:19:08 +0000 Subject: [njs] Added tag 0.1.6 for changeset 44b524f7e313 Message-ID: details: http://hg.nginx.org/njs/rev/43582218defe branches: changeset: 283:43582218defe user: Igor Sysoev date: Tue Dec 13 14:18:40 2016 +0300 description: Added tag 0.1.6 for changeset 44b524f7e313 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 44b524f7e313 -r 43582218defe .hgtags --- a/.hgtags Tue Dec 13 14:18:11 2016 +0300 +++ b/.hgtags Tue Dec 13 14:18:40 2016 +0300 @@ -4,3 +4,4 @@ 5b066b4db54c17dc0a9a72948474f36957462e87 360449773d51e7f451e5396e27021badc6b86085 0.1.3 508689c1fb94c23f6b24be087c1dc63b2f9e6654 0.1.4 9c813c2bb2acfd5b6e9d1e9b6699af928baea15a 0.1.5 +44b524f7e313369cd062a387511ea6fdc427875f 0.1.6 From iasybvm at qq.com Tue Dec 13 12:36:53 2016 From: iasybvm at qq.com (=?gb18030?B?tv7JtdfT?=) Date: Tue, 13 Dec 2016 20:36:53 +0800 Subject: nodigest References: Message-ID: no-digest------------------ Original ------------------ From: "nginx-devel-request" Date: Tue, Dec 13, 2016 08:00 PM To: "nginx-devel"; Subject: nginx-devel Digest, Vol 86, Issue 12 Send nginx-devel mailing list submissions to nginx-devel at nginx.org To subscribe or unsubscribe via the World Wide Web, visit http://mailman.nginx.org/mailman/listinfo/nginx-devel or, via email, send a message with subject or body 'help' to nginx-devel-request at nginx.org You can reach the person managing the list at nginx-devel-owner at nginx.org When replying, please edit your Subject line so it is more specific than "Re: Contents of nginx-devel digest..." Today's Topics: 1. [nginx.vim][PATCH] add 'commentstring' for vim-commentary support (Armin Grodon) 2. [njs] Disabled js_set at server{} and location{} levels. (Roman Arutyunyan) 3. [njs] Version 0.1.6. (Igor Sysoev) 4. [njs] Added tag 0.1.6 for changeset 44b524f7e313 (Igor Sysoev) ---------------------------------------------------------------------- Message: 1 Date: Tue, 13 Dec 2016 01:08:49 +0100 From: Armin Grodon To: nginx-devel at nginx.org Subject: [nginx.vim][PATCH] add 'commentstring' for vim-commentary support Message-ID: <20161213000849.GA30641 at armingrodon.de> Content-Type: text/plain; charset=us-ascii Hi, this small path adds the correct comments for the widely used vim-plugin 'commentary.vim'. # HG changeset patch # User Armin Grodon # Date 1481586584 -3600 # Tue Dec 13 00:49:44 2016 +0100 # Node ID 21d59bd866499df91c0b3d8a9d4d81457db32dd5 # Parent e02f1977846b18fadc3e30e2ca97d35eb788cbf9 add 'commentstring' for vim-commentary support diff -r e02f1977846b -r 21d59bd86649 contrib/vim/ftplugin/nginx.vim --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/vim/ftplugin/nginx.vim Tue Dec 13 00:49:44 2016 +0100 @@ -0,0 +1,1 @@ +setlocal commentstring=#\ %s Best regards, Armin ------------------------------ Message: 2 Date: Tue, 13 Dec 2016 11:06:15 +0000 From: Roman Arutyunyan To: nginx-devel at nginx.org Subject: [njs] Disabled js_set at server{} and location{} levels. Message-ID: Content-Type: text/plain; charset="us-ascii" details: http://hg.nginx.org/njs/rev/b54508367550 branches: changeset: 281:b54508367550 user: Roman Arutyunyan date: Tue Dec 13 14:04:46 2016 +0300 description: Disabled js_set at server{} and location{} levels. diffstat: nginx/ngx_http_js_module.c | 2 +- nginx/ngx_stream_js_module.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (24 lines): diff -r db0d8e2a4928 -r b54508367550 nginx/ngx_http_js_module.c --- a/nginx/ngx_http_js_module.c Thu Dec 08 01:52:41 2016 +0300 +++ b/nginx/ngx_http_js_module.c Tue Dec 13 14:04:46 2016 +0300 @@ -137,7 +137,7 @@ static ngx_command_t ngx_http_js_comman NULL }, { ngx_string("js_set"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, + NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2, ngx_http_js_set, NGX_HTTP_LOC_CONF_OFFSET, 0, diff -r db0d8e2a4928 -r b54508367550 nginx/ngx_stream_js_module.c --- a/nginx/ngx_stream_js_module.c Thu Dec 08 01:52:41 2016 +0300 +++ b/nginx/ngx_stream_js_module.c Tue Dec 13 14:04:46 2016 +0300 @@ -112,7 +112,7 @@ static ngx_command_t ngx_stream_js_comm NULL }, { ngx_string("js_set"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2, + NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE2, ngx_stream_js_set, NGX_STREAM_SRV_CONF_OFFSET, 0, ------------------------------ Message: 3 Date: Tue, 13 Dec 2016 11:19:06 +0000 From: Igor Sysoev To: nginx-devel at nginx.org Subject: [njs] Version 0.1.6. Message-ID: Content-Type: text/plain; charset="us-ascii" details: http://hg.nginx.org/njs/rev/44b524f7e313 branches: changeset: 282:44b524f7e313 user: Igor Sysoev date: Tue Dec 13 14:18:11 2016 +0300 description: Version 0.1.6. diffstat: Makefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (10 lines): diff -r b54508367550 -r 44b524f7e313 Makefile --- a/Makefile Tue Dec 13 14:04:46 2016 +0300 +++ b/Makefile Tue Dec 13 14:18:11 2016 +0300 @@ -1,5 +1,5 @@ -NJS_VER = 0.1.5 +NJS_VER = 0.1.6 NXT_LIB = nxt ------------------------------ Message: 4 Date: Tue, 13 Dec 2016 11:19:08 +0000 From: Igor Sysoev To: nginx-devel at nginx.org Subject: [njs] Added tag 0.1.6 for changeset 44b524f7e313 Message-ID: Content-Type: text/plain; charset="us-ascii" details: http://hg.nginx.org/njs/rev/43582218defe branches: changeset: 283:43582218defe user: Igor Sysoev date: Tue Dec 13 14:18:40 2016 +0300 description: Added tag 0.1.6 for changeset 44b524f7e313 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 44b524f7e313 -r 43582218defe .hgtags --- a/.hgtags Tue Dec 13 14:18:11 2016 +0300 +++ b/.hgtags Tue Dec 13 14:18:40 2016 +0300 @@ -4,3 +4,4 @@ 5b066b4db54c17dc0a9a72948474f36957462e87 360449773d51e7f451e5396e27021badc6b86085 0.1.3 508689c1fb94c23f6b24be087c1dc63b2f9e6654 0.1.4 9c813c2bb2acfd5b6e9d1e9b6699af928baea15a 0.1.5 +44b524f7e313369cd062a387511ea6fdc427875f 0.1.6 ------------------------------ Subject: Digest Footer _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel ------------------------------ End of nginx-devel Digest, Vol 86, Issue 12 ******************************************* -------------- next part -------------- An HTML attachment was scrubbed... URL: From arut at nginx.com Tue Dec 13 14:21:23 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 13 Dec 2016 14:21:23 +0000 Subject: [njs] Disabled js_include at server{} and location{} levels. Message-ID: details: http://hg.nginx.org/njs/rev/f9d2302afda1 branches: changeset: 284:f9d2302afda1 user: Roman Arutyunyan date: Tue Dec 13 17:17:25 2016 +0300 description: Disabled js_include at server{} and location{} levels. diffstat: nginx/ngx_http_js_module.c | 2 +- nginx/ngx_stream_js_module.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (24 lines): diff -r 43582218defe -r f9d2302afda1 nginx/ngx_http_js_module.c --- a/nginx/ngx_http_js_module.c Tue Dec 13 14:18:40 2016 +0300 +++ b/nginx/ngx_http_js_module.c Tue Dec 13 17:17:25 2016 +0300 @@ -130,7 +130,7 @@ static char *ngx_http_js_merge_loc_conf( static ngx_command_t ngx_http_js_commands[] = { { ngx_string("js_include"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, ngx_http_js_include, NGX_HTTP_LOC_CONF_OFFSET, 0, diff -r 43582218defe -r f9d2302afda1 nginx/ngx_stream_js_module.c --- a/nginx/ngx_stream_js_module.c Tue Dec 13 14:18:40 2016 +0300 +++ b/nginx/ngx_stream_js_module.c Tue Dec 13 17:17:25 2016 +0300 @@ -105,7 +105,7 @@ static ngx_int_t ngx_stream_js_init(ngx_ static ngx_command_t ngx_stream_js_commands[] = { { ngx_string("js_include"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1, ngx_stream_js_include, NGX_STREAM_SRV_CONF_OFFSET, 0, From arut at nginx.com Tue Dec 13 14:52:00 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 13 Dec 2016 14:52:00 +0000 Subject: [njs] Replaced README contents with online documentation links. Message-ID: details: http://hg.nginx.org/njs/rev/b5e47a364c02 branches: changeset: 285:b5e47a364c02 user: Roman Arutyunyan date: Tue Dec 13 17:50:06 2016 +0300 description: Replaced README contents with online documentation links. diffstat: README | 287 +---------------------------------------------------------------- 1 files changed, 4 insertions(+), 283 deletions(-) diffs (298 lines): diff -r f9d2302afda1 -r b5e47a364c02 README --- a/README Tue Dec 13 17:17:25 2016 +0300 +++ b/README Tue Dec 13 17:50:06 2016 +0300 @@ -1,290 +1,11 @@ - -Configure nginx with HTTP and Stream JavaScript modules using the --add-module -option: - - ./configure --add-module=/nginx +The documentation is available online: -Alternatively, you can build a dynamic version of the modules - - ./configure --add-dynamic-module=/nginx - -and add the following lines to nginx.conf to load them - - load_module modules/ngx_http_js_module.so; - load_module modules/ngx_stream_js_module.so; + http://nginx.org/en/docs/njs_about.html + http://nginx.org/en/docs/http/ngx_http_js_module.html + http://nginx.org/en/docs/stream/ngx_stream_js_module.html Please report your experiences to the NGINX development mailing list nginx-devel at nginx.org (http://mailman.nginx.org/mailman/listinfo/nginx-devel). - -HTTP JavaScript module ----------------------- - -Each HTTP JavaScript handler receives two arguments - request and response. - - function foo(req, res) { - .. - } - -The following properties are available: - -req - - uri - - method - - httpVersion - - remoteAddress - - headers{} - - args{} - - variables{} - - log() - -res - - status - - headers{} - - contentType - - contentLength - - sendHeader() - - send() - - finish() - - -Example nginx.conf: - - # load dynamic HTTP JavaScript module - load_module modules/ngx_http_js_module.so; - - worker_processes 1; - pid logs/nginx.pid; - - events { - worker_connections 256; - } - - http { - # include JavaScript file - js_include http.js; - - server { - listen 8000; - - location / { - # create $foo variable and set JavaScript function foo() - # from the included JavaScript file as its handler - js_set $foo foo; - - add_header X-Foo $foo; - - # register JavaScript function bar() as content handler - js_content baz; - } - - location /summary { - js_set $summary summary; - - return 200 $summary; - } - } - } - - -http.js: - - function foo(req, res) { - req.log("hello from foo() handler"); - return "foo"; - } - - function summary(req, res) { - var a, s, h; - - s = "JS summary\n\n"; - - s += "Method: " + req.method + "\n"; - s += "HTTP version: " + req.httpVersion + "\n"; - s += "Host: " + req.headers.host + "\n"; - s += "Remote Address: " + req.remoteAddress + "\n"; - s += "URI: " + req.uri + "\n"; - - s += "Headers:\n"; - for (h in req.headers) { - s += " header '" + h + "' is '" + req.headers[h] + "'\n"; - } - - s += "Args:\n"; - for (a in req.args) { - s += " arg '" + a + "' is '" + req.args[a] + "'\n"; - } - - return s; - } - - function baz(req, res) { - res.headers.foo = 1234; - res.status = 200; - res.contentType = "text/plain; charset=utf-8"; - res.contentLength = 15; - res.sendHeader(); - res.send("nginx"); - res.send("java"); - res.send("script"); - - res.finish(); - } - - -Stream JavaScript module ------------------------- - -Each Stream JavaScript handler receives one argument - stream session object. - - function foo(s) { - .. - } - -The following properties are available in the session object: - - - remoteAddress - - eof - - fromUpstream - - buffer - - variables{} - - log() - - OK - - DECLINED - - AGAIN - - ERROR - - ABORT - - -Example nginx.conf: - - # load dynamic Stream JavaScript module - load_module modules/ngx_stream_js_module.so; - - worker_processes 1; - pid logs/nginx.pid; - - events { - worker_connections 256; - } - - stream { - # include JavaScript file - js_include stream.js; - - server { - listen 8000; - - # preread data with qux() - js_preread qux; - - # create $foo and $bar variables and set JavaScript - # functions foo() and bar() from the included JavaScript - # file as their handlers - js_set $foo foo; - js_set $bar bar; - - # echo-server: return preread data - return foo; - } - - server { - listen 8001; - - # check access in xyz() - js_access xyz; - - proxy_pass 127.0.0.1:9000; - - # add JavaScript filter baz() from the included - # JavaScript file - js_filter baz; - } - } - - http { - server { - listen 9000; - location / { - return 200 $http_foo\n; - } - } - } - - -stream.js: - - var req = ''; - var matched = 0; - var line = ''; - - function qux(s) { - n = s.buffer.indexOf('\n'); - if (n == -1) { - return s.AGAIN; - } - - line = s.buffer.substr(0, n); - } - - function foo(s) { - return line; - } - - function bar(s) { - var v = s.variables; - s.log("hello from bar() handler!"); - return "foo-var" + v.remote_port + "; pid=" + v.pid; - } - - // The filter processes one buffer per call. - // The buffer is available in s.buffer both for - // reading and writing. Called for both directions. - - function baz(s) { - if (s.fromUpstream || matched) { - return; - } - - // Disable certain addresses. - - if (s.remoteAddress.match('^192.*')) { - return s.ERROR; - } - - // Read HTTP request line. - // Collect bytes in 'req' until request - // line is read. Clear current buffer to - // disable output. - - req = req + s.buffer; - s.buffer = ''; - - n = req.search('\n'); - - if (n != -1) { - // Inject a new HTTP header. - var rest = req.substr(n + 1); - req = req.substr(0, n + 1); - - addr = s.remoteAddress; - - s.log('req:' + req); - s.log('rest:' + rest); - - // Output the result and skip further - // processing. - - s.buffer = req + 'Foo: addr_' + addr + '\r\n' + rest; - matched = 1; - } - } - - function xyz(s) { - if (s.remoteAddress.match('^192.*')) { - return s.ABORT; - } - } - -- NGINX, Inc., http://nginx.com From mdounin at mdounin.ru Tue Dec 13 15:27:01 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 13 Dec 2016 15:27:01 +0000 Subject: [nginx] nginx-1.11.7-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/5c8f60faf33c branches: changeset: 6835:5c8f60faf33c user: Maxim Dounin date: Tue Dec 13 18:21:23 2016 +0300 description: nginx-1.11.7-RELEASE diffstat: docs/xml/nginx/changes.xml | 94 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 94 insertions(+), 0 deletions(-) diffs (104 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,100 @@ + + + + +?????????? $ssl_client_verify ?????? +? ?????? ?????? ???????? ??????????? ??????????? +???????? ?????? ? ????????? ??????, +????????, "FAILED:certificate has expired". + + +now in case of a client certificate verification error +the $ssl_client_verify variable contains a string with the failure reason, +for example, "FAILED:certificate has expired". + + + + + +?????????? $ssl_ciphers, $ssl_curves, +$ssl_client_v_start, $ssl_client_v_end ? $ssl_client_v_remain. + + +the $ssl_ciphers, $ssl_curves, +$ssl_client_v_start, $ssl_client_v_end, and $ssl_client_v_remain variables. + + + + + +???????? volatile ????????? map. + + +the "volatile" parameter of the "map" directive. + + + + + +??? ?????? ???????????? ??????? +?? ??????????? ???????? ??? ?????? ???????????. + + +dependencies specified for a module +were ignored while building dynamic modules. + + + + + +??? ????????????? HTTP/2 ? ???????? limit_req ??? auth_request +???? ??????? ????? ???? ??????????; +?????? ????????? ? 1.11.0. + + +when using HTTP/2 and the "limit_req" or "auth_request" directives +client request body might be corrupted; +the bug had appeared in 1.11.0. + + + + + +??? ????????????? HTTP/2 ? ??????? ???????? ??? ????????? segmentation fault; +?????? ????????? ? 1.11.3. + + +a segmentation fault might occur in a worker process when using HTTP/2; +the bug had appeared in 1.11.3. + + + + + +? ?????? ngx_http_mp4_module.
+??????? Congcong Hu. +
+ +in the ngx_http_mp4_module.
+Thanks to Congcong Hu. +
+
+ + + +? ?????? ngx_http_perl_module. + + +in the ngx_http_perl_module. + + + +
+ + From mdounin at mdounin.ru Tue Dec 13 15:27:04 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 13 Dec 2016 15:27:04 +0000 Subject: [nginx] release-1.11.7 tag Message-ID: details: http://hg.nginx.org/nginx/rev/25a64c864f4d branches: changeset: 6836:25a64c864f4d user: Maxim Dounin date: Tue Dec 13 18:21:23 2016 +0300 description: release-1.11.7 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -405,3 +405,4 @@ b83a067949a3384a49fd3d943eb8d0997b31f87b 953512ca02c6f63b4fcbbc3e10d0d9835896bf99 release-1.11.4 5253015a339aaca0a3111473d3e931b6d4752393 release-1.11.5 5e371426b3bcba4312ce08606194b89b758927d1 release-1.11.6 +5c8f60faf33ca8926473d2da27b4c3c417bd4630 release-1.11.7 From ru at nginx.com Tue Dec 13 19:04:27 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 13 Dec 2016 19:04:27 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/2c62d5613992 branches: changeset: 6837:2c62d5613992 user: Ruslan Ermilov date: Tue Dec 13 22:00:42 2016 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r 25a64c864f4d -r 2c62d5613992 src/core/nginx.h --- a/src/core/nginx.h Tue Dec 13 18:21:23 2016 +0300 +++ b/src/core/nginx.h Tue Dec 13 22:00:42 2016 +0300 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1011007 -#define NGINX_VERSION "1.11.7" +#define nginx_version 1011008 +#define NGINX_VERSION "1.11.8" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From ru at nginx.com Tue Dec 13 19:04:29 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 13 Dec 2016 19:04:29 +0000 Subject: [nginx] The size of cmcf->phase_engine.handlers explained. Message-ID: details: http://hg.nginx.org/nginx/rev/666b2bea3cb9 branches: changeset: 6838:666b2bea3cb9 user: Ruslan Ermilov date: Tue Dec 13 22:00:49 2016 +0300 description: The size of cmcf->phase_engine.handlers explained. diffstat: src/http/ngx_http.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (15 lines): diff -r 2c62d5613992 -r 666b2bea3cb9 src/http/ngx_http.c --- a/src/http/ngx_http.c Tue Dec 13 22:00:42 2016 +0300 +++ b/src/http/ngx_http.c Tue Dec 13 22:00:49 2016 +0300 @@ -457,7 +457,10 @@ ngx_http_init_phase_handlers(ngx_conf_t use_rewrite = cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers.nelts ? 1 : 0; use_access = cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers.nelts ? 1 : 0; - n = use_rewrite + use_access + cmcf->try_files + 1 /* find config phase */; + n = 1 /* find config phase */ + + use_rewrite /* post rewrite phase */ + + use_access /* post access phase */ + + cmcf->try_files; for (i = 0; i < NGX_HTTP_LOG_PHASE; i++) { n += cmcf->phases[i].handlers.nelts; From mdounin at mdounin.ru Tue Dec 13 20:40:58 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 13 Dec 2016 20:40:58 +0000 Subject: [nginx] Contrib: added 'commentstring' for vim-commentary support. Message-ID: details: http://hg.nginx.org/nginx/rev/32714e608629 branches: changeset: 6839:32714e608629 user: Armin Grodon date: Tue Dec 13 00:49:44 2016 +0100 description: Contrib: added 'commentstring' for vim-commentary support. diffstat: contrib/vim/ftplugin/nginx.vim | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (6 lines): diff --git a/contrib/vim/ftplugin/nginx.vim b/contrib/vim/ftplugin/nginx.vim new file mode 100644 --- /dev/null +++ b/contrib/vim/ftplugin/nginx.vim @@ -0,0 +1,1 @@ +setlocal commentstring=#\ %s From mdounin at mdounin.ru Tue Dec 13 20:41:39 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 13 Dec 2016 23:41:39 +0300 Subject: [nginx.vim][PATCH] add 'commentstring' for vim-commentary support In-Reply-To: <20161213000849.GA30641@armingrodon.de> References: <20161213000849.GA30641@armingrodon.de> Message-ID: <20161213204139.GH18639@mdounin.ru> Hello! On Tue, Dec 13, 2016 at 01:08:49AM +0100, Armin Grodon wrote: > Hi, > > this small path adds the correct comments for the widely used vim-plugin > 'commentary.vim'. > > > # HG changeset patch > # User Armin Grodon > # Date 1481586584 -3600 > # Tue Dec 13 00:49:44 2016 +0100 > # Node ID 21d59bd866499df91c0b3d8a9d4d81457db32dd5 > # Parent e02f1977846b18fadc3e30e2ca97d35eb788cbf9 > add 'commentstring' for vim-commentary support > > diff -r e02f1977846b -r 21d59bd86649 contrib/vim/ftplugin/nginx.vim > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/contrib/vim/ftplugin/nginx.vim Tue Dec 13 00:49:44 2016 +0100 > @@ -0,0 +1,1 @@ > +setlocal commentstring=#\ %s Committed with minor style changes to commit log, thanks. -- Maxim Dounin http://nginx.org/ From piotrsikora at google.com Tue Dec 13 22:20:40 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 13 Dec 2016 14:20:40 -0800 Subject: [PATCH] SSL: fix call to BIO_get_mem_data() Message-ID: # HG changeset patch # User Piotr Sikora # Date 1481667570 28800 # Tue Dec 13 14:19:30 2016 -0800 # Node ID c0b6eef901895a4790db1e62d2822651977399a4 # Parent 25a64c864f4d31761eb42d39cda8b0e80277816d SSL: fix call to BIO_get_mem_data(). Fixes build with BoringSSL. Signed-off-by: Piotr Sikora diff -r 25a64c864f4d -r c0b6eef90189 src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -4069,7 +4069,7 @@ ngx_ssl_parse_time( BIO_write(bio, "Tue ", sizeof("Tue ") - 1); ASN1_TIME_print(bio, asn1time); - len = BIO_get_mem_data(bio, &value); + len = BIO_get_mem_data(bio, (char **) &value); time = ngx_parse_http_time(value, len); From piotrsikora at google.com Tue Dec 13 23:41:44 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 13 Dec 2016 15:41:44 -0800 Subject: [nginx] SSL: $ssl_curves (ticket #1088). In-Reply-To: References: Message-ID: Hey Maxim, > details: http://hg.nginx.org/nginx/rev/e75e854657ba > branches: > changeset: 6817:e75e854657ba > user: Maxim Dounin > date: Mon Dec 05 22:23:23 2016 +0300 > description: > SSL: $ssl_curves (ticket #1088). > > The variable contains a list of curves as supported by the client. Why this isn't called $ssl_client_curves, then? Same question applies to $ssl_ciphers. Best regards, Piotr Sikora From khara at sios.com Wed Dec 14 04:38:37 2016 From: khara at sios.com (khara at sios.com) Date: Wed, 14 Dec 2016 13:38:37 +0900 Subject: [PATCH 1 of 2] rpm: Fixed incorrect change log day of the week Message-ID: <9c4a4bd4be50d4002300.1481690317@18c3d77e2113> # HG changeset patch # User Kazuhisa Hara # Date 1481688313 -32400 # Wed Dec 14 13:05:13 2016 +0900 # Node ID 9c4a4bd4be50d4002300dee737d9c0e610dbf898 # Parent 349953fceb547fa665faedc42127f61fa4d598d3 rpm: Fixed incorrect change log day of the week. rpmbuild warns of bogus dates. May 24, 2016 is Tuesday. diff -r 349953fceb54 -r 9c4a4bd4be50 rpm/SPECS/nginx.spec.in --- a/rpm/SPECS/nginx.spec.in Tue Dec 13 19:34:23 2016 +0300 +++ b/rpm/SPECS/nginx.spec.in Wed Dec 14 13:05:13 2016 +0900 @@ -328,7 +328,7 @@ * Tue May 31 2016 Konstantin Pavlov - 1.11.1 -* Wed May 24 2016 Sergey Budnevitch +* Tue May 24 2016 Sergey Budnevitch - Fixed logrotate error if nginx is not running - 1.11.0 From khara at sios.com Wed Dec 14 04:38:38 2016 From: khara at sios.com (khara at sios.com) Date: Wed, 14 Dec 2016 13:38:38 +0900 Subject: [PATCH 2 of 2] rpm: Added support for Fedora 18 or later In-Reply-To: <9c4a4bd4be50d4002300.1481690317@18c3d77e2113> References: <9c4a4bd4be50d4002300.1481690317@18c3d77e2113> Message-ID: <7d336407f7acef880435.1481690318@18c3d77e2113> # HG changeset patch # User Kazuhisa Hara # Date 1481688579 -32400 # Wed Dec 14 13:09:39 2016 +0900 # Node ID 7d336407f7acef88043531bc23e70b407642af91 # Parent 9c4a4bd4be50d4002300dee737d9c0e610dbf898 rpm: Added support for Fedora 18 or later. For Fedora 18 and later, the same build method as RHEL 7 can be used. diff -r 9c4a4bd4be50 -r 7d336407f7ac rpm/SPECS/nginx.spec.in --- a/rpm/SPECS/nginx.spec.in Wed Dec 14 13:05:13 2016 +0900 +++ b/rpm/SPECS/nginx.spec.in Wed Dec 14 13:09:39 2016 +0900 @@ -25,7 +25,7 @@ BuildRequires: openssl-devel >= 1.0.1 %endif -%if 0%{?rhel} == 7 +%if 0%{?rhel} == 7 || 0%{?fedora} >= 18) %define _group System Environment/Daemons %define epoch 1 Epoch: %{epoch} From khara at sios.com Wed Dec 14 04:44:54 2016 From: khara at sios.com (=?UTF-8?B?5Y6f5ZKM5LmF?=) Date: Wed, 14 Dec 2016 13:44:54 +0900 Subject: [PATCH 2 of 2] rpm: Added support for Fedora 18 or later In-Reply-To: <7d336407f7acef880435.1481690318@18c3d77e2113> References: <9c4a4bd4be50d4002300.1481690317@18c3d77e2113> <7d336407f7acef880435.1481690318@18c3d77e2113> Message-ID: Hi, These two patches are for the pkg-oss repository. Could you take a look at the following patch? Thanks and regards. 2016-12-14 13:38 GMT+09:00 : > # HG changeset patch > # User Kazuhisa Hara > # Date 1481688579 -32400 > # Wed Dec 14 13:09:39 2016 +0900 > # Node ID 7d336407f7acef88043531bc23e70b407642af91 > # Parent 9c4a4bd4be50d4002300dee737d9c0e610dbf898 > rpm: Added support for Fedora 18 or later. > > For Fedora 18 and later, the same build method as RHEL 7 can be used. > > diff -r 9c4a4bd4be50 -r 7d336407f7ac rpm/SPECS/nginx.spec.in > --- a/rpm/SPECS/nginx.spec.in Wed Dec 14 13:05:13 2016 +0900 > +++ b/rpm/SPECS/nginx.spec.in Wed Dec 14 13:09:39 2016 +0900 > @@ -25,7 +25,7 @@ > BuildRequires: openssl-devel >= 1.0.1 > %endif > > -%if 0%{?rhel} == 7 > +%if 0%{?rhel} == 7 || 0%{?fedora} >= 18) > %define _group System Environment/Daemons > %define epoch 1 > Epoch: %{epoch} > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -- Kazuhisa Hara Software Engineer OSS Technology Center Engineering Department SIOS Technology, Inc. Tel. +81-3-6401-5117 From mdounin at mdounin.ru Wed Dec 14 14:48:56 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 14 Dec 2016 17:48:56 +0300 Subject: [nginx] SSL: $ssl_curves (ticket #1088). In-Reply-To: References: Message-ID: <20161214144856.GJ18639@mdounin.ru> Hello! On Tue, Dec 13, 2016 at 03:41:44PM -0800, Piotr Sikora via nginx-devel wrote: > > details: http://hg.nginx.org/nginx/rev/e75e854657ba > > branches: > > changeset: 6817:e75e854657ba > > user: Maxim Dounin > > date: Mon Dec 05 22:23:23 2016 +0300 > > description: > > SSL: $ssl_curves (ticket #1088). > > > > The variable contains a list of curves as supported by the client. > > Why this isn't called $ssl_client_curves, then? > > Same question applies to $ssl_ciphers. The $ssl_client_* variables are used for variables related to client certificate verification, more specifically - client certificate and its properties. Various other entities, including ones supplied by the client, do not use "client" prefix - e.g., $ssl_server_name. -- Maxim Dounin http://nginx.org/ From maxim at nginx.com Wed Dec 14 16:54:19 2016 From: maxim at nginx.com (Maxim Konovalov) Date: Wed, 14 Dec 2016 19:54:19 +0300 Subject: [PATCH 1 of 2] rpm: Fixed incorrect change log day of the week In-Reply-To: <9c4a4bd4be50d4002300.1481690317@18c3d77e2113> References: <9c4a4bd4be50d4002300.1481690317@18c3d77e2113> Message-ID: <2cc074e2-a7a9-895c-08a2-aba3b2296fcd@nginx.com> Hello, On 12/14/16 7:38 AM, khara at sios.com wrote: > # HG changeset patch > # User Kazuhisa Hara > # Date 1481688313 -32400 > # Wed Dec 14 13:05:13 2016 +0900 > # Node ID 9c4a4bd4be50d4002300dee737d9c0e610dbf898 > # Parent 349953fceb547fa665faedc42127f61fa4d598d3 > rpm: Fixed incorrect change log day of the week. > > rpmbuild warns of bogus dates. > May 24, 2016 is Tuesday. > > diff -r 349953fceb54 -r 9c4a4bd4be50 rpm/SPECS/nginx.spec.in > --- a/rpm/SPECS/nginx.spec.in Tue Dec 13 19:34:23 2016 +0300 > +++ b/rpm/SPECS/nginx.spec.in Wed Dec 14 13:05:13 2016 +0900 > @@ -328,7 +328,7 @@ > * Tue May 31 2016 Konstantin Pavlov > - 1.11.1 > > -* Wed May 24 2016 Sergey Budnevitch > +* Tue May 24 2016 Sergey Budnevitch > - Fixed logrotate error if nginx is not running > - 1.11.0 > Thanks for the patch! Just curious: how did you find that? -- Maxim Konovalov From sb at nginx.com Wed Dec 14 17:10:07 2016 From: sb at nginx.com (Sergey Budnevitch) Date: Wed, 14 Dec 2016 20:10:07 +0300 Subject: [PATCH 1 of 2] rpm: Fixed incorrect change log day of the week In-Reply-To: <9c4a4bd4be50d4002300.1481690317@18c3d77e2113> References: <9c4a4bd4be50d4002300.1481690317@18c3d77e2113> Message-ID: <7667AA4E-B5AF-4F00-B2BC-EB5EF8CB9761@nginx.com> This patch committed, thanks, second one was not as we have no plans to support fedora. > On 14 Dec 2016, at 07:38, khara at sios.com wrote: > > # HG changeset patch > # User Kazuhisa Hara > # Date 1481688313 -32400 > # Wed Dec 14 13:05:13 2016 +0900 > # Node ID 9c4a4bd4be50d4002300dee737d9c0e610dbf898 > # Parent 349953fceb547fa665faedc42127f61fa4d598d3 > rpm: Fixed incorrect change log day of the week. > > rpmbuild warns of bogus dates. > May 24, 2016 is Tuesday. > > diff -r 349953fceb54 -r 9c4a4bd4be50 rpm/SPECS/nginx.spec.in > --- a/rpm/SPECS/nginx.spec.in Tue Dec 13 19:34:23 2016 +0300 > +++ b/rpm/SPECS/nginx.spec.in Wed Dec 14 13:05:13 2016 +0900 > @@ -328,7 +328,7 @@ > * Tue May 31 2016 Konstantin Pavlov > - 1.11.1 > > -* Wed May 24 2016 Sergey Budnevitch > +* Tue May 24 2016 Sergey Budnevitch > - Fixed logrotate error if nginx is not running > - 1.11.0 > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From mdounin at mdounin.ru Wed Dec 14 17:17:27 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 14 Dec 2016 20:17:27 +0300 Subject: [PATCH] SSL: fix call to BIO_get_mem_data() In-Reply-To: References: Message-ID: <20161214171727.GN18639@mdounin.ru> Hello! On Tue, Dec 13, 2016 at 02:20:40PM -0800, Piotr Sikora via nginx-devel wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1481667570 28800 > # Tue Dec 13 14:19:30 2016 -0800 > # Node ID c0b6eef901895a4790db1e62d2822651977399a4 > # Parent 25a64c864f4d31761eb42d39cda8b0e80277816d > SSL: fix call to BIO_get_mem_data(). > > Fixes build with BoringSSL. > > Signed-off-by: Piotr Sikora > > diff -r 25a64c864f4d -r c0b6eef90189 src/event/ngx_event_openssl.c > --- a/src/event/ngx_event_openssl.c > +++ b/src/event/ngx_event_openssl.c > @@ -4069,7 +4069,7 @@ ngx_ssl_parse_time( > > BIO_write(bio, "Tue ", sizeof("Tue ") - 1); > ASN1_TIME_print(bio, asn1time); > - len = BIO_get_mem_data(bio, &value); > + len = BIO_get_mem_data(bio, (char **) &value); > > time = ngx_parse_http_time(value, len); > If the goal is to fix the call, shouldn't identical one in src/event/ngx_event_openssl_stapling.c be fixed as well? -- Maxim Dounin http://nginx.org/ From piotrsikora at google.com Wed Dec 14 19:43:08 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 14 Dec 2016 11:43:08 -0800 Subject: [PATCH] SSL: fix call to BIO_get_mem_data() In-Reply-To: <20161214171727.GN18639@mdounin.ru> References: <20161214171727.GN18639@mdounin.ru> Message-ID: <4848b2eea6ba373d29c0.1481744588@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1481667570 28800 # Tue Dec 13 14:19:30 2016 -0800 # Node ID 4848b2eea6ba373d29c036b3b5acbeaf0f038587 # Parent 25a64c864f4d31761eb42d39cda8b0e80277816d SSL: fix call to BIO_get_mem_data(). Fixes build with BoringSSL. Signed-off-by: Piotr Sikora diff -r 25a64c864f4d -r 4848b2eea6ba src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -4069,7 +4069,7 @@ ngx_ssl_parse_time( BIO_write(bio, "Tue ", sizeof("Tue ") - 1); ASN1_TIME_print(bio, asn1time); - len = BIO_get_mem_data(bio, &value); + len = BIO_get_mem_data(bio, (char **) &value); time = ngx_parse_http_time(value, len); diff -r 25a64c864f4d -r 4848b2eea6ba src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c +++ b/src/event/ngx_event_openssl_stapling.c @@ -793,7 +793,7 @@ ngx_ssl_stapling_time(ASN1_GENERALIZEDTI BIO_write(bio, "Tue ", sizeof("Tue ") - 1); ASN1_GENERALIZEDTIME_print(bio, asn1time); - len = BIO_get_mem_data(bio, &value); + len = BIO_get_mem_data(bio, (char **) &value); time = ngx_parse_http_time(value, len); From piotrsikora at google.com Wed Dec 14 19:43:49 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 14 Dec 2016 11:43:49 -0800 Subject: [PATCH] SSL: fix call to BIO_get_mem_data() In-Reply-To: <20161214171727.GN18639@mdounin.ru> References: <20161214171727.GN18639@mdounin.ru> Message-ID: Hey Maxim, > If the goal is to fix the call, shouldn't identical one in > src/event/ngx_event_openssl_stapling.c be fixed as well? Good catch, thanks! Best regards, Piotr Sikora From khara at sios.com Thu Dec 15 01:05:26 2016 From: khara at sios.com (=?UTF-8?B?5Y6f5ZKM5LmF?=) Date: Thu, 15 Dec 2016 10:05:26 +0900 Subject: [PATCH 1 of 2] rpm: Fixed incorrect change log day of the week In-Reply-To: <7667AA4E-B5AF-4F00-B2BC-EB5EF8CB9761@nginx.com> References: <9c4a4bd4be50d4002300.1481690317@18c3d77e2113> <7667AA4E-B5AF-4F00-B2BC-EB5EF8CB9761@nginx.com> Message-ID: Hi, > This patch committed, thanks, second one was not as we have no > plans to support fedora. Thank you for the merge. and I understood about support of fedora. # I'm interested in using mainline version with fedora. # But fedora is fast to update, therefore also understand that # maintenance are many hardships... > Just curious: how did you find that? I found it when I watching Mercurial page. hg.nginx.org/nginx -> Mercurial(Page Top Link) -> pkg-oss Thanks and regards. -- Kazuhisa Hara Software Engineer OSS Technology Center Engineering Department SIOS Technology, Inc. Tel. +81-3-6401-5117 From vbart at nginx.com Thu Dec 15 13:26:05 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 15 Dec 2016 13:26:05 +0000 Subject: [nginx] Access log: support for json escaping. Message-ID: details: http://hg.nginx.org/nginx/rev/0cf4e82e7c48 branches: changeset: 6840:0cf4e82e7c48 user: Valentin Bartenev date: Thu Dec 15 16:25:42 2016 +0300 description: Access log: support for json escaping. diffstat: src/http/modules/ngx_http_log_module.c | 83 +++++++++++++++++++++++++++++++-- src/stream/ngx_stream_log_module.c | 83 +++++++++++++++++++++++++++++++-- 2 files changed, 154 insertions(+), 12 deletions(-) diffs (275 lines): diff -r 32714e608629 -r 0cf4e82e7c48 src/http/modules/ngx_http_log_module.c --- a/src/http/modules/ngx_http_log_module.c Tue Dec 13 00:49:44 2016 +0100 +++ b/src/http/modules/ngx_http_log_module.c Thu Dec 15 16:25:42 2016 +0300 @@ -126,12 +126,16 @@ static u_char *ngx_http_log_request_leng ngx_http_log_op_t *op); static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf, - ngx_http_log_op_t *op, ngx_str_t *value); + ngx_http_log_op_t *op, ngx_str_t *value, ngx_uint_t json); static size_t ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data); static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size); +static size_t ngx_http_log_json_variable_getlen(ngx_http_request_t *r, + uintptr_t data); +static u_char *ngx_http_log_json_variable(ngx_http_request_t *r, u_char *buf, + ngx_http_log_op_t *op); static void *ngx_http_log_create_main_conf(ngx_conf_t *cf); @@ -909,7 +913,7 @@ ngx_http_log_request_length(ngx_http_req static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf, ngx_http_log_op_t *op, - ngx_str_t *value) + ngx_str_t *value, ngx_uint_t json) { ngx_int_t index; @@ -919,8 +923,16 @@ ngx_http_log_variable_compile(ngx_conf_t } op->len = 0; - op->getlen = ngx_http_log_variable_getlen; - op->run = ngx_http_log_variable; + + if (json) { + op->getlen = ngx_http_log_json_variable_getlen; + op->run = ngx_http_log_json_variable; + + } else { + op->getlen = ngx_http_log_variable_getlen; + op->run = ngx_http_log_variable; + } + op->data = index; return NGX_OK; @@ -1028,6 +1040,47 @@ ngx_http_log_escape(u_char *dst, u_char } +static size_t +ngx_http_log_json_variable_getlen(ngx_http_request_t *r, uintptr_t data) +{ + uintptr_t len; + ngx_http_variable_value_t *value; + + value = ngx_http_get_indexed_variable(r, data); + + if (value == NULL || value->not_found) { + return 0; + } + + len = ngx_escape_json(NULL, value->data, value->len); + + value->escape = len ? 1 : 0; + + return value->len + len; +} + + +static u_char * +ngx_http_log_json_variable(ngx_http_request_t *r, u_char *buf, + ngx_http_log_op_t *op) +{ + ngx_http_variable_value_t *value; + + value = ngx_http_get_indexed_variable(r, op->data); + + if (value == NULL || value->not_found) { + return buf; + } + + if (value->escape == 0) { + return ngx_cpymem(buf, value->data, value->len); + + } else { + return (u_char *) ngx_escape_json(buf, value->data, value->len); + } +} + + static void * ngx_http_log_create_main_conf(ngx_conf_t *cf) { @@ -1491,12 +1544,28 @@ ngx_http_log_compile_format(ngx_conf_t * size_t i, len; ngx_str_t *value, var; ngx_int_t *flush; - ngx_uint_t bracket; + ngx_uint_t bracket, json; ngx_http_log_op_t *op; ngx_http_log_var_t *v; + json = 0; value = args->elts; + if (s < args->nelts && ngx_strncmp(value[s].data, "escape=", 7) == 0) { + data = value[s].data + 7; + + if (ngx_strcmp(data, "json") == 0) { + json = 1; + + } else if (ngx_strcmp(data, "default") != 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unknown log format escaping \"%s\"", data); + return NGX_CONF_ERROR; + } + + s++; + } + for ( /* void */ ; s < args->nelts; s++) { i = 0; @@ -1575,7 +1644,9 @@ ngx_http_log_compile_format(ngx_conf_t * } } - if (ngx_http_log_variable_compile(cf, op, &var) != NGX_OK) { + if (ngx_http_log_variable_compile(cf, op, &var, json) + != NGX_OK) + { return NGX_CONF_ERROR; } diff -r 32714e608629 -r 0cf4e82e7c48 src/stream/ngx_stream_log_module.c --- a/src/stream/ngx_stream_log_module.c Tue Dec 13 00:49:44 2016 +0100 +++ b/src/stream/ngx_stream_log_module.c Thu Dec 15 16:25:42 2016 +0300 @@ -106,12 +106,16 @@ static void ngx_stream_log_flush(ngx_ope static void ngx_stream_log_flush_handler(ngx_event_t *ev); static ngx_int_t ngx_stream_log_variable_compile(ngx_conf_t *cf, - ngx_stream_log_op_t *op, ngx_str_t *value); + ngx_stream_log_op_t *op, ngx_str_t *value, ngx_uint_t json); static size_t ngx_stream_log_variable_getlen(ngx_stream_session_t *s, uintptr_t data); static u_char *ngx_stream_log_variable(ngx_stream_session_t *s, u_char *buf, ngx_stream_log_op_t *op); static uintptr_t ngx_stream_log_escape(u_char *dst, u_char *src, size_t size); +static size_t ngx_stream_log_json_variable_getlen(ngx_stream_session_t *s, + uintptr_t data); +static u_char *ngx_stream_log_json_variable(ngx_stream_session_t *s, + u_char *buf, ngx_stream_log_op_t *op); static void *ngx_stream_log_create_main_conf(ngx_conf_t *cf); @@ -686,7 +690,7 @@ ngx_stream_log_copy_long(ngx_stream_sess static ngx_int_t ngx_stream_log_variable_compile(ngx_conf_t *cf, ngx_stream_log_op_t *op, - ngx_str_t *value) + ngx_str_t *value, ngx_uint_t json) { ngx_int_t index; @@ -696,8 +700,16 @@ ngx_stream_log_variable_compile(ngx_conf } op->len = 0; - op->getlen = ngx_stream_log_variable_getlen; - op->run = ngx_stream_log_variable; + + if (json) { + op->getlen = ngx_stream_log_json_variable_getlen; + op->run = ngx_stream_log_json_variable; + + } else { + op->getlen = ngx_stream_log_variable_getlen; + op->run = ngx_stream_log_variable; + } + op->data = index; return NGX_OK; @@ -806,6 +818,47 @@ ngx_stream_log_escape(u_char *dst, u_cha } +static size_t +ngx_stream_log_json_variable_getlen(ngx_stream_session_t *s, uintptr_t data) +{ + uintptr_t len; + ngx_stream_variable_value_t *value; + + value = ngx_stream_get_indexed_variable(s, data); + + if (value == NULL || value->not_found) { + return 0; + } + + len = ngx_escape_json(NULL, value->data, value->len); + + value->escape = len ? 1 : 0; + + return value->len + len; +} + + +static u_char * +ngx_stream_log_json_variable(ngx_stream_session_t *s, u_char *buf, + ngx_stream_log_op_t *op) +{ + ngx_stream_variable_value_t *value; + + value = ngx_stream_get_indexed_variable(s, op->data); + + if (value == NULL || value->not_found) { + return buf; + } + + if (value->escape == 0) { + return ngx_cpymem(buf, value->data, value->len); + + } else { + return (u_char *) ngx_escape_json(buf, value->data, value->len); + } +} + + static void * ngx_stream_log_create_main_conf(ngx_conf_t *cf) { @@ -1220,11 +1273,27 @@ ngx_stream_log_compile_format(ngx_conf_t size_t i, len; ngx_str_t *value, var; ngx_int_t *flush; - ngx_uint_t bracket; + ngx_uint_t bracket, json; ngx_stream_log_op_t *op; + json = 0; value = args->elts; + if (s < args->nelts && ngx_strncmp(value[s].data, "escape=", 7) == 0) { + data = value[s].data + 7; + + if (ngx_strcmp(data, "json") == 0) { + json = 1; + + } else if (ngx_strcmp(data, "default") != 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unknown log format escaping \"%s\"", data); + return NGX_CONF_ERROR; + } + + s++; + } + for ( /* void */ ; s < args->nelts; s++) { i = 0; @@ -1289,7 +1358,9 @@ ngx_stream_log_compile_format(ngx_conf_t goto invalid; } - if (ngx_stream_log_variable_compile(cf, op, &var) != NGX_OK) { + if (ngx_stream_log_variable_compile(cf, op, &var, json) + != NGX_OK) + { return NGX_CONF_ERROR; } From mdounin at mdounin.ru Thu Dec 15 15:30:57 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 15 Dec 2016 15:30:57 +0000 Subject: [nginx] SSL: fix call to BIO_get_mem_data(). Message-ID: details: http://hg.nginx.org/nginx/rev/e7cb5deb951d branches: changeset: 6841:e7cb5deb951d user: Piotr Sikora date: Tue Dec 13 14:19:30 2016 -0800 description: SSL: fix call to BIO_get_mem_data(). Fixes build with BoringSSL. Signed-off-by: Piotr Sikora diffstat: src/event/ngx_event_openssl.c | 2 +- src/event/ngx_event_openssl_stapling.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (24 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -4069,7 +4069,7 @@ ngx_ssl_parse_time( BIO_write(bio, "Tue ", sizeof("Tue ") - 1); ASN1_TIME_print(bio, asn1time); - len = BIO_get_mem_data(bio, &value); + len = BIO_get_mem_data(bio, (char **) &value); time = ngx_parse_http_time(value, len); diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c +++ b/src/event/ngx_event_openssl_stapling.c @@ -793,7 +793,7 @@ ngx_ssl_stapling_time(ASN1_GENERALIZEDTI BIO_write(bio, "Tue ", sizeof("Tue ") - 1); ASN1_GENERALIZEDTIME_print(bio, asn1time); - len = BIO_get_mem_data(bio, &value); + len = BIO_get_mem_data(bio, (char **) &value); time = ngx_parse_http_time(value, len); From mdounin at mdounin.ru Thu Dec 15 15:31:31 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 15 Dec 2016 18:31:31 +0300 Subject: [PATCH] SSL: fix call to BIO_get_mem_data() In-Reply-To: <4848b2eea6ba373d29c0.1481744588@piotrsikora.sfo.corp.google.com> References: <20161214171727.GN18639@mdounin.ru> <4848b2eea6ba373d29c0.1481744588@piotrsikora.sfo.corp.google.com> Message-ID: <20161215153131.GT18639@mdounin.ru> Hello! On Wed, Dec 14, 2016 at 11:43:08AM -0800, Piotr Sikora via nginx-devel wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1481667570 28800 > # Tue Dec 13 14:19:30 2016 -0800 > # Node ID 4848b2eea6ba373d29c036b3b5acbeaf0f038587 > # Parent 25a64c864f4d31761eb42d39cda8b0e80277816d > SSL: fix call to BIO_get_mem_data(). > > Fixes build with BoringSSL. > > Signed-off-by: Piotr Sikora > > diff -r 25a64c864f4d -r 4848b2eea6ba src/event/ngx_event_openssl.c > --- a/src/event/ngx_event_openssl.c > +++ b/src/event/ngx_event_openssl.c > @@ -4069,7 +4069,7 @@ ngx_ssl_parse_time( > > BIO_write(bio, "Tue ", sizeof("Tue ") - 1); > ASN1_TIME_print(bio, asn1time); > - len = BIO_get_mem_data(bio, &value); > + len = BIO_get_mem_data(bio, (char **) &value); > > time = ngx_parse_http_time(value, len); > > diff -r 25a64c864f4d -r 4848b2eea6ba src/event/ngx_event_openssl_stapling.c > --- a/src/event/ngx_event_openssl_stapling.c > +++ b/src/event/ngx_event_openssl_stapling.c > @@ -793,7 +793,7 @@ ngx_ssl_stapling_time(ASN1_GENERALIZEDTI > > BIO_write(bio, "Tue ", sizeof("Tue ") - 1); > ASN1_GENERALIZEDTIME_print(bio, asn1time); > - len = BIO_get_mem_data(bio, &value); > + len = BIO_get_mem_data(bio, (char **) &value); > > time = ngx_parse_http_time(value, len); > Committed, thanks. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Thu Dec 15 17:06:28 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 15 Dec 2016 17:06:28 +0000 Subject: [nginx] SSL: backed out changeset e7cb5deb951d, reimplemented properly. Message-ID: details: http://hg.nginx.org/nginx/rev/25d0d6dabe00 branches: changeset: 6842:25d0d6dabe00 user: Maxim Dounin date: Thu Dec 15 19:00:23 2016 +0300 description: SSL: backed out changeset e7cb5deb951d, reimplemented properly. Changeset e7cb5deb951d breaks build on CentOS 5 with "dereferencing type-punned pointer will break strict-aliasing rules" warning. It is backed out. Instead, to keep builds with BoringSSL happy, type of the "value" variable changed to "char *", and an explicit cast added before calling ngx_parse_http_time(). diffstat: src/event/ngx_event_openssl.c | 8 ++++---- src/event/ngx_event_openssl_stapling.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diffs (49 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -4049,7 +4049,7 @@ ngx_ssl_parse_time( ASN1_TIME *asn1time) { BIO *bio; - u_char *value; + char *value; size_t len; time_t time; @@ -4069,9 +4069,9 @@ ngx_ssl_parse_time( BIO_write(bio, "Tue ", sizeof("Tue ") - 1); ASN1_TIME_print(bio, asn1time); - len = BIO_get_mem_data(bio, (char **) &value); - - time = ngx_parse_http_time(value, len); + len = BIO_get_mem_data(bio, &value); + + time = ngx_parse_http_time((u_char *) value, len); BIO_free(bio); diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c +++ b/src/event/ngx_event_openssl_stapling.c @@ -773,7 +773,7 @@ static time_t ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time) { BIO *bio; - u_char *value; + char *value; size_t len; time_t time; @@ -793,9 +793,9 @@ ngx_ssl_stapling_time(ASN1_GENERALIZEDTI BIO_write(bio, "Tue ", sizeof("Tue ") - 1); ASN1_GENERALIZEDTIME_print(bio, asn1time); - len = BIO_get_mem_data(bio, (char **) &value); + len = BIO_get_mem_data(bio, &value); - time = ngx_parse_http_time(value, len); + time = ngx_parse_http_time((u_char *) value, len); BIO_free(bio); From mdounin at mdounin.ru Thu Dec 15 17:07:48 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 15 Dec 2016 20:07:48 +0300 Subject: [PATCH] SSL: fix call to BIO_get_mem_data() In-Reply-To: <20161215153131.GT18639@mdounin.ru> References: <20161214171727.GN18639@mdounin.ru> <4848b2eea6ba373d29c0.1481744588@piotrsikora.sfo.corp.google.com> <20161215153131.GT18639@mdounin.ru> Message-ID: <20161215170747.GV18639@mdounin.ru> Hello! On Thu, Dec 15, 2016 at 06:31:31PM +0300, Maxim Dounin wrote: > Hello! > > On Wed, Dec 14, 2016 at 11:43:08AM -0800, Piotr Sikora via nginx-devel wrote: > > > # HG changeset patch > > # User Piotr Sikora > > # Date 1481667570 28800 > > # Tue Dec 13 14:19:30 2016 -0800 > > # Node ID 4848b2eea6ba373d29c036b3b5acbeaf0f038587 > > # Parent 25a64c864f4d31761eb42d39cda8b0e80277816d > > SSL: fix call to BIO_get_mem_data(). > > > > Fixes build with BoringSSL. > > > > Signed-off-by: Piotr Sikora > > > > diff -r 25a64c864f4d -r 4848b2eea6ba src/event/ngx_event_openssl.c > > --- a/src/event/ngx_event_openssl.c > > +++ b/src/event/ngx_event_openssl.c > > @@ -4069,7 +4069,7 @@ ngx_ssl_parse_time( > > > > BIO_write(bio, "Tue ", sizeof("Tue ") - 1); > > ASN1_TIME_print(bio, asn1time); > > - len = BIO_get_mem_data(bio, &value); > > + len = BIO_get_mem_data(bio, (char **) &value); > > > > time = ngx_parse_http_time(value, len); > > > > diff -r 25a64c864f4d -r 4848b2eea6ba src/event/ngx_event_openssl_stapling.c > > --- a/src/event/ngx_event_openssl_stapling.c > > +++ b/src/event/ngx_event_openssl_stapling.c > > @@ -793,7 +793,7 @@ ngx_ssl_stapling_time(ASN1_GENERALIZEDTI > > > > BIO_write(bio, "Tue ", sizeof("Tue ") - 1); > > ASN1_GENERALIZEDTIME_print(bio, asn1time); > > - len = BIO_get_mem_data(bio, &value); > > + len = BIO_get_mem_data(bio, (char **) &value); > > > > time = ngx_parse_http_time(value, len); > > > > Committed, thanks. Uhm, this change breaks build on CentOS 5: src/event/ngx_event_openssl.c: In function ?ngx_ssl_parse_time?: src/event/ngx_event_openssl.c:4072: warning: dereferencing type-punned pointer will break strict-aliasing rules Backed out, replaced with an alternative solution which seems to fix BoringSSL as well, see http://hg.nginx.org/nginx/rev/25d0d6dabe00. -- Maxim Dounin http://nginx.org/ From ru at nginx.com Thu Dec 15 19:01:15 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 15 Dec 2016 19:01:15 +0000 Subject: [nginx] Resolver: fixed possible use-after-free in worker on fast shutdown. Message-ID: details: http://hg.nginx.org/nginx/rev/a3dc657f4e95 branches: changeset: 6843:a3dc657f4e95 user: Ruslan Ermilov date: Thu Dec 15 21:44:34 2016 +0300 description: Resolver: fixed possible use-after-free in worker on fast shutdown. diffstat: src/core/ngx_resolver.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r 25d0d6dabe00 -r a3dc657f4e95 src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Thu Dec 15 19:00:23 2016 +0300 +++ b/src/core/ngx_resolver.c Thu Dec 15 21:44:34 2016 +0300 @@ -300,6 +300,10 @@ ngx_resolver_cleanup(void *data) #endif if (r->event) { + if (r->event->timer_set) { + ngx_del_timer(r->event); + } + ngx_free(r->event); } From thibaultcha at fastmail.com Fri Dec 16 01:17:30 2016 From: thibaultcha at fastmail.com (Thibault Charbonnier) Date: Thu, 15 Dec 2016 17:17:30 -0800 Subject: [PATCH] ignore ipv6=off resolver option when no ipv6 support Message-ID: Hello, Please let me know how you feel about this relatively simple patch which aims at making the "resolver" directive more robust with regards to the "ipv6=" option when Nginx is built without IPv6 support. Thanks! # HG changeset patch # User Thibault Charbonnier # Date 1481847421 28800 # Thu Dec 15 16:17:01 2016 -0800 # Node ID 8bf038fe006fd8ae253d6b41fc6cf109a8912d3e # Parent a3dc657f4e9530623683e6b85bd7492662e4dc47 Resolver: ignore ipv6=off resolver option when no ipv6 support Makes the resolver directive more robust: we only error out when ipv6 resolution is desired but not supported (ipv6=on). use case 1: some configurations are sometimes re-used between builds with and without ipv6 support. This patch avoids the need to remove the "ipv6=off" flag. use case 2: currently, some tools rely on the --with-ipv6 configure option from "nginx -V" to determine if ipv6 resolution should be disabled in some cases. With this option disappearing in Nginx 1.11.5, this patch would allow such tools to assume "ipv6=off" to be safe regardless of ipv6 support in the current build. diff -r a3dc657f4e95 -r 8bf038fe006f src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Thu Dec 15 21:44:34 2016 +0300 +++ b/src/core/ngx_resolver.c Thu Dec 15 16:17:01 2016 -0800 @@ -224,14 +224,22 @@ continue; } -#if (NGX_HAVE_INET6) if (ngx_strncmp(names[i].data, "ipv6=", 5) == 0) { if (ngx_strcmp(&names[i].data[5], "on") == 0) { +#if (NGX_HAVE_INET6) r->ipv6 = 1; +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "no ipv6 support but \"%V\" in resolver", + &names[i]); + return NULL; +#endif } else if (ngx_strcmp(&names[i].data[5], "off") == 0) { +#if (NGX_HAVE_INET6) r->ipv6 = 0; +#endif } else { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -241,7 +249,6 @@ continue; } -#endif ngx_memzero(&u, sizeof(ngx_url_t)); From mdounin at mdounin.ru Fri Dec 16 15:07:27 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 16 Dec 2016 18:07:27 +0300 Subject: [PATCH] ignore ipv6=off resolver option when no ipv6 support In-Reply-To: References: Message-ID: <20161216150727.GC18639@mdounin.ru> Hello! On Thu, Dec 15, 2016 at 05:17:30PM -0800, Thibault Charbonnier wrote: > Please let me know how you feel about this relatively simple patch which > aims at making the "resolver" directive more robust with regards to the > "ipv6=" option when Nginx is built without IPv6 support. Builds without IPv6 support is something we are phasing out. Starting with nginx 1.11.5 IPv6 support is automatically configured as long as supported by OS: Changes with nginx 1.11.5, 11 Oct 2016: *) Change: the --with-ipv6 configure option was removed, now IPv6 support is configured automatically. So I don't think that such a change will make any difference. -- Maxim Dounin http://nginx.org/ From ru at nginx.com Fri Dec 16 15:16:41 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Fri, 16 Dec 2016 15:16:41 +0000 Subject: [nginx] Resolver: fixed possible use-after-free in worker on fast shutdown. Message-ID: details: http://hg.nginx.org/nginx/rev/259e2a76e8fb branches: changeset: 6844:259e2a76e8fb user: Ruslan Ermilov date: Fri Dec 16 14:53:28 2016 +0300 description: Resolver: fixed possible use-after-free in worker on fast shutdown. The fix in a3dc657f4e95 was incomplete. diffstat: src/core/ngx_resolver.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r a3dc657f4e95 -r 259e2a76e8fb src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Thu Dec 15 21:44:34 2016 +0300 +++ b/src/core/ngx_resolver.c Fri Dec 16 14:53:28 2016 +0300 @@ -351,6 +351,10 @@ ngx_resolver_cleanup_tree(ngx_resolver_t next = ctx->next; if (ctx->event) { + if (ctx->event->timer_set) { + ngx_del_timer(ctx->event); + } + ngx_resolver_free(r, ctx->event); } From xeioex at nginx.com Fri Dec 16 15:22:12 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 16 Dec 2016 15:22:12 +0000 Subject: [nginx] Resolver: fixed possible premature stop of the resend timer. Message-ID: details: http://hg.nginx.org/nginx/rev/9abba5b70ea0 branches: changeset: 6845:9abba5b70ea0 user: Dmitry Volyntsev date: Fri Dec 16 18:21:42 2016 +0300 description: Resolver: fixed possible premature stop of the resend timer. Previously, ngx_resolve_name_done() and ngx_resolve_addr_done() may have stopped the resend timer prematurely while srv_resend_queue was not empty. diffstat: src/core/ngx_resolver.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 259e2a76e8fb -r 9abba5b70ea0 src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Fri Dec 16 14:53:28 2016 +0300 +++ b/src/core/ngx_resolver.c Fri Dec 16 18:21:42 2016 +0300 @@ -1556,6 +1556,7 @@ static ngx_uint_t ngx_resolver_resend_empty(ngx_resolver_t *r) { return ngx_queue_empty(&r->name_resend_queue) + && ngx_queue_empty(&r->srv_resend_queue) #if (NGX_HAVE_INET6) && ngx_queue_empty(&r->addr6_resend_queue) #endif From xeioex at nginx.com Fri Dec 16 15:22:15 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 16 Dec 2016 15:22:15 +0000 Subject: [nginx] Resolver: fixed a race between parallel name and addr resolves. Message-ID: details: http://hg.nginx.org/nginx/rev/c3a895b94d3f branches: changeset: 6846:c3a895b94d3f user: Dmitry Volyntsev date: Fri Dec 16 18:21:55 2016 +0300 description: Resolver: fixed a race between parallel name and addr resolves. Previously, ngx_resolve_name() and ngx_resolve_addr() may have rescheduled the resend timer while it was already in progress. diffstat: src/core/ngx_resolver.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 9abba5b70ea0 -r c3a895b94d3f src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Fri Dec 16 18:21:42 2016 +0300 +++ b/src/core/ngx_resolver.c Fri Dec 16 18:21:55 2016 +0300 @@ -875,7 +875,7 @@ ngx_resolve_name_locked(ngx_resolver_t * ngx_add_timer(ctx->event, ctx->timeout); } - if (ngx_queue_empty(resend_queue)) { + if (ngx_resolver_resend_empty(r)) { ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000)); } @@ -1098,7 +1098,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx ngx_add_timer(ctx->event, ctx->timeout); } - if (ngx_queue_empty(resend_queue)) { + if (ngx_resolver_resend_empty(r)) { ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000)); } From xeioex at nginx.com Fri Dec 16 15:22:18 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 16 Dec 2016 15:22:18 +0000 Subject: [nginx] Resolver: fixed handling of partially resolved SRV. Message-ID: details: http://hg.nginx.org/nginx/rev/d72b38376092 branches: changeset: 6847:d72b38376092 user: Dmitry Volyntsev date: Fri Dec 16 18:21:55 2016 +0300 description: Resolver: fixed handling of partially resolved SRV. The resolver handles SRV requests in two stages. In the first stage it gets all SRV RRs, and in the second stage it resolves the names from SRV RRs into addresses. Previously, if a response to an SRV request was cached, the queries to resolve names were not limited by a timeout. If a response to any of these queries was not received, the SRV request could never complete. If a response to an SRV request was not cached, and some of the queries to resolve names timed out, NGX_RESOLVE_TIMEDOUT was returned instead of successfully resolved addresses. To fix both issues, resolving of names is now always limited by a timeout. diffstat: src/core/ngx_resolver.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diffs (23 lines): diff -r c3a895b94d3f -r d72b38376092 src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Fri Dec 16 18:21:55 2016 +0300 +++ b/src/core/ngx_resolver.c Fri Dec 16 18:21:55 2016 +0300 @@ -2955,6 +2955,10 @@ ngx_resolver_resolve_srv_names(ngx_resol ctx->srvs = srvs; ctx->nsrvs = rn->nsrvs; + if (ctx->event && ctx->event->timer_set) { + ngx_del_timer(ctx->event); + } + for (i = 0; i < rn->nsrvs; i++) { srvs[i].name.data = ngx_resolver_alloc(r, rn->u.srvs[i].name.len); if (srvs[i].name.data == NULL) { @@ -2974,7 +2978,7 @@ ngx_resolver_resolve_srv_names(ngx_resol cctx->handler = ngx_resolver_srv_names_handler; cctx->data = ctx; cctx->srvs = &srvs[i]; - cctx->timeout = 0; + cctx->timeout = ctx->timeout; srvs[i].priority = rn->u.srvs[i].priority; srvs[i].weight = rn->u.srvs[i].weight; From vbart at nginx.com Fri Dec 16 15:24:26 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 16 Dec 2016 15:24:26 +0000 Subject: [njs] Math.pow() method fix. Message-ID: details: http://hg.nginx.org/njs/rev/631a3be91d22 branches: changeset: 286:631a3be91d22 user: Valentin Bartenev date: Fri Dec 16 17:52:15 2016 +0300 description: Math.pow() method fix. diffstat: njs/njs_math.c | 7 ++++--- njs/test/njs_unit_test.c | 6 ++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diffs (35 lines): diff -r b5e47a364c02 -r 631a3be91d22 njs/njs_math.c --- a/njs/njs_math.c Tue Dec 13 17:50:06 2016 +0300 +++ b/njs/njs_math.c Fri Dec 16 17:52:15 2016 +0300 @@ -579,11 +579,12 @@ njs_object_math_pow(njs_vm_t *vm, njs_va exponent = args[2].data.u.number; /* - * Accordig to ECMA-262 the result of Math.pow(+/-1, +/-Infinity) - * should be NaN. + * According to ECMA-262: + * 1. If exponent is NaN, the result should be NaN; + * 2. The result of Math.pow(+/-1, +/-Infinity) should be NaN. */ - if (fabs(base) != 1 || !isinf(exponent)) { + if (fabs(base) != 1 || (!isnan(exponent) && !isinf(exponent))) { num = pow(base, exponent); } else { diff -r b5e47a364c02 -r 631a3be91d22 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Dec 13 17:50:06 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Dec 16 17:52:15 2016 +0300 @@ -6215,6 +6215,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.pow()"), nxt_string("NaN") }, + { nxt_string("Math.pow(1, NaN)"), + nxt_string("NaN") }, + + { nxt_string("Math.pow(3, NaN)"), + nxt_string("NaN") }, + { nxt_string("Math.pow('a', -0)"), nxt_string("1") }, From ru at nginx.com Fri Dec 16 16:55:12 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Fri, 16 Dec 2016 16:55:12 +0000 Subject: [nginx] Configure: detect nginx version for nginx.pm at make time. Message-ID: details: http://hg.nginx.org/nginx/rev/53ea5694d1cc branches: changeset: 6848:53ea5694d1cc user: Ruslan Ermilov date: Fri Dec 16 19:54:37 2016 +0300 description: Configure: detect nginx version for nginx.pm at make time. diffstat: auto/lib/perl/make | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diffs (26 lines): diff -r d72b38376092 -r 53ea5694d1cc auto/lib/perl/make --- a/auto/lib/perl/make Fri Dec 16 18:21:55 2016 +0300 +++ b/auto/lib/perl/make Fri Dec 16 19:54:37 2016 +0300 @@ -3,9 +3,6 @@ # Copyright (C) Nginx, Inc. -v=`grep 'define NGINX_VERSION' src/core/nginx.h | sed -e 's/^.*"\(.*\)".*/\1/'` - - cat << END >> $NGX_MAKEFILE $NGX_OBJS/src/http/modules/perl/ngx_http_perl_module.o: \\ @@ -27,7 +24,11 @@ cat << END src/http/modules/perl/nginx.pm \\ src/http/modules/perl/nginx.xs \\ src/http/modules/perl/typemap - sed "s/%%VERSION%%/$v/" src/http/modules/perl/nginx.pm > \\ + grep 'define NGINX_VERSION' src/core/nginx.h \\ + | sed -e 's/^.*"\(.*\)".*/\1/' > \\ + $NGX_OBJS/src/http/modules/perl/version + sed "s/%%VERSION%%/\`cat $NGX_OBJS/src/http/modules/perl/version\`/" \\ + src/http/modules/perl/nginx.pm > \\ $NGX_OBJS/src/http/modules/perl/nginx.pm cp -p src/http/modules/perl/nginx.xs $NGX_OBJS/src/http/modules/perl/ cp -p src/http/modules/perl/typemap $NGX_OBJS/src/http/modules/perl/ From thibaultcha at fastmail.com Fri Dec 16 19:35:44 2016 From: thibaultcha at fastmail.com (Thibault Charbonnier) Date: Fri, 16 Dec 2016 11:35:44 -0800 Subject: [PATCH] ignore ipv6=off resolver option when no ipv6 support In-Reply-To: <20161216150727.GC18639@mdounin.ru> References: <20161216150727.GC18639@mdounin.ru> Message-ID: <7c283468-a7f9-53a2-7a86-f933f357b2d1@fastmail.com> On 12/16/16 7:07 AM, Maxim Dounin wrote: > Hello! Hi, > Builds without IPv6 support is something we are phasing out. > Starting with nginx 1.11.5 IPv6 support is automatically > configured as long as supported by OS: > > Changes with nginx 1.11.5, 11 Oct 2016: > > *) Change: the --with-ipv6 configure option was removed, now IPv6 > support is configured automatically. > > So I don't think that such a change will make any difference. Perhaps I wasn't clear enough about the use case when proposing this patch. Its intent is actually to consolidate on the change you highlighted. I would like to clarify the use case, if you allow me: Say we wish to disable IPv6 resolution regardless of whether nginx was built with our without support for it: resolver 8.8.8.8 8.8.4.4 ipv6=off; Now the issue is that ipv6=off raises this - cryptic to the neophytes - error if nginx was built without IPv6 support: [emerg] host not found in resolver "ipv6=off" Prior to the change introduced in 1.11.5, one could rely on the --with-ipv6 option from 'nginx -V' to add the ipv6=off flag or not, and avoid this error. However, with this change you referred to, we have no way of programmatically determine if nginx was built with our without support for IPv6 (I would love to be proven wrong here, if you happen to be aware of another way to do so). Hence, this patch's intent is to make the "ipv6=off" token safe in both modes, and avoid trying to parse it as a regular address. With this patch, one can safely assume that IPv6 resolution can *always* be disabled by simply adding the "ipv6=off" parameter. Additionally, we also provide a less cryptic error message in case of no support for IPv6 but "ipv6=on" option. Hence, this patch's primary intent is to consolidate on the referred change by making the "resolver" directive parsing more robust. -- Thibault From mdounin at mdounin.ru Fri Dec 16 20:04:47 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 16 Dec 2016 23:04:47 +0300 Subject: [PATCH] ignore ipv6=off resolver option when no ipv6 support In-Reply-To: <7c283468-a7f9-53a2-7a86-f933f357b2d1@fastmail.com> References: <20161216150727.GC18639@mdounin.ru> <7c283468-a7f9-53a2-7a86-f933f357b2d1@fastmail.com> Message-ID: <20161216200447.GE18639@mdounin.ru> Hello! On Fri, Dec 16, 2016 at 11:35:44AM -0800, Thibault Charbonnier wrote: [...] > Say we wish to disable IPv6 resolution regardless of whether nginx was > built with our without support for it: > > resolver 8.8.8.8 8.8.4.4 ipv6=off; > > Now the issue is that ipv6=off raises this - cryptic to the neophytes - > error if nginx was built without IPv6 support: > > [emerg] host not found in resolver "ipv6=off" I very much doubt there are any neophytes who try to use nginx on operating systems without IPv6 support. A neophyte most likely won't be able to find such OS nowadays. -- Maxim Dounin http://nginx.org/ From andrew at benton.io Fri Dec 16 23:20:27 2016 From: andrew at benton.io (Andrew Benton) Date: Fri, 16 Dec 2016 15:20:27 -0800 Subject: HPKP directives for SSL module Message-ID: Been working for a couple hours on an addition to the SSL module that would help users implement HPKP ( https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning). The idea is to add a directive that would be easily configurable to have nginx present the appropriate PKP header on HTTP responses. Rather than continuing to work on this in a vacuum though, I thought maybe I should chime in on here to discuss the desirability of such a feature and get some consensus about the directive's API. Having implemented HPKP in a few environments, one of the more frustrating problems is the need to extract public key data from a certificate or key and hardcode it into an add_header directive. Given that nginx already has access to the public key data for at least one possible pin (given TLS enabled and configured properly) in memory, it would seem to make sense to just have nginx handle this. So that's the motivation. The things that are configurable in the HTTP PKP header are: 1 or more pins, extracted from public key information max-age, a number of seconds that the pins are valid includeSubdomains, an optional flag reportUri, an optional url for the browser to report pin validation failures So the proposal would be to have some new directives: ssl_hpkp (on/off flag directive, default off) ssl_hpkp_pins (variable args, possibly string filenames for more cert/keys to use, need help here) ssl_hpkp_max_age (number of seconds, default of 1) ssl_hpkp_include_subdomains (on/off flag directive, default off) ssl_hpkp_report_uri (string directive for optional reporting url, default empty) Of these, the only one I think is difficult is the one concerning pins. So I'd love to see suggestions for that. In general, let me know what you all think. -------------- next part -------------- An HTML attachment was scrubbed... URL: From arut at nginx.com Mon Dec 19 11:11:40 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Mon, 19 Dec 2016 11:11:40 +0000 Subject: [nginx] Stream ssl_preread: relaxed SSL version check. Message-ID: details: http://hg.nginx.org/nginx/rev/01adb18a5d23 branches: changeset: 6849:01adb18a5d23 user: Roman Arutyunyan date: Mon Dec 19 14:02:39 2016 +0300 description: Stream ssl_preread: relaxed SSL version check. SSL version 3.0 can be specified by the client at the record level for compatibility reasons. Previously, ssl_preread module rejected such connections, presuming they don't have SNI. Now SSL 3.0 is allowed at the record level. diffstat: src/stream/ngx_stream_ssl_preread_module.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 53ea5694d1cc -r 01adb18a5d23 src/stream/ngx_stream_ssl_preread_module.c --- a/src/stream/ngx_stream_ssl_preread_module.c Fri Dec 16 19:54:37 2016 +0300 +++ b/src/stream/ngx_stream_ssl_preread_module.c Mon Dec 19 14:02:39 2016 +0300 @@ -142,7 +142,7 @@ ngx_stream_ssl_preread_handler(ngx_strea return NGX_DECLINED; } - if (p[1] != 3 || p[2] == 0) { + if (p[1] != 3) { ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, "ssl preread: unsupported SSL version"); return NGX_DECLINED; From vbart at nginx.com Mon Dec 19 11:34:05 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Mon, 19 Dec 2016 11:34:05 +0000 Subject: [njs] The nxt_expect() macro. Message-ID: details: http://hg.nginx.org/njs/rev/a76d7066a117 branches: changeset: 287:a76d7066a117 user: Valentin Bartenev date: Mon Dec 19 14:19:43 2016 +0300 description: The nxt_expect() macro. diffstat: nxt/nxt_clang.h | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (18 lines): diff -r 631a3be91d22 -r a76d7066a117 nxt/nxt_clang.h --- a/nxt/nxt_clang.h Fri Dec 16 17:52:15 2016 +0300 +++ b/nxt/nxt_clang.h Mon Dec 19 14:19:43 2016 +0300 @@ -27,10 +27,12 @@ #if (NXT_HAVE_BUILTIN_EXPECT) -#define nxt_fast_path(x) __builtin_expect((long) (x), 1) -#define nxt_slow_path(x) __builtin_expect((long) (x), 0) +#define nxt_expect(c, x) __builtin_expect((long) (x), (c)) +#define nxt_fast_path(x) nxt_expect(1, x) +#define nxt_slow_path(x) nxt_expect(0, x) #else +#define nxt_expect(c, x) (x) #define nxt_fast_path(x) (x) #define nxt_slow_path(x) (x) #endif From vbart at nginx.com Mon Dec 19 11:34:07 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Mon, 19 Dec 2016 11:34:07 +0000 Subject: [njs] Exponentiation operators. Message-ID: details: http://hg.nginx.org/njs/rev/f5225d9cc97b branches: changeset: 288:f5225d9cc97b user: Valentin Bartenev date: Mon Dec 19 14:19:59 2016 +0300 description: Exponentiation operators. diffstat: njs/njs_disassembler.c | 2 + njs/njs_generator.c | 2 + njs/njs_lexer.c | 6 + njs/njs_parser.h | 3 + njs/njs_parser_expression.c | 76 +++++++++++++++++++++- njs/njs_vm.c | 34 +++++++++ njs/njs_vm.h | 2 + njs/test/njs_unit_test.c | 157 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 281 insertions(+), 1 deletions(-) diffs (406 lines): diff -r a76d7066a117 -r f5225d9cc97b njs/njs_disassembler.c --- a/njs/njs_disassembler.c Mon Dec 19 14:19:43 2016 +0300 +++ b/njs/njs_disassembler.c Mon Dec 19 14:19:59 2016 +0300 @@ -87,6 +87,8 @@ static njs_code_name_t code_names[] = { nxt_string("SUBSTRACT ") }, { njs_vmcode_multiplication, sizeof(njs_vmcode_3addr_t), nxt_string("MULTIPLY ") }, + { njs_vmcode_exponentiation, sizeof(njs_vmcode_3addr_t), + nxt_string("POWER ") }, { njs_vmcode_division, sizeof(njs_vmcode_3addr_t), nxt_string("DIVIDE ") }, { njs_vmcode_remainder, sizeof(njs_vmcode_3addr_t), diff -r a76d7066a117 -r f5225d9cc97b njs/njs_generator.c --- a/njs/njs_generator.c Mon Dec 19 14:19:43 2016 +0300 +++ b/njs/njs_generator.c Mon Dec 19 14:19:59 2016 +0300 @@ -184,6 +184,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_ADDITION_ASSIGNMENT: case NJS_TOKEN_SUBSTRACTION_ASSIGNMENT: case NJS_TOKEN_MULTIPLICATION_ASSIGNMENT: + case NJS_TOKEN_EXPONENTIATION_ASSIGNMENT: case NJS_TOKEN_DIVISION_ASSIGNMENT: case NJS_TOKEN_REMAINDER_ASSIGNMENT: return njs_generate_operation_assignment(vm, parser, node); @@ -219,6 +220,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_ADDITION: case NJS_TOKEN_SUBSTRACTION: case NJS_TOKEN_MULTIPLICATION: + case NJS_TOKEN_EXPONENTIATION: case NJS_TOKEN_DIVISION: case NJS_TOKEN_REMAINDER: case NJS_TOKEN_PROPERTY_DELETE: diff -r a76d7066a117 -r f5225d9cc97b njs/njs_lexer.c --- a/njs/njs_lexer.c Mon Dec 19 14:19:43 2016 +0300 +++ b/njs/njs_lexer.c Mon Dec 19 14:19:59 2016 +0300 @@ -203,8 +203,14 @@ static const njs_lexer_multi_t njs_subs }; +static const njs_lexer_multi_t njs_exponentiation_token[] = { + { '=', NJS_TOKEN_EXPONENTIATION_ASSIGNMENT, 0, NULL }, +}; + + static const njs_lexer_multi_t njs_multiplication_token[] = { { '=', NJS_TOKEN_MULTIPLICATION_ASSIGNMENT, 0, NULL }, + { '*', NJS_TOKEN_EXPONENTIATION, 1, njs_exponentiation_token }, }; diff -r a76d7066a117 -r f5225d9cc97b njs/njs_parser.h --- a/njs/njs_parser.h Mon Dec 19 14:19:43 2016 +0300 +++ b/njs/njs_parser.h Mon Dec 19 14:19:59 2016 +0300 @@ -41,6 +41,7 @@ typedef enum { NJS_TOKEN_ADDITION_ASSIGNMENT, NJS_TOKEN_SUBSTRACTION_ASSIGNMENT, NJS_TOKEN_MULTIPLICATION_ASSIGNMENT, + NJS_TOKEN_EXPONENTIATION_ASSIGNMENT, NJS_TOKEN_DIVISION_ASSIGNMENT, NJS_TOKEN_REMAINDER_ASSIGNMENT, NJS_TOKEN_LEFT_SHIFT_ASSIGNMENT, @@ -69,6 +70,8 @@ typedef enum { NJS_TOKEN_MULTIPLICATION, + NJS_TOKEN_EXPONENTIATION, + NJS_TOKEN_DIVISION, NJS_TOKEN_REMAINDER, diff -r a76d7066a117 -r f5225d9cc97b njs/njs_parser_expression.c --- a/njs/njs_parser_expression.c Mon Dec 19 14:19:43 2016 +0300 +++ b/njs/njs_parser_expression.c Mon Dec 19 14:19:59 2016 +0300 @@ -63,6 +63,9 @@ static njs_token_t njs_parser_conditiona static njs_token_t njs_parser_binary_expression(njs_vm_t *vm, njs_parser_t *parser, const njs_parser_expression_t *expr, njs_token_t token); +static njs_token_t njs_parser_exponential_expression(njs_vm_t *vm, + njs_parser_t *parser, const njs_parser_expression_t *expr, + njs_token_t token); static njs_token_t njs_parser_unary_expression(njs_vm_t *vm, njs_parser_t *parser, const njs_parser_expression_t *expr, njs_token_t token); @@ -83,7 +86,7 @@ static njs_token_t njs_parser_property_b static const njs_parser_expression_t njs_parser_factor_expression = { - njs_parser_unary_expression, + njs_parser_exponential_expression, NULL, 3, { { NJS_TOKEN_MULTIPLICATION, njs_vmcode_multiplication, @@ -391,6 +394,11 @@ njs_parser_assignment_expression(njs_vm_ operation = njs_vmcode_multiplication; break; + case NJS_TOKEN_EXPONENTIATION_ASSIGNMENT: + nxt_thread_log_debug("JS: **="); + operation = njs_vmcode_exponentiation; + break; + case NJS_TOKEN_DIVISION_ASSIGNMENT: nxt_thread_log_debug("JS: /="); operation = njs_vmcode_division; @@ -685,6 +693,64 @@ njs_parser_binary_expression(njs_vm_t *v static njs_token_t +njs_parser_exponential_expression(njs_vm_t *vm, njs_parser_t *parser, + const njs_parser_expression_t *expr, njs_token_t token) +{ + njs_parser_node_t *node; + + token = njs_parser_unary_expression(vm, parser, NULL, token); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + for ( ;; ) { + if (token == NJS_TOKEN_EXPONENTIATION) { + + node = njs_parser_node_alloc(vm); + if (nxt_slow_path(node == NULL)) { + return NJS_TOKEN_ERROR; + } + + node->token = token; + node->u.operation = njs_vmcode_exponentiation; + node->left = parser->node; + node->left->dest = node; + + parser->code_size += sizeof(njs_vmcode_3addr_t); + + token = njs_parser_token(parser); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + token = njs_parser_exponential_expression(vm, parser, NULL, token); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + node->right = parser->node; + node->right->dest = node; + parser->node = node; + } + + if (token == NJS_TOKEN_LINE_END) { + + token = njs_lexer_token(parser->lexer); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + if (njs_parser_expression_operator(token)) { + continue; + } + } + + return token; + } +} + + +static njs_token_t njs_parser_unary_expression(njs_vm_t *vm, njs_parser_t *parser, const njs_parser_expression_t *expr, njs_token_t token) { @@ -739,6 +805,14 @@ njs_parser_unary_expression(njs_vm_t *vm return next; } + if (next == NJS_TOKEN_EXPONENTIATION) { + nxt_alert(&vm->trace, NXT_LEVEL_ERROR, + "SyntaxError: Either left-hand side or entire exponentiation " + "must be parenthesized"); + + return NJS_TOKEN_ILLEGAL; + } + if (token == NJS_TOKEN_UNARY_PLUS && parser->node->token == NJS_TOKEN_NUMBER) { diff -r a76d7066a117 -r f5225d9cc97b njs/njs_vm.c --- a/njs/njs_vm.c Mon Dec 19 14:19:43 2016 +0300 +++ b/njs/njs_vm.c Mon Dec 19 14:19:59 2016 +0300 @@ -1598,6 +1598,40 @@ njs_vmcode_multiplication(njs_vm_t *vm, njs_ret_t +njs_vmcode_exponentiation(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2) +{ + double num, base, exponent; + nxt_bool_t valid; + + if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { + base = val1->data.u.number; + exponent = val2->data.u.number; + + /* + * According to ES7: + * 1. If exponent is NaN, the result should be NaN; + * 2. The result of +/-1 ** +/-Infinity should be NaN. + */ + valid = nxt_expect(1, fabs(base) != 1 + || (!isnan(exponent) && !isinf(exponent))); + + if (valid) { + num = pow(base, exponent); + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return sizeof(njs_vmcode_3addr_t); + } + + return NJS_TRAP_NUMBERS; +} + + +njs_ret_t njs_vmcode_division(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2) { double num; diff -r a76d7066a117 -r f5225d9cc97b njs/njs_vm.h --- a/njs/njs_vm.h Mon Dec 19 14:19:43 2016 +0300 +++ b/njs/njs_vm.h Mon Dec 19 14:19:59 2016 +0300 @@ -927,6 +927,8 @@ njs_ret_t njs_vmcode_substraction(njs_vm njs_value_t *val2); njs_ret_t njs_vmcode_multiplication(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2); +njs_ret_t njs_vmcode_exponentiation(njs_vm_t *vm, njs_value_t *val1, + njs_value_t *val2); njs_ret_t njs_vmcode_division(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2); njs_ret_t njs_vmcode_remainder(njs_vm_t *vm, njs_value_t *val1, diff -r a76d7066a117 -r f5225d9cc97b njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Dec 19 14:19:43 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Dec 19 14:19:59 2016 +0300 @@ -224,6 +224,163 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = 1; function f(x) { a = x; return 2 }; a += f(5)"), nxt_string("3") }, + /* Exponentiation. */ + + { nxt_string("2 ** (3 ** 2)"), + nxt_string("512") }, + + { nxt_string("(2 ** 3) ** 2"), + nxt_string("64") }, + + { nxt_string("3 ** 2 - 9"), + nxt_string("0") }, + + { nxt_string("-9 + 3 ** 2"), + nxt_string("0") }, + + { nxt_string("-3 ** 2"), + nxt_string("SyntaxError: Either left-hand side or entire exponentiation " + "must be parenthesized in 1") }, + + { nxt_string("-(3) ** 2"), + nxt_string("SyntaxError: Either left-hand side or entire exponentiation " + "must be parenthesized in 1") }, + + { nxt_string("-(3 ** 2)"), + nxt_string("-9") }, + + { nxt_string("(-3) ** 2"), + nxt_string("9") }, + + { nxt_string("1 ** NaN"), + nxt_string("NaN") }, + + { nxt_string("'a' ** -0"), + nxt_string("1") }, + + { nxt_string("1.1 ** Infinity"), + nxt_string("Infinity") }, + + { nxt_string("(-1.1) ** -Infinity"), + nxt_string("0") }, + + { nxt_string("(-1) ** Infinity"), + nxt_string("NaN") }, + + { nxt_string("1 ** -Infinity"), + nxt_string("NaN") }, + + { nxt_string("(-0.9) ** Infinity"), + nxt_string("0") }, + + { nxt_string("0.9 ** -Infinity"), + nxt_string("Infinity") }, + + { nxt_string("'Infinity' ** 0.1"), + nxt_string("Infinity") }, + + { nxt_string("Infinity ** '-0.1'"), + nxt_string("0") }, + + { nxt_string("(-Infinity) ** 3"), + nxt_string("-Infinity") }, + + { nxt_string("'-Infinity' ** '3.1'"), + nxt_string("Infinity") }, + + { nxt_string("(-Infinity) ** '-3'"), + nxt_string("-0") }, + + { nxt_string("'-Infinity' ** -2"), + nxt_string("0") }, + + { nxt_string("'0' ** 0.1"), + nxt_string("0") }, + + { nxt_string("0 ** '-0.1'"), + nxt_string("Infinity") }, + + { nxt_string("(-0) ** 3"), + nxt_string("-0") }, + + { nxt_string("'-0' ** '3.1'"), + nxt_string("0") }, + + { nxt_string("(-0) ** '-3'"), + nxt_string("-Infinity") }, + + { nxt_string("'-0' ** -2"), + nxt_string("Infinity") }, + + { nxt_string("(-3) ** 0.1"), + nxt_string("NaN") }, + + { nxt_string("var a = 0.1; a **= -2"), + nxt_string("100") }, + + { nxt_string("var a = 1; a **= NaN"), + nxt_string("NaN") }, + + { nxt_string("var a = 'a'; a **= -0"), + nxt_string("1") }, + + { nxt_string("var a = 1.1; a **= Infinity"), + nxt_string("Infinity") }, + + { nxt_string("var a = -1.1; a **= -Infinity"), + nxt_string("0") }, + + { nxt_string("var a = -1; a **= Infinity"), + nxt_string("NaN") }, + + { nxt_string("var a = 1; a **= -Infinity"), + nxt_string("NaN") }, + + { nxt_string("var a = -0.9; a **= Infinity"), + nxt_string("0") }, + + { nxt_string("var a = 0.9; a **= -Infinity"), + nxt_string("Infinity") }, + + { nxt_string("var a = 'Infinity'; a **= 0.1"), + nxt_string("Infinity") }, + + { nxt_string("var a = Infinity; a **= '-0.1'"), + nxt_string("0") }, + + { nxt_string("var a = -Infinity; a **= 3"), + nxt_string("-Infinity") }, + + { nxt_string("var a = '-Infinity'; a **= '3.1'"), + nxt_string("Infinity") }, + + { nxt_string("var a = -Infinity; a **= '-3'"), + nxt_string("-0") }, + + { nxt_string("var a = '-Infinity'; a **= -2"), + nxt_string("0") }, + + { nxt_string("var a = '0'; a **= 0.1"), + nxt_string("0") }, + + { nxt_string("var a = 0; a **= '-0.1'"), + nxt_string("Infinity") }, + + { nxt_string("var a = -0; a **= 3"), + nxt_string("-0") }, + + { nxt_string("var a = '-0'; a **= '3.1'"), + nxt_string("0") }, + + { nxt_string("var a = -0; a **= '-3'"), + nxt_string("-Infinity") }, + + { nxt_string("var a = '-0'; a **= -2"), + nxt_string("Infinity") }, + + { nxt_string("var a = -3; a **= 0.1"), + nxt_string("NaN") }, + /**/ { nxt_string("12 | 6"), From vl at nginx.com Tue Dec 20 09:53:23 2016 From: vl at nginx.com (Vladimir Homutov) Date: Tue, 20 Dec 2016 09:53:23 +0000 Subject: [nginx] Stream: client SSL certificates verification support. Message-ID: details: http://hg.nginx.org/nginx/rev/41cb1b64561d branches: changeset: 6850:41cb1b64561d user: Vladimir Homutov date: Tue Dec 20 12:05:14 2016 +0300 description: Stream: client SSL certificates verification support. New directives: "ssl_verify_client", "ssl_verify_depth", "ssl_client_certificate", "ssl_trusted_certificate", and "ssl_crl". New variables: $ssl_client_cert, $ssl_client_raw_cert, $ssl_client_s_dn, $ssl_client_i_dn, $ssl_client_serial, $ssl_client_fingerprint, $ssl_client_verify, $ssl_client_v_start, $ssl_client_v_end, and $ssl_client_v_remain. diffstat: src/stream/ngx_stream_ssl_module.c | 151 +++++++++++++++++++++++++++++++++++++ src/stream/ngx_stream_ssl_module.h | 6 + 2 files changed, 157 insertions(+), 0 deletions(-) diffs (254 lines): diff -r 01adb18a5d23 -r 41cb1b64561d src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c Mon Dec 19 14:02:39 2016 +0300 +++ b/src/stream/ngx_stream_ssl_module.c Tue Dec 20 12:05:14 2016 +0300 @@ -49,6 +49,15 @@ static ngx_conf_bitmask_t ngx_stream_ss }; +static ngx_conf_enum_t ngx_stream_ssl_verify[] = { + { ngx_string("off"), 0 }, + { ngx_string("on"), 1 }, + { ngx_string("optional"), 2 }, + { ngx_string("optional_no_ca"), 3 }, + { ngx_null_string, 0 } +}; + + static ngx_command_t ngx_stream_ssl_commands[] = { { ngx_string("ssl_handshake_timeout"), @@ -107,6 +116,34 @@ static ngx_command_t ngx_stream_ssl_com offsetof(ngx_stream_ssl_conf_t, ciphers), NULL }, + { ngx_string("ssl_verify_client"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_enum_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_ssl_conf_t, verify), + &ngx_stream_ssl_verify }, + + { ngx_string("ssl_verify_depth"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_ssl_conf_t, verify_depth), + NULL }, + + { ngx_string("ssl_client_certificate"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_ssl_conf_t, client_certificate), + NULL }, + + { ngx_string("ssl_trusted_certificate"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_ssl_conf_t, trusted_certificate), + NULL }, + { ngx_string("ssl_prefer_server_ciphers"), NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -142,6 +179,13 @@ static ngx_command_t ngx_stream_ssl_com offsetof(ngx_stream_ssl_conf_t, session_timeout), NULL }, + { ngx_string("ssl_crl"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_ssl_conf_t, crl), + NULL }, + ngx_null_command }; @@ -197,6 +241,37 @@ static ngx_stream_variable_t ngx_stream { ngx_string("ssl_server_name"), NULL, ngx_stream_ssl_variable, (uintptr_t) ngx_ssl_get_server_name, NGX_STREAM_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_cert"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_certificate, NGX_STREAM_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_raw_cert"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_raw_certificate, + NGX_STREAM_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_s_dn"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_subject_dn, NGX_STREAM_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_i_dn"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_issuer_dn, NGX_STREAM_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_serial"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_serial_number, NGX_STREAM_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_fingerprint"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_fingerprint, NGX_STREAM_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_verify"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_client_verify, NGX_STREAM_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_v_start"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_client_v_start, NGX_STREAM_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_v_end"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_client_v_end, NGX_STREAM_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_v_remain"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_client_v_remain, NGX_STREAM_VAR_CHANGEABLE, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; @@ -207,6 +282,8 @@ static ngx_str_t ngx_stream_ssl_sess_id_ static ngx_int_t ngx_stream_ssl_handler(ngx_stream_session_t *s) { + long rc; + X509 *cert; ngx_connection_t *c; ngx_stream_ssl_conf_t *sslcf; @@ -227,6 +304,37 @@ ngx_stream_ssl_handler(ngx_stream_sessio return ngx_stream_ssl_init_connection(&sslcf->ssl, c); } + if (sslcf->verify) { + rc = SSL_get_verify_result(c->ssl->connection); + + if (rc != X509_V_OK + && (sslcf->verify != 3 || !ngx_ssl_verify_error_optional(rc))) + { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client SSL certificate verify error: (%l:%s)", + rc, X509_verify_cert_error_string(rc)); + + ngx_ssl_remove_cached_session(sslcf->ssl.ctx, + (SSL_get0_session(c->ssl->connection))); + return NGX_ERROR; + } + + if (sslcf->verify == 1) { + cert = SSL_get_peer_certificate(c->ssl->connection); + + if (cert == NULL) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client sent no required SSL certificate"); + + ngx_ssl_remove_cached_session(sslcf->ssl.ctx, + (SSL_get0_session(c->ssl->connection))); + return NGX_ERROR; + } + + X509_free(cert); + } + } + return NGX_OK; } @@ -384,6 +492,9 @@ ngx_stream_ssl_create_conf(ngx_conf_t *c * scf->protocols = 0; * scf->dhparam = { 0, NULL }; * scf->ecdh_curve = { 0, NULL }; + * scf->client_certificate = { 0, NULL }; + * scf->trusted_certificate = { 0, NULL }; + * scf->crl = { 0, NULL }; * scf->ciphers = { 0, NULL }; * scf->shm_zone = NULL; */ @@ -393,6 +504,8 @@ ngx_stream_ssl_create_conf(ngx_conf_t *c scf->certificate_keys = NGX_CONF_UNSET_PTR; scf->passwords = NGX_CONF_UNSET_PTR; scf->prefer_server_ciphers = NGX_CONF_UNSET; + scf->verify = NGX_CONF_UNSET_UINT; + scf->verify_depth = NGX_CONF_UNSET_UINT; scf->builtin_session_cache = NGX_CONF_UNSET; scf->session_timeout = NGX_CONF_UNSET; scf->session_tickets = NGX_CONF_UNSET; @@ -423,6 +536,9 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); + ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); + ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1); + ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL); ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys, NULL); @@ -431,6 +547,12 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, ""); + ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate, + ""); + ngx_conf_merge_str_value(conf->trusted_certificate, + prev->trusted_certificate, ""); + ngx_conf_merge_str_value(conf->crl, prev->crl, ""); + ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve, NGX_DEFAULT_ECDH_CURVE); @@ -480,6 +602,35 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf return NGX_CONF_ERROR; } + if (conf->verify) { + + if (conf->client_certificate.len == 0 && conf->verify != 3) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "no ssl_client_certificate for ssl_client_verify"); + return NGX_CONF_ERROR; + } + + if (ngx_ssl_client_certificate(cf, &conf->ssl, + &conf->client_certificate, + conf->verify_depth) + != NGX_OK) + { + return NGX_CONF_ERROR; + } + + if (ngx_ssl_trusted_certificate(cf, &conf->ssl, + &conf->trusted_certificate, + conf->verify_depth) + != NGX_OK) + { + return NGX_CONF_ERROR; + } + + if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { + return NGX_CONF_ERROR; + } + } + if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } diff -r 01adb18a5d23 -r 41cb1b64561d src/stream/ngx_stream_ssl_module.h --- a/src/stream/ngx_stream_ssl_module.h Mon Dec 19 14:02:39 2016 +0300 +++ b/src/stream/ngx_stream_ssl_module.h Tue Dec 20 12:05:14 2016 +0300 @@ -23,6 +23,9 @@ typedef struct { ngx_uint_t protocols; + ngx_uint_t verify; + ngx_uint_t verify_depth; + ssize_t builtin_session_cache; time_t session_timeout; @@ -32,6 +35,9 @@ typedef struct { ngx_str_t dhparam; ngx_str_t ecdh_curve; + ngx_str_t client_certificate; + ngx_str_t trusted_certificate; + ngx_str_t crl; ngx_str_t ciphers; From yohan.rizk at gmail.com Tue Dec 20 14:39:15 2016 From: yohan.rizk at gmail.com (Yohan Rizk) Date: Tue, 20 Dec 2016 14:39:15 +0000 Subject: Building from source code Message-ID: Hello! My name is yohan, I am interested in helping out with nginx. I've read the links about building the project from the source code in the mercurial repo and I have that cloned. However, there isn't a configure bash script in the root level of the project as this page seems to imply. the auto/ directory has one, but then the paths are not configured. I downloaded a stable version from here and built that successfully, but I'm guessing contributors don't work there. I apologize if this problem is rather fundamental. I hope to hear back soon. Thank you -------------- next part -------------- An HTML attachment was scrubbed... URL: From eran.kornblau at kaltura.com Tue Dec 20 16:04:43 2016 From: eran.kornblau at kaltura.com (Eran Kornblau) Date: Tue, 20 Dec 2016 16:04:43 +0000 Subject: Building from source code In-Reply-To: References: Message-ID: You need to stand on the nginx root folder and execute: auto/configure Eran From: nginx-devel [mailto:nginx-devel-bounces at nginx.org] On Behalf Of Yohan Rizk Sent: Tuesday, December 20, 2016 4:39 PM To: nginx-devel at nginx.org Subject: Building from source code Hello! My name is yohan, I am interested in helping out with nginx. I've read the links about building the project from the source code in the mercurial repo and I have that cloned. However, there isn't a configure bash script in the root level of the project as this page seems to imply. the auto/ directory has one, but then the paths are not configured. I downloaded a stable version from here and built that successfully, but I'm guessing contributors don't work there. I apologize if this problem is rather fundamental. I hope to hear back soon. Thank you -------------- next part -------------- An HTML attachment was scrubbed... URL: From ru at nginx.com Thu Dec 22 07:00:39 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 22 Dec 2016 07:00:39 +0000 Subject: [nginx] Limited recursion when evaluating variables. Message-ID: details: http://hg.nginx.org/nginx/rev/8cd97c14b0e2 branches: changeset: 6851:8cd97c14b0e2 user: Ruslan Ermilov date: Wed Dec 21 22:01:24 2016 +0300 description: Limited recursion when evaluating variables. Unlimited recursion might cause stack exhaustion in some misconfigurations. diffstat: src/http/ngx_http_variables.c | 42 ++++++++++++++++++++++++++++++-------- src/stream/ngx_stream_variables.c | 42 ++++++++++++++++++++++++++++++-------- 2 files changed, 66 insertions(+), 18 deletions(-) diffs (157 lines): diff -r 41cb1b64561d -r 8cd97c14b0e2 src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c Tue Dec 20 12:05:14 2016 +0300 +++ b/src/http/ngx_http_variables.c Wed Dec 21 22:01:24 2016 +0300 @@ -366,6 +366,9 @@ ngx_http_variable_value_t ngx_http_vari ngx_http_variable("1"); +static ngx_uint_t ngx_http_variable_depth = 100; + + ngx_http_variable_t * ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) { @@ -517,9 +520,20 @@ ngx_http_get_indexed_variable(ngx_http_r v = cmcf->variables.elts; + if (ngx_http_variable_depth == 0) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "cycle while evaluating variable \"%V\"", + &v[index].name); + return NULL; + } + + ngx_http_variable_depth--; + if (v[index].get_handler(r, &r->variables[index], v[index].data) == NGX_OK) { + ngx_http_variable_depth++; + if (v[index].flags & NGX_HTTP_VAR_NOCACHEABLE) { r->variables[index].no_cacheable = 1; } @@ -527,6 +541,8 @@ ngx_http_get_indexed_variable(ngx_http_r return &r->variables[index]; } + ngx_http_variable_depth++; + r->variables[index].valid = 0; r->variables[index].not_found = 1; @@ -568,17 +584,25 @@ ngx_http_get_variable(ngx_http_request_t if (v) { if (v->flags & NGX_HTTP_VAR_INDEXED) { return ngx_http_get_flushed_variable(r, v->index); - - } else { - - vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); - - if (vv && v->get_handler(r, vv, v->data) == NGX_OK) { - return vv; - } - + } + + if (ngx_http_variable_depth == 0) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "cycle while evaluating variable \"%V\"", name); return NULL; } + + ngx_http_variable_depth--; + + vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); + + if (vv && v->get_handler(r, vv, v->data) == NGX_OK) { + ngx_http_variable_depth++; + return vv; + } + + ngx_http_variable_depth++; + return NULL; } vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); diff -r 41cb1b64561d -r 8cd97c14b0e2 src/stream/ngx_stream_variables.c --- a/src/stream/ngx_stream_variables.c Tue Dec 20 12:05:14 2016 +0300 +++ b/src/stream/ngx_stream_variables.c Wed Dec 21 22:01:24 2016 +0300 @@ -119,6 +119,9 @@ ngx_stream_variable_value_t ngx_stream_ ngx_stream_variable("1"); +static ngx_uint_t ngx_stream_variable_depth = 100; + + ngx_stream_variable_t * ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) { @@ -270,9 +273,20 @@ ngx_stream_get_indexed_variable(ngx_stre v = cmcf->variables.elts; + if (ngx_stream_variable_depth == 0) { + ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, + "cycle while evaluating variable \"%V\"", + &v[index].name); + return NULL; + } + + ngx_stream_variable_depth--; + if (v[index].get_handler(s, &s->variables[index], v[index].data) == NGX_OK) { + ngx_stream_variable_depth++; + if (v[index].flags & NGX_STREAM_VAR_NOCACHEABLE) { s->variables[index].no_cacheable = 1; } @@ -280,6 +294,8 @@ ngx_stream_get_indexed_variable(ngx_stre return &s->variables[index]; } + ngx_stream_variable_depth++; + s->variables[index].valid = 0; s->variables[index].not_found = 1; @@ -322,18 +338,26 @@ ngx_stream_get_variable(ngx_stream_sessi if (v) { if (v->flags & NGX_STREAM_VAR_INDEXED) { return ngx_stream_get_flushed_variable(s, v->index); - - } else { + } - vv = ngx_palloc(s->connection->pool, - sizeof(ngx_stream_variable_value_t)); - - if (vv && v->get_handler(s, vv, v->data) == NGX_OK) { - return vv; - } - + if (ngx_stream_variable_depth == 0) { + ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, + "cycle while evaluating variable \"%V\"", name); return NULL; } + + ngx_stream_variable_depth--; + + vv = ngx_palloc(s->connection->pool, + sizeof(ngx_stream_variable_value_t)); + + if (vv && v->get_handler(s, vv, v->data) == NGX_OK) { + ngx_stream_variable_depth++; + return vv; + } + + ngx_stream_variable_depth++; + return NULL; } vv = ngx_palloc(s->connection->pool, sizeof(ngx_stream_variable_value_t)); From ru at nginx.com Thu Dec 22 07:00:43 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 22 Dec 2016 07:00:43 +0000 Subject: [nginx] Core: relative redirects (closes #1000). Message-ID: details: http://hg.nginx.org/nginx/rev/d15172ebb400 branches: changeset: 6852:d15172ebb400 user: Ruslan Ermilov date: Wed Dec 21 23:10:51 2016 +0300 description: Core: relative redirects (closes #1000). The current version of HTTP/1.1 standard allows relative references in redirects (https://tools.ietf.org/html/rfc7231#section-7.1.2). Allow this form for redirects generated by nginx by introducing the new directive absolute_redirect. diffstat: src/http/ngx_http_core_module.c | 10 ++++++++++ src/http/ngx_http_core_module.h | 1 + src/http/ngx_http_header_filter_module.c | 3 ++- src/http/v2/ngx_http_v2_filter_module.c | 4 +++- 4 files changed, 16 insertions(+), 2 deletions(-) diffs (72 lines): diff -r 8cd97c14b0e2 -r d15172ebb400 src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Wed Dec 21 22:01:24 2016 +0300 +++ b/src/http/ngx_http_core_module.c Wed Dec 21 23:10:51 2016 +0300 @@ -542,6 +542,13 @@ static ngx_command_t ngx_http_core_comm offsetof(ngx_http_core_loc_conf_t, reset_timedout_connection), NULL }, + { ngx_string("absolute_redirect"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_core_loc_conf_t, absolute_redirect), + NULL }, + { ngx_string("server_name_in_redirect"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -3563,6 +3570,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t clcf->lingering_timeout = NGX_CONF_UNSET_MSEC; clcf->resolver_timeout = NGX_CONF_UNSET_MSEC; clcf->reset_timedout_connection = NGX_CONF_UNSET; + clcf->absolute_redirect = NGX_CONF_UNSET; clcf->server_name_in_redirect = NGX_CONF_UNSET; clcf->port_in_redirect = NGX_CONF_UNSET; clcf->msie_padding = NGX_CONF_UNSET; @@ -3825,6 +3833,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t ngx_conf_merge_value(conf->reset_timedout_connection, prev->reset_timedout_connection, 0); + ngx_conf_merge_value(conf->absolute_redirect, + prev->absolute_redirect, 1); ngx_conf_merge_value(conf->server_name_in_redirect, prev->server_name_in_redirect, 0); ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1); diff -r 8cd97c14b0e2 -r d15172ebb400 src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h Wed Dec 21 22:01:24 2016 +0300 +++ b/src/http/ngx_http_core_module.h Wed Dec 21 23:10:51 2016 +0300 @@ -385,6 +385,7 @@ struct ngx_http_core_loc_conf_s { ngx_flag_t tcp_nopush; /* tcp_nopush */ ngx_flag_t tcp_nodelay; /* tcp_nodelay */ ngx_flag_t reset_timedout_connection; /* reset_timedout_connection */ + ngx_flag_t absolute_redirect; /* absolute_redirect */ ngx_flag_t server_name_in_redirect; /* server_name_in_redirect */ ngx_flag_t port_in_redirect; /* port_in_redirect */ ngx_flag_t msie_padding; /* msie_padding */ diff -r 8cd97c14b0e2 -r d15172ebb400 src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c Wed Dec 21 22:01:24 2016 +0300 +++ b/src/http/ngx_http_header_filter_module.c Wed Dec 21 23:10:51 2016 +0300 @@ -309,7 +309,8 @@ ngx_http_header_filter(ngx_http_request_ if (r->headers_out.location && r->headers_out.location->value.len - && r->headers_out.location->value.data[0] == '/') + && r->headers_out.location->value.data[0] == '/' + && clcf->absolute_redirect) { r->headers_out.location->hash = 0; diff -r 8cd97c14b0e2 -r d15172ebb400 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Wed Dec 21 22:01:24 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Wed Dec 21 23:10:51 2016 +0300 @@ -263,7 +263,9 @@ ngx_http_v2_header_filter(ngx_http_reque if (r->headers_out.location && r->headers_out.location->value.len) { - if (r->headers_out.location->value.data[0] == '/') { + if (r->headers_out.location->value.data[0] == '/' + && clcf->absolute_redirect) + { if (clcf->server_name_in_redirect) { cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); host = cscf->server_name; From ru at nginx.com Thu Dec 22 07:06:29 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 22 Dec 2016 10:06:29 +0300 Subject: [nginx] Map: the "volatile" parameter. In-Reply-To: References: Message-ID: <20161222070629.GK9508@lo0.su> On Fri, Dec 09, 2016 at 10:41:41AM +0800, ??? wrote: > Hi! > > It's still a problem when the variable generated by map and including > itself. For example: > > map $host $abc { > default $abc; > } > > server { > listen 80; > > location / { > return 200 $abc; > } > } Unlimited recursion is now detected and handled: http://hg.nginx.org/nginx/rev/8cd97c14b0e2 Enjoy! From ru at nginx.com Thu Dec 22 14:31:01 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 22 Dec 2016 14:31:01 +0000 Subject: [nginx] Fixed missing "Location" field with some relative redirects. Message-ID: details: http://hg.nginx.org/nginx/rev/c85dfd99a2dd branches: changeset: 6853:c85dfd99a2dd user: Ruslan Ermilov date: Thu Dec 22 11:58:52 2016 +0300 description: Fixed missing "Location" field with some relative redirects. Relative redirects did not work with directory redirects and auto redirects issued by nginx. diffstat: src/http/modules/ngx_http_dav_module.c | 9 +++------ src/http/modules/ngx_http_static_module.c | 9 +++------ src/http/ngx_http_core_module.c | 6 ++---- src/http/ngx_http_upstream.c | 4 ++-- 4 files changed, 10 insertions(+), 18 deletions(-) diffs (82 lines): diff -r d15172ebb400 -r c85dfd99a2dd src/http/modules/ngx_http_dav_module.c --- a/src/http/modules/ngx_http_dav_module.c Wed Dec 21 23:10:51 2016 +0300 +++ b/src/http/modules/ngx_http_dav_module.c Thu Dec 22 11:58:52 2016 +0300 @@ -1067,7 +1067,7 @@ ngx_http_dav_location(ngx_http_request_t u_char *location; ngx_http_core_loc_conf_t *clcf; - r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t)); + r->headers_out.location = ngx_list_push(&r->headers_out.headers); if (r->headers_out.location == NULL) { return NGX_ERROR; } @@ -1086,11 +1086,8 @@ ngx_http_dav_location(ngx_http_request_t ngx_memcpy(location, r->uri.data, r->uri.len); } - /* - * we do not need to set the r->headers_out.location->hash and - * r->headers_out.location->key fields - */ - + r->headers_out.location->hash = 1; + ngx_str_set(&r->headers_out.location->key, "Location"); r->headers_out.location->value.len = r->uri.len; r->headers_out.location->value.data = location; diff -r d15172ebb400 -r c85dfd99a2dd src/http/modules/ngx_http_static_module.c --- a/src/http/modules/ngx_http_static_module.c Wed Dec 21 23:10:51 2016 +0300 +++ b/src/http/modules/ngx_http_static_module.c Thu Dec 22 11:58:52 2016 +0300 @@ -150,7 +150,7 @@ ngx_http_static_handler(ngx_http_request ngx_http_clear_location(r); - r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t)); + r->headers_out.location = ngx_list_push(&r->headers_out.headers); if (r->headers_out.location == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -182,11 +182,8 @@ ngx_http_static_handler(ngx_http_request } } - /* - * we do not need to set the r->headers_out.location->hash and - * r->headers_out.location->key fields - */ - + r->headers_out.location->hash = 1; + ngx_str_set(&r->headers_out.location->key, "Location"); r->headers_out.location->value.len = len; r->headers_out.location->value.data = location; diff -r d15172ebb400 -r c85dfd99a2dd src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Wed Dec 21 23:10:51 2016 +0300 +++ b/src/http/ngx_http_core_module.c Thu Dec 22 11:58:52 2016 +0300 @@ -983,10 +983,8 @@ ngx_http_core_find_config_phase(ngx_http return NGX_OK; } - /* - * we do not need to set the r->headers_out.location->hash and - * r->headers_out.location->key fields - */ + r->headers_out.location->hash = 1; + ngx_str_set(&r->headers_out.location->key, "Location"); if (r->args.len == 0) { r->headers_out.location->value = clcf->name; diff -r d15172ebb400 -r c85dfd99a2dd src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Wed Dec 21 23:10:51 2016 +0300 +++ b/src/http/ngx_http_upstream.c Thu Dec 22 11:58:52 2016 +0300 @@ -4927,8 +4927,8 @@ ngx_http_upstream_rewrite_location(ngx_h } /* - * we do not set r->headers_out.location here to avoid the handling - * the local redirects without a host name by ngx_http_header_filter() + * we do not set r->headers_out.location here to avoid handling + * relative redirects in ngx_http_header_filter() */ return NGX_OK; From mdounin at mdounin.ru Fri Dec 23 14:51:40 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 23 Dec 2016 14:51:40 +0000 Subject: [nginx] SSL: support AES256 encryption of tickets. Message-ID: details: http://hg.nginx.org/nginx/rev/75e7d55214bd branches: changeset: 6854:75e7d55214bd user: Maxim Dounin date: Fri Dec 23 17:28:20 2016 +0300 description: SSL: support AES256 encryption of tickets. This implies ticket key size of 80 bytes instead of previously used 48, as both HMAC and AES keys are 32 bytes now. When an old 48-byte ticket key is provided, we fall back to using backward-compatible AES128 encryption. OpenSSL switched to using AES256 in 1.1.0, and we are providing equivalent security. While here, order of HMAC and AES keys was reverted to make the implementation compatible with keys used by OpenSSL with SSL_CTX_set_tlsext_ticket_keys(). Prodded by Christian Klinger. diffstat: src/event/ngx_event_openssl.c | 58 ++++++++++++++++++++++++++++++++---------- src/event/ngx_event_openssl.h | 5 ++- 2 files changed, 47 insertions(+), 16 deletions(-) diffs (155 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -2856,7 +2856,8 @@ ngx_ssl_session_rbtree_insert_value(ngx_ ngx_int_t ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths) { - u_char buf[48]; + u_char buf[80]; + size_t size; ssize_t n; ngx_str_t *path; ngx_file_t file; @@ -2899,13 +2900,15 @@ ngx_ssl_session_ticket_keys(ngx_conf_t * goto failed; } - if (ngx_file_size(&fi) != 48) { + size = ngx_file_size(&fi); + + if (size != 48 && size != 80) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"%V\" must be 48 bytes", &file.name); + "\"%V\" must be 48 or 80 bytes", &file.name); goto failed; } - n = ngx_read_file(&file, buf, 48, 0); + n = ngx_read_file(&file, buf, size, 0); if (n == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno, @@ -2913,10 +2916,10 @@ ngx_ssl_session_ticket_keys(ngx_conf_t * goto failed; } - if (n != 48) { + if ((size_t) n != size) { ngx_conf_log_error(NGX_LOG_CRIT, cf, 0, ngx_read_file_n " \"%V\" returned only " - "%z bytes instead of 48", &file.name, n); + "%z bytes instead of %uz", &file.name, n, size); goto failed; } @@ -2925,9 +2928,18 @@ ngx_ssl_session_ticket_keys(ngx_conf_t * goto failed; } - ngx_memcpy(key->name, buf, 16); - ngx_memcpy(key->aes_key, buf + 16, 16); - ngx_memcpy(key->hmac_key, buf + 32, 16); + if (size == 48) { + key->size = 48; + ngx_memcpy(key->name, buf, 16); + ngx_memcpy(key->aes_key, buf + 16, 16); + ngx_memcpy(key->hmac_key, buf + 32, 16); + + } else { + key->size = 80; + ngx_memcpy(key->name, buf, 16); + ngx_memcpy(key->hmac_key, buf + 16, 32); + ngx_memcpy(key->aes_key, buf + 48, 32); + } if (ngx_close_file(file.fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, @@ -2972,6 +2984,7 @@ ngx_ssl_session_ticket_key_callback(ngx_ unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc) { + size_t size; SSL_CTX *ssl_ctx; ngx_uint_t i; ngx_array_t *keys; @@ -2986,7 +2999,6 @@ ngx_ssl_session_ticket_key_callback(ngx_ c = ngx_ssl_get_connection(ssl_conn); ssl_ctx = c->ssl->session_ctx; - cipher = EVP_aes_128_cbc(); #ifdef OPENSSL_NO_SHA256 digest = EVP_sha1(); #else @@ -3008,6 +3020,15 @@ ngx_ssl_session_ticket_key_callback(ngx_ ngx_hex_dump(buf, key[0].name, 16) - buf, buf, SSL_session_reused(ssl_conn) ? "reused" : "new"); + if (key[0].size == 48) { + cipher = EVP_aes_128_cbc(); + size = 16; + + } else { + cipher = EVP_aes_256_cbc(); + size = 32; + } + if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) { ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "RAND_bytes() failed"); return -1; @@ -3020,12 +3041,12 @@ ngx_ssl_session_ticket_key_callback(ngx_ } #if OPENSSL_VERSION_NUMBER >= 0x10000000L - if (HMAC_Init_ex(hctx, key[0].hmac_key, 16, digest, NULL) != 1) { + if (HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL) != 1) { ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed"); return -1; } #else - HMAC_Init_ex(hctx, key[0].hmac_key, 16, digest, NULL); + HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL); #endif ngx_memcpy(name, key[0].name, 16); @@ -3054,13 +3075,22 @@ ngx_ssl_session_ticket_key_callback(ngx_ ngx_hex_dump(buf, key[i].name, 16) - buf, buf, (i == 0) ? " (default)" : ""); + if (key[i].size == 48) { + cipher = EVP_aes_128_cbc(); + size = 16; + + } else { + cipher = EVP_aes_256_cbc(); + size = 32; + } + #if OPENSSL_VERSION_NUMBER >= 0x10000000L - if (HMAC_Init_ex(hctx, key[i].hmac_key, 16, digest, NULL) != 1) { + if (HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL) != 1) { ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed"); return -1; } #else - HMAC_Init_ex(hctx, key[i].hmac_key, 16, digest, NULL); + HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL); #endif if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) { diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -117,9 +117,10 @@ typedef struct { #ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB typedef struct { + size_t size; u_char name[16]; - u_char aes_key[16]; - u_char hmac_key[16]; + u_char hmac_key[32]; + u_char aes_key[32]; } ngx_ssl_session_ticket_key_t; #endif From vbart at nginx.com Fri Dec 23 16:46:24 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 23 Dec 2016 16:46:24 +0000 Subject: [njs] Test for right-associativity of exponential operator. Message-ID: details: http://hg.nginx.org/njs/rev/58342f302de3 branches: changeset: 289:58342f302de3 user: Valentin Bartenev date: Fri Dec 23 19:42:15 2016 +0300 description: Test for right-associativity of exponential operator. diffstat: njs/test/njs_unit_test.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r f5225d9cc97b -r 58342f302de3 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Dec 19 14:19:59 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Dec 23 19:42:15 2016 +0300 @@ -226,6 +226,9 @@ static njs_unit_test_t njs_test[] = /* Exponentiation. */ + { nxt_string("2 ** 3 ** 2"), + nxt_string("512") }, + { nxt_string("2 ** (3 ** 2)"), nxt_string("512") }, From mdounin at mdounin.ru Sat Dec 24 16:25:32 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 24 Dec 2016 16:25:32 +0000 Subject: [nginx] Win32: added a variable to specify compiler. Message-ID: details: http://hg.nginx.org/nginx/rev/c2c13f1f47fd branches: changeset: 6855:c2c13f1f47fd user: Maxim Dounin date: Sat Dec 24 18:01:14 2016 +0300 description: Win32: added a variable to specify compiler. This allows to set a different one from command line when needed. For example, to configure nginx with gcc as a compiler one could use "make -f misc/GNUmakefile win32 CC=gcc". diffstat: misc/GNUmakefile | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (20 lines): diff --git a/misc/GNUmakefile b/misc/GNUmakefile --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -4,6 +4,7 @@ VER = $(shell grep 'define NGINX_VERSIO NGINX = nginx-$(VER) TEMP = tmp +CC = cl OBJS = objs.msvc8 OPENSSL = openssl-1.0.2j ZLIB = zlib-1.2.8 @@ -47,7 +48,7 @@ RELEASE: win32: ./auto/configure \ - --with-cc=cl \ + --with-cc=$(CC) \ --builddir=$(OBJS) \ --with-debug \ --prefix= \ From mdounin at mdounin.ru Sat Dec 24 16:25:41 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 24 Dec 2016 16:25:41 +0000 Subject: [nginx] Win32: fixed building with newer versions of MinGW GCC. Message-ID: details: http://hg.nginx.org/nginx/rev/28a8497bf39c branches: changeset: 6856:28a8497bf39c user: Maxim Dounin date: Sat Dec 24 18:01:14 2016 +0300 description: Win32: fixed building with newer versions of MinGW GCC. Macro to indicate that off_t was defined has been changed, so we now additionally define the new one. diffstat: src/os/win32/ngx_win32_config.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -51,6 +51,7 @@ /* GCC MinGW's stdio.h includes sys/types.h */ #define _OFF_T_ +#define __have_typedef_off_t #endif From mdounin at mdounin.ru Sat Dec 24 16:25:43 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 24 Dec 2016 16:25:43 +0000 Subject: [nginx] Win32: stdint.h used for MinGW GCC. Message-ID: details: http://hg.nginx.org/nginx/rev/26d88ec9baf4 branches: changeset: 6857:26d88ec9baf4 user: Maxim Dounin date: Sat Dec 24 18:01:14 2016 +0300 description: Win32: stdint.h used for MinGW GCC. There is no need to restrict stdint.h only to MinGW-w64 GCC, it is available with MinGW GCC as well. diffstat: src/os/win32/ngx_win32_config.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -58,7 +58,7 @@ #include #include #include -#ifdef __MINGW64_VERSION_MAJOR +#ifdef __GNUC__ #include #endif #include From mdounin at mdounin.ru Sat Dec 24 16:25:45 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 24 Dec 2016 16:25:45 +0000 Subject: [nginx] Win32: minimized redefinition of intptr_t/uintptr_t. Message-ID: details: http://hg.nginx.org/nginx/rev/f39ceadf0441 branches: changeset: 6858:f39ceadf0441 user: Maxim Dounin date: Sat Dec 24 18:01:14 2016 +0300 description: Win32: minimized redefinition of intptr_t/uintptr_t. These types are available with MSVC (at least since 2003, in stddef.h), all variants of GCC (in stdint.h) and Watcom C. We need to define them only for Borland C. diffstat: src/os/win32/ngx_win32_config.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -152,7 +152,7 @@ typedef unsigned short int uint16_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; -#if !defined(__WATCOMC__) && !defined(__MINGW64_VERSION_MAJOR) +#if __BORLANDC__ typedef int intptr_t; typedef u_int uintptr_t; #endif From mdounin at mdounin.ru Sat Dec 24 16:25:48 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 24 Dec 2016 16:25:48 +0000 Subject: [nginx] Win32: minimized redefinition of ssize_t. Message-ID: details: http://hg.nginx.org/nginx/rev/38df52d4e250 branches: changeset: 6859:38df52d4e250 user: Maxim Dounin date: Sat Dec 24 18:01:14 2016 +0300 description: Win32: minimized redefinition of ssize_t. All variants of GCC have ssize_t available, there is no need to redefine it. diffstat: src/os/win32/ngx_win32_config.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -185,7 +185,7 @@ typedef unsigned int ino_t; #endif -#ifndef __MINGW64_VERSION_MAJOR +#ifndef __GNUC__ typedef int ssize_t; #endif From mdounin at mdounin.ru Sat Dec 24 16:25:50 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 24 Dec 2016 16:25:50 +0000 Subject: [nginx] Win32: fixed some warnings reported by Borland C. Message-ID: details: http://hg.nginx.org/nginx/rev/f18c285c2e59 branches: changeset: 6860:f18c285c2e59 user: Maxim Dounin date: Sat Dec 24 18:01:14 2016 +0300 description: Win32: fixed some warnings reported by Borland C. Most notably, warning W8012 (comparing signed and unsigned values) reported in multiple places where an unsigned value of small type (e.g., u_short) is promoted to an int and compared to an unsigned value. Warning W8072 (suspicious pointer arithmetic) disabled, it is reported when we increment base pointer in ngx_shm_alloc(). diffstat: src/core/ngx_resolver.c | 10 +++++----- src/http/modules/ngx_http_sub_filter_module.c | 4 ++-- src/http/ngx_http_file_cache.c | 6 +++--- src/mail/ngx_mail_smtp_module.c | 2 +- src/os/win32/ngx_win32_config.h | 3 +++ 5 files changed, 14 insertions(+), 11 deletions(-) diffs (112 lines): diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -780,7 +780,7 @@ ngx_resolve_name_locked(ngx_resolver_t * #endif if (rn->nsrvs) { - for (i = 0; i < rn->nsrvs; i++) { + for (i = 0; i < (ngx_uint_t) rn->nsrvs; i++) { if (rn->u.srvs[i].name.data) { ngx_resolver_free_locked(r, rn->u.srvs[i].name.data); } @@ -2959,7 +2959,7 @@ ngx_resolver_resolve_srv_names(ngx_resol ngx_del_timer(ctx->event); } - for (i = 0; i < rn->nsrvs; i++) { + for (i = 0; i < (ngx_uint_t) rn->nsrvs; i++) { srvs[i].name.data = ngx_resolver_alloc(r, rn->u.srvs[i].name.len); if (srvs[i].name.data == NULL) { goto failed; @@ -4077,7 +4077,7 @@ ngx_resolver_free_node(ngx_resolver_t *r #endif if (rn->nsrvs) { - for (i = 0; i < rn->nsrvs; i++) { + for (i = 0; i < (ngx_uint_t) rn->nsrvs; i++) { if (rn->u.srvs[i].name.data) { ngx_resolver_free_locked(r, rn->u.srvs[i].name.data); } @@ -4206,10 +4206,10 @@ ngx_resolver_export(ngx_resolver_t *r, n d = 0; } - if (j == rn->naddrs) { + if (j == (ngx_uint_t) rn->naddrs) { j = 0; } - } while (++i < rn->naddrs); + } while (++i < (ngx_uint_t) rn->naddrs); } #if (NGX_HAVE_INET6) diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c --- a/src/http/modules/ngx_http_sub_filter_module.c +++ b/src/http/modules/ngx_http_sub_filter_module.c @@ -645,7 +645,7 @@ ngx_http_sub_parse(ngx_http_request_t *r start = offset - (ngx_int_t) tables->min_match_len + 1; - i = ngx_max(tables->index[c], ctx->index); + i = ngx_max((ngx_uint_t) tables->index[c], ctx->index); j = tables->index[c + 1]; while (i != j) { @@ -978,7 +978,7 @@ ngx_http_sub_init_tables(ngx_http_sub_ta } c = match[i].match.data[tables->min_match_len - 1]; - while (ch <= c) { + while (ch <= (ngx_uint_t) c) { tables->index[ch++] = (u_char) i; } } diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c @@ -553,7 +553,7 @@ ngx_http_file_cache_read(ngx_http_reques return NGX_DECLINED; } - if (h->crc32 != c->crc32 || h->header_start != c->header_start) { + if (h->crc32 != c->crc32 || (size_t) h->header_start != c->header_start) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, "cache file \"%s\" has md5 collision", c->file.name.data); return NGX_DECLINED; @@ -1495,8 +1495,8 @@ ngx_http_file_cache_update_header(ngx_ht if (h.version != NGX_HTTP_CACHE_VERSION || h.last_modified != c->last_modified || h.crc32 != c->crc32 - || h.header_start != c->header_start - || h.body_start != c->body_start) + || (size_t) h.header_start != c->header_start + || (size_t) h.body_start != c->body_start) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http file cache \"%s\" content changed", diff --git a/src/mail/ngx_mail_smtp_module.c b/src/mail/ngx_mail_smtp_module.c --- a/src/mail/ngx_mail_smtp_module.c +++ b/src/mail/ngx_mail_smtp_module.c @@ -280,7 +280,7 @@ ngx_mail_smtp_merge_srv_conf(ngx_conf_t p = ngx_cpymem(p, conf->capability.data, conf->capability.len); - p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1); + ngx_memcpy(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1); p = conf->starttls_capability.data + (last - conf->capability.data) + 3; diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -119,6 +119,9 @@ typedef long time_t; /* unreferenced formal parameter */ #pragma warn -8057 +/* suspicious pointer arithmetic */ +#pragma warn -8072 + #endif From mdounin at mdounin.ru Sat Dec 24 16:25:53 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 24 Dec 2016 16:25:53 +0000 Subject: [nginx] Win32: support 64-bit compilation with MSVC. Message-ID: details: http://hg.nginx.org/nginx/rev/e4590dfd97ff branches: changeset: 6861:e4590dfd97ff user: Maxim Dounin date: Sat Dec 24 18:01:14 2016 +0300 description: Win32: support 64-bit compilation with MSVC. There are lots of C4244 warnings (conversion from 'type1' to 'type2', possible loss of data), so they were disabled. The same applies to C4267 warnings (conversion from 'size_t' to 'type', possible loss of data), most notably - conversion from ngx_str_t.len to ngx_variable_value_t.len (which is unsigned:28). Additionally, there is at least one case when it is not possible to fix the warning properly without introducing win32-specific code: recv() on win32 uses "int len", while POSIX defines "size_t len". The ssize_t type now properly defined for 64-bit compilation with MSVC. Caught by warning C4305 (truncation from '__int64' to 'ssize_t'), on "cutoff = NGX_MAX_SIZE_T_VALUE / 10" in ngx_atosz()). Several C4334 warnings (result of 32-bit shift implicitly converted to 64 bits) were fixed by adding explicit conversions. Several C4214 warnings (nonstandard extension used: bit field types other than int) in ngx_http_script.h fixed by changing bit field types from uintptr_t to unsigned. diffstat: src/core/ngx_slab.c | 6 +++--- src/http/ngx_http_script.c | 4 ++-- src/http/ngx_http_script.h | 22 +++++++++++----------- src/os/win32/ngx_win32_config.h | 10 ++++++++++ 4 files changed, 26 insertions(+), 16 deletions(-) diffs (121 lines): diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c --- a/src/core/ngx_slab.c +++ b/src/core/ngx_slab.c @@ -101,7 +101,7 @@ ngx_slab_init(ngx_slab_pool_t *pool) } /**/ - pool->min_size = 1 << pool->min_shift; + pool->min_size = (size_t) 1 << pool->min_shift; slots = ngx_slab_slots(pool); @@ -473,7 +473,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *po case NGX_SLAB_SMALL: shift = slab & NGX_SLAB_SHIFT_MASK; - size = 1 << shift; + size = (size_t) 1 << shift; if ((uintptr_t) p & (size - 1)) { goto wrong_chunk; @@ -568,7 +568,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *po case NGX_SLAB_BIG: shift = slab & NGX_SLAB_SHIFT_MASK; - size = 1 << shift; + size = (size_t) 1 << shift; if ((uintptr_t) p & (size - 1)) { goto wrong_chunk; diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c --- a/src/http/ngx_http_script.c +++ b/src/http/ngx_http_script.c @@ -356,11 +356,11 @@ ngx_http_script_compile(ngx_http_script_ n = sc->source->data[i] - '0'; - if (sc->captures_mask & (1 << n)) { + if (sc->captures_mask & ((ngx_uint_t) 1 << n)) { sc->dup_capture = 1; } - sc->captures_mask |= 1 << n; + sc->captures_mask |= (ngx_uint_t) 1 << n; if (ngx_http_script_add_capture_code(sc, n) != NGX_OK) { return NGX_ERROR; diff --git a/src/http/ngx_http_script.h b/src/http/ngx_http_script.h --- a/src/http/ngx_http_script.h +++ b/src/http/ngx_http_script.h @@ -121,16 +121,16 @@ typedef struct { uintptr_t status; uintptr_t next; - uintptr_t test:1; - uintptr_t negative_test:1; - uintptr_t uri:1; - uintptr_t args:1; + unsigned test:1; + unsigned negative_test:1; + unsigned uri:1; + unsigned args:1; /* add the r->args to the new arguments */ - uintptr_t add_args:1; + unsigned add_args:1; - uintptr_t redirect:1; - uintptr_t break_cycle:1; + unsigned redirect:1; + unsigned break_cycle:1; ngx_str_t name; } ngx_http_script_regex_code_t; @@ -139,13 +139,13 @@ typedef struct { typedef struct { ngx_http_script_code_pt code; - uintptr_t uri:1; - uintptr_t args:1; + unsigned uri:1; + unsigned args:1; /* add the r->args to the new arguments */ - uintptr_t add_args:1; + unsigned add_args:1; - uintptr_t redirect:1; + unsigned redirect:1; } ngx_http_script_regex_end_code_t; #endif diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -94,6 +94,12 @@ typedef long time_t; /* FD_SET() and FD_CLR(): conditional expression is constant */ #pragma warning(disable:4127) +/* conversion from 'type1' to 'type2', possible loss of data */ +#pragma warning(disable:4244) + +/* conversion from 'size_t' to 'type', possible loss of data */ +#pragma warning(disable:4267) + /* array is too small to include a terminating null character */ #pragma warning(disable:4295) @@ -189,8 +195,12 @@ typedef unsigned int ino_t; #ifndef __GNUC__ +#ifdef _WIN64 +typedef __int64 ssize_t; +#else typedef int ssize_t; #endif +#endif typedef uint32_t in_addr_t; From mdounin at mdounin.ru Sat Dec 24 16:25:55 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 24 Dec 2016 16:25:55 +0000 Subject: [nginx] Win32: compatiblity with OpenSSL 1.1.0. Message-ID: details: http://hg.nginx.org/nginx/rev/abb0a4189cf7 branches: changeset: 6862:abb0a4189cf7 user: Maxim Dounin date: Sat Dec 24 18:01:14 2016 +0300 description: Win32: compatiblity with OpenSSL 1.1.0. OpenSSL 1.1.0 now uses normal "nmake; nmake install" instead of using custom "ms\do_ms.bat" script and "ms\nt.mak" makefile. And Configure now requires --prefix to be absolute, and no longer derives --openssldir from prefix (so it's specified explicitly). Generated libraries are now called "libcrypto.lib" and "libssl.lib" instead of "libeay32.lib" and "ssleay32.lib". Appropriate tests added to support both old and new variants. Additionally, openssl/lhash.h now triggers warning C4090 ('function' : different 'const' qualifiers), so the warning was disabled. diffstat: auto/lib/openssl/conf | 12 ++++++++++-- auto/lib/openssl/makefile.msvc | 17 ++++++++++++----- src/os/win32/ngx_win32_config.h | 3 +++ 3 files changed, 25 insertions(+), 7 deletions(-) diffs (60 lines): diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf --- a/auto/lib/openssl/conf +++ b/auto/lib/openssl/conf @@ -15,8 +15,16 @@ if [ $OPENSSL != NONE ]; then CORE_INCS="$CORE_INCS $OPENSSL/openssl/include" CORE_DEPS="$CORE_DEPS $OPENSSL/openssl/include/openssl/ssl.h" - CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/ssleay32.lib" - CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libeay32.lib" + + if [ -f $OPENSSL/ms/do_ms.bat ]; then + # before OpenSSL 1.1.0 + CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/ssleay32.lib" + CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libeay32.lib" + else + # OpenSSL 1.1.0+ + CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libssl.lib" + CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libcrypto.lib" + fi # libeay32.lib requires gdi32.lib CORE_LIBS="$CORE_LIBS gdi32.lib" diff --git a/auto/lib/openssl/makefile.msvc b/auto/lib/openssl/makefile.msvc --- a/auto/lib/openssl/makefile.msvc +++ b/auto/lib/openssl/makefile.msvc @@ -6,9 +6,16 @@ all: cd $(OPENSSL) - perl Configure VC-WIN32 no-shared --prefix=openssl $(OPENSSL_OPT) + perl Configure VC-WIN32 no-shared \ + --prefix="%cd%/openssl" \ + --openssldir="%cd%/openssl/ssl" \ + $(OPENSSL_OPT) - ms\do_ms - - $(MAKE) -f ms\nt.mak - $(MAKE) -f ms\nt.mak install + if exist ms\do_ms.bat ( \ + ms\do_ms \ + && $(MAKE) -f ms\nt.mak \ + && $(MAKE) -f ms\nt.mak install \ + ) else ( \ + $(MAKE) \ + && $(MAKE) install_sw \ + ) diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -88,6 +88,9 @@ typedef long time_t; /* 'type cast': from data pointer to function pointer */ #pragma warning(disable:4055) +/* 'function' : different 'const' qualifiers */ +#pragma warning(disable:4090) + /* unreferenced formal parameter */ #pragma warning(disable:4100) From arut at nginx.com Mon Dec 26 13:33:30 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Mon, 26 Dec 2016 13:33:30 +0000 Subject: [nginx] Stream: speed up TCP peer recovery. Message-ID: details: http://hg.nginx.org/nginx/rev/54cf51c4f07a branches: changeset: 6863:54cf51c4f07a user: Roman Arutyunyan date: Mon Dec 26 14:27:05 2016 +0300 description: Stream: speed up TCP peer recovery. Previously, an unavailable peer was considered recovered after a successful proxy session to this peer. Until then, only a single client connection per fail_timeout was allowed to be proxied to the peer. Since stream sessions can be long, it may take indefinite time for a peer to recover, limiting the ability of the peer to receive new connections. Now, a peer is considered recovered after a successful TCP connection is established to it. Balancers are notified of this event via the notify() callback. diffstat: src/stream/ngx_stream_proxy_module.c | 5 ++++ src/stream/ngx_stream_upstream.h | 3 ++ src/stream/ngx_stream_upstream_round_robin.c | 29 ++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 0 deletions(-) diffs (81 lines): diff -r abb0a4189cf7 -r 54cf51c4f07a src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Sat Dec 24 18:01:14 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Mon Dec 26 14:27:05 2016 +0300 @@ -808,6 +808,11 @@ ngx_stream_proxy_init_upstream(ngx_strea u->state->connect_time = ngx_current_msec - u->state->response_time; + if (u->peer.notify) { + u->peer.notify(&u->peer, u->peer.data, + NGX_STREAM_UPSTREAM_NOTIFY_CONNECT); + } + c->log->action = "proxying connection"; if (u->upstream_buf.start == NULL) { diff -r abb0a4189cf7 -r 54cf51c4f07a src/stream/ngx_stream_upstream.h --- a/src/stream/ngx_stream_upstream.h Sat Dec 24 18:01:14 2016 +0300 +++ b/src/stream/ngx_stream_upstream.h Mon Dec 26 14:27:05 2016 +0300 @@ -24,6 +24,9 @@ #define NGX_STREAM_UPSTREAM_MAX_CONNS 0x0100 +#define NGX_STREAM_UPSTREAM_NOTIFY_CONNECT 0x1 + + typedef struct { ngx_array_t upstreams; /* ngx_stream_upstream_srv_conf_t */ diff -r abb0a4189cf7 -r 54cf51c4f07a src/stream/ngx_stream_upstream_round_robin.c --- a/src/stream/ngx_stream_upstream_round_robin.c Sat Dec 24 18:01:14 2016 +0300 +++ b/src/stream/ngx_stream_upstream_round_robin.c Mon Dec 26 14:27:05 2016 +0300 @@ -16,6 +16,8 @@ static ngx_stream_upstream_rr_peer_t *ngx_stream_upstream_get_peer( ngx_stream_upstream_rr_peer_data_t *rrp); +static void ngx_stream_upstream_notify_round_robin_peer( + ngx_peer_connection_t *pc, void *data, ngx_uint_t state); #if (NGX_STREAM_SSL) @@ -288,6 +290,7 @@ ngx_stream_upstream_init_round_robin_pee s->upstream->peer.get = ngx_stream_upstream_get_round_robin_peer; s->upstream->peer.free = ngx_stream_upstream_free_round_robin_peer; + s->upstream->peer.notify = ngx_stream_upstream_notify_round_robin_peer; s->upstream->peer.tries = ngx_stream_upstream_tries(rrp->peers); #if (NGX_STREAM_SSL) s->upstream->peer.set_session = @@ -659,6 +662,32 @@ ngx_stream_upstream_free_round_robin_pee } +static void +ngx_stream_upstream_notify_round_robin_peer(ngx_peer_connection_t *pc, + void *data, ngx_uint_t type) +{ + ngx_stream_upstream_rr_peer_data_t *rrp = data; + + ngx_stream_upstream_rr_peer_t *peer; + + peer = rrp->current; + + if (type == NGX_STREAM_UPSTREAM_NOTIFY_CONNECT + && pc->connection->type == SOCK_STREAM) + { + ngx_stream_upstream_rr_peers_rlock(rrp->peers); + ngx_stream_upstream_rr_peer_lock(rrp->peers, peer); + + if (peer->accessed < peer->checked) { + peer->fails = 0; + } + + ngx_stream_upstream_rr_peer_unlock(rrp->peers, peer); + ngx_stream_upstream_rr_peers_unlock(rrp->peers); + } +} + + #if (NGX_STREAM_SSL) static ngx_int_t From igor at sysoev.ru Tue Dec 27 07:40:27 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 27 Dec 2016 07:40:27 +0000 Subject: [njs] Version 0.1.7. Message-ID: details: http://hg.nginx.org/njs/rev/15dc54100400 branches: changeset: 290:15dc54100400 user: Igor Sysoev date: Tue Dec 27 10:39:53 2016 +0300 description: Version 0.1.7. diffstat: Makefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (10 lines): diff -r 58342f302de3 -r 15dc54100400 Makefile --- a/Makefile Fri Dec 23 19:42:15 2016 +0300 +++ b/Makefile Tue Dec 27 10:39:53 2016 +0300 @@ -1,5 +1,5 @@ -NJS_VER = 0.1.6 +NJS_VER = 0.1.7 NXT_LIB = nxt From igor at sysoev.ru Tue Dec 27 07:40:29 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 27 Dec 2016 07:40:29 +0000 Subject: [njs] Added tag 0.1.7 for changeset 15dc54100400 Message-ID: details: http://hg.nginx.org/njs/rev/1944eaa4b2cf branches: changeset: 291:1944eaa4b2cf user: Igor Sysoev date: Tue Dec 27 10:40:08 2016 +0300 description: Added tag 0.1.7 for changeset 15dc54100400 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 15dc54100400 -r 1944eaa4b2cf .hgtags --- a/.hgtags Tue Dec 27 10:39:53 2016 +0300 +++ b/.hgtags Tue Dec 27 10:40:08 2016 +0300 @@ -5,3 +5,4 @@ 360449773d51e7f451e5396e27021badc6b86085 508689c1fb94c23f6b24be087c1dc63b2f9e6654 0.1.4 9c813c2bb2acfd5b6e9d1e9b6699af928baea15a 0.1.5 44b524f7e313369cd062a387511ea6fdc427875f 0.1.6 +15dc54100400f99c3ec044d8fb0175dd3d69adcb 0.1.7 From mdounin at mdounin.ru Tue Dec 27 14:27:15 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 27 Dec 2016 14:27:15 +0000 Subject: [nginx] nginx-1.11.8-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/4591da489a30 branches: changeset: 6864:4591da489a30 user: Maxim Dounin date: Tue Dec 27 17:23:07 2016 +0300 description: nginx-1.11.8-RELEASE diffstat: docs/xml/nginx/changes.xml | 107 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 107 insertions(+), 0 deletions(-) diffs (117 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,113 @@ + + + + +????????? absolute_redirect. + + +the "absolute_redirect" directive. + + + + + +???????? escape ????????? log_format. + + +the "escape" parameter of the "log_format" directive. + + + + + +???????? ?????????? SSL-???????????? ? ?????? stream. + + +client SSL certificates verification in the stream module. + + + + + +????????? ssl_session_ticket_key ???????????? +?????????? TLS session tickets ? ??????? AES256 +??? ????????????? ? 80-???????? ???????. + + +the "ssl_session_ticket_key" directive supports +AES256 encryption of TLS session tickets +when used with 80-byte keys. + + + + + +????????? vim-commentary ? ???????? ??? vim.
+??????? Armin Grodon. +
+ +vim-commentary support in vim scripts.
+Thanks to Armin Grodon. +
+
+ + + +???????? ??? ????????? ???????? ?????????? ?? ??????????????. + + +recursion when evaluating variables was not limited. + + + + + +? ?????? ngx_stream_ssl_preread_module. + + +in the ngx_stream_ssl_preread_module. + + + + + +???? ??????, ????????? ? ????? upstream ? ?????? stream, +??? ??????? ????????????, ?? ????? ????????? fail_timeout ?? +??????????? ?????????? ?????? ????? ?????????? ????????? ??????????; +?????? ??????????, ????? ?????????? ???? ??????? ???????????. + + +if a server in an upstream in the stream module failed, +it was considered alive only when a test connection sent +to it after fail_timeout was closed; +now a successfully established connection is enough. + + + + + +nginx/Windows ?? ????????? ? 64-?????? Visual Studio. + + +nginx/Windows could not be built with 64-bit Visual Studio. + + + + + +nginx/Windows ?? ????????? ? OpenSSL 1.1.0. + + +nginx/Windows could not be built with OpenSSL 1.1.0. + + + +
+ + From mdounin at mdounin.ru Tue Dec 27 14:27:17 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 27 Dec 2016 14:27:17 +0000 Subject: [nginx] release-1.11.8 tag Message-ID: details: http://hg.nginx.org/nginx/rev/a42afc225e98 branches: changeset: 6865:a42afc225e98 user: Maxim Dounin date: Tue Dec 27 17:23:08 2016 +0300 description: release-1.11.8 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -406,3 +406,4 @@ 953512ca02c6f63b4fcbbc3e10d0d9835896bf99 5253015a339aaca0a3111473d3e931b6d4752393 release-1.11.5 5e371426b3bcba4312ce08606194b89b758927d1 release-1.11.6 5c8f60faf33ca8926473d2da27b4c3c417bd4630 release-1.11.7 +4591da489a30f790def29bc5987f43409b503cae release-1.11.8 From timo at incline.eu Tue Dec 27 14:27:20 2016 From: timo at incline.eu (Timo Beckers) Date: Tue, 27 Dec 2016 15:27:20 +0100 Subject: [PATCH] Disable ETag handling in slice filter Message-ID: Hi, We use Nginx to locally cache large binary content. Cache efficiency is of high importance, so the slice filter is excellent for this purpose! Here's a (very) short relevant configuration snippet for a particular location we use: slice 1m; proxy_cache data; proxy_pass http://$host$request_uri; proxy_cache_key $uri$slice_range; proxy_set_header Range $slice_range; Since we've adopted the slice filter, we've been seeing a lot of 'etag mismatch in slice response' errors because the upstream provider serves content from multiple CDNs that provide the exact same URI namespace. For example, consider the following resource: /tpr/hs/data/7c/bf/7cbf4dbce9233a57ff6c1cbf84db77d8 Level3 serves this resource with ETag 74bc439-54261c855fd64. Akamai serves this resource with ETag 1273157742232ec1b8d3afc4c41a2a9c:1480362585. Since we value cache efficiency over anything else, adding the host to the cache key is not an option. The alternative is pinning proxy_pass to one specific CDN, but that approach has several other downsides. So, I decided to try my hand at (slightly) altering the filter to make it more configurable, I've posted the result below. Further improvements might include: - A (regex?) transformation for the ETag field, but that wouldn't be useful in the scenario above - exporting the ETag field out of the slice filter as a variable, effectively making the cache mutable 'slice_etag' might be slightly too obscure to people unfamiliar with the internals, perhaps 'slice_match_etag' would be more descriptive, but I'll leave that up to the maintainers. I've seen 'ngx_flag_t' in other *_conf_t typedefs, I hope that's appropriate. I'm not a C programmer, but I did the best I could. Any feedback is highly appreciated. Take care, Timo # HG changeset patch # User Timo Beckers # Date 1482843958 -3600 # Tue Dec 27 14:05:58 2016 +0100 # Node ID 9e8c70191f0a9db9ad08bfb959fc1b1404d312ec # Parent 54cf51c4f07add000b824036d4dce4bc60e67bcf Slice filter: add slice_etag config var to disable etag handling When caching 206 requests from multiple CDNs that serve identical resources but have a different ETag scheme, this setting can be used to disable the ETag checking during processing of response headers. This comes in handy when seeing an excessive amount of 'etag mismatch in slice response' errors and the cache is short-lived enough to ensure clients don't receive stale content. diff -r 54cf51c4f07a -r 9e8c70191f0a src/http/modules/ngx_http_slice_filter_module.c --- a/src/http/modules/ngx_http_slice_filter_module.c Mon Dec 26 14:27:05 2016 +0300 +++ b/src/http/modules/ngx_http_slice_filter_module.c Tue Dec 27 14:05:58 2016 +0100 @@ -12,6 +12,7 @@ typedef struct { size_t size; + ngx_flag_t etag; } ngx_http_slice_loc_conf_t; @@ -48,6 +49,13 @@ static ngx_command_t ngx_http_slice_filter_commands[] = { + { ngx_string("slice_etag"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_slice_loc_conf_t, etag), + NULL }, + { ngx_string("slice"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, @@ -123,22 +131,26 @@ return NGX_ERROR; } - h = r->headers_out.etag; + slcf = ngx_http_get_module_loc_conf(r, ngx_http_slice_filter_module); - if (ctx->etag.len) { - if (h == NULL - || h->value.len != ctx->etag.len - || ngx_strncmp(h->value.data, ctx->etag.data, ctx->etag.len) - != 0) - { - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "etag mismatch in slice response"); - return NGX_ERROR; + if (slcf->etag) { + h = r->headers_out.etag; + + if (ctx->etag.len) { + if (h == NULL + || h->value.len != ctx->etag.len + || ngx_strncmp(h->value.data, ctx->etag.data, ctx->etag.len) + != 0) + { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "etag mismatch in slice response"); + return NGX_ERROR; + } } - } - if (h) { - ctx->etag = h->value; + if (h) { + ctx->etag = h->value; + } } if (ngx_http_slice_parse_content_range(r, &cr) != NGX_OK) { @@ -157,8 +169,6 @@ "http slice response range: %O-%O/%O", cr.start, cr.end, cr.complete_length); - slcf = ngx_http_get_module_loc_conf(r, ngx_http_slice_filter_module); - end = ngx_min(cr.start + (off_t) slcf->size, cr.complete_length); if (cr.start != ctx->start || cr.end != end) { @@ -480,6 +490,7 @@ } slcf->size = NGX_CONF_UNSET_SIZE; + slcf->etag = NGX_CONF_UNSET; return slcf; } @@ -492,6 +503,7 @@ ngx_http_slice_loc_conf_t *conf = child; ngx_conf_merge_size_value(conf->size, prev->size, 0); + ngx_conf_merge_off_value(conf->etag, prev->etag, 1); return NGX_CONF_OK; } From mdounin at mdounin.ru Tue Dec 27 15:02:25 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 27 Dec 2016 18:02:25 +0300 Subject: [PATCH] Disable ETag handling in slice filter In-Reply-To: References: Message-ID: <20161227150225.GA18639@mdounin.ru> Hello! On Tue, Dec 27, 2016 at 03:27:20PM +0100, Timo Beckers wrote: > Hi, > > We use Nginx to locally cache large binary content. Cache efficiency > is of high importance, so the slice filter is excellent for this > purpose! Here's a (very) short relevant configuration snippet for a > particular location we use: > > slice 1m; > proxy_cache data; > proxy_pass http://$host$request_uri; > proxy_cache_key $uri$slice_range; > proxy_set_header Range $slice_range; > > Since we've adopted the slice filter, we've been seeing a lot of 'etag > mismatch in slice response' errors because the upstream provider > serves content from multiple CDNs that provide the exact same URI > namespace. For example, consider the following resource: > > /tpr/hs/data/7c/bf/7cbf4dbce9233a57ff6c1cbf84db77d8 > > Level3 serves this resource with ETag 74bc439-54261c855fd64. > Akamai serves this resource with ETag > 1273157742232ec1b8d3afc4c41a2a9c:1480362585. > > Since we value cache efficiency over anything else, adding the host to > the cache key is not an option. The alternative is pinning proxy_pass > to one specific CDN, but that approach has several other downsides. > So, I decided to try my hand at (slightly) altering the filter to make > it more configurable, I've posted the result below. Further > improvements might include: Try proxy_hide_header ETag; instead, it should help. The other side effect of this is that there will be no ETag in responses returned. This is clearly a good thing in the scenario described, as ETag in your case is broken as it changes from one request to another. Removing it altogether will also help clients to use range requests and local caching. [...] -- Maxim Dounin http://nginx.org/ From joel.cunningham at me.com Tue Dec 27 22:37:36 2016 From: joel.cunningham at me.com (Joel Cunningham) Date: Tue, 27 Dec 2016 16:37:36 -0600 Subject: [PATCH] Fix drain logic for small number of connections In-Reply-To: <691A2C9B-3561-4223-895B-EDBA1884743A@me.com> References: <691A2C9B-3561-4223-895B-EDBA1884743A@me.com> Message-ID: <9FA73531-083D-40B8-9A45-A571CA55EAA2@me.com> Ping?any interest in accepting this patch? > On Dec 7, 2016, at 3:50 PM, Joel Cunningham wrote: > > Hi, > > I run NGINX in an embedded environment with limited resources. We have NGINX configured with a small number of maximum connections (worker_connections is 16). I?ve found the ngx_drain_connection() logic uses a hard-coded value to limit the number of reaped reusable connections. This works fine with the default 512, but is too aggressive for small number of connections and ends up reaping all reusable connections. These include new connections just accepted on the previous event loop cycle (which had not yet had a chance to receive a request) at the head of the list. > > The below patch switches to the minimum of 32 or 1/4 of the number of connections. This should be less aggressive, even when the number of connections is slightly larger than 32, e.g. 48 or 64. > > Joel > > # HG changeset patch > # User Joel Cunningham > # Date 1481145862 21600 > # Wed Dec 07 15:24:22 2016 -0600 > # Node ID b103dddcee7322522651f9aca764d499d5822ac1 > # Parent 75dbab4ea930bc73cca98d183c2f556eb5125462 > Fix drain logic for small number of connections > > This commit fixes the ngx_drain_connections logic when maximum number of > connections are small (16/32/64). Using a hardcoded value of 32 when > the number of connections is small is overlly aggressive and will result > in repeaing the entire (or large portion of) the reusable_connections_queue, > which includes at the tail newly accepted connections that have not received > a request yet > > The logic is updated to use the minimum of 1/4 the number of connections > or 32, which ever is smaller > > diff -r 75dbab4ea930 -r b103dddcee73 src/core/ngx_connection.c > --- a/src/core/ngx_connection.c Mon Nov 21 16:03:42 2016 +0300 > +++ b/src/core/ngx_connection.c Wed Dec 07 15:24:22 2016 -0600 > @@ -1232,7 +1232,7 @@ > ngx_queue_t *q; > ngx_connection_t *c; > > - for (i = 0; i < 32; i++) { > + for (i = 0; i < ngx_min(32, ngx_cycle->connection_n / 4); i++) { > if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) { > break; > } > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From mdounin at mdounin.ru Wed Dec 28 17:05:15 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 28 Dec 2016 20:05:15 +0300 Subject: [PATCH] Fix drain logic for small number of connections In-Reply-To: <9FA73531-083D-40B8-9A45-A571CA55EAA2@me.com> References: <691A2C9B-3561-4223-895B-EDBA1884743A@me.com> <9FA73531-083D-40B8-9A45-A571CA55EAA2@me.com> Message-ID: <20161228170515.GE18639@mdounin.ru> Hello! On Tue, Dec 27, 2016 at 04:37:36PM -0600, Joel Cunningham wrote: > Ping?any interest in accepting this patch? I'm not sure this patch improves things. Currently, 32 means that under constant load nginx will drain old connections once per 32 connection attempts. With the patch, 32 is reduced to a smaller number, but this doesn't make any difference under constant load: if there are enough connections accepted on the current event loop iteration, all connections from the previous event loop iteration will be closed as long as they haven't managed to provide some data. The difference may occur if worker_connections limit is reached occasionally: in this case smaller number can mean that not all keepalive connections will be closed. But it is not clear how this is different from a server with a large number of established connections and only a small number of reusable ones. It is also not clear why use so small number of worker connections, but this is another question. -- Maxim Dounin http://nginx.org/ From joel.cunningham at me.com Wed Dec 28 18:56:46 2016 From: joel.cunningham at me.com (Joel Cunningham) Date: Wed, 28 Dec 2016 12:56:46 -0600 Subject: [PATCH] Fix drain logic for small number of connections In-Reply-To: <20161228170515.GE18639@mdounin.ru> References: <691A2C9B-3561-4223-895B-EDBA1884743A@me.com> <9FA73531-083D-40B8-9A45-A571CA55EAA2@me.com> <20161228170515.GE18639@mdounin.ru> Message-ID: > On Dec 28, 2016, at 11:05 AM, Maxim Dounin wrote: > > Hello! > > On Tue, Dec 27, 2016 at 04:37:36PM -0600, Joel Cunningham wrote: > >> Ping?any interest in accepting this patch? > > I'm not sure this patch improves things. > > Currently, 32 means that under constant load nginx will drain old > connections once per 32 connection attempts. With the patch, 32 > is reduced to a smaller number, but this doesn't make any > difference under constant load: if there are enough connections > accepted on the current event loop iteration, all connections from > the previous event loop iteration will be closed as long as they > haven't managed to provide some data. > You?re correct that when the worker limit is small (less than 4 times 32), we?ll will free less connections during a drain and under a constant load, ngx_drain_connections ends being called more often. This seemed a non-issue for situations with small worker limits because freeing up to half or more (in my case all) of the connections on the reusable_connections_queue seemed inappropriate. Is it the case that 32 was chosen to limit how often we drain rather than being a limit on how much of the queue to drain (and limiting the drain is just a side-effect)? > The difference may occur if worker_connections limit is reached > occasionally: in this case smaller number can mean that not all > keepalive connections will be closed. But it is not clear how > this is different from a server with a large number of established > connections and only a small number of reusable ones. This is the case I?m running into. You?re correct that we?d still close out newly accepted connections if the number of reusable_connections_queue is smaller than the drain limit. It happens to be the case in my situation where the reusable_connections_queue is 99% keep alive connections and only a single accepted connection which hasn?t been given the chance to receive the request (the request is actually already queued in the socket buffer, but since accept FD has a lower value than the new connection FD, the connection gets closed out before we can receive on it) > > It is also not clear why use so small number of worker > connections, but this is another question. Joel From mdounin at mdounin.ru Thu Dec 29 19:13:34 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 29 Dec 2016 22:13:34 +0300 Subject: [PATCH] Fix drain logic for small number of connections In-Reply-To: References: <691A2C9B-3561-4223-895B-EDBA1884743A@me.com> <9FA73531-083D-40B8-9A45-A571CA55EAA2@me.com> <20161228170515.GE18639@mdounin.ru> Message-ID: <20161229191334.GI18639@mdounin.ru> Hello! On Wed, Dec 28, 2016 at 12:56:46PM -0600, Joel Cunningham wrote: > > On Dec 28, 2016, at 11:05 AM, Maxim Dounin wrote: > > > > Hello! > > > > On Tue, Dec 27, 2016 at 04:37:36PM -0600, Joel Cunningham wrote: > > > >> Ping?any interest in accepting this patch? > > > > I'm not sure this patch improves things. > > > > Currently, 32 means that under constant load nginx will drain old > > connections once per 32 connection attempts. With the patch, 32 > > is reduced to a smaller number, but this doesn't make any > > difference under constant load: if there are enough connections > > accepted on the current event loop iteration, all connections from > > the previous event loop iteration will be closed as long as they > > haven't managed to provide some data. > > > > You?re correct that when the worker limit is small (less than 4 > times 32), we?ll will free less connections during a drain and > under a constant load, ngx_drain_connections ends being called > more often. This seemed a non-issue for situations with small > worker limits because freeing up to half or more (in my case > all) of the connections on the reusable_connections_queue seemed > inappropriate. > > Is it the case that 32 was chosen to limit how often we drain > rather than being a limit on how much of the queue to drain (and > limiting the drain is just a side-effect)? The idea of draining multiple connections at once is to minimize further need for draining, by providing some amount of free connections. This allows to save some resources by improving memory access locality. Additionally, this also provides some time for connections to be closed - e.g., it might not be possible to close an SSL connection immediately. > > The difference may occur if worker_connections limit is reached > > occasionally: in this case smaller number can mean that not all > > keepalive connections will be closed. But it is not clear how > > this is different from a server with a large number of established > > connections and only a small number of reusable ones. > > This is the case I?m running into. You?re correct that we?d > still close out newly accepted connections if the number of > reusable_connections_queue is smaller than the drain limit. It > happens to be the case in my situation where the > reusable_connections_queue is 99% keep alive connections and > only a single accepted connection which hasn?t been given the > chance to receive the request (the request is actually already > queued in the socket buffer, but since accept FD has a lower > value than the new connection FD, the connection gets closed out > before we can receive on it) Order of events is not bound to the file descriptor value. For most event methods it is rather bound to the time of the event. Moreover, using accept filters and/or deferred accept allows to read requests immediately from newly accepted sockets, making it completely up to the client to provide requests fast enough. I agree though that if connection shortage is occasional the current behaviour might not be optimal with worker_connections set to a small value, or there are only a few connections can be reused. Instead of gradually reducing keepalive (and post accept) timeout to a smaller value it closes all keepalive connections from time to time. Probably optimal solution would be to close no more than some fraction of reusable connections at once. Patch series below. # HG changeset patch # User Maxim Dounin # Date 1483036498 -10800 # Thu Dec 29 21:34:58 2016 +0300 # Node ID 016ea0d2dc42b5945a037618920ea8ed2d07a186 # Parent a42afc225e98afe1f7c3b428c81c8af7eba362c0 Added cycle parameter to ngx_drain_connections(). No functional changes, mostly style. diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -13,7 +13,7 @@ ngx_os_io_t ngx_io; -static void ngx_drain_connections(void); +static void ngx_drain_connections(ngx_cycle_t *cycle); ngx_listening_t * @@ -1046,7 +1046,7 @@ ngx_get_connection(ngx_socket_t s, ngx_l c = ngx_cycle->free_connections; if (c == NULL) { - ngx_drain_connections(); + ngx_drain_connections((ngx_cycle_t *) ngx_cycle); c = ngx_cycle->free_connections; } @@ -1226,18 +1226,18 @@ ngx_reusable_connection(ngx_connection_t static void -ngx_drain_connections(void) +ngx_drain_connections(ngx_cycle_t *cycle) { ngx_int_t i; ngx_queue_t *q; ngx_connection_t *c; for (i = 0; i < 32; i++) { - if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) { + if (ngx_queue_empty(&cycle->reusable_connections_queue)) { break; } - q = ngx_queue_last(&ngx_cycle->reusable_connections_queue); + q = ngx_queue_last(&cycle->reusable_connections_queue); c = ngx_queue_data(q, ngx_connection_t, queue); ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0, # HG changeset patch # User Maxim Dounin # Date 1483036544 -10800 # Thu Dec 29 21:35:44 2016 +0300 # Node ID 166379461168a32d2137053961e8afc3435567db # Parent 016ea0d2dc42b5945a037618920ea8ed2d07a186 Improved connection draining with small number of connections. Closing up to 32 connections might be too aggressive if worker_connections is set to a comparable number (and/or there are only a small number of reusable connections). If an occasional connection shorage happens in such a configuration, it leads to closing all reusable connections instead of gradually reducing keepalive timeout to a smaller value. To improve granularity in such configurations we now close no more than 1/8 of all reusable connections at once. Suggested by Joel Cunningham. diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -1204,6 +1204,7 @@ ngx_reusable_connection(ngx_connection_t if (c->reusable) { ngx_queue_remove(&c->queue); + ngx_cycle->reusable_connections_n++; #if (NGX_STAT_STUB) (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1); @@ -1217,6 +1218,7 @@ ngx_reusable_connection(ngx_connection_t ngx_queue_insert_head( (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue); + ngx_cycle->reusable_connections_n--; #if (NGX_STAT_STUB) (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1); @@ -1228,11 +1230,13 @@ ngx_reusable_connection(ngx_connection_t static void ngx_drain_connections(ngx_cycle_t *cycle) { - ngx_int_t i; + ngx_uint_t i, n; ngx_queue_t *q; ngx_connection_t *c; - for (i = 0; i < 32; i++) { + n = ngx_max(ngx_min(32, cycle->reusable_connections_n / 8), 1); + + for (i = 0; i < n; i++) { if (ngx_queue_empty(&cycle->reusable_connections_queue)) { break; } diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -53,6 +53,7 @@ struct ngx_cycle_s { ngx_uint_t modules_used; /* unsigned modules_used:1; */ ngx_queue_t reusable_connections_queue; + ngx_uint_t reusable_connections_n; ngx_array_t listening; ngx_array_t paths; -- Maxim Dounin http://nginx.org/ From witekfl at gazeta.pl Fri Dec 30 13:36:00 2016 From: witekfl at gazeta.pl (Witold Filipczyk) Date: Fri, 30 Dec 2016 14:36:00 +0100 Subject: How to read variable in C code? Message-ID: <20161230133600.GA15686@lenovo> Hi, there is map: map $http_host $hosts { hostnames; default 0; .example.com 1; .example.net 1; ... .example.org 1; } How to read the value of $hosts in C module code? How to make it right, that's mean do not evaluate it more than once per request? I want to do some modifications of body response based on 'type' of host and map would simplify the code, at least hope so. From joel.cunningham at me.com Fri Dec 30 18:13:01 2016 From: joel.cunningham at me.com (Joel Cunningham) Date: Fri, 30 Dec 2016 12:13:01 -0600 Subject: [PATCH] Fix drain logic for small number of connections In-Reply-To: <20161229191334.GI18639@mdounin.ru> References: <691A2C9B-3561-4223-895B-EDBA1884743A@me.com> <9FA73531-083D-40B8-9A45-A571CA55EAA2@me.com> <20161228170515.GE18639@mdounin.ru> <20161229191334.GI18639@mdounin.ru> Message-ID: <492FC288-6BCE-46D4-9EB1-C20C85C3F8A4@me.com> > On Dec 29, 2016, at 1:13 PM, Maxim Dounin wrote: > > Hello! > > On Wed, Dec 28, 2016 at 12:56:46PM -0600, Joel Cunningham wrote: > >>> On Dec 28, 2016, at 11:05 AM, Maxim Dounin wrote: >>> >>> Hello! >>> >>> On Tue, Dec 27, 2016 at 04:37:36PM -0600, Joel Cunningham wrote: >>> >>>> Ping?any interest in accepting this patch? >>> >>> I'm not sure this patch improves things. >>> >>> Currently, 32 means that under constant load nginx will drain old >>> connections once per 32 connection attempts. With the patch, 32 >>> is reduced to a smaller number, but this doesn't make any >>> difference under constant load: if there are enough connections >>> accepted on the current event loop iteration, all connections from >>> the previous event loop iteration will be closed as long as they >>> haven't managed to provide some data. >>> >> >> You?re correct that when the worker limit is small (less than 4 >> times 32), we?ll will free less connections during a drain and >> under a constant load, ngx_drain_connections ends being called >> more often. This seemed a non-issue for situations with small >> worker limits because freeing up to half or more (in my case >> all) of the connections on the reusable_connections_queue seemed >> inappropriate. >> >> Is it the case that 32 was chosen to limit how often we drain >> rather than being a limit on how much of the queue to drain (and >> limiting the drain is just a side-effect)? > > The idea of draining multiple connections at once is to minimize > further need for draining, by providing some amount of free > connections. This allows to save some resources by improving > memory access locality. > > Additionally, this also provides some time for connections to be > closed - e.g., it might not be possible to close an SSL connection > immediately. > >>> The difference may occur if worker_connections limit is reached >>> occasionally: in this case smaller number can mean that not all >>> keepalive connections will be closed. But it is not clear how >>> this is different from a server with a large number of established >>> connections and only a small number of reusable ones. >> >> This is the case I?m running into. You?re correct that we?d >> still close out newly accepted connections if the number of >> reusable_connections_queue is smaller than the drain limit. It >> happens to be the case in my situation where the >> reusable_connections_queue is 99% keep alive connections and >> only a single accepted connection which hasn?t been given the >> chance to receive the request (the request is actually already >> queued in the socket buffer, but since accept FD has a lower >> value than the new connection FD, the connection gets closed out >> before we can receive on it) > > Order of events is not bound to the file descriptor value. For > most event methods it is rather bound to the time of the event. > Moreover, using accept filters and/or deferred accept allows to > read requests immediately from newly accepted sockets, making it > completely up to the client to provide requests fast enough. Thanks for mentioning the accept filters/deferred accept. I?ll have to look into enabling that in my port > > I agree though that if connection shortage is occasional the > current behaviour might not be optimal with worker_connections set > to a small value, or there are only a few connections can be > reused. Instead of gradually reducing keepalive (and post accept) > timeout to a smaller value it closes all keepalive connections > from time to time. > > Probably optimal solution would be to close no more than some > fraction of reusable connections at once. Patch series below. I tested out the patch series and I did run into a problem. Looks like the reusable_connections_n increment and decrement are swapped. The first call to ngx_reusable_connection causes unsigned integer wrap around. I swapped the increment/decrement and the patch gives the expected behavior of only freeing 1/8 (or at least 1) of the reusable connections. Thanks for the alternate approach, I agree it?s better use a drain limit based on the number of reusable connections rather than total number of connections (worker limit) > > # HG changeset patch > # User Maxim Dounin > # Date 1483036498 -10800 > # Thu Dec 29 21:34:58 2016 +0300 > # Node ID 016ea0d2dc42b5945a037618920ea8ed2d07a186 > # Parent a42afc225e98afe1f7c3b428c81c8af7eba362c0 > Added cycle parameter to ngx_drain_connections(). > > No functional changes, mostly style. > > diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c > --- a/src/core/ngx_connection.c > +++ b/src/core/ngx_connection.c > @@ -13,7 +13,7 @@ > ngx_os_io_t ngx_io; > > > -static void ngx_drain_connections(void); > +static void ngx_drain_connections(ngx_cycle_t *cycle); > > > ngx_listening_t * > @@ -1046,7 +1046,7 @@ ngx_get_connection(ngx_socket_t s, ngx_l > c = ngx_cycle->free_connections; > > if (c == NULL) { > - ngx_drain_connections(); > + ngx_drain_connections((ngx_cycle_t *) ngx_cycle); > c = ngx_cycle->free_connections; > } > > @@ -1226,18 +1226,18 @@ ngx_reusable_connection(ngx_connection_t > > > static void > -ngx_drain_connections(void) > +ngx_drain_connections(ngx_cycle_t *cycle) > { > ngx_int_t i; > ngx_queue_t *q; > ngx_connection_t *c; > > for (i = 0; i < 32; i++) { > - if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) { > + if (ngx_queue_empty(&cycle->reusable_connections_queue)) { > break; > } > > - q = ngx_queue_last(&ngx_cycle->reusable_connections_queue); > + q = ngx_queue_last(&cycle->reusable_connections_queue); > c = ngx_queue_data(q, ngx_connection_t, queue); > > ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0, > # HG changeset patch > # User Maxim Dounin > # Date 1483036544 -10800 > # Thu Dec 29 21:35:44 2016 +0300 > # Node ID 166379461168a32d2137053961e8afc3435567db > # Parent 016ea0d2dc42b5945a037618920ea8ed2d07a186 > Improved connection draining with small number of connections. > > Closing up to 32 connections might be too aggressive if worker_connections > is set to a comparable number (and/or there are only a small number of > reusable connections). If an occasional connection shorage happens in > such a configuration, it leads to closing all reusable connections instead > of gradually reducing keepalive timeout to a smaller value. To improve > granularity in such configurations we now close no more than 1/8 of all > reusable connections at once. > > Suggested by Joel Cunningham. > > diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c > --- a/src/core/ngx_connection.c > +++ b/src/core/ngx_connection.c > @@ -1204,6 +1204,7 @@ ngx_reusable_connection(ngx_connection_t > > if (c->reusable) { > ngx_queue_remove(&c->queue); > + ngx_cycle->reusable_connections_n++; > > #if (NGX_STAT_STUB) > (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1); > @@ -1217,6 +1218,7 @@ ngx_reusable_connection(ngx_connection_t > > ngx_queue_insert_head( > (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue); > + ngx_cycle->reusable_connections_n?; > > #if (NGX_STAT_STUB) > (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1); > @@ -1228,11 +1230,13 @@ ngx_reusable_connection(ngx_connection_t > static void > ngx_drain_connections(ngx_cycle_t *cycle) > { > - ngx_int_t i; > + ngx_uint_t i, n; > ngx_queue_t *q; > ngx_connection_t *c; > > - for (i = 0; i < 32; i++) { > + n = ngx_max(ngx_min(32, cycle->reusable_connections_n / 8), 1); > + > + for (i = 0; i < n; i++) { > if (ngx_queue_empty(&cycle->reusable_connections_queue)) { > break; > } > diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h > --- a/src/core/ngx_cycle.h > +++ b/src/core/ngx_cycle.h > @@ -53,6 +53,7 @@ struct ngx_cycle_s { > ngx_uint_t modules_used; /* unsigned modules_used:1; */ > > ngx_queue_t reusable_connections_queue; > + ngx_uint_t reusable_connections_n; > > ngx_array_t listening; > ngx_array_t paths; > > Joel From mdounin at mdounin.ru Sat Dec 31 02:04:14 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 31 Dec 2016 05:04:14 +0300 Subject: [PATCH] Fix drain logic for small number of connections In-Reply-To: <492FC288-6BCE-46D4-9EB1-C20C85C3F8A4@me.com> References: <691A2C9B-3561-4223-895B-EDBA1884743A@me.com> <9FA73531-083D-40B8-9A45-A571CA55EAA2@me.com> <20161228170515.GE18639@mdounin.ru> <20161229191334.GI18639@mdounin.ru> <492FC288-6BCE-46D4-9EB1-C20C85C3F8A4@me.com> Message-ID: <20161231020414.GJ18639@mdounin.ru> Hello! On Fri, Dec 30, 2016 at 12:13:01PM -0600, Joel Cunningham wrote: > > On Dec 29, 2016, at 1:13 PM, Maxim Dounin wrote: [...] > > I agree though that if connection shortage is occasional the > > current behaviour might not be optimal with worker_connections set > > to a small value, or there are only a few connections can be > > reused. Instead of gradually reducing keepalive (and post accept) > > timeout to a smaller value it closes all keepalive connections > > from time to time. > > > > Probably optimal solution would be to close no more than some > > fraction of reusable connections at once. Patch series below. > > I tested out the patch series and I did run into a problem. > Looks like the reusable_connections_n increment and decrement > are swapped. The first call to ngx_reusable_connection causes > unsigned integer wrap around. I swapped the increment/decrement > and the patch gives the expected behavior of only freeing 1/8 > (or at least 1) of the reusable connections. Thanks for noticing this, fixed. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Sat Dec 31 02:42:34 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 31 Dec 2016 05:42:34 +0300 Subject: How to read variable in C code? In-Reply-To: <20161230133600.GA15686@lenovo> References: <20161230133600.GA15686@lenovo> Message-ID: <20161231024234.GK18639@mdounin.ru> Hello! On Fri, Dec 30, 2016 at 02:36:00PM +0100, Witold Filipczyk wrote: > Hi, > > there is map: > map $http_host $hosts { > hostnames; > default 0; > .example.com 1; > .example.net 1; > ... > .example.org 1; > } > > How to read the value of $hosts in C module code? If you only need a single variable, most effective approach is to use indexed variables. The ngx_http_get_variable_index() function is used to obtain an index during configuration parsing / module initialization, and ngx_http_get_indexed_variable() to obtain a value at runtime. E.g., memcached module uses this to access $memcached_key variable, see here: http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_memcached_module.c#l716 http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_memcached_module.c#l243 More universal approach is to use complex values. Complex values can contain arbitrary combinations of variables and static strings. During configuration parsing complex values are compiled using ngx_http_compile_complex_value() (ngx_http_set_complex_value_slot can do it automatically if there is a dedicated configuration directive), and then ngx_http_complex_value() can be used to obtain a value. E.g., map itself uses complex value to handle the first parameter, "$http_host" in your case, see here: http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_map_module.c#l209 http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_map_module.c#l120 > How to make it right, that's mean do not evaluate it more than once per request? Map results are automatically cached by nginx, much like all variables not explicitly declared as non-cacheable, so you don't really need to worry. On the other hand, usually it's a good idea to remember the value obtained in your module data if you are going to use it again. -- Maxim Dounin http://nginx.org/