From mdounin at mdounin.ru Tue Nov 1 17:39:50 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 01 Nov 2016 17:39:50 +0000 Subject: [nginx] Perl: fixed optimization in SSI command handler. Message-ID: details: http://hg.nginx.org/nginx/rev/cb4a4e9bba8e branches: changeset: 6791:cb4a4e9bba8e user: Maxim Dounin date: Tue Nov 01 20:39:21 2016 +0300 description: Perl: fixed optimization in SSI command handler. As the pointer to the first argument was tested instead of the argument itself, array of arguments was always created, even if there were no arguments. Fix is to test args[0] instead of args. Found by Coverity (CID 1356862). diffstat: src/http/modules/perl/ngx_http_perl_module.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 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 @@ -410,7 +410,7 @@ ngx_http_perl_ssi(ngx_http_request_t *r, args = ¶ms[NGX_HTTP_PERL_SSI_ARG]; - if (args) { + if (args[0]) { for (i = 0; args[i]; i++) { /* void */ } From pluknet at nginx.com Wed Nov 2 08:48:16 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Wed, 02 Nov 2016 08:48:16 +0000 Subject: [nginx] HTTP/2: flow control debugging. Message-ID: details: http://hg.nginx.org/nginx/rev/45d553812055 branches: changeset: 6792:45d553812055 user: Sergey Kandaurov date: Wed Nov 02 11:47:12 2016 +0300 description: HTTP/2: flow control debugging. diffstat: src/http/v2/ngx_http_v2_filter_module.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r cb4a4e9bba8e -r 45d553812055 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Tue Nov 01 20:39:21 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Wed Nov 02 11:47:12 2016 +0300 @@ -1079,6 +1079,10 @@ static ngx_inline ngx_int_t ngx_http_v2_flow_control(ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream) { + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "http2:%ui available windows: conn:%uz stream:%z", + stream->node->id, h2c->send_window, stream->send_window); + if (stream->send_window <= 0) { stream->exhausted = 1; return NGX_DECLINED; From xeioex at nginx.com Wed Nov 2 18:39:54 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 02 Nov 2016 18:39:54 +0000 Subject: [nginx] Cache: proxy_cache_max_range_offset and friends. Message-ID: details: http://hg.nginx.org/nginx/rev/0fba3ed4e7eb branches: changeset: 6793:0fba3ed4e7eb user: Dmitry Volyntsev date: Wed Nov 02 20:05:21 2016 +0300 description: Cache: proxy_cache_max_range_offset and friends. It configures a threshold in bytes, above which client range requests are not cached. In such a case the client's Range header is passed directly to a proxied server. diffstat: src/http/modules/ngx_http_fastcgi_module.c | 12 ++++++ src/http/modules/ngx_http_proxy_module.c | 12 ++++++ src/http/modules/ngx_http_scgi_module.c | 12 ++++++ src/http/modules/ngx_http_uwsgi_module.c | 12 ++++++ src/http/ngx_http_upstream.c | 55 ++++++++++++++++++++++++++++++ src/http/ngx_http_upstream.h | 2 + 6 files changed, 105 insertions(+), 0 deletions(-) diffs (235 lines): diff -r 45d553812055 -r 0fba3ed4e7eb src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c Wed Nov 02 11:47:12 2016 +0300 +++ b/src/http/modules/ngx_http_fastcgi_module.c Wed Nov 02 20:05:21 2016 +0300 @@ -420,6 +420,13 @@ static ngx_command_t ngx_http_fastcgi_c offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_min_uses), NULL }, + { ngx_string("fastcgi_cache_max_range_offset"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_off_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_max_range_offset), + NULL }, + { ngx_string("fastcgi_cache_use_stale"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_conf_set_bitmask_slot, @@ -2754,6 +2761,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_con #if (NGX_HTTP_CACHE) conf->upstream.cache = NGX_CONF_UNSET; conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; + conf->upstream.cache_max_range_offset = NGX_CONF_UNSET; conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR; conf->upstream.no_cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; @@ -2999,6 +3007,10 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf ngx_conf_merge_uint_value(conf->upstream.cache_min_uses, prev->upstream.cache_min_uses, 1); + ngx_conf_merge_off_value(conf->upstream.cache_max_range_offset, + prev->upstream.cache_max_range_offset, + NGX_MAX_OFF_T_VALUE); + ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale, prev->upstream.cache_use_stale, (NGX_CONF_BITMASK_SET diff -r 45d553812055 -r 0fba3ed4e7eb src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Wed Nov 02 11:47:12 2016 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Wed Nov 02 20:05:21 2016 +0300 @@ -492,6 +492,13 @@ static ngx_command_t ngx_http_proxy_com offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_min_uses), NULL }, + { ngx_string("proxy_cache_max_range_offset"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_off_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_max_range_offset), + NULL }, + { ngx_string("proxy_cache_use_stale"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_conf_set_bitmask_slot, @@ -2847,6 +2854,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ #if (NGX_HTTP_CACHE) conf->upstream.cache = NGX_CONF_UNSET; conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; + conf->upstream.cache_max_range_offset = NGX_CONF_UNSET; conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR; conf->upstream.no_cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; @@ -3108,6 +3116,10 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t ngx_conf_merge_uint_value(conf->upstream.cache_min_uses, prev->upstream.cache_min_uses, 1); + ngx_conf_merge_off_value(conf->upstream.cache_max_range_offset, + prev->upstream.cache_max_range_offset, + NGX_MAX_OFF_T_VALUE); + ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale, prev->upstream.cache_use_stale, (NGX_CONF_BITMASK_SET diff -r 45d553812055 -r 0fba3ed4e7eb src/http/modules/ngx_http_scgi_module.c --- a/src/http/modules/ngx_http_scgi_module.c Wed Nov 02 11:47:12 2016 +0300 +++ b/src/http/modules/ngx_http_scgi_module.c Wed Nov 02 20:05:21 2016 +0300 @@ -270,6 +270,13 @@ static ngx_command_t ngx_http_scgi_comma offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_min_uses), NULL }, + { ngx_string("scgi_cache_max_range_offset"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_off_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_max_range_offset), + NULL }, + { ngx_string("scgi_cache_use_stale"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_conf_set_bitmask_slot, @@ -1204,6 +1211,7 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t #if (NGX_HTTP_CACHE) conf->upstream.cache = NGX_CONF_UNSET; conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; + conf->upstream.cache_max_range_offset = NGX_CONF_UNSET; conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR; conf->upstream.no_cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; @@ -1444,6 +1452,10 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t ngx_conf_merge_uint_value(conf->upstream.cache_min_uses, prev->upstream.cache_min_uses, 1); + ngx_conf_merge_off_value(conf->upstream.cache_max_range_offset, + prev->upstream.cache_max_range_offset, + NGX_MAX_OFF_T_VALUE); + ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale, prev->upstream.cache_use_stale, (NGX_CONF_BITMASK_SET diff -r 45d553812055 -r 0fba3ed4e7eb src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c Wed Nov 02 11:47:12 2016 +0300 +++ b/src/http/modules/ngx_http_uwsgi_module.c Wed Nov 02 20:05:21 2016 +0300 @@ -330,6 +330,13 @@ static ngx_command_t ngx_http_uwsgi_comm offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_min_uses), NULL }, + { ngx_string("uwsgi_cache_max_range_offset"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_off_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_max_range_offset), + NULL }, + { ngx_string("uwsgi_cache_use_stale"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_conf_set_bitmask_slot, @@ -1410,6 +1417,7 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_ #if (NGX_HTTP_CACHE) conf->upstream.cache = NGX_CONF_UNSET; conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; + conf->upstream.cache_max_range_offset = NGX_CONF_UNSET; conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR; conf->upstream.no_cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; @@ -1658,6 +1666,10 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t ngx_conf_merge_uint_value(conf->upstream.cache_min_uses, prev->upstream.cache_min_uses, 1); + ngx_conf_merge_off_value(conf->upstream.cache_max_range_offset, + prev->upstream.cache_max_range_offset, + NGX_MAX_OFF_T_VALUE); + ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale, prev->upstream.cache_use_stale, (NGX_CONF_BITMASK_SET diff -r 45d553812055 -r 0fba3ed4e7eb src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Wed Nov 02 11:47:12 2016 +0300 +++ b/src/http/ngx_http_upstream.c Wed Nov 02 20:05:21 2016 +0300 @@ -17,6 +17,8 @@ static ngx_int_t ngx_http_upstream_cache ngx_http_upstream_t *u, ngx_http_file_cache_t **cache); static ngx_int_t ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u); +static ngx_int_t ngx_http_upstream_cache_check_range(ngx_http_request_t *r, + ngx_http_upstream_t *u); static ngx_int_t ngx_http_upstream_cache_status(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_upstream_cache_last_modified(ngx_http_request_t *r, @@ -922,6 +924,10 @@ ngx_http_upstream_cache(ngx_http_request return rc; } + if (ngx_http_upstream_cache_check_range(r, u) == NGX_DECLINED) { + u->cacheable = 0; + } + r->cached = 0; return NGX_DECLINED; @@ -1023,6 +1029,55 @@ ngx_http_upstream_cache_send(ngx_http_re return rc; } + +static ngx_int_t +ngx_http_upstream_cache_check_range(ngx_http_request_t *r, + ngx_http_upstream_t *u) +{ + off_t offset; + u_char *p, *start; + ngx_table_elt_t *h; + + h = r->headers_in.range; + + if (h == NULL + || !u->cacheable + || u->conf->cache_max_range_offset == NGX_MAX_OFF_T_VALUE) + { + return NGX_OK; + } + + if (u->conf->cache_max_range_offset == 0) { + return NGX_DECLINED; + } + + if (h->value.len < 7 + || ngx_strncasecmp(h->value.data, (u_char *) "bytes=", 6) != 0) + { + return NGX_OK; + } + + p = h->value.data + 6; + + while (*p == ' ') { p++; } + + if (*p == '-') { + return NGX_DECLINED; + } + + start = p; + + while (*p >= '0' && *p <= '9') { p++; } + + offset = ngx_atoof(start, p - start); + + if (offset >= u->conf->cache_max_range_offset) { + return NGX_DECLINED; + } + + return NGX_OK; +} + #endif diff -r 45d553812055 -r 0fba3ed4e7eb src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h Wed Nov 02 11:47:12 2016 +0300 +++ b/src/http/ngx_http_upstream.h Wed Nov 02 20:05:21 2016 +0300 @@ -198,6 +198,8 @@ typedef struct { ngx_uint_t cache_use_stale; ngx_uint_t cache_methods; + off_t cache_max_range_offset; + ngx_flag_t cache_lock; ngx_msec_t cache_lock_timeout; ngx_msec_t cache_lock_age; From xray at randoman.ru Thu Nov 3 12:47:16 2016 From: xray at randoman.ru (Sergey S. Kovalev) Date: Thu, 3 Nov 2016 19:47:16 +0700 Subject: [PATCH] Events: add ability to receive sockets by SCM_RIGHTS Message-ID: <3a13d8ab-4f3c-9062-2f65-ff8c1a85eeb9@randoman.ru> # HG changeset patch # User Sergey Kovalev # Date 1478146426 -25200 # Thu Nov 03 11:13:46 2016 +0700 # Node ID 57a3036fd504a93dcbfd75a263a5d71523cdc379 # Parent cb4a4e9bba8ed7038dc423a9ad07139215db3363 Events: add ability to receive sockets by SCM_RIGHTS With this patch ngx_event_recvmsg() handler can process SCM_RIGHTS messages and treat received sockets as new accepted connections. This feature can be used to improve overall performance with tricky request routing (like sharing port for several daemons) or can be used in some security systems to check connection data before passing it to nginx. To build nginx with this feature, add configuration option: $ ./configure --with-cmsg-recv-sockets To use it, declare listen on unix socket with "cmsg" option on it: listen unix:/tmp/nginx-cmsg.sock cmsg default_server; This socket is created as SOCK_DGRAM and can't be used for direct request processing. diff -r cb4a4e9bba8e -r 57a3036fd504 auto/modules --- a/auto/modules Tue Nov 01 20:39:21 2016 +0300 +++ b/auto/modules Thu Nov 03 11:13:46 2016 +0700 @@ -1133,6 +1133,10 @@ fi +if [ $CMSG_RECV_SOCKETS = YES ]; then + have=NGX_CMSG_RECV_SOCKETS . auto/have +fi + #if [ -r $NGX_OBJS/auto ]; then # . $NGX_OBJS/auto #fi diff -r cb4a4e9bba8e -r 57a3036fd504 auto/options --- a/auto/options Tue Nov 01 20:39:21 2016 +0300 +++ b/auto/options Thu Nov 03 11:13:46 2016 +0700 @@ -149,6 +149,8 @@ ZLIB_OPT= ZLIB_ASM=NO +CMSG_RECV_SOCKETS=NO + USE_PERL=NO NGX_PERL=perl @@ -324,6 +326,9 @@ --without-stream_upstream_zone_module) STREAM_UPSTREAM_ZONE=NO ;; + --with-cmsg-recv-sockets) CMSG_RECV_SOCKETS=YES ;; + + --with-google_perftools_module) NGX_GOOGLE_PERFTOOLS=YES ;; --with-cpp_test_module) NGX_CPP_TEST=YES ;; @@ -532,6 +537,10 @@ --without-stream_upstream_zone_module disable ngx_stream_upstream_zone_module + --with-cmsg-recv-sockets enable accepting sockets passed via + unix datagram socket with SCM_RIGHTS + ability + --with-google_perftools_module enable ngx_google_perftools_module --with-cpp_test_module enable ngx_cpp_test_module diff -r cb4a4e9bba8e -r 57a3036fd504 src/core/ngx_connection.c --- a/src/core/ngx_connection.c Tue Nov 01 20:39:21 2016 +0300 +++ b/src/core/ngx_connection.c Thu Nov 03 11:13:46 2016 +0700 @@ -18,7 +18,7 @@ ngx_listening_t * ngx_create_listening(ngx_conf_t *cf, struct sockaddr *sockaddr, - socklen_t socklen) + socklen_t socklen, ngx_int_t socktype) { size_t len; ngx_listening_t *ls; @@ -73,7 +73,7 @@ ngx_memcpy(ls->addr_text.data, text, len); ls->fd = (ngx_socket_t) -1; - ls->type = SOCK_STREAM; + ls->type = socktype; ls->backlog = NGX_LISTEN_BACKLOG; ls->rcvbuf = -1; diff -r cb4a4e9bba8e -r 57a3036fd504 src/core/ngx_connection.h --- a/src/core/ngx_connection.h Tue Nov 01 20:39:21 2016 +0300 +++ b/src/core/ngx_connection.h Thu Nov 03 11:13:46 2016 +0700 @@ -66,6 +66,10 @@ unsigned addr_ntop:1; unsigned wildcard:1; +#if (NGX_HAVE_MSGHDR_MSG_CONTROL && NGX_CMSG_RECV_SOCKETS) + unsigned cmsg:1; +#endif + #if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif @@ -204,7 +208,7 @@ ngx_listening_t *ngx_create_listening(ngx_conf_t *cf, struct sockaddr *sockaddr, - socklen_t socklen); + socklen_t socklen, ngx_int_t socktype); ngx_int_t ngx_clone_listening(ngx_conf_t *cf, ngx_listening_t *ls); ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle); ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *cycle); diff -r cb4a4e9bba8e -r 57a3036fd504 src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c Tue Nov 01 20:39:21 2016 +0300 +++ b/src/event/ngx_event_accept.c Thu Nov 03 11:13:46 2016 +0700 @@ -19,18 +19,206 @@ #endif +static inline ngx_int_t ngx_accept_socket(ngx_event_t *ev, ngx_socket_t s, + ngx_sockaddr_t *sa, socklen_t socklen) +{ + ngx_log_t *log; + ngx_event_t *rev, *wev; + ngx_listening_t *ls; + ngx_connection_t *c, *lc; + + lc = ev->data; + ls = lc->listening; + +#if (NGX_STAT_STUB) + (void) ngx_atomic_fetch_add(ngx_stat_accepted, 1); +#endif + + ngx_accept_disabled = ngx_cycle->connection_n / 8 + - ngx_cycle->free_connection_n; + + c = ngx_get_connection(s, ev->log); + + if (c == NULL) { + if (ngx_close_socket(s) == -1) { + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, + ngx_close_socket_n " failed"); + } + + return NGX_ERROR; + } + + c->type = SOCK_STREAM; + +#if (NGX_STAT_STUB) + (void) ngx_atomic_fetch_add(ngx_stat_active, 1); +#endif + + c->pool = ngx_create_pool(ls->pool_size, ev->log); + if (c->pool == NULL) { + ngx_close_accepted_connection(c); + return NGX_ERROR; + } + + c->sockaddr = ngx_palloc(c->pool, socklen); + if (c->sockaddr == NULL) { + ngx_close_accepted_connection(c); + return NGX_ERROR; + } + + ngx_memcpy(c->sockaddr, sa, socklen); + + log = ngx_palloc(c->pool, sizeof(ngx_log_t)); + if (log == NULL) { + ngx_close_accepted_connection(c); + return NGX_ERROR; + } + + /* set a blocking mode for iocp and non-blocking mode for others */ + + if (ngx_inherited_nonblocking) { + if (ngx_event_flags & NGX_USE_IOCP_EVENT) { + if (ngx_blocking(s) == -1) { + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, + ngx_blocking_n " failed"); + ngx_close_accepted_connection(c); + return NGX_ERROR; + } + } + + } else { + if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) { + if (ngx_nonblocking(s) == -1) { + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, + ngx_nonblocking_n " failed"); + ngx_close_accepted_connection(c); + return NGX_ERROR; + } + } + } + + *log = ls->log; + + c->recv = ngx_recv; + c->send = ngx_send; + c->recv_chain = ngx_recv_chain; + c->send_chain = ngx_send_chain; + + c->log = log; + c->pool->log = log; + + c->socklen = socklen; + c->listening = ls; + c->local_sockaddr = ls->sockaddr; + c->local_socklen = ls->socklen; + +#if (NGX_HAVE_UNIX_DOMAIN) + if (c->sockaddr->sa_family == AF_UNIX) { + c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; + c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; +#if (NGX_SOLARIS) + /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */ + c->sendfile = 0; +#endif + } +#endif + + rev = c->read; + wev = c->write; + + wev->ready = 1; + + if (ngx_event_flags & NGX_USE_IOCP_EVENT) { + rev->ready = 1; + } + + if (ev->deferred_accept) { + rev->ready = 1; +#if (NGX_HAVE_KQUEUE) + rev->available = 1; +#endif + } + + rev->log = log; + wev->log = log; + + /* + * TODO: MT: - ngx_atomic_fetch_add() + * or protection by critical section or light mutex + * + * TODO: MP: - allocated in a shared memory + * - ngx_atomic_fetch_add() + * or protection by critical section or light mutex + */ + + c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); + +#if (NGX_STAT_STUB) + (void) ngx_atomic_fetch_add(ngx_stat_handled, 1); +#endif + + if (ls->addr_ntop) { + c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len); + if (c->addr_text.data == NULL) { + ngx_close_accepted_connection(c); + return NGX_ERROR; + } + + c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen, + c->addr_text.data, + ls->addr_text_max_len, 0); + if (c->addr_text.len == 0) { + ngx_close_accepted_connection(c); + return NGX_ERROR; + } + } + +#if (NGX_DEBUG) + { + ngx_str_t addr; + u_char text[NGX_SOCKADDR_STRLEN]; + ngx_event_conf_t *ecf; + + ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); + + ngx_debug_accepted_connection(ecf, c); + + if (log->log_level & NGX_LOG_DEBUG_EVENT) { + addr.data = text; + addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text, + NGX_SOCKADDR_STRLEN, 1); + + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, + "*%uA accept: %V fd:%d", c->number, &addr, s); + } + + } +#endif + + if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) { + if (ngx_add_conn(c) == NGX_ERROR) { + ngx_close_accepted_connection(c); + return NGX_ERROR; + } + } + + log->data = NULL; + log->handler = NULL; + + ls->handler(c); + + return NGX_OK; +} + void ngx_event_accept(ngx_event_t *ev) { socklen_t socklen; ngx_err_t err; - ngx_log_t *log; ngx_uint_t level; ngx_socket_t s; - ngx_event_t *rev, *wev; ngx_sockaddr_t sa; - ngx_listening_t *ls; - ngx_connection_t *c, *lc; + ngx_connection_t *lc; ngx_event_conf_t *ecf; #if (NGX_HAVE_ACCEPT4) static ngx_uint_t use_accept4 = 1; @@ -51,7 +239,6 @@ } lc = ev->data; - ls = lc->listening; ev->ready = 0; ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, @@ -134,180 +321,10 @@ return; } -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_accepted, 1); -#endif - - ngx_accept_disabled = ngx_cycle->connection_n / 8 - - ngx_cycle->free_connection_n; - - c = ngx_get_connection(s, ev->log); - - if (c == NULL) { - if (ngx_close_socket(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, - ngx_close_socket_n " failed"); - } - + if (ngx_accept_socket(ev, s, &sa, socklen) != NGX_OK) { return; } - c->type = SOCK_STREAM; - -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_active, 1); -#endif - - c->pool = ngx_create_pool(ls->pool_size, ev->log); - if (c->pool == NULL) { - ngx_close_accepted_connection(c); - return; - } - - c->sockaddr = ngx_palloc(c->pool, socklen); - if (c->sockaddr == NULL) { - ngx_close_accepted_connection(c); - return; - } - - ngx_memcpy(c->sockaddr, &sa, socklen); - - log = ngx_palloc(c->pool, sizeof(ngx_log_t)); - if (log == NULL) { - ngx_close_accepted_connection(c); - return; - } - - /* set a blocking mode for iocp and non-blocking mode for others */ - - if (ngx_inherited_nonblocking) { - if (ngx_event_flags & NGX_USE_IOCP_EVENT) { - if (ngx_blocking(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, - ngx_blocking_n " failed"); - ngx_close_accepted_connection(c); - return; - } - } - - } else { - if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) { - if (ngx_nonblocking(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, - ngx_nonblocking_n " failed"); - ngx_close_accepted_connection(c); - return; - } - } - } - - *log = ls->log; - - c->recv = ngx_recv; - c->send = ngx_send; - c->recv_chain = ngx_recv_chain; - c->send_chain = ngx_send_chain; - - c->log = log; - c->pool->log = log; - - c->socklen = socklen; - c->listening = ls; - c->local_sockaddr = ls->sockaddr; - c->local_socklen = ls->socklen; - -#if (NGX_HAVE_UNIX_DOMAIN) - if (c->sockaddr->sa_family == AF_UNIX) { - c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; - c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; -#if (NGX_SOLARIS) - /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */ - c->sendfile = 0; -#endif - } -#endif - - rev = c->read; - wev = c->write; - - wev->ready = 1; - - if (ngx_event_flags & NGX_USE_IOCP_EVENT) { - rev->ready = 1; - } - - if (ev->deferred_accept) { - rev->ready = 1; -#if (NGX_HAVE_KQUEUE) - rev->available = 1; -#endif - } - - rev->log = log; - wev->log = log; - - /* - * TODO: MT: - ngx_atomic_fetch_add() - * or protection by critical section or light mutex - * - * TODO: MP: - allocated in a shared memory - * - ngx_atomic_fetch_add() - * or protection by critical section or light mutex - */ - - c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); - -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_handled, 1); -#endif - - if (ls->addr_ntop) { - c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len); - if (c->addr_text.data == NULL) { - ngx_close_accepted_connection(c); - return; - } - - c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen, - c->addr_text.data, - ls->addr_text_max_len, 0); - if (c->addr_text.len == 0) { - ngx_close_accepted_connection(c); - return; - } - } - -#if (NGX_DEBUG) - { - ngx_str_t addr; - u_char text[NGX_SOCKADDR_STRLEN]; - - ngx_debug_accepted_connection(ecf, c); - - if (log->log_level & NGX_LOG_DEBUG_EVENT) { - addr.data = text; - addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text, - NGX_SOCKADDR_STRLEN, 1); - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, - "*%uA accept: %V fd:%d", c->number, &addr, s); - } - - } -#endif - - if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) { - if (ngx_add_conn(c) == NGX_ERROR) { - ngx_close_accepted_connection(c); - return; - } - } - - log->data = NULL; - log->handler = NULL; - - ls->handler(c); - if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { ev->available--; } @@ -335,6 +352,10 @@ #if (NGX_HAVE_MSGHDR_MSG_CONTROL) +#if (NGX_CMSG_RECV_SOCKETS) + u_char msg_control_rights[CMSG_SPACE(sizeof(ngx_int_t))]; +#endif + #if (NGX_HAVE_IP_RECVDSTADDR) u_char msg_control[CMSG_SPACE(sizeof(struct in_addr))]; #elif (NGX_HAVE_IP_PKTINFO) @@ -380,7 +401,12 @@ msg.msg_iovlen = 1; #if (NGX_HAVE_MSGHDR_MSG_CONTROL) - +#if (NGX_CMSG_RECV_SOCKETS) + if (ls->cmsg) { + msg.msg_control = &msg_control_rights; + msg.msg_controllen = sizeof(msg_control_rights); + } else +#endif if (ls->wildcard) { #if (NGX_HAVE_IP_RECVDSTADDR || NGX_HAVE_IP_PKTINFO) @@ -426,6 +452,44 @@ "recvmsg() truncated data"); continue; } + +#if (NGX_CMSG_RECV_SOCKETS) + if (ls->cmsg) { + struct cmsghdr *cmsg; + for (cmsg = CMSG_FIRSTHDR(&msg); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) + { + if ((cmsg->cmsg_level == SOL_SOCKET) + && (cmsg->cmsg_type == SCM_RIGHTS)) + { + ngx_sockaddr_t sa; + socklen_t sa_len; + ngx_socket_t s; + + sa_len = sizeof(sa); + s = *((ngx_socket_t *) CMSG_DATA(cmsg)); + + if (getpeername(s, (struct sockaddr *)&sa, &sa_len) == -1) { + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, + "getpeername() failed"); + + ngx_close_socket(s); + } else { + if (ngx_nonblocking(s) == -1) { + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, + ngx_nonblocking_n " failed"); + + ngx_close_socket(s); + } else { + ngx_accept_socket(ev, s, &sa, sa_len); + } + } + } + + } + } else { +#endif #endif ngx_accept_disabled = ngx_cycle->connection_n / 8 @@ -625,6 +689,9 @@ ls->handler(c); +#if (NGX_HAVE_MSGHDR_MSG_CONTROL && NGX_CMSG_RECV_SOCKETS) + } +#endif if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { ev->available -= n; } diff -r cb4a4e9bba8e -r 57a3036fd504 src/http/ngx_http.c --- a/src/http/ngx_http.c Tue Nov 01 20:39:21 2016 +0300 +++ b/src/http/ngx_http.c Thu Nov 03 11:13:46 2016 +0700 @@ -1703,9 +1703,16 @@ ngx_listening_t *ls; ngx_http_core_loc_conf_t *clcf; ngx_http_core_srv_conf_t *cscf; + ngx_int_t socktype = SOCK_STREAM; + +#if (NGX_HAVE_MSGHDR_MSG_CONTROL && NGX_CMSG_RECV_SOCKETS) + if (addr->opt.cmsg) { + socktype = SOCK_DGRAM; + } +#endif ls = ngx_create_listening(cf, &addr->opt.sockaddr.sockaddr, - addr->opt.socklen); + addr->opt.socklen, socktype); if (ls == NULL) { return NULL; } @@ -1772,6 +1779,10 @@ ls->reuseport = addr->opt.reuseport; #endif +#if (NGX_HAVE_MSGHDR_MSG_CONTROL && NGX_CMSG_RECV_SOCKETS) + ls->cmsg = addr->opt.cmsg; +#endif + return ls; } diff -r cb4a4e9bba8e -r 57a3036fd504 src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Tue Nov 01 20:39:21 2016 +0300 +++ b/src/http/ngx_http_core_module.c Thu Nov 03 11:13:46 2016 +0700 @@ -4246,6 +4246,13 @@ continue; } +#if (NGX_HAVE_MSGHDR_MSG_CONTROL && NGX_CMSG_RECV_SOCKETS) + if (ngx_strcmp(value[n].data, "cmsg") == 0) { + lsopt.cmsg = 1; + continue; + } +#endif + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[n]); return NGX_CONF_ERROR; diff -r cb4a4e9bba8e -r 57a3036fd504 src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h Tue Nov 01 20:39:21 2016 +0300 +++ b/src/http/ngx_http_core_module.h Thu Nov 03 11:13:46 2016 +0700 @@ -77,6 +77,10 @@ unsigned so_keepalive:2; unsigned proxy_protocol:1; +#if (NGX_HAVE_MSGHDR_MSG_CONTROL && NGX_CMSG_RECV_SOCKETS) + unsigned cmsg:1; +#endif + int backlog; int rcvbuf; int sndbuf; diff -r cb4a4e9bba8e -r 57a3036fd504 src/mail/ngx_mail.c --- a/src/mail/ngx_mail.c Tue Nov 01 20:39:21 2016 +0300 +++ b/src/mail/ngx_mail.c Thu Nov 03 11:13:46 2016 +0700 @@ -317,7 +317,7 @@ } ls = ngx_create_listening(cf, &addr[i].opt.sockaddr.sockaddr, - addr[i].opt.socklen); + addr[i].opt.socklen, SOCK_STREAM); if (ls == NULL) { return NGX_CONF_ERROR; } diff -r cb4a4e9bba8e -r 57a3036fd504 src/stream/ngx_stream.c --- a/src/stream/ngx_stream.c Tue Nov 01 20:39:21 2016 +0300 +++ b/src/stream/ngx_stream.c Thu Nov 03 11:13:46 2016 +0700 @@ -477,7 +477,7 @@ } ls = ngx_create_listening(cf, &addr[i].opt.sockaddr.sockaddr, - addr[i].opt.socklen); + addr[i].opt.socklen, SOCK_STREAM); if (ls == NULL) { return NGX_CONF_ERROR; } From mdounin at mdounin.ru Thu Nov 3 14:10:23 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 03 Nov 2016 14:10:23 +0000 Subject: [nginx] Upstream: avoid holding a cache node with upgraded connections. Message-ID: details: http://hg.nginx.org/nginx/rev/93b294c5d581 branches: changeset: 6794:93b294c5d581 user: Maxim Dounin date: Thu Nov 03 17:09:32 2016 +0300 description: Upstream: avoid holding a cache node with upgraded connections. Holding a cache node lock doesn't make sense as we can't use caching anyway, and results in "ignore long locked inactive cache entry" alerts if a node is locked for a long time. The same is done for unbuffered connections, as they can be alive for a long time as well. diffstat: src/http/ngx_http_upstream.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-) diffs (34 lines): diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -2760,6 +2760,15 @@ ngx_http_upstream_send_response(ngx_http u->header_sent = 1; if (u->upgrade) { + +#if (NGX_HTTP_CACHE) + + if (r->cache) { + ngx_http_file_cache_free(r->cache, u->pipe->temp_file); + } + +#endif + ngx_http_upstream_upgrade(r, u); return; } @@ -2790,6 +2799,14 @@ ngx_http_upstream_send_response(ngx_http if (!u->buffering) { +#if (NGX_HTTP_CACHE) + + if (r->cache) { + ngx_http_file_cache_free(r->cache, u->pipe->temp_file); + } + +#endif + if (u->input_filter == NULL) { u->input_filter_init = ngx_http_upstream_non_buffered_filter_init; u->input_filter = ngx_http_upstream_non_buffered_filter; From mdounin at mdounin.ru Thu Nov 3 14:13:49 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 03 Nov 2016 14:13:49 +0000 Subject: [nginx] Cache: prefix-based temporary files. Message-ID: details: http://hg.nginx.org/nginx/rev/1a917932db96 branches: changeset: 6795:1a917932db96 user: Maxim Dounin date: Thu Nov 03 17:10:29 2016 +0300 description: Cache: prefix-based temporary files. On Linux, the rename syscall can be slow due to a global file system lock, acquired for the entire rename operation, unless both old and new files are in the same directory. To address this temporary files are now created in the same directory as the expected resulting cache file when using the "use_temp_path=off" parameter. This change mostly reverts 99639bfdfa2a and 3281de8142f5, restoring the behaviour as of a9138c35120d (with minor changes). diffstat: src/core/ngx_file.c | 32 +++++++++++++++++++++++++---- src/http/ngx_http_cache.h | 4 ++- src/http/ngx_http_file_cache.c | 45 ++++++++++++----------------------------- src/http/ngx_http_upstream.c | 5 ++- 4 files changed, 46 insertions(+), 40 deletions(-) diffs (174 lines): diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -141,12 +141,27 @@ ngx_int_t ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool, ngx_uint_t persistent, ngx_uint_t clean, ngx_uint_t access) { + size_t levels; + u_char *p; uint32_t n; ngx_err_t err; + ngx_str_t name; + ngx_uint_t prefix; ngx_pool_cleanup_t *cln; ngx_pool_cleanup_file_t *clnf; - file->name.len = path->name.len + 1 + path->len + 10; + if (file->name.len) { + name = file->name; + levels = 0; + prefix = 1; + + } else { + name = path->name; + levels = path->len; + prefix = 0; + } + + file->name.len = name.len + 1 + levels + 10; file->name.data = ngx_pnalloc(pool, file->name.len + 1); if (file->name.data == NULL) { @@ -159,7 +174,13 @@ ngx_create_temp_file(ngx_file_t *file, n } #endif - ngx_memcpy(file->name.data, path->name.data, path->name.len); + p = ngx_cpymem(file->name.data, name.data, name.len); + + if (prefix) { + *p = '.'; + } + + p += 1 + levels; n = (uint32_t) ngx_next_temp_number(0); @@ -169,10 +190,11 @@ ngx_create_temp_file(ngx_file_t *file, n } for ( ;; ) { - (void) ngx_sprintf(file->name.data + path->name.len + 1 + path->len, - "%010uD%Z", n); + (void) ngx_sprintf(p, "%010uD%Z", n); - ngx_create_hashed_filename(path, file->name.data, file->name.len); + if (!prefix) { + ngx_create_hashed_filename(path, file->name.data, file->name.len); + } ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0, "hashed path: %s", file->name.data); diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h --- a/src/http/ngx_http_cache.h +++ b/src/http/ngx_http_cache.h @@ -151,7 +151,6 @@ struct ngx_http_file_cache_s { ngx_slab_pool_t *shpool; ngx_path_t *path; - ngx_path_t *temp_path; off_t max_size; size_t bsize; @@ -171,6 +170,9 @@ struct ngx_http_file_cache_s { ngx_msec_t manager_threshold; ngx_shm_zone_t *shm_zone; + + ngx_uint_t use_temp_path; + /* unsigned use_temp_path:1 */ }; 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 @@ -2112,6 +2112,17 @@ ngx_http_file_cache_add_file(ngx_tree_ct return NGX_ERROR; } + /* + * Temporary files in cache have a suffix consisting of a dot + * followed by 10 digits. + */ + + if (name->len >= 2 * NGX_HTTP_CACHE_KEY_LEN + 1 + 10 + && name->data[name->len - 10 - 1] == '.') + { + return NGX_OK; + } + if (ctx->size < (off_t) sizeof(ngx_http_file_cache_header_t)) { ngx_log_error(NGX_LOG_CRIT, ctx->log, 0, "cache file \"%s\" is too small", name->data); @@ -2256,7 +2267,6 @@ ngx_http_file_cache_set_slot(ngx_conf_t off_t max_size; u_char *last, *p; time_t inactive; - size_t len; ssize_t size; ngx_str_t s, name, *value; ngx_int_t loader_files, manager_files; @@ -2529,37 +2539,6 @@ ngx_http_file_cache_set_slot(ngx_conf_t return NGX_CONF_ERROR; } - if (!use_temp_path) { - cache->temp_path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t)); - if (cache->temp_path == NULL) { - return NGX_CONF_ERROR; - } - - len = cache->path->name.len + sizeof("/temp") - 1; - - p = ngx_pnalloc(cf->pool, len + 1); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - cache->temp_path->name.len = len; - cache->temp_path->name.data = p; - - p = ngx_cpymem(p, cache->path->name.data, cache->path->name.len); - ngx_memcpy(p, "/temp", sizeof("/temp")); - - ngx_memcpy(&cache->temp_path->level, &cache->path->level, - NGX_MAX_PATH_LEVEL * sizeof(size_t)); - - cache->temp_path->len = cache->path->len; - cache->temp_path->conf_file = cf->conf_file->file.name.data; - cache->temp_path->line = cf->conf_file->line; - - if (ngx_add_path(cf, &cache->temp_path) != NGX_OK) { - return NGX_CONF_ERROR; - } - } - cache->shm_zone = ngx_shared_memory_add(cf, &name, size, cmd->post); if (cache->shm_zone == NULL) { return NGX_CONF_ERROR; @@ -2575,6 +2554,8 @@ ngx_http_file_cache_set_slot(ngx_conf_t cache->shm_zone->init = ngx_http_file_cache_init; cache->shm_zone->data = cache; + cache->use_temp_path = use_temp_path; + cache->inactive = inactive; cache->max_size = max_size; diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -2997,8 +2997,9 @@ ngx_http_upstream_send_response(ngx_http p->temp_file->persistent = 1; #if (NGX_HTTP_CACHE) - if (r->cache && r->cache->file_cache->temp_path) { - p->temp_file->path = r->cache->file_cache->temp_path; + if (r->cache && !r->cache->file_cache->use_temp_path) { + p->temp_file->path = r->cache->file_cache->path; + p->temp_file->file.name = r->cache->file.name; } #endif From zelenkov at nginx.com Thu Nov 3 15:14:21 2016 From: zelenkov at nginx.com (Andrey Zelenkov) Date: Thu, 03 Nov 2016 15:14:21 +0000 Subject: [njs] String.prototype.repeat method fix. Message-ID: details: http://hg.nginx.org/njs/rev/ff8f717db1be branches: changeset: 234:ff8f717db1be user: Andrey Zelenkov date: Thu Nov 03 18:12:10 2016 +0300 description: String.prototype.repeat method fix. Found with afl-fuzz. diffstat: njs/njs_string.c | 5 +++++ njs/test/njs_unit_test.c | 3 +++ 2 files changed, 8 insertions(+), 0 deletions(-) diffs (28 lines): diff -r d7a10c0dfcce -r ff8f717db1be njs/njs_string.c --- a/njs/njs_string.c Mon Oct 31 16:28:12 2016 +0300 +++ b/njs/njs_string.c Thu Nov 03 18:12:10 2016 +0300 @@ -1756,6 +1756,11 @@ njs_string_prototype_repeat(njs_vm_t *vm (void) njs_string_prop(&string, &args[0]); + if (string.size == 0) { + vm->retval = njs_string_empty; + return NXT_OK; + } + if (nargs > 1) { max = NJS_STRING_MAX_LENGTH / string.size; n = args[1].data.u.number; diff -r d7a10c0dfcce -r ff8f717db1be njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Oct 31 16:28:12 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Nov 03 18:12:10 2016 +0300 @@ -3618,6 +3618,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("'???'.repeat(3)"), nxt_string("?????????") }, + { nxt_string("''.repeat(3)"), + nxt_string("") }, + { nxt_string("'abc'.repeat(0)"), nxt_string("") }, From maxim at mailgunhq.com Thu Nov 3 16:41:03 2016 From: maxim at mailgunhq.com (Maxim Vladimirsky) Date: Thu, 3 Nov 2016 09:41:03 -0700 Subject: [PATCH] Add support for Proxy Protocol to mail SMTP Message-ID: Hi Folks, I was not sure if you would be interested in this, but decided to run it by you anyway. We need to run Nginx as an SMTP proxy sitting behind ELB in AWS, but we also want the upstream SMTP server to get the real client ip, so Nginx is configured to provide it via an XCLIENT command. However the stock version of Nginx provides ELB's ip instead, because it does not recognize the Proxy Protocol header (http://docs.aws.amazon.com/elasticloadbalancing/latest/ classic/enable-proxy-protocol.html#proxy-protocol) sent to it by ELB. The following patch updates the mail module so that it can be configured to expect Proxy Protocol header by setting `proxy_protocol on`. In that case Proxy Protocol header is parsed, a client IP is retrieved and passed to an SMTP upstream in an XCLIENT command. Here it is: # HG changeset patch # User Maxim Vladimirskiy # Date 1478116426 25200 # Wed Nov 02 12:53:46 2016 -0700 # Node ID fcb527c8ade6db113acbee677f321fa0249348a2 # Parent 0fba3ed4e7eba474e3f518763d9e02851c9ff024 Add support for Proxy Protocol to mail SMTP When nginx is not the first proxy in a proxy chain it needs to be able to understand the Proxy Protocol Header to retrieve client IP and pass it downstream in an XCLIENT command. With these changes one can do that by setting `proxy_protocol on;` in the mail module config. diff -r 0fba3ed4e7eb -r fcb527c8ade6 src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h Wed Nov 02 20:05:21 2016 +0300 +++ b/src/mail/ngx_mail.h Wed Nov 02 12:53:46 2016 -0700 @@ -185,6 +185,7 @@ void **ctx; void **main_conf; void **srv_conf; + ngx_mail_addr_conf_t *addr_conf; ngx_resolver_ctx_t *resolver_ctx; diff -r 0fba3ed4e7eb -r fcb527c8ade6 src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c Wed Nov 02 20:05:21 2016 +0300 +++ b/src/mail/ngx_mail_handler.c Wed Nov 02 12:53:46 2016 -0700 @@ -9,9 +9,12 @@ #include #include #include +#include static void ngx_mail_init_session(ngx_connection_t *c); +static void ngx_mail_proxy_protocol_handler(ngx_event_t *rev); +static void ngx_mail_init_session_handler(ngx_event_t *rev); #if (NGX_MAIL_SSL) static void ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); @@ -34,6 +37,8 @@ ngx_mail_session_t *s; ngx_mail_addr_conf_t *addr_conf; ngx_mail_core_srv_conf_t *cscf; + ngx_mail_proxy_conf_t *pcf; + ngx_event_t *rev; u_char text[NGX_SOCKADDR_STRLEN]; #if (NGX_HAVE_INET6) struct sockaddr_in6 *sin6; @@ -128,6 +133,7 @@ s->main_conf = addr_conf->ctx->main_conf; s->srv_conf = addr_conf->ctx->srv_conf; + s->addr_conf = addr_conf; s->addr_text = &addr_conf->addr_text; @@ -159,10 +165,31 @@ c->log_error = NGX_ERROR_INFO; + rev = c->read; + + pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); + if (pcf->proxy_protocol) { + rev->handler = ngx_mail_proxy_protocol_handler; + ngx_mail_proxy_protocol_handler(rev); + return; + } + + ngx_mail_init_session_handler(rev); +} + + +static void +ngx_mail_init_session_handler(ngx_event_t *rev) +{ + ngx_connection_t *c; + + c = rev->data; + #if (NGX_MAIL_SSL) - { ngx_mail_ssl_conf_t *sslcf; + ngx_mail_session_t *s; + s = c->data; sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); if (sslcf->enable) { @@ -172,7 +199,7 @@ return; } - if (addr_conf->ssl) { + if (s->addr_conf->ssl) { c->log->action = "SSL handshaking"; @@ -187,8 +214,6 @@ ngx_mail_ssl_init_connection(&sslcf->ssl, c); return; } - - } #endif ngx_mail_init_session(c); @@ -898,3 +923,73 @@ return p; } + + +static void +ngx_mail_proxy_protocol_handler(ngx_event_t *rev) +{ + ngx_mail_session_t *s; + ngx_mail_core_srv_conf_t *cscf; + u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1]; + size_t size; + ssize_t n; + ngx_connection_t *c; + + c = rev->data; + s = c->data; + + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, + "read proxy protocol header"); + + if (rev->timedout) { + ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); + ngx_mail_close_connection(c); + return; + } + + if (c->close) { + ngx_mail_close_connection(c); + return; + } + + n = recv(c->fd, (char *) buf, sizeof(buf), MSG_PEEK); + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %z", n); + + if (n == -1) { + if (ngx_socket_errno == NGX_EAGAIN) { + rev->ready = 0; + + if (!rev->timer_set) { + ngx_add_timer(rev, cscf->timeout); + ngx_reusable_connection(c, 1); + } + + if (ngx_handle_read_event(rev, 0) != NGX_OK) { + ngx_mail_close_connection(c); + } + return; + } + + ngx_connection_error(c, ngx_socket_errno, "recv() failed"); + ngx_mail_close_connection(c); + return; + } + + p = ngx_proxy_protocol_read(c, buf, buf + n); + if (p == NULL) { + ngx_mail_close_connection(c); + return; + } + + // Purge the Proxy Protocol header from the network buffer. + size = p - buf; + if (c->recv(c, buf, size) != (ssize_t) size) { + ngx_mail_close_connection(c); + return; + } + + ngx_mail_init_session_handler(rev); +} \ No newline at end of file diff -r 0fba3ed4e7eb -r fcb527c8ade6 src/mail/ngx_mail_proxy_module.c --- a/src/mail/ngx_mail_proxy_module.c Wed Nov 02 20:05:21 2016 +0300 +++ b/src/mail/ngx_mail_proxy_module.c Wed Nov 02 12:53:46 2016 -0700 @@ -10,15 +10,7 @@ #include #include #include - - -typedef struct { - ngx_flag_t enable; - ngx_flag_t pass_error_message; - ngx_flag_t xclient; - size_t buffer_size; - ngx_msec_t timeout; -} ngx_mail_proxy_conf_t; +#include static void ngx_mail_proxy_block_read(ngx_event_t *rev); @@ -74,6 +66,13 @@ offsetof(ngx_mail_proxy_conf_t, xclient), NULL }, + { ngx_string("proxy_protocol"), + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_MAIL_SRV_CONF_OFFSET, + offsetof(ngx_mail_proxy_conf_t, proxy_protocol), + NULL }, + ngx_null_command }; @@ -456,6 +455,7 @@ ngx_mail_session_t *s; ngx_mail_proxy_conf_t *pcf; ngx_mail_core_srv_conf_t *cscf; + ngx_str_t client_addr; ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy smtp auth handler"); @@ -525,9 +525,12 @@ s->connection->log->action = "sending XCLIENT to upstream"; - line.len = sizeof("XCLIENT ADDR= LOGIN= NAME=" - CRLF) - 1 - + s->connection->addr_text.len + s->login.len + s->host.len; + client_addr = s->connection->addr_text; + if (s->connection->proxy_protocol_addr.data != NULL) { + client_addr = s->connection->proxy_protocol_addr; + } + line.len = sizeof("XCLIENT ADDR= LOGIN= NAME=" CRLF) - 1 + + client_addr.len + s->login.len + s->host.len; #if (NGX_HAVE_INET6) if (s->connection->sockaddr->sa_family == AF_INET6) { @@ -549,9 +552,7 @@ } #endif - p = ngx_copy(p, s->connection->addr_text.data, - s->connection->addr_text.len); - + p = ngx_copy(p, client_addr.data, client_addr.len); if (s->login.len) { p = ngx_cpymem(p, " LOGIN=", sizeof(" LOGIN=") - 1); p = ngx_copy(p, s->login.data, s->login.len); @@ -1099,6 +1100,7 @@ pcf->enable = NGX_CONF_UNSET; pcf->pass_error_message = NGX_CONF_UNSET; pcf->xclient = NGX_CONF_UNSET; + pcf->proxy_protocol = NGX_CONF_UNSET; pcf->buffer_size = NGX_CONF_UNSET_SIZE; pcf->timeout = NGX_CONF_UNSET_MSEC; @@ -1115,6 +1117,7 @@ ngx_conf_merge_value(conf->enable, prev->enable, 0); ngx_conf_merge_value(conf->pass_error_message, prev->pass_error_message, 0); ngx_conf_merge_value(conf->xclient, prev->xclient, 1); + ngx_conf_merge_value(conf->proxy_protocol, prev->proxy_protocol, 0); ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, (size_t) ngx_pagesize); ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000); diff -r 0fba3ed4e7eb -r fcb527c8ade6 src/mail/ngx_mail_proxy_module.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mail/ngx_mail_proxy_module.h Wed Nov 02 12:53:46 2016 -0700 @@ -0,0 +1,29 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) Nginx, Inc. + */ + + +#ifndef _NGX_MAIL_PROXY_MODULE_H_INCLUDED_ +#define _NGX_MAIL_PROXY_MODULE_H_INCLUDED_ + + +#include +#include + + +typedef struct { + ngx_flag_t enable; + ngx_flag_t pass_error_message; + ngx_flag_t xclient; + ngx_flag_t proxy_protocol; + size_t buffer_size; + ngx_msec_t timeout; +} ngx_mail_proxy_conf_t; + + +extern ngx_module_t ngx_mail_proxy_module; + + +#endif /* _NGX_MAIL_PROXY_MODULE_H_INCLUDED_ */ Cheers Maxim Vladimirskiy GitHub Profile: https://github.com/horkhe -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Thu Nov 3 17:13:03 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 3 Nov 2016 20:13:03 +0300 Subject: [PATCH] Add support for Proxy Protocol to mail SMTP In-Reply-To: References: Message-ID: <20161103171302.GT73038@mdounin.ru> Hello! On Thu, Nov 03, 2016 at 09:41:03AM -0700, Maxim Vladimirsky wrote: > Hi Folks, > > I was not sure if you would be interested in this, but decided to run it by > you anyway. > > We need to run Nginx as an SMTP proxy sitting behind ELB in AWS, but we > also want the upstream SMTP server to get the real client ip, so Nginx is > configured to provide it via an XCLIENT command. However the stock version > of Nginx provides ELB's ip instead, because it does not recognize the Proxy > Protocol header (http://docs.aws.amazon.com/elasticloadbalancing/latest/ > classic/enable-proxy-protocol.html#proxy-protocol) sent to it by ELB. Seems to be perfectly valid use case. > The following patch updates the mail module so that it can be configured to > expect Proxy Protocol header by setting `proxy_protocol on`. In that case > Proxy Protocol header is parsed, a client IP is retrieved and passed to an > SMTP upstream in an XCLIENT command. The "proxy_protocol on" is expected to configure sending PROXY protocol to an upstream server, similar to how it already works in the stream module: http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_protocol Accepting PROXY protocol from clients is expected to be enabled using a listening socket option instead, similar to what we have in http and stream modules: http://nginx.org/en/docs/http/ngx_http_core_module.html#listen http://nginx.org/en/docs/stream/ngx_stream_core_module.html#listen Open question is how it should work though. I.e., if it should just unconditionally set provided address as a client one, similar to how listen 80 proxy_protocol; real_ip_header proxy_protocol; set_real_ip_from 0.0.0.0/0; works in stream / http, or there should be some advanced control like the realip module in stream / http. -- Maxim Dounin http://nginx.org/ From maxim at mailgunhq.com Thu Nov 3 17:40:21 2016 From: maxim at mailgunhq.com (Maxim Vladimirsky) Date: Thu, 3 Nov 2016 10:40:21 -0700 Subject: [PATCH] Add support for Proxy Protocol to mail SMTP In-Reply-To: <20161103171302.GT73038@mdounin.ru> References: <20161103171302.GT73038@mdounin.ru> Message-ID: Thanks for quick response. See my comment below: On Thu, Nov 3, 2016 at 10:13 AM, Maxim Dounin wrote: > Hello! > > On Thu, Nov 03, 2016 at 09:41:03AM -0700, Maxim Vladimirsky wrote: > > > Hi Folks, > > > > I was not sure if you would be interested in this, but decided to run it > by > > you anyway. > > > > We need to run Nginx as an SMTP proxy sitting behind ELB in AWS, but we > > also want the upstream SMTP server to get the real client ip, so Nginx is > > configured to provide it via an XCLIENT command. However the stock > version > > of Nginx provides ELB's ip instead, because it does not recognize the > Proxy > > Protocol header (http://docs.aws.amazon.com/elasticloadbalancing/latest/ > > classic/enable-proxy-protocol.html#proxy-protocol) sent to it by ELB. > > Seems to be perfectly valid use case. > > > The following patch updates the mail module so that it can be configured > to > > expect Proxy Protocol header by setting `proxy_protocol on`. In that case > > Proxy Protocol header is parsed, a client IP is retrieved and passed to > an > > SMTP upstream in an XCLIENT command. > > The "proxy_protocol on" is expected to configure sending PROXY > protocol to an upstream server, similar to how it already works in > the stream module: > > http://nginx.org/en/docs/stream/ngx_stream_proxy_ > module.html#proxy_protocol > > Accepting PROXY protocol from clients is expected to be enabled > using a listening socket option instead, similar to what we have > in http and stream modules: > > http://nginx.org/en/docs/http/ngx_http_core_module.html#listen > http://nginx.org/en/docs/stream/ngx_stream_core_module.html#listen I will fix that. > > > Open question is how it should work though. I.e., if it should > just unconditionally set provided address as a client one, similar > to how > > listen 80 proxy_protocol; > real_ip_header proxy_protocol; > set_real_ip_from 0.0.0.0/0; > > works in stream / http, or there should be some advanced control > like the realip module in stream / http. > Taking ip from Proxy Protocol header and passing in via XCLIENT is really all we need, and I cannot even think of a scenario where we would need any kind of fine tuning of this logic. So this is probably a question to a broader audience. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bjornar.ness at gmail.com Thu Nov 3 19:37:04 2016 From: bjornar.ness at gmail.com (=?UTF-8?Q?Bj=C3=B8rnar_Ness?=) Date: Thu, 3 Nov 2016 20:37:04 +0100 Subject: [PATCH] proxy-protocol dst variables and proxy-proxy-protocol In-Reply-To: References: <1474200506-9206-1-git-send-email-bjornar.ness@gmail.com> Message-ID: Maxim: what needs change to get this merged? Followup will be mail pp support, which I saw a patch for today from somone else. -------------- next part -------------- An HTML attachment was scrubbed... URL: From maxim at mailgunhq.com Fri Nov 4 00:04:11 2016 From: maxim at mailgunhq.com (Maxim Vladimirsky) Date: Thu, 3 Nov 2016 17:04:11 -0700 Subject: [PATCH] Add support for Proxy Protocol to mail SMTP In-Reply-To: References: <20161103171302.GT73038@mdounin.ru> Message-ID: Please find below and updated patch that allows enabling accepting Proxy Protocol header from clients by setting `proxy_protocol` on a listening socket. As for how the feature should work in the great schema things, I propose the following: Taking client IP from a Proxy Protocol header and passing it to an upstream SMTP server seems to be a good enough default behavior imho. If somebody needs a more complex logic similar to `real_ip_header` and `set_real_ip_from`, that can always be implemented later on top of these changes. How about that? # HG changeset patch # User Maxim Vladimirskiy # Date 1478216956 25200 # Thu Nov 03 16:49:16 2016 -0700 # Node ID f7d710f1eaed454b73cc2e9c3318d1384de208d5 # Parent 1a917932db963e7ecf4d786cc02bd54bd4548b88 Add support for Proxy Protocol to mail SMTP When Nginx is not the first proxy in a proxy chain it needs to be able to understand the Proxy Protocol header to retrieve client IP and pass it upstream in an XCLIENT command. With these changes one can configure Nginx to do that by adding `proxy_protocol` to a listener description. diff -r 1a917932db96 -r f7d710f1eaed src/mail/ngx_mail.c --- a/src/mail/ngx_mail.c Thu Nov 03 17:10:29 2016 +0300 +++ b/src/mail/ngx_mail.c Thu Nov 03 16:49:16 2016 -0700 @@ -403,6 +403,7 @@ addrs[i].addr = sin->sin_addr.s_addr; addrs[i].conf.ctx = addr[i].opt.ctx; + addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol; #if (NGX_MAIL_SSL) addrs[i].conf.ssl = addr[i].opt.ssl; #endif @@ -452,6 +453,7 @@ addrs6[i].addr6 = sin6->sin6_addr; addrs6[i].conf.ctx = addr[i].opt.ctx; + addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol; #if (NGX_MAIL_SSL) addrs6[i].conf.ssl = addr[i].opt.ssl; #endif diff -r 1a917932db96 -r f7d710f1eaed src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h Thu Nov 03 17:10:29 2016 +0300 +++ b/src/mail/ngx_mail.h Thu Nov 03 16:49:16 2016 -0700 @@ -40,6 +40,7 @@ unsigned ipv6only:1; #endif unsigned so_keepalive:2; + unsigned proxy_protocol:1; #if (NGX_HAVE_KEEPALIVE_TUNABLE) int tcp_keepidle; int tcp_keepintvl; @@ -53,6 +54,7 @@ ngx_mail_conf_ctx_t *ctx; ngx_str_t addr_text; ngx_uint_t ssl; /* unsigned ssl:1; */ + unsigned proxy_protocol:1; } ngx_mail_addr_conf_t; typedef struct { @@ -185,6 +187,7 @@ void **ctx; void **main_conf; void **srv_conf; + ngx_mail_addr_conf_t *addr_conf; ngx_resolver_ctx_t *resolver_ctx; diff -r 1a917932db96 -r f7d710f1eaed src/mail/ngx_mail_core_module.c --- a/src/mail/ngx_mail_core_module.c Thu Nov 03 17:10:29 2016 +0300 +++ b/src/mail/ngx_mail_core_module.c Thu Nov 03 16:49:16 2016 -0700 @@ -540,6 +540,11 @@ #endif } + if (ngx_strcmp(value[i].data, "proxy_protocol") == 0) { + ls->proxy_protocol = 1; + continue; + } + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the invalid \"%V\" parameter", &value[i]); return NGX_CONF_ERROR; diff -r 1a917932db96 -r f7d710f1eaed src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c Thu Nov 03 17:10:29 2016 +0300 +++ b/src/mail/ngx_mail_handler.c Thu Nov 03 16:49:16 2016 -0700 @@ -12,6 +12,8 @@ static void ngx_mail_init_session(ngx_connection_t *c); +static void ngx_mail_proxy_protocol_handler(ngx_event_t *rev); +static void ngx_mail_init_session_handler(ngx_event_t *rev); #if (NGX_MAIL_SSL) static void ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); @@ -34,6 +36,7 @@ ngx_mail_session_t *s; ngx_mail_addr_conf_t *addr_conf; ngx_mail_core_srv_conf_t *cscf; + ngx_event_t *rev; u_char text[NGX_SOCKADDR_STRLEN]; #if (NGX_HAVE_INET6) struct sockaddr_in6 *sin6; @@ -128,6 +131,7 @@ s->main_conf = addr_conf->ctx->main_conf; s->srv_conf = addr_conf->ctx->srv_conf; + s->addr_conf = addr_conf; s->addr_text = &addr_conf->addr_text; @@ -159,10 +163,30 @@ c->log_error = NGX_ERROR_INFO; + rev = c->read; + + if (addr_conf->proxy_protocol) { + rev->handler = ngx_mail_proxy_protocol_handler; + ngx_mail_proxy_protocol_handler(rev); + return; + } + + ngx_mail_init_session_handler(rev); +} + + +static void +ngx_mail_init_session_handler(ngx_event_t *rev) +{ + ngx_connection_t *c; + + c = rev->data; + #if (NGX_MAIL_SSL) - { ngx_mail_ssl_conf_t *sslcf; + ngx_mail_session_t *s; + s = c->data; sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); if (sslcf->enable) { @@ -172,7 +196,7 @@ return; } - if (addr_conf->ssl) { + if (s->addr_conf->ssl) { c->log->action = "SSL handshaking"; @@ -187,8 +211,6 @@ ngx_mail_ssl_init_connection(&sslcf->ssl, c); return; } - - } #endif ngx_mail_init_session(c); @@ -898,3 +920,72 @@ return p; } + + +static void +ngx_mail_proxy_protocol_handler(ngx_event_t *rev) +{ + ngx_mail_session_t *s; + ngx_mail_core_srv_conf_t *cscf; + u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1]; + size_t size; + ssize_t n; + ngx_connection_t *c; + + c = rev->data; + s = c->data; + + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, + "read proxy protocol header"); + + if (rev->timedout) { + ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); + ngx_mail_close_connection(c); + return; + } + + if (c->close) { + ngx_mail_close_connection(c); + return; + } + + n = recv(c->fd, (char *) buf, sizeof(buf), MSG_PEEK); + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %z", n); + + if (n == -1) { + if (ngx_socket_errno == NGX_EAGAIN) { + rev->ready = 0; + + if (!rev->timer_set) { + ngx_add_timer(rev, cscf->timeout); + ngx_reusable_connection(c, 1); + } + + if (ngx_handle_read_event(rev, 0) != NGX_OK) { + ngx_mail_close_connection(c); + } + return; + } + + ngx_connection_error(c, ngx_socket_errno, "recv() failed"); + ngx_mail_close_connection(c); + return; + } + + p = ngx_proxy_protocol_read(c, buf, buf + n); + if (p == NULL) { + ngx_mail_close_connection(c); + return; + } + + size = p - buf; + if (c->recv(c, buf, size) != (ssize_t) size) { + ngx_mail_close_connection(c); + return; + } + + ngx_mail_init_session_handler(rev); +} \ No newline at end of file diff -r 1a917932db96 -r f7d710f1eaed src/mail/ngx_mail_proxy_module.c --- a/src/mail/ngx_mail_proxy_module.c Thu Nov 03 17:10:29 2016 +0300 +++ b/src/mail/ngx_mail_proxy_module.c Thu Nov 03 16:49:16 2016 -0700 @@ -456,6 +456,7 @@ ngx_mail_session_t *s; ngx_mail_proxy_conf_t *pcf; ngx_mail_core_srv_conf_t *cscf; + ngx_str_t client_addr; ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy smtp auth handler"); @@ -525,9 +526,12 @@ s->connection->log->action = "sending XCLIENT to upstream"; - line.len = sizeof("XCLIENT ADDR= LOGIN= NAME=" - CRLF) - 1 - + s->connection->addr_text.len + s->login.len + s->host.len; + client_addr = s->connection->addr_text; + if (s->connection->proxy_protocol_addr.data != NULL) { + client_addr = s->connection->proxy_protocol_addr; + } + line.len = sizeof("XCLIENT ADDR= LOGIN= NAME=" CRLF) - 1 + + client_addr.len + s->login.len + s->host.len; #if (NGX_HAVE_INET6) if (s->connection->sockaddr->sa_family == AF_INET6) { @@ -549,9 +553,7 @@ } #endif - p = ngx_copy(p, s->connection->addr_text.data, - s->connection->addr_text.len); - + p = ngx_copy(p, client_addr.data, client_addr.len); if (s->login.len) { p = ngx_cpymem(p, " LOGIN=", sizeof(" LOGIN=") - 1); p = ngx_copy(p, s->login.data, s->login.len); On Thu, Nov 3, 2016 at 10:40 AM, Maxim Vladimirsky wrote: > Thanks for quick response. See my comment below: > > On Thu, Nov 3, 2016 at 10:13 AM, Maxim Dounin wrote: > >> Hello! >> >> On Thu, Nov 03, 2016 at 09:41:03AM -0700, Maxim Vladimirsky wrote: >> >> > Hi Folks, >> > >> > I was not sure if you would be interested in this, but decided to run >> it by >> > you anyway. >> > >> > We need to run Nginx as an SMTP proxy sitting behind ELB in AWS, but we >> > also want the upstream SMTP server to get the real client ip, so Nginx >> is >> > configured to provide it via an XCLIENT command. However the stock >> version >> > of Nginx provides ELB's ip instead, because it does not recognize the >> Proxy >> > Protocol header (http://docs.aws.amazon.com/el >> asticloadbalancing/latest/ >> > classic/enable-proxy-protocol.html#proxy-protocol) sent to it by ELB. >> >> Seems to be perfectly valid use case. >> >> > The following patch updates the mail module so that it can be >> configured to >> > expect Proxy Protocol header by setting `proxy_protocol on`. In that >> case >> > Proxy Protocol header is parsed, a client IP is retrieved and passed to >> an >> > SMTP upstream in an XCLIENT command. >> >> The "proxy_protocol on" is expected to configure sending PROXY >> protocol to an upstream server, similar to how it already works in >> the stream module: >> >> http://nginx.org/en/docs/stream/ngx_stream_proxy_module. >> html#proxy_protocol >> >> Accepting PROXY protocol from clients is expected to be enabled >> using a listening socket option instead, similar to what we have >> in http and stream modules: >> >> http://nginx.org/en/docs/http/ngx_http_core_module.html#listen >> http://nginx.org/en/docs/stream/ngx_stream_core_module.html#listen > > > I will fix that. > > >> >> >> Open question is how it should work though. I.e., if it should >> just unconditionally set provided address as a client one, similar >> to how >> >> listen 80 proxy_protocol; >> real_ip_header proxy_protocol; >> set_real_ip_from 0.0.0.0/0; >> >> works in stream / http, or there should be some advanced control >> like the realip module in stream / http. >> > > Taking ip from Proxy Protocol header and passing in via XCLIENT is really > all we need, and I cannot even think of a scenario where we would need any > kind of fine tuning of this logic. So this is probably a question to a > broader audience. > > >> >> -- >> Maxim Dounin >> http://nginx.org/ >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dannym at scratchpost.org Fri Nov 4 10:17:21 2016 From: dannym at scratchpost.org (Danny Milosavljevic) Date: Fri, 4 Nov 2016 11:17:21 +0100 Subject: Contributing a package - How? Message-ID: <20161104111721.25821f54@scratchpost.org> Hello, how can I contribute a package for inclusion in ? I'd like to contribute a package for the HTTP SPNEGO (single sign-on) authentication module for nginx. See . Using packagespecs/centos6 it builds a RPM package and we tested it and it works fine. (The packagespec was created by copying the specs of existing nginx modules into a new file and adapting it) From igor at sysoev.ru Fri Nov 4 13:23:33 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 04 Nov 2016 13:23:33 +0000 Subject: [njs] String.prototype.repeat() did not check the count parameter Message-ID: details: http://hg.nginx.org/njs/rev/e16086a85f0b branches: changeset: 235:e16086a85f0b user: Igor Sysoev date: Fri Nov 04 16:22:56 2016 +0300 description: String.prototype.repeat() did not check the count parameter for single character strings. The count parameter should be checked also for empty string. In collaboration with Andrey Zelenkov and Valentin Bartenev. diffstat: njs/njs_string.c | 22 ++++++++++++---------- njs/test/njs_unit_test.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 10 deletions(-) diffs (78 lines): diff -r ff8f717db1be -r e16086a85f0b njs/njs_string.c --- a/njs/njs_string.c Thu Nov 03 18:12:10 2016 +0300 +++ b/njs/njs_string.c Fri Nov 04 16:22:56 2016 +0300 @@ -1756,21 +1756,23 @@ njs_string_prototype_repeat(njs_vm_t *vm (void) njs_string_prop(&string, &args[0]); + if (nargs > 1) { + max = (string.size > 1) ? NJS_STRING_MAX_LENGTH / string.size + : NJS_STRING_MAX_LENGTH; + + n = args[1].data.u.number; + + if (nxt_slow_path(n < 0 || n >= max)) { + vm->exception = &njs_exception_range_error; + return NXT_ERROR; + } + } + if (string.size == 0) { vm->retval = njs_string_empty; return NXT_OK; } - if (nargs > 1) { - max = NJS_STRING_MAX_LENGTH / string.size; - n = args[1].data.u.number; - - if (nxt_slow_path(n < 0 || n > max)) { - vm->exception = &njs_exception_range_error; - return NXT_ERROR; - } - } - size = string.size * n; length = string.length * n; diff -r ff8f717db1be -r e16086a85f0b njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Nov 03 18:12:10 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Nov 04 16:22:56 2016 +0300 @@ -3633,6 +3633,37 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abc'.repeat(-1)"), nxt_string("RangeError") }, + { nxt_string("''.repeat(-1)"), + nxt_string("RangeError") }, + + { nxt_string("'a'.repeat(2147483647)"), + nxt_string("RangeError") }, + + { nxt_string("'a'.repeat(2147483648)"), + nxt_string("RangeError") }, + + { nxt_string("'a'.repeat(Infinity)"), + nxt_string("RangeError") }, + + { nxt_string("'a'.repeat(NaN)"), + nxt_string("") }, + + { nxt_string("''.repeat(2147483646)"), + nxt_string("") }, + + /* ES6: "". */ + { nxt_string("''.repeat(2147483647)"), + nxt_string("RangeError") }, + + { nxt_string("''.repeat(2147483648)"), + nxt_string("RangeError") }, + + { nxt_string("''.repeat(Infinity)"), + nxt_string("RangeError") }, + + { nxt_string("''.repeat(NaN)"), + nxt_string("") }, + { nxt_string("encodeURI()"), nxt_string("undefined")}, From vbart at nginx.com Fri Nov 4 13:53:07 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Fri, 04 Nov 2016 16:53:07 +0300 Subject: Contributing a package - How? In-Reply-To: <20161104111721.25821f54@scratchpost.org> References: <20161104111721.25821f54@scratchpost.org> Message-ID: <3184123.iLt4qV9WPT@vbart-laptop> On Friday 04 November 2016 11:17:21 Danny Milosavljevic wrote: > Hello, > > how can I contribute a package for inclusion in ? > > I'd like to contribute a package for the HTTP SPNEGO (single sign-on) authentication module for nginx. > > See . Using packagespecs/centos6 it builds a RPM package and we tested it and it works fine. > > (The packagespec was created by copying the specs of existing nginx modules into a new file and adapting it) > Our official builds don't include 3rd-party modules. Sorry. wbr, Valentin V. Bartenev From vbart at nginx.com Fri Nov 4 15:25:14 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 04 Nov 2016 15:25:14 +0000 Subject: [njs] More precise Math constants. Message-ID: details: http://hg.nginx.org/njs/rev/a713275dc4cb branches: changeset: 236:a713275dc4cb user: Valentin Bartenev date: Fri Nov 04 18:25:55 2016 +0300 description: More precise Math constants. diffstat: njs/njs_math.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) diffs (61 lines): diff -r e16086a85f0b -r a713275dc4cb njs/njs_math.c --- a/njs/njs_math.c Fri Nov 04 16:22:56 2016 +0300 +++ b/njs/njs_math.c Fri Nov 04 18:25:55 2016 +0300 @@ -437,49 +437,49 @@ static const njs_object_prop_t njs_math { .type = NJS_PROPERTY, .name = njs_string("E"), - .value = njs_value(NJS_NUMBER, 1, 2.718281828459045), + .value = njs_value(NJS_NUMBER, 1, M_E), }, { .type = NJS_PROPERTY, .name = njs_string("LN10"), - .value = njs_value(NJS_NUMBER, 1, 2.302585092994046), + .value = njs_value(NJS_NUMBER, 1, M_LN10), }, { .type = NJS_PROPERTY, .name = njs_string("LN2"), - .value = njs_value(NJS_NUMBER, 1, 0.6931471805599453), + .value = njs_value(NJS_NUMBER, 1, M_LN2), }, { .type = NJS_PROPERTY, .name = njs_string("LOG10E"), - .value = njs_value(NJS_NUMBER, 1, 0.4342944819032518), + .value = njs_value(NJS_NUMBER, 1, M_LOG10E), }, { .type = NJS_PROPERTY, .name = njs_string("LOG2E"), - .value = njs_value(NJS_NUMBER, 1, 1.4426950408889634), + .value = njs_value(NJS_NUMBER, 1, M_LOG2E), }, { .type = NJS_PROPERTY, .name = njs_string("PI"), - .value = njs_value(NJS_NUMBER, 1, 3.141592653589793), + .value = njs_value(NJS_NUMBER, 1, M_PI), }, { .type = NJS_PROPERTY, .name = njs_string("SQRT1_2"), - .value = njs_value(NJS_NUMBER, 1, 0.7071067811865476), + .value = njs_value(NJS_NUMBER, 1, M_SQRT1_2), }, { .type = NJS_PROPERTY, .name = njs_string("SQRT2"), - .value = njs_value(NJS_NUMBER, 1, 1.4142135623730951), + .value = njs_value(NJS_NUMBER, 1, M_SQRT2), }, { From vbart at nginx.com Fri Nov 4 15:25:15 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 04 Nov 2016 15:25:15 +0000 Subject: [njs] Removed redefinition of NAN and INFINITY macros. Message-ID: details: http://hg.nginx.org/njs/rev/bcd4910c5be9 branches: changeset: 237:bcd4910c5be9 user: Valentin Bartenev date: Fri Nov 04 18:25:55 2016 +0300 description: Removed redefinition of NAN and INFINITY macros. diffstat: njs/njs_builtin.c | 2 +- njs/njs_date.c | 98 ++++++++++++++++++++++++------------------------ njs/njs_lexer_keyword.c | 4 +- njs/njs_math.c | 42 ++++++++++---------- njs/njs_number.c | 6 +- njs/njs_number.h | 4 -- njs/njs_string.c | 10 ++-- njs/njs_vm.c | 8 ++-- 8 files changed, 85 insertions(+), 89 deletions(-) diffs (730 lines): diff -r a713275dc4cb -r bcd4910c5be9 njs/njs_builtin.c --- a/njs/njs_builtin.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_builtin.c Fri Nov 04 18:25:55 2016 +0300 @@ -93,7 +93,7 @@ njs_builtin_objects_create(njs_vm_t *vm) { .object = { .type = NJS_REGEXP } }, - { .date = { .time = NJS_NAN, + { .date = { .time = NAN, .object = { .type = NJS_DATE } } }, }; diff -r a713275dc4cb -r bcd4910c5be9 njs/njs_date.c --- a/njs/njs_date.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_date.c Fri Nov 04 18:25:55 2016 +0300 @@ -178,7 +178,7 @@ njs_date_utc(njs_vm_t *vm, njs_value_t * nxt_uint_t i, n; int32_t values[8]; - time = NJS_NAN; + time = NAN; if (nargs > 2) { memset(values, 0, 8 * sizeof(int32_t)); @@ -292,7 +292,7 @@ njs_date_parse(njs_vm_t *vm, njs_value_t time = njs_date_string_parse(&args[1]); } else { - time = NJS_NAN; + time = NAN; } njs_number_set(&vm->retval, time); @@ -316,7 +316,7 @@ njs_date_string_parse(njs_value_t *date) end = p + string.size; if (nxt_slow_path(p >= end)) { - return NJS_NAN; + return NAN; } if (*p == '+') { @@ -351,14 +351,14 @@ njs_date_string_parse(njs_value_t *date) next = njs_date_number_parse(&ext, next, end, 2); if (nxt_slow_path(next == NULL)) { - return NJS_NAN; + return NAN; } tm.tm_year = tm.tm_year * 100 + ext; if (string.start[0] == '-') { if (tm.tm_year == 0) { - return NJS_NAN; + return NAN; } tm.tm_year = -tm.tm_year; @@ -369,7 +369,7 @@ njs_date_string_parse(njs_value_t *date) } if (*next != '-') { - return NJS_NAN; + return NAN; } } @@ -377,7 +377,7 @@ njs_date_string_parse(njs_value_t *date) p = njs_date_number_parse(&tm.tm_mon, next + 1, end, 2); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } tm.tm_mon--; @@ -387,12 +387,12 @@ njs_date_string_parse(njs_value_t *date) } if (nxt_slow_path(*p != '-')) { - return NJS_NAN; + return NAN; } p = njs_date_number_parse(&tm.tm_mday, p + 1, end, 2); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } if (p == end) { @@ -400,12 +400,12 @@ njs_date_string_parse(njs_value_t *date) } if (nxt_slow_path(*p != 'T')) { - return NJS_NAN; + return NAN; } p = njs_date_time_parse(&tm, p + 1, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } if (p == end) { @@ -413,23 +413,23 @@ njs_date_string_parse(njs_value_t *date) } if (nxt_slow_path(p >= end || *p != '.')) { - return NJS_NAN; + return NAN; } p = njs_date_number_parse(&ms, p + 1, end, 3); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } if (nxt_slow_path(p >= end || *p != 'Z')) { - return NJS_NAN; + return NAN; } return njs_timegm(&tm) * 1000 + ms; } if (sign) { - return NJS_NAN; + return NAN; } week = 1; @@ -456,17 +456,17 @@ njs_date_string_parse(njs_value_t *date) } if (!week) { - return NJS_NAN; + return NAN; } p = njs_date_skip_week_day(p, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } p = njs_date_skip_spaces(p, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } week = 0; @@ -489,22 +489,22 @@ njs_date_rfc2822_string_parse(struct tm p = njs_date_skip_spaces(p, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } tm->tm_mon = njs_date_month_parse(p, end); if (nxt_slow_path(tm->tm_mon < 0)) { - return NJS_NAN; + return NAN; } p = njs_date_skip_spaces(p + 3, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } p = njs_date_number_parse(&tm->tm_year, p, end, 4); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } tm->tm_year -= 1900; @@ -515,7 +515,7 @@ njs_date_rfc2822_string_parse(struct tm p = njs_date_skip_spaces(p, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } if (p == end) { @@ -524,7 +524,7 @@ njs_date_rfc2822_string_parse(struct tm p = njs_date_time_parse(tm, p, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } if (p == end) { @@ -533,7 +533,7 @@ njs_date_rfc2822_string_parse(struct tm p = njs_date_skip_spaces(p, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } if (p == end) { @@ -541,7 +541,7 @@ njs_date_rfc2822_string_parse(struct tm } if (nxt_slow_path(p + 2 >= end)) { - return NJS_NAN; + return NAN; } if ((p[0] == 'G' && p[1] == 'M' && p[2] == 'T') @@ -553,7 +553,7 @@ njs_date_rfc2822_string_parse(struct tm gmtoff = njs_date_gmtoff_parse(p, end); if (nxt_slow_path(gmtoff == -1)) { - return NJS_NAN; + return NAN; } } @@ -572,22 +572,22 @@ njs_date_js_string_parse(struct tm *tm, p = njs_date_skip_spaces(p, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } p = njs_date_number_parse(&tm->tm_mday, p, end, 2); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } p = njs_date_skip_spaces(p, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } p = njs_date_number_parse(&tm->tm_year, p, end, 4); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } tm->tm_year -= 1900; @@ -598,7 +598,7 @@ njs_date_js_string_parse(struct tm *tm, p = njs_date_skip_spaces(p, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } if (p == end) { @@ -607,7 +607,7 @@ njs_date_js_string_parse(struct tm *tm, p = njs_date_time_parse(tm, p, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } if (p == end) { @@ -616,7 +616,7 @@ njs_date_js_string_parse(struct tm *tm, p = njs_date_skip_spaces(p, end); if (nxt_slow_path(p == NULL)) { - return NJS_NAN; + return NAN; } if (p == end) { @@ -632,7 +632,7 @@ njs_date_js_string_parse(struct tm *tm, } } - return NJS_NAN; + return NAN; done: @@ -1391,7 +1391,7 @@ njs_date_prototype_set_time(njs_vm_t *vm time = args[1].data.u.number; } else { - time = NJS_NAN; + time = NAN; } } @@ -1416,7 +1416,7 @@ njs_date_prototype_set_milliseconds(njs_ time = (int64_t) (time / 1000) * 1000 + args[1].data.u.number; } else { - time = NJS_NAN; + time = NAN; } } @@ -1445,7 +1445,7 @@ njs_date_prototype_set_seconds(njs_vm_t time = (int64_t) (time / 60000) * 60000 + sec * 1000 + ms; } else { - time = NJS_NAN; + time = NAN; } } @@ -1484,7 +1484,7 @@ njs_date_prototype_set_minutes(njs_vm_t time = njs_date_time(&tm, ms); } else { - time = NJS_NAN; + time = NAN; } } @@ -1519,7 +1519,7 @@ njs_date_prototype_set_utc_minutes(njs_v time = clock * 1000 + ms; } else { - time = NJS_NAN; + time = NAN; } } @@ -1562,7 +1562,7 @@ njs_date_prototype_set_hours(njs_vm_t *v time = njs_date_time(&tm, ms); } else { - time = NJS_NAN; + time = NAN; } } @@ -1598,7 +1598,7 @@ njs_date_prototype_set_utc_hours(njs_vm_ time = clock * 1000 + ms; } else { - time = NJS_NAN; + time = NAN; } } @@ -1630,7 +1630,7 @@ njs_date_prototype_set_date(njs_vm_t *vm time = njs_date_time(&tm, (int64_t) time % 1000); } else { - time = NJS_NAN; + time = NAN; } } @@ -1662,7 +1662,7 @@ njs_date_prototype_set_utc_date(njs_vm_t time = njs_date_utc_time(&tm, time); } else { - time = NJS_NAN; + time = NAN; } } @@ -1698,7 +1698,7 @@ njs_date_prototype_set_month(njs_vm_t *v time = njs_date_time(&tm, (int64_t) time % 1000); } else { - time = NJS_NAN; + time = NAN; } } @@ -1734,7 +1734,7 @@ njs_date_prototype_set_utc_month(njs_vm_ time = njs_date_utc_time(&tm, time); } else { - time = NJS_NAN; + time = NAN; } } @@ -1774,7 +1774,7 @@ njs_date_prototype_set_full_year(njs_vm_ time = njs_date_time(&tm, (int64_t) time % 1000); } else { - time = NJS_NAN; + time = NAN; } } @@ -1814,7 +1814,7 @@ njs_date_prototype_set_utc_full_year(njs time = njs_date_utc_time(&tm, time); } else { - time = NJS_NAN; + time = NAN; } } @@ -1838,7 +1838,7 @@ njs_date_time(struct tm *tm, int64_t ms) time = (int64_t) clock * 1000 + ms; } else { - time = NJS_NAN; + time = NAN; } return time; diff -r a713275dc4cb -r bcd4910c5be9 njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_lexer_keyword.c Fri Nov 04 18:25:55 2016 +0300 @@ -38,8 +38,8 @@ static const njs_keyword_t njs_keywords { nxt_string("null"), NJS_TOKEN_NULL, 0 }, { nxt_string("false"), NJS_TOKEN_BOOLEAN, 0 }, { nxt_string("true"), NJS_TOKEN_BOOLEAN, 1 }, - { nxt_string("NaN"), NJS_TOKEN_NUMBER, NJS_NAN }, - { nxt_string("Infinity"), NJS_TOKEN_NUMBER, NJS_INFINITY }, + { nxt_string("NaN"), NJS_TOKEN_NUMBER, NAN }, + { nxt_string("Infinity"), NJS_TOKEN_NUMBER, INFINITY }, /* Operators. */ diff -r a713275dc4cb -r bcd4910c5be9 njs/njs_math.c --- a/njs/njs_math.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_math.c Fri Nov 04 18:25:55 2016 +0300 @@ -31,7 +31,7 @@ njs_object_math_abs(njs_vm_t *vm, njs_va num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, fabs(num)); @@ -50,7 +50,7 @@ njs_object_math_acos(njs_vm_t *vm, njs_v num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, acos(num)); @@ -69,7 +69,7 @@ njs_object_math_asin(njs_vm_t *vm, njs_v num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, asin(num)); @@ -88,7 +88,7 @@ njs_object_math_atan(njs_vm_t *vm, njs_v num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, atan(num)); @@ -103,8 +103,8 @@ njs_object_math_atan2(njs_vm_t *vm, njs_ { double y, x; - y = NJS_NAN; - x = NJS_NAN; + y = NAN; + x = NAN; if (nargs > 1) { y = args[1].data.u.number; @@ -130,7 +130,7 @@ njs_object_math_ceil(njs_vm_t *vm, njs_v num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, ceil(num)); @@ -149,7 +149,7 @@ njs_object_math_cos(njs_vm_t *vm, njs_va num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, cos(num)); @@ -168,7 +168,7 @@ njs_object_math_exp(njs_vm_t *vm, njs_va num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, exp(num)); @@ -187,7 +187,7 @@ njs_object_math_floor(njs_vm_t *vm, njs_ num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, floor(num)); @@ -206,7 +206,7 @@ njs_object_math_log(njs_vm_t *vm, njs_va num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, log(num)); @@ -237,7 +237,7 @@ njs_object_math_max(njs_vm_t *vm, njs_va } } else { - num = -NJS_INFINITY; + num = -INFINITY; } njs_number_set(&vm->retval, num); @@ -268,7 +268,7 @@ njs_object_math_min(njs_vm_t *vm, njs_va } } else { - num = NJS_INFINITY; + num = INFINITY; } njs_number_set(&vm->retval, num); @@ -283,8 +283,8 @@ njs_object_math_pow(njs_vm_t *vm, njs_va { double base, exponent; - base = NJS_NAN; - exponent = NJS_NAN; + base = NAN; + exponent = NAN; if (nargs > 1) { base = args[1].data.u.number; @@ -324,7 +324,7 @@ njs_object_math_round(njs_vm_t *vm, njs_ num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, round(num)); @@ -347,7 +347,7 @@ njs_object_math_sign(njs_vm_t *vm, njs_v } } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, num); @@ -366,7 +366,7 @@ njs_object_math_sin(njs_vm_t *vm, njs_va num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, sin(num)); @@ -385,7 +385,7 @@ njs_object_math_sqrt(njs_vm_t *vm, njs_v num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, sqrt(num)); @@ -404,7 +404,7 @@ njs_object_math_tan(njs_vm_t *vm, njs_va num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, tan(num)); @@ -423,7 +423,7 @@ njs_object_math_trunc(njs_vm_t *vm, njs_ num = args[1].data.u.number; } else { - num = NJS_NAN; + num = NAN; } njs_number_set(&vm->retval, trunc(num)); diff -r a713275dc4cb -r bcd4910c5be9 njs/njs_number.c --- a/njs/njs_number.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_number.c Fri Nov 04 18:25:55 2016 +0300 @@ -59,7 +59,7 @@ njs_value_to_number(njs_value_t *value) } } - return NJS_NAN; + return NAN; } @@ -489,7 +489,7 @@ njs_number_parse_int(njs_vm_t *vm, njs_v nxt_bool_t minus; njs_string_prop_t string; - num = NJS_NAN; + num = NAN; if (nargs > 1) { (void) njs_string_prop(&string, &args[1]); @@ -559,7 +559,7 @@ njs_number_parse_float(njs_vm_t *vm, njs { double num; - num = NJS_NAN; + num = NAN; if (nargs > 1) { num = njs_string_to_number(&args[1], 0); diff -r a713275dc4cb -r bcd4910c5be9 njs/njs_number.h --- a/njs/njs_number.h Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_number.h Fri Nov 04 18:25:55 2016 +0300 @@ -11,10 +11,6 @@ #include -#define NJS_NAN NAN -#define NJS_INFINITY INFINITY - - #define njs_is_infinity(n) \ isinf(n) diff -r a713275dc4cb -r bcd4910c5be9 njs/njs_string.c --- a/njs/njs_string.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_string.c Fri Nov 04 18:25:55 2016 +0300 @@ -1127,7 +1127,7 @@ njs_string_prototype_char_code_at(njs_vm index = args[1].data.u.number; if (nxt_slow_path(index < 0 || index >= length)) { - num = NJS_NAN; + num = NAN; goto done; } } @@ -2921,7 +2921,7 @@ njs_string_to_number(njs_value_t *value, } if (p == end) { - return NJS_NAN; + return NAN; } if (*p >= '0' && *p <= '9') { @@ -2929,17 +2929,17 @@ njs_string_to_number(njs_value_t *value, } else { if (p + infinity > end || memcmp(p, "Infinity", infinity) != 0) { - return NJS_NAN; + return NAN; } - num = NJS_INFINITY; + num = INFINITY; p += infinity; } if (exact) { while (p < end) { if (*p != ' ' && *p != '\t') { - return NJS_NAN; + return NAN; } p++; diff -r a713275dc4cb -r bcd4910c5be9 njs/njs_vm.c --- a/njs/njs_vm.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_vm.c Fri Nov 04 18:25:55 2016 +0300 @@ -116,11 +116,11 @@ void njs_debug(njs_index_t index, njs_va const njs_value_t njs_value_null = njs_value(NJS_NULL, 0, 0.0); -const njs_value_t njs_value_void = njs_value(NJS_VOID, 0, NJS_NAN); +const njs_value_t njs_value_void = njs_value(NJS_VOID, 0, NAN); const njs_value_t njs_value_false = njs_value(NJS_BOOLEAN, 0, 0.0); const njs_value_t njs_value_true = njs_value(NJS_BOOLEAN, 1, 1.0); const njs_value_t njs_value_zero = njs_value(NJS_NUMBER, 0, 0.0); -const njs_value_t njs_value_nan = njs_value(NJS_NUMBER, 0, NJS_NAN); +const njs_value_t njs_value_nan = njs_value(NJS_NUMBER, 0, NAN); const njs_value_t njs_string_empty = njs_string(""); @@ -2962,7 +2962,7 @@ njs_vmcode_number_primitive(njs_vm_t *vm if (nxt_fast_path(ret > 0)) { if (!njs_is_numeric(value)) { - num = NJS_NAN; + num = NAN; if (njs_is_string(value)) { num = njs_string_to_number(value, 1); @@ -3015,7 +3015,7 @@ njs_vmcode_number_argument(njs_vm_t *vm, if (nxt_fast_path(ret > 0)) { if (!njs_is_numeric(value)) { - num = NJS_NAN; + num = NAN; if (njs_is_string(value)) { num = njs_string_to_number(value, 1); From vbart at nginx.com Fri Nov 4 15:25:17 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 04 Nov 2016 15:25:17 +0000 Subject: [njs] Removed redefinition of isinf() and isnan(). Message-ID: details: http://hg.nginx.org/njs/rev/109932e1d3c8 branches: changeset: 238:109932e1d3c8 user: Valentin Bartenev date: Fri Nov 04 18:25:55 2016 +0300 description: Removed redefinition of isinf() and isnan(). diffstat: njs/njs_array.c | 4 +- njs/njs_date.c | 66 ++++++++++++++++++++++++++++---------------------------- njs/njs_math.c | 2 +- njs/njs_number.c | 8 +++--- njs/njs_number.h | 8 ------ njs/njs_string.c | 2 +- njs/njs_vm.c | 6 +--- njs/njs_vm.h | 2 +- 8 files changed, 44 insertions(+), 54 deletions(-) diffs (429 lines): diff -r bcd4910c5be9 -r 109932e1d3c8 njs/njs_array.c --- a/njs/njs_array.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_array.c Fri Nov 04 18:25:55 2016 +0300 @@ -1131,12 +1131,12 @@ njs_array_prototype_includes(njs_vm_t *v start = array->start; value = &args[1]; - if (njs_is_number(value) && njs_is_nan(value->data.u.number)) { + if (njs_is_number(value) && isnan(value->data.u.number)) { do { value = &start[i]; - if (njs_is_number(value) && njs_is_nan(value->data.u.number)) { + if (njs_is_number(value) && isnan(value->data.u.number)) { retval = &njs_value_true; break; } diff -r bcd4910c5be9 -r 109932e1d3c8 njs/njs_date.c --- a/njs/njs_date.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_date.c Fri Nov 04 18:25:55 2016 +0300 @@ -114,7 +114,7 @@ njs_date_constructor(njs_vm_t *vm, njs_v num = args[i].data.u.number; - if (njs_is_nan(num)) { + if (isnan(num)) { time = num; goto done; } @@ -193,7 +193,7 @@ njs_date_utc(njs_vm_t *vm, njs_value_t * num = args[i].data.u.number; - if (njs_is_nan(num)) { + if (isnan(num)) { goto done; } @@ -951,7 +951,7 @@ njs_date_string(njs_vm_t *vm, const char u_char buf[NJS_DATE_TIME_LEN]; struct tm tm; - if (!njs_is_nan(time)) { + if (!isnan(time)) { clock = time / 1000; localtime_r(&clock, &tm); @@ -984,7 +984,7 @@ njs_date_prototype_to_utc_string(njs_vm_ time = args[0].data.u.date->time; - if (!njs_is_nan(time)) { + if (!isnan(time)) { clock = time / 1000; gmtime_r(&clock, &tm); @@ -1016,7 +1016,7 @@ njs_date_prototype_to_iso_string(njs_vm_ time = args[0].data.u.date->time; - if (!njs_is_nan(time)) { + if (!isnan(time)) { clock = time / 1000; gmtime_r(&clock, &tm); @@ -1049,7 +1049,7 @@ njs_date_prototype_get_full_year(njs_vm_ value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; localtime_r(&clock, &tm); @@ -1072,7 +1072,7 @@ njs_date_prototype_get_utc_full_year(njs value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; gmtime_r(&clock, &tm); @@ -1095,7 +1095,7 @@ njs_date_prototype_get_month(njs_vm_t *v value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; localtime_r(&clock, &tm); @@ -1118,7 +1118,7 @@ njs_date_prototype_get_utc_month(njs_vm_ value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; gmtime_r(&clock, &tm); @@ -1142,7 +1142,7 @@ njs_date_prototype_get_date(njs_vm_t *vm value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; localtime_r(&clock, &tm); @@ -1165,7 +1165,7 @@ njs_date_prototype_get_utc_date(njs_vm_t value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; gmtime_r(&clock, &tm); @@ -1188,7 +1188,7 @@ njs_date_prototype_get_day(njs_vm_t *vm, value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; localtime_r(&clock, &tm); @@ -1211,7 +1211,7 @@ njs_date_prototype_get_utc_day(njs_vm_t value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; gmtime_r(&clock, &tm); @@ -1234,7 +1234,7 @@ njs_date_prototype_get_hours(njs_vm_t *v value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; localtime_r(&clock, &tm); @@ -1258,7 +1258,7 @@ njs_date_prototype_get_utc_hours(njs_vm_ value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; gmtime_r(&clock, &tm); @@ -1281,7 +1281,7 @@ njs_date_prototype_get_minutes(njs_vm_t value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; localtime_r(&clock, &tm); @@ -1305,7 +1305,7 @@ njs_date_prototype_get_utc_minutes(njs_v value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; gmtime_r(&clock, &tm); @@ -1326,7 +1326,7 @@ njs_date_prototype_get_seconds(njs_vm_t value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { value = (int64_t) (value / 1000) % 60; } @@ -1344,7 +1344,7 @@ njs_date_prototype_get_milliseconds(njs_ value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { value = (int64_t) value % 1000; } @@ -1364,7 +1364,7 @@ njs_date_prototype_get_timezone_offset(n value = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(value))) { + if (nxt_fast_path(!isnan(value))) { clock = value / 1000; localtime_r(&clock, &tm); @@ -1385,7 +1385,7 @@ njs_date_prototype_set_time(njs_vm_t *vm time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { time = args[1].data.u.number; @@ -1410,7 +1410,7 @@ njs_date_prototype_set_milliseconds(njs_ time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { time = (int64_t) (time / 1000) * 1000 + args[1].data.u.number; @@ -1436,7 +1436,7 @@ njs_date_prototype_set_seconds(njs_vm_t time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { sec = args[1].data.u.number; @@ -1467,7 +1467,7 @@ njs_date_prototype_set_minutes(njs_vm_t time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { clock = time / 1000; @@ -1504,7 +1504,7 @@ njs_date_prototype_set_utc_minutes(njs_v time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { clock = time / 1000; @@ -1541,7 +1541,7 @@ njs_date_prototype_set_hours(njs_vm_t *v time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { clock = time / 1000; @@ -1582,7 +1582,7 @@ njs_date_prototype_set_utc_hours(njs_vm_ time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { clock = time / 1000; @@ -1619,7 +1619,7 @@ njs_date_prototype_set_date(njs_vm_t *vm time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { clock = time / 1000; @@ -1651,7 +1651,7 @@ njs_date_prototype_set_utc_date(njs_vm_t time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { clock = time / 1000; @@ -1683,7 +1683,7 @@ njs_date_prototype_set_month(njs_vm_t *v time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { clock = time / 1000; @@ -1719,7 +1719,7 @@ njs_date_prototype_set_utc_month(njs_vm_ time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { clock = time / 1000; @@ -1755,7 +1755,7 @@ njs_date_prototype_set_full_year(njs_vm_ time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { clock = time / 1000; @@ -1795,7 +1795,7 @@ njs_date_prototype_set_utc_full_year(njs time = args[0].data.u.date->time; - if (nxt_fast_path(!njs_is_nan(time))) { + if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { clock = time / 1000; diff -r bcd4910c5be9 -r 109932e1d3c8 njs/njs_math.c --- a/njs/njs_math.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_math.c Fri Nov 04 18:25:55 2016 +0300 @@ -342,7 +342,7 @@ njs_object_math_sign(njs_vm_t *vm, njs_v if (nargs > 1) { num = args[1].data.u.number; - if (!njs_is_nan(num) && num != 0) { + if (!isnan(num) && num != 0) { num = signbit(num) ? -1 : 1; } diff -r bcd4910c5be9 -r 109932e1d3c8 njs/njs_number.c --- a/njs/njs_number.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_number.c Fri Nov 04 18:25:55 2016 +0300 @@ -177,10 +177,10 @@ njs_number_to_string(njs_vm_t *vm, njs_v num = number->data.u.number; - if (njs_is_nan(num)) { + if (isnan(num)) { value = &njs_string_nan; - } else if (njs_is_infinity(num)) { + } else if (isinf(num)) { if (num < 0) { value = &njs_string_minus_infinity; @@ -445,7 +445,7 @@ njs_number_is_nan(njs_vm_t *vm, njs_valu value = &njs_value_true; - if (nargs > 1 && !njs_is_nan(args[1].data.u.number)) { + if (nargs > 1 && !isnan(args[1].data.u.number)) { value = &njs_value_false; } @@ -467,7 +467,7 @@ njs_number_is_finite(njs_vm_t *vm, njs_v if (nargs > 1) { num = args[1].data.u.number; - if (!njs_is_nan(num) && !njs_is_infinity(num)) { + if (!isnan(num) && !isinf(num)) { value = &njs_value_true; } } diff -r bcd4910c5be9 -r 109932e1d3c8 njs/njs_number.h --- a/njs/njs_number.h Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_number.h Fri Nov 04 18:25:55 2016 +0300 @@ -11,14 +11,6 @@ #include -#define njs_is_infinity(n) \ - isinf(n) - - -#define njs_is_nan(n) \ - isnan(n) - - double njs_value_to_number(njs_value_t *value); double njs_number_parse(const u_char **start, const u_char *end); int64_t njs_number_radix_parse(u_char *p, u_char *end, uint8_t radix, diff -r bcd4910c5be9 -r 109932e1d3c8 njs/njs_string.c --- a/njs/njs_string.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_string.c Fri Nov 04 18:25:55 2016 +0300 @@ -1174,7 +1174,7 @@ njs_string_from_char_code(njs_vm_t *vm, for (i = 1; i < nargs; i++) { num = args[i].data.u.number; - if (njs_is_nan(num)) { + if (isnan(num)) { goto range_error; } diff -r bcd4910c5be9 -r 109932e1d3c8 njs/njs_vm.c --- a/njs/njs_vm.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_vm.c Fri Nov 04 18:25:55 2016 +0300 @@ -1973,9 +1973,7 @@ njs_values_compare(njs_value_t *val1, nj if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { /* NaN and void values are not comparable with anything. */ - if (njs_is_nan(val1->data.u.number) - || njs_is_nan(val2->data.u.number)) - { + if (isnan(val1->data.u.number) || isnan(val2->data.u.number)) { return -1; } @@ -2471,7 +2469,7 @@ njs_normalize_args(njs_vm_t *vm, njs_val /* Numbers are truncated to fit in 32-bit integers. */ - if (njs_is_nan(args->data.u.number)) { + if (isnan(args->data.u.number)) { args->data.u.number = 0; } else if (args->data.u.number > 2147483647.0) { diff -r bcd4910c5be9 -r 109932e1d3c8 njs/njs_vm.h --- a/njs/njs_vm.h Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_vm.h Fri Nov 04 18:25:55 2016 +0300 @@ -376,7 +376,7 @@ typedef njs_ret_t (*njs_vmcode_operation /* Testing for NaN first generates a better code at least on i386/amd64. */ #define njs_is_number_true(num) \ - (!njs_is_nan(num) && num != 0) + (!isnan(num) && num != 0) #define njs_is_numeric(value) \ From ru at nginx.com Fri Nov 4 16:13:31 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Fri, 04 Nov 2016 16:13:31 +0000 Subject: [nginx] Style: switch. Message-ID: details: http://hg.nginx.org/nginx/rev/92ad1c92bcf9 branches: changeset: 6796:92ad1c92bcf9 user: Ruslan Ermilov date: Fri Nov 04 19:12:19 2016 +0300 description: Style: switch. diffstat: src/http/ngx_http_core_module.c | 2 -- src/http/ngx_http_special_response.c | 1 - 2 files changed, 0 insertions(+), 3 deletions(-) diffs (23 lines): diff -r 1a917932db96 -r 92ad1c92bcf9 src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Thu Nov 03 17:10:29 2016 +0300 +++ b/src/http/ngx_http_core_module.c Fri Nov 04 19:12:19 2016 +0300 @@ -4827,8 +4827,6 @@ ngx_http_core_error_page(ngx_conf_t *cf, case NGX_HTTPS_CERT_ERROR: case NGX_HTTPS_NO_CERT: err->overwrite = NGX_HTTP_BAD_REQUEST; - default: - break; } } diff -r 1a917932db96 -r 92ad1c92bcf9 src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c Thu Nov 03 17:10:29 2016 +0300 +++ b/src/http/ngx_http_special_response.c Fri Nov 04 19:12:19 2016 +0300 @@ -473,7 +473,6 @@ ngx_http_special_response_handler(ngx_ht case NGX_HTTPS_NO_CERT: case NGX_HTTP_REQUEST_HEADER_TOO_LARGE: r->err_status = NGX_HTTP_BAD_REQUEST; - break; } } else { From igor at sysoev.ru Fri Nov 4 20:51:53 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 04 Nov 2016 20:51:53 +0000 Subject: [njs] Function expressions did not have prototypes. Message-ID: details: http://hg.nginx.org/njs/rev/53d2024f6ca3 branches: changeset: 239:53d2024f6ca3 user: Igor Sysoev date: Fri Nov 04 23:45:35 2016 +0300 description: Function expressions did not have prototypes. diffstat: njs/njs_vm.c | 1 + njs/test/njs_unit_test.c | 11 +++++++++++ 2 files changed, 12 insertions(+), 0 deletions(-) diffs (32 lines): diff -r 109932e1d3c8 -r 53d2024f6ca3 njs/njs_vm.c --- a/njs/njs_vm.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/njs_vm.c Fri Nov 04 23:45:35 2016 +0300 @@ -414,6 +414,7 @@ njs_vmcode_function(njs_vm_t *vm, njs_va function = nxt_mem_cache_zalloc(vm->mem_cache_pool, sizeof(njs_function_t)); if (nxt_fast_path(function != NULL)) { + function->object.shared_hash = vm->shared->function_prototype_hash; function->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION].object; function->args_offset = 1; diff -r 109932e1d3c8 -r 53d2024f6ca3 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Nov 04 18:25:55 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Nov 04 23:45:35 2016 +0300 @@ -4167,6 +4167,17 @@ static njs_unit_test_t njs_test[] = "o.constructor === F"), nxt_string("true") }, + { nxt_string("function F() { return }" + "var o = new F();" + "o.__proto__ === F.prototype"), + nxt_string("true") }, + + { nxt_string("function F(){}; typeof F.prototype"), + nxt_string("object") }, + + { nxt_string("var F = function (){}; typeof F.prototype"), + nxt_string("object") }, + { nxt_string("function F() { return Number }" "var o = new (F())(5);" "typeof o +' '+ o"), From c.klinger at lirum.at Sat Nov 5 23:24:08 2016 From: c.klinger at lirum.at (Christian Klinger) Date: Sun, 06 Nov 2016 00:24:08 +0100 Subject: [PATCH] Follow OpenSSL's switch from AES128 to AES256 for session tickets Message-ID: <5719a734584d23a6bcd2.1478388248@spencer.quelltextlich.at> # HG changeset patch # User Christian Klinger # Date 1478383992 -3600 # Node ID 5719a734584d23a6bcd22a3e59dd36138d06b803 # Parent 92ad1c92bcf93310bf59447dd581cac37af87adb Follow OpenSSL's switch from AES128 to AES256 for session tickets OpenSSL switched from AES128 to AES256 for de-/encryption of session tickets in May 2016 (commit 05df5c2036f1244fe3df70de7d8079a5d86b999d), while we still used AES128, if `ssl_session_ticket_key` was set. Using AES128 for session tickets means that even when using an AES256 cipher suite, the session's master key (and hence the whole connection) is effectively only protected by AES128, which silently weakens encryption. Hence, we follow OpenSSL's lead and switch from AES128 to AES256 for session tickets, if `ssl_session_ticket_key` is set. While the switch from AES128 to AES256 warrants reading additional 16 bytes from the key file, we nonetheless increase by 32 bytes, reading a total of 80 bytes instead of previously 48 bytes. The additional 16 bytes flow into the key for the SHA256 HMAC. Previously, the SHA256 HMAC only used a 16 byte key, and thereby used only half of SHA256 HMAC's 32 byte key space. We now provide a 32 byte key to the SHA256 HMAC and finally fully use the available key space. diff -r 92ad1c92bcf9 -r 5719a734584d src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Fri Nov 04 19:12:19 2016 +0300 +++ b/src/event/ngx_event_openssl.c Sat Nov 05 23:13:12 2016 +0100 @@ -2832,8 +2832,10 @@ 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]; ssize_t n; + ssize_t name_len; + ssize_t key_len; ngx_str_t *path; ngx_file_t file; ngx_uint_t i; @@ -2875,13 +2877,16 @@ goto failed; } - if (ngx_file_size(&fi) != 48) { + // We expect 80 bytes, but we allow 48 bytes to not break legacy setups + if (ngx_file_size(&fi) != 80 && ngx_file_size(&fi) != 48) { + // We only mention 80 bytes in the log message, as that is what we + // want to gravitate towards. ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"%V\" must be 48 bytes", &file.name); + "\"%V\" must be 80 bytes", &file.name); goto failed; } - n = ngx_read_file(&file, buf, 48, 0); + n = ngx_read_file(&file, buf, 80, 0); if (n == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno, @@ -2889,21 +2894,47 @@ goto failed; } - if (n != 48) { - ngx_conf_log_error(NGX_LOG_CRIT, cf, 0, - ngx_read_file_n " \"%V\" returned only " - "%z bytes instead of 48", &file.name, n); - goto failed; + if (n != 80) { + if (n == 48) { + // 48 was the old ngx_ssl_session_ticket_key_t length. 48 bytes + // do not allow us to fully seed recent algos. We'd need + // 80 bytes to fully seed them. But to avoid breaking legacy + // setups for which 48 byte seeding was sufficient, we use those + // 48 bytes. 48 bytes on recent algos is not worse than 48 bytes + // on old algos. But although we're not aborting, we at least + // warn users that they should provide more randomness. + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + ngx_read_file_n " \"%V\" returned only " + "%z bytes instead of 80. Please provide " + "80 bytes to fully seed used algorithms", + &file.name, n); + } else { + // Neither the new default 80 bytes, nor the legacy 48 bytes + // of randomness. + ngx_conf_log_error(NGX_LOG_CRIT, cf, 0, + ngx_read_file_n " \"%V\" returned only " + "%z bytes instead of 80", &file.name, n); + goto failed; + } } key = ngx_array_push(keys); if (key == NULL) { goto failed; } - - ngx_memcpy(key->name, buf, 16); - ngx_memcpy(key->aes_key, buf + 16, 16); - ngx_memcpy(key->hmac_key, buf + 32, 16); + // Since the read in randomness need not fill the whole key, we zero + // out the key before to make sure keys agree if the randomness file + // is re-used across servers. + ngx_memzero(key, sizeof(ngx_ssl_session_ticket_key_t)); + name_len = sizeof(key->name); + // When the random file contained only 48 bytes of randomnes, we rather + // split the available randomness between aes and hmac, instead of only + // seeding one of the two. key_len holds how many bytes of the + // randomness flows into seeding each of aes and hmac. + key_len = (n - name_len) / 2; + ngx_memcpy(key->name, buf, name_len); + ngx_memcpy(key->aes_key, buf + name_len, key_len); + ngx_memcpy(key->hmac_key, buf + name_len + key_len, key_len); if (ngx_close_file(file.fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, @@ -2962,7 +2993,7 @@ c = ngx_ssl_get_connection(ssl_conn); ssl_ctx = c->ssl->session_ctx; - cipher = EVP_aes_128_cbc(); + cipher = EVP_aes_256_cbc(); #ifdef OPENSSL_NO_SHA256 digest = EVP_sha1(); #else @@ -2996,12 +3027,14 @@ } #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, sizeof(key[0].hmac_key), + 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, sizeof(key[0].hmac_key), digest, + NULL); #endif ngx_memcpy(name, key[0].name, 16); @@ -3031,12 +3064,14 @@ (i == 0) ? " (default)" : ""); #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, sizeof(key[i].hmac_key), + 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, sizeof(key[i].hmac_key), digest, + NULL); #endif if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) { diff -r 92ad1c92bcf9 -r 5719a734584d src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Fri Nov 04 19:12:19 2016 +0300 +++ b/src/event/ngx_event_openssl.h Sat Nov 05 23:13:12 2016 +0100 @@ -118,8 +118,8 @@ typedef struct { u_char name[16]; - u_char aes_key[16]; - u_char hmac_key[16]; + u_char aes_key[32]; + u_char hmac_key[32]; } ngx_ssl_session_ticket_key_t; #endif From piotrsikora at google.com Sun Nov 6 02:07:23 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Sat, 5 Nov 2016 19:07:23 -0700 Subject: [PATCH] Follow OpenSSL's switch from AES128 to AES256 for session tickets In-Reply-To: <5719a734584d23a6bcd2.1478388248@spencer.quelltextlich.at> References: <5719a734584d23a6bcd2.1478388248@spencer.quelltextlich.at> Message-ID: Hey Christian, > # HG changeset patch > # User Christian Klinger > # Date 1478383992 -3600 > # Node ID 5719a734584d23a6bcd22a3e59dd36138d06b803 > # Parent 92ad1c92bcf93310bf59447dd581cac37af87adb > Follow OpenSSL's switch from AES128 to AES256 for session tickets > > OpenSSL switched from AES128 to AES256 for de-/encryption of session > tickets in May 2016 (commit 05df5c2036f1244fe3df70de7d8079a5d86b999d), > while we still used AES128, if `ssl_session_ticket_key` was set. > > Using AES128 for session tickets means that even when using an AES256 > cipher suite, the session's master key (and hence the whole > connection) is effectively only protected by AES128, which silently > weakens encryption. > > Hence, we follow OpenSSL's lead and switch from AES128 to AES256 for > session tickets, if `ssl_session_ticket_key` is set. > > While the switch from AES128 to AES256 warrants reading additional > 16 bytes from the key file, we nonetheless increase by 32 bytes, > reading a total of 80 bytes instead of previously 48 bytes. > The additional 16 bytes flow into the key for the SHA256 HMAC. > Previously, the SHA256 HMAC only used a 16 byte key, and thereby used > only half of SHA256 HMAC's 32 byte key space. We now provide a 32 byte > key to the SHA256 HMAC and finally fully use the available key space. While I agree that we should bump this to AES256 (or at least, make it work with both), your change to use AES256 with keys that are half-filled with zeros doesn't seem very appealing... I suggest that "ssl_session_ticket_key" should either accept only 80 byte files (for use with AES256) or both: 48 byte files (for use with AES128) & 80 byte files (for use with AES256). Whether or not we want to support both is up to Maxim, but considering that this is "advanced" feature, which users are expected to know how to generate new keys, I'd recommend that NGINX should migrate to 80 byte files for use with AES256, without backward-compatibility for 48 byte keys. Also, considering that recent versions of OpenSSL use AES256 by default (i.e. when keys are not provided using "ssl_session_ticket_key" directive), we shouldn't provide a way lower the security of Session Tickets. Best regards, Piotr Sikora From piotrsikora at google.com Sun Nov 6 11:19:36 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Sun, 6 Nov 2016 03:19:36 -0800 Subject: [PATCH] Follow OpenSSL's switch from AES128 to AES256 for session tickets In-Reply-To: References: <5719a734584d23a6bcd2.1478388248@spencer.quelltextlich.at> Message-ID: Hey, > While I agree that we should bump this to AES256 (or at least, make it > work with both), your change to use AES256 with keys that are > half-filled with zeros doesn't seem very appealing... > > I suggest that "ssl_session_ticket_key" should either accept only 80 > byte files (for use with AES256) or both: 48 byte files (for use with > AES128) & 80 byte files (for use with AES256). > > Whether or not we want to support both is up to Maxim, but considering > that this is "advanced" feature, which users are expected to know how > to generate new keys, I'd recommend that NGINX should migrate to 80 > byte files for use with AES256, without backward-compatibility for 48 > byte keys. > > Also, considering that recent versions of OpenSSL use AES256 by > default (i.e. when keys are not provided using > "ssl_session_ticket_key" directive), we shouldn't provide a way lower > the security of Session Tickets. ...and while we're breaking backward-compatibility, we should also change the order in which values are read from files to match what OpenSSL, BoringSSL & Apache are doing, i.e. key name, HMAC key, AES key: ngx_memcpy(key->name, buf, 16); ngx_memcpy(key->hmac_key, buf + 16, 32); ngx_memcpy(key->aes_key, buf + 48, 32); instead of the current: key name, AES key, HMAC key, which I introduced by mistake and which has been annoying me ever since. Best regards, Piotr Sikora From vbart at nginx.com Sun Nov 6 13:05:22 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Sun, 06 Nov 2016 13:05:22 +0000 Subject: [njs] Various Number constants. Message-ID: details: http://hg.nginx.org/njs/rev/8722dc4bdeb4 branches: changeset: 240:8722dc4bdeb4 user: Valentin Bartenev date: Sun Nov 06 16:03:03 2016 +0300 description: Various Number constants. diffstat: njs/njs_number.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 60 insertions(+), 0 deletions(-) diffs (77 lines): diff -r 53d2024f6ca3 -r 8722dc4bdeb4 njs/njs_number.c --- a/njs/njs_number.c Fri Nov 04 23:45:35 2016 +0300 +++ b/njs/njs_number.c Sun Nov 06 16:03:03 2016 +0300 @@ -22,6 +22,15 @@ #include #include #include +#include + + +/* + * 2^53 - 1 is the largest integer n such that n and n + 1 + * as well as -n and -n - 1 are all exactly representable + * in the IEEE-754 format. + */ +#define NJS_MAX_SAFE_INTEGER ((1LL << 53) - 1) static njs_ret_t njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string, @@ -273,6 +282,57 @@ static const njs_object_prop_t njs_numb .name = njs_string("prototype"), .value = njs_native_getter(njs_object_prototype_create), }, + + /* ES6. */ + { + .type = NJS_PROPERTY, + .name = njs_string("EPSILON"), + .value = njs_value(NJS_NUMBER, 1, DBL_EPSILON), + }, + + /* ES6. */ + { + .type = NJS_PROPERTY, + .name = njs_long_string("MAX_SAFE_INTEGER"), + .value = njs_value(NJS_NUMBER, 1, NJS_MAX_SAFE_INTEGER), + }, + + /* ES6. */ + { + .type = NJS_PROPERTY, + .name = njs_long_string("MIN_SAFE_INTEGER"), + .value = njs_value(NJS_NUMBER, 1, -NJS_MAX_SAFE_INTEGER), + }, + + { + .type = NJS_PROPERTY, + .name = njs_string("MAX_VALUE"), + .value = njs_value(NJS_NUMBER, 1, DBL_MAX), + }, + + { + .type = NJS_PROPERTY, + .name = njs_string("MIN_VALUE"), + .value = njs_value(NJS_NUMBER, 1, DBL_MIN), + }, + + { + .type = NJS_PROPERTY, + .name = njs_string("NaN"), + .value = njs_value(NJS_NUMBER, 0, NAN), + }, + + { + .type = NJS_PROPERTY, + .name = njs_long_string("POSITIVE_INFINITY"), + .value = njs_value(NJS_NUMBER, 1, INFINITY), + }, + + { + .type = NJS_PROPERTY, + .name = njs_long_string("NEGATIVE_INFINITY"), + .value = njs_value(NJS_NUMBER, 1, -INFINITY), + }, }; From vbart at nginx.com Sun Nov 6 13:05:25 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Sun, 06 Nov 2016 13:05:25 +0000 Subject: [njs] Various Number methods. Message-ID: details: http://hg.nginx.org/njs/rev/ad4b6e0b5014 branches: changeset: 241:ad4b6e0b5014 user: Valentin Bartenev date: Sun Nov 06 16:03:29 2016 +0300 description: Various Number methods. diffstat: njs/njs_builtin.c | 2 +- njs/njs_number.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++- njs/njs_number.h | 4 +- njs/test/njs_unit_test.c | 89 ++++++++++++++++++++++++++++++++++++ 4 files changed, 206 insertions(+), 5 deletions(-) diffs (272 lines): diff -r 8722dc4bdeb4 -r ad4b6e0b5014 njs/njs_builtin.c --- a/njs/njs_builtin.c Sun Nov 06 16:03:03 2016 +0300 +++ b/njs/njs_builtin.c Sun Nov 06 16:03:29 2016 +0300 @@ -143,7 +143,7 @@ njs_builtin_objects_create(njs_vm_t *vm) /* SunC does not allow empty array initialization. */ { njs_eval_function, { 0 } }, { njs_object_prototype_to_string, { 0 } }, - { njs_number_is_nan, { NJS_SKIP_ARG, NJS_NUMBER_ARG } }, + { njs_number_global_is_nan, { NJS_SKIP_ARG, NJS_NUMBER_ARG } }, { njs_number_is_finite, { NJS_SKIP_ARG, NJS_NUMBER_ARG } }, { njs_number_parse_int, { NJS_SKIP_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG } }, diff -r 8722dc4bdeb4 -r ad4b6e0b5014 njs/njs_number.c --- a/njs/njs_number.c Sun Nov 06 16:03:03 2016 +0300 +++ b/njs/njs_number.c Sun Nov 06 16:03:29 2016 +0300 @@ -260,6 +260,74 @@ njs_number_constructor(njs_vm_t *vm, njs } +static njs_ret_t +njs_number_is_integer(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + const njs_value_t *value; + + value = &njs_value_false; + + if (nargs > 1 && njs_is_number(&args[1])) { + num = args[1].data.u.number; + + if (num == trunc(num) && !isinf(num)) { + value = &njs_value_true; + } + } + + vm->retval = *value; + + return NXT_OK; +} + + + +static njs_ret_t +njs_number_is_safe_integer(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + const njs_value_t *value; + + value = &njs_value_false; + + if (nargs > 1 && njs_is_number(&args[1])) { + num = args[1].data.u.number; + + if (num == (int64_t) num && fabs(num) <= NJS_MAX_SAFE_INTEGER) { + value = &njs_value_true; + } + } + + vm->retval = *value; + + return NXT_OK; +} + + +static njs_ret_t +njs_number_is_nan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + const njs_value_t *value; + + value = &njs_value_false; + + if (nargs > 1 + && njs_is_number(&args[1]) + && isnan(args[1].data.u.number)) + { + value = &njs_value_true; + } + + vm->retval = *value; + + return NXT_OK; +} + + static const njs_object_prop_t njs_number_constructor_properties[] = { /* Number.name == "Number". */ @@ -333,6 +401,50 @@ static const njs_object_prop_t njs_numb .name = njs_long_string("NEGATIVE_INFINITY"), .value = njs_value(NJS_NUMBER, 1, -INFINITY), }, + + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("isFinite"), + .value = njs_native_function(njs_number_is_finite, 0, 0), + }, + + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("isInteger"), + .value = njs_native_function(njs_number_is_integer, 0, 0), + }, + + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("isSafeInteger"), + .value = njs_native_function(njs_number_is_safe_integer, 0, 0), + }, + + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("isNaN"), + .value = njs_native_function(njs_number_is_nan, 0, 0), + }, + + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("parseFloat"), + .value = njs_native_function(njs_number_parse_float, 0, + NJS_SKIP_ARG, NJS_STRING_ARG), + }, + + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("parseInt"), + .value = njs_native_function(njs_number_parse_int, 0, + NJS_SKIP_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG), + }, }; @@ -498,7 +610,7 @@ const njs_object_init_t njs_number_prot njs_ret_t -njs_number_is_nan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_number_global_is_nan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { const njs_value_t *value; @@ -524,7 +636,7 @@ njs_number_is_finite(njs_vm_t *vm, njs_v value = &njs_value_false; - if (nargs > 1) { + if (nargs > 1 && njs_is_number(&args[1])) { num = args[1].data.u.number; if (!isnan(num) && !isinf(num)) { diff -r 8722dc4bdeb4 -r ad4b6e0b5014 njs/njs_number.h --- a/njs/njs_number.h Sun Nov 06 16:03:03 2016 +0300 +++ b/njs/njs_number.h Sun Nov 06 16:03:29 2016 +0300 @@ -19,8 +19,8 @@ njs_ret_t njs_number_to_string(njs_vm_t const njs_value_t *number); njs_ret_t njs_number_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -njs_ret_t njs_number_is_nan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, - njs_index_t unused); +njs_ret_t njs_number_global_is_nan(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); njs_ret_t njs_number_is_finite(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); njs_ret_t njs_number_parse_int(njs_vm_t *vm, njs_value_t *args, diff -r 8722dc4bdeb4 -r ad4b6e0b5014 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sun Nov 06 16:03:03 2016 +0300 +++ b/njs/test/njs_unit_test.c Sun Nov 06 16:03:29 2016 +0300 @@ -4766,6 +4766,95 @@ static njs_unit_test_t njs_test[] = { nxt_string("var n = new Number(1); n.__proto__ === Number.prototype"), nxt_string("true") }, + { nxt_string("Number.isFinite()"), + nxt_string("false") }, + + { nxt_string("Number.isFinite(123)"), + nxt_string("true") }, + + { nxt_string("Number.isFinite('123')"), + nxt_string("false") }, + + { nxt_string("Number.isFinite(Infinity)"), + nxt_string("false") }, + + { nxt_string("Number.isFinite(NaN)"), + nxt_string("false") }, + + { nxt_string("Number.isInteger()"), + nxt_string("false") }, + + { nxt_string("Number.isInteger('123')"), + nxt_string("false") }, + + { nxt_string("Number.isInteger(123)"), + nxt_string("true") }, + + { nxt_string("Number.isInteger(-123.0)"), + nxt_string("true") }, + + { nxt_string("Number.isInteger(123.4)"), + nxt_string("false") }, + + { nxt_string("Number.isInteger(Infinity)"), + nxt_string("false") }, + + { nxt_string("Number.isInteger(NaN)"), + nxt_string("false") }, + + { nxt_string("Number.isSafeInteger()"), + nxt_string("false") }, + + { nxt_string("Number.isSafeInteger('123')"), + nxt_string("false") }, + + { nxt_string("Number.isSafeInteger(9007199254740991)"), + nxt_string("true") }, + + { nxt_string("Number.isSafeInteger(-9007199254740991.0)"), + nxt_string("true") }, + + { nxt_string("Number.isSafeInteger(9007199254740992)"), + nxt_string("false") }, + + { nxt_string("Number.isSafeInteger(-9007199254740992.0)"), + nxt_string("false") }, + + { nxt_string("Number.isSafeInteger(123.4)"), + nxt_string("false") }, + + { nxt_string("Number.isSafeInteger(Infinity)"), + nxt_string("false") }, + + { nxt_string("Number.isSafeInteger(-Infinity)"), + nxt_string("false") }, + + { nxt_string("Number.isSafeInteger(NaN)"), + nxt_string("false") }, + + { nxt_string("Number.isNaN()"), + nxt_string("false") }, + + { nxt_string("Number.isNaN('NaN')"), + nxt_string("false") }, + + { nxt_string("Number.isNaN(NaN)"), + nxt_string("true") }, + + { nxt_string("Number.isNaN(123)"), + nxt_string("false") }, + + { nxt_string("Number.isNaN(Infinity)"), + nxt_string("false") }, + +#if 0 + { nxt_string("parseFloat === Number.parseFloat"), + nxt_string("true") }, + + { nxt_string("parseInt === Number.parseInt"), + nxt_string("true") }, +#endif + { nxt_string("String()"), nxt_string("") }, From c.klinger at lirum.at Sun Nov 6 21:53:10 2016 From: c.klinger at lirum.at (Christian Klinger) Date: Sun, 6 Nov 2016 22:53:10 +0100 Subject: [PATCH] Follow OpenSSL's switch from AES128 to AES256 for session tickets In-Reply-To: References: <5719a734584d23a6bcd2.1478388248@spencer.quelltextlich.at> Message-ID: <20161106215310.GA27676@lirum.at> Hi, On Sat, Nov 05, 2016 at 07:07:23PM -0700, Piotr Sikora wrote: > Also, considering that recent versions of OpenSSL use AES256 by > default (i.e. when keys are not provided using > "ssl_session_ticket_key" directive), we shouldn't provide a way lower > the security of Session Tickets. If backward compatibility isn't a thing, the patch gets a bit simpler. All the better. Let me send and updated variant. Best regards, Christian From c.klinger at lirum.at Sun Nov 6 21:54:48 2016 From: c.klinger at lirum.at (Christian Klinger) Date: Sun, 6 Nov 2016 22:54:48 +0100 Subject: [PATCH] Follow OpenSSL's switch from AES128 to AES256 for session tickets In-Reply-To: References: <5719a734584d23a6bcd2.1478388248@spencer.quelltextlich.at> Message-ID: <20161106215448.GB27676@lirum.at> # HG changeset patch # User Christian Klinger # Date 1478468739 -3600 # Node ID 9cfbbce1ec24a31c29ea2f20cb21e32e5173bc60 # Parent 92ad1c92bcf93310bf59447dd581cac37af87adb Follow OpenSSL's switch from AES128 to AES256 for session tickets OpenSSL switched from AES128 to AES256 for de-/encryption of session tickets in May 2016 (commit 05df5c2036f1244fe3df70de7d8079a5d86b999d), while we still used AES128, if `ssl_session_ticket_key` was set. Using AES128 for session tickets means that even when using an AES256 cipher suite, the session's master key (and hence the whole connection) is effectively only protected by AES128, which silently weakens encryption. Hence, we follow OpenSSL's lead and switch from AES128 to AES256 for session tickets, if `ssl_session_ticket_key` is set. While the switch from AES128 to AES256 warrants reading additional 16 bytes from the key file, we nonetheless increase by 32 bytes, reading a total of 80 bytes instead of previously 48 bytes. The additional 16 bytes flow into the key for the SHA256 HMAC. Previously, the SHA256 HMAC only used a 16 byte key, and thereby used only half of SHA256 HMAC's 32 byte key space. We now provide a 32 byte key to the SHA256 HMAC and finally fully use the available key space. diff -r 92ad1c92bcf9 -r 9cfbbce1ec24 src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Fri Nov 04 19:12:19 2016 +0300 +++ b/src/event/ngx_event_openssl.c Sun Nov 06 22:45:39 2016 +0100 @@ -2832,7 +2832,7 @@ 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]; ssize_t n; ngx_str_t *path; ngx_file_t file; @@ -2875,13 +2875,13 @@ goto failed; } - if (ngx_file_size(&fi) != 48) { + if (ngx_file_size(&fi) != 80) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"%V\" must be 48 bytes", &file.name); + "\"%V\" must be 80 bytes", &file.name); goto failed; } - n = ngx_read_file(&file, buf, 48, 0); + n = ngx_read_file(&file, buf, 80, 0); if (n == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno, @@ -2889,10 +2889,10 @@ goto failed; } - if (n != 48) { + if (n != 80) { 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 80", &file.name, n); goto failed; } @@ -2900,10 +2900,9 @@ if (key == NULL) { goto failed; } - ngx_memcpy(key->name, buf, 16); - ngx_memcpy(key->aes_key, buf + 16, 16); - ngx_memcpy(key->hmac_key, buf + 32, 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, @@ -2962,7 +2961,7 @@ c = ngx_ssl_get_connection(ssl_conn); ssl_ctx = c->ssl->session_ctx; - cipher = EVP_aes_128_cbc(); + cipher = EVP_aes_256_cbc(); #ifdef OPENSSL_NO_SHA256 digest = EVP_sha1(); #else @@ -2996,12 +2995,14 @@ } #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, sizeof(key[0].hmac_key), + 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, sizeof(key[0].hmac_key), digest, + NULL); #endif ngx_memcpy(name, key[0].name, 16); @@ -3031,12 +3032,14 @@ (i == 0) ? " (default)" : ""); #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, sizeof(key[i].hmac_key), + 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, sizeof(key[i].hmac_key), digest, + NULL); #endif if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) { diff -r 92ad1c92bcf9 -r 9cfbbce1ec24 src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Fri Nov 04 19:12:19 2016 +0300 +++ b/src/event/ngx_event_openssl.h Sun Nov 06 22:45:39 2016 +0100 @@ -118,8 +118,8 @@ typedef struct { u_char name[16]; - u_char aes_key[16]; - u_char hmac_key[16]; + u_char aes_key[32]; + u_char hmac_key[32]; } ngx_ssl_session_ticket_key_t; #endif From c.klinger at lirum.at Sun Nov 6 21:55:40 2016 From: c.klinger at lirum.at (Christian Klinger) Date: Sun, 6 Nov 2016 22:55:40 +0100 Subject: [PATCH] Follow OpenSSL's switch from AES128 to AES256 for session tickets In-Reply-To: References: <5719a734584d23a6bcd2.1478388248@spencer.quelltextlich.at> Message-ID: <20161106215540.GC27676@lirum.at> Hi, On Sun, Nov 06, 2016 at 03:19:36AM -0800, Piotr Sikora wrote: > ...and while we're breaking backward-compatibility, we should also > change the order in which values are read from files to match what > OpenSSL, BoringSSL & Apache are doing, [...] Done. (See follow-up message) Best regards, Christian From piotrsikora at google.com Sun Nov 6 22:31:49 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Sun, 6 Nov 2016 14:31:49 -0800 Subject: [PATCH] Follow OpenSSL's switch from AES128 to AES256 for session tickets In-Reply-To: <20161106215448.GB27676@lirum.at> References: <5719a734584d23a6bcd2.1478388248@spencer.quelltextlich.at> <20161106215448.GB27676@lirum.at> Message-ID: Hey Christian, > # HG changeset patch > # User Christian Klinger > # Date 1478468739 -3600 > # Node ID 9cfbbce1ec24a31c29ea2f20cb21e32e5173bc60 > # Parent 92ad1c92bcf93310bf59447dd581cac37af87adb > Follow OpenSSL's switch from AES128 to AES256 for session tickets This should be: SSL: switch from AES128 to AES256 for TLS Session Tickets. > > OpenSSL switched from AES128 to AES256 for de-/encryption of session > tickets in May 2016 (commit 05df5c2036f1244fe3df70de7d8079a5d86b999d), > while we still used AES128, if `ssl_session_ticket_key` was set. > > Using AES128 for session tickets means that even when using an AES256 > cipher suite, the session's master key (and hence the whole > connection) is effectively only protected by AES128, which silently > weakens encryption. > > Hence, we follow OpenSSL's lead and switch from AES128 to AES256 for > session tickets, if `ssl_session_ticket_key` is set. > > While the switch from AES128 to AES256 warrants reading additional > 16 bytes from the key file, we nonetheless increase by 32 bytes, > reading a total of 80 bytes instead of previously 48 bytes. > The additional 16 bytes flow into the key for the SHA256 HMAC. > Previously, the SHA256 HMAC only used a 16 byte key, and thereby used > only half of SHA256 HMAC's 32 byte key space. We now provide a 32 byte > key to the SHA256 HMAC and finally fully use the available key space. > > diff -r 92ad1c92bcf9 -r 9cfbbce1ec24 src/event/ngx_event_openssl.c > --- a/src/event/ngx_event_openssl.c Fri Nov 04 19:12:19 2016 +0300 > +++ b/src/event/ngx_event_openssl.c Sun Nov 06 22:45:39 2016 +0100 > @@ -2832,7 +2832,7 @@ > 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]; > ssize_t n; > ngx_str_t *path; > ngx_file_t file; > @@ -2875,13 +2875,13 @@ > goto failed; > } > > - if (ngx_file_size(&fi) != 48) { > + if (ngx_file_size(&fi) != 80) { > ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, > - "\"%V\" must be 48 bytes", &file.name); > + "\"%V\" must be 80 bytes", &file.name); > goto failed; > } > > - n = ngx_read_file(&file, buf, 48, 0); > + n = ngx_read_file(&file, buf, 80, 0); > > if (n == NGX_ERROR) { > ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno, > @@ -2889,10 +2889,10 @@ > goto failed; > } > > - if (n != 48) { > + if (n != 80) { > 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 80", &file.name, n); > goto failed; > } > > @@ -2900,10 +2900,9 @@ > if (key == NULL) { > goto failed; > } > - Style: leave empty line. > ngx_memcpy(key->name, buf, 16); > - ngx_memcpy(key->aes_key, buf + 16, 16); > - ngx_memcpy(key->hmac_key, buf + 32, 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, > @@ -2962,7 +2961,7 @@ > c = ngx_ssl_get_connection(ssl_conn); > ssl_ctx = c->ssl->session_ctx; > > - cipher = EVP_aes_128_cbc(); > + cipher = EVP_aes_256_cbc(); > #ifdef OPENSSL_NO_SHA256 > digest = EVP_sha1(); > #else > @@ -2996,12 +2995,14 @@ > } > > #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, sizeof(key[0].hmac_key), > + digest, NULL) != 1) { Style, this should be: if (HMAC_Init_ex(hctx, key[0].hmac_key, sizeof(key[0].hmac_key), digest, NULL) != 1) { which is why I'm not sure if the use of sizeof() instead of hardcoded "32" is a good choice, since it changes 1 line to 4 lines (here and in other places). > 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, sizeof(key[0].hmac_key), digest, > + NULL); > #endif > > ngx_memcpy(name, key[0].name, 16); > @@ -3031,12 +3032,14 @@ > (i == 0) ? " (default)" : ""); > > #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, sizeof(key[i].hmac_key), > + 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, sizeof(key[i].hmac_key), digest, > + NULL); > #endif > > if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) { > diff -r 92ad1c92bcf9 -r 9cfbbce1ec24 src/event/ngx_event_openssl.h > --- a/src/event/ngx_event_openssl.h Fri Nov 04 19:12:19 2016 +0300 > +++ b/src/event/ngx_event_openssl.h Sun Nov 06 22:45:39 2016 +0100 > @@ -118,8 +118,8 @@ > > typedef struct { > u_char name[16]; > - u_char aes_key[16]; > - u_char hmac_key[16]; > + u_char aes_key[32]; > + u_char hmac_key[32]; > } ngx_ssl_session_ticket_key_t; > > #endif We might change the order here as well (name, hmac_key, aes_key). Best regards, Piotr Sikora From c.klinger at lirum.at Sun Nov 6 23:09:40 2016 From: c.klinger at lirum.at (Christian Klinger) Date: Mon, 7 Nov 2016 00:09:40 +0100 Subject: [PATCH] Follow OpenSSL's switch from AES128 to AES256 for session tickets In-Reply-To: References: <5719a734584d23a6bcd2.1478388248@spencer.quelltextlich.at> <20161106215448.GB27676@lirum.at> Message-ID: <20161106230940.GA9951@lirum.at> # HG changeset patch # User Christian Klinger # Date 1478473338 -3600 # Node ID 36f66e94771dd39e8948ba1023e5ca0677655840 # Parent 92ad1c92bcf93310bf59447dd581cac37af87adb SSL: switch from AES128 to AES256 for TLS Session Tickets. OpenSSL switched from AES128 to AES256 for de-/encryption of session tickets in May 2016 (commit 05df5c2036f1244fe3df70de7d8079a5d86b999d), while we still used AES128, if `ssl_session_ticket_key` was set. Using AES128 for session tickets means that even when using an AES256 cipher suite, the session's master key (and hence the whole connection) is effectively only protected by AES128, which silently weakens encryption. Hence, we follow OpenSSL's lead and switch from AES128 to AES256 for session tickets, if `ssl_session_ticket_key` is set. While the switch from AES128 to AES256 warrants reading additional 16 bytes from the key file, we nonetheless increase by 32 bytes, reading a total of 80 bytes instead of previously 48 bytes. The additional 16 bytes flow into the key for the SHA256 HMAC. Previously, the SHA256 HMAC only used a 16 byte key, and thereby used only half of SHA256 HMAC's 32 byte key space. We now provide a 32 byte key to the SHA256 HMAC and finally fully use the available key space. diff -r 92ad1c92bcf9 -r 36f66e94771d src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Fri Nov 04 19:12:19 2016 +0300 +++ b/src/event/ngx_event_openssl.c Mon Nov 07 00:02:18 2016 +0100 @@ -2832,7 +2832,7 @@ 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]; ssize_t n; ngx_str_t *path; ngx_file_t file; @@ -2875,13 +2875,13 @@ goto failed; } - if (ngx_file_size(&fi) != 48) { + if (ngx_file_size(&fi) != 80) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"%V\" must be 48 bytes", &file.name); + "\"%V\" must be 80 bytes", &file.name); goto failed; } - n = ngx_read_file(&file, buf, 48, 0); + n = ngx_read_file(&file, buf, 80, 0); if (n == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno, @@ -2889,10 +2889,10 @@ goto failed; } - if (n != 48) { + if (n != 80) { 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 80", &file.name, n); goto failed; } @@ -2902,8 +2902,8 @@ } ngx_memcpy(key->name, buf, 16); - ngx_memcpy(key->aes_key, buf + 16, 16); - ngx_memcpy(key->hmac_key, buf + 32, 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, @@ -2962,7 +2962,7 @@ c = ngx_ssl_get_connection(ssl_conn); ssl_ctx = c->ssl->session_ctx; - cipher = EVP_aes_128_cbc(); + cipher = EVP_aes_256_cbc(); #ifdef OPENSSL_NO_SHA256 digest = EVP_sha1(); #else @@ -2996,12 +2996,12 @@ } #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, 32, 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, 32, digest, NULL); #endif ngx_memcpy(name, key[0].name, 16); @@ -3031,12 +3031,12 @@ (i == 0) ? " (default)" : ""); #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, 32, 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, 32, digest, NULL); #endif if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) { diff -r 92ad1c92bcf9 -r 36f66e94771d src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Fri Nov 04 19:12:19 2016 +0300 +++ b/src/event/ngx_event_openssl.h Mon Nov 07 00:02:18 2016 +0100 @@ -118,8 +118,8 @@ typedef struct { 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 czerny599 at yahoo.com Mon Nov 7 06:54:48 2016 From: czerny599 at yahoo.com (laser) Date: Mon, 7 Nov 2016 06:54:48 +0000 (UTC) Subject: Help on NGINX css/js/image error 18679 In-Reply-To: References: Message-ID: <1595096195.1959252.1478501688681@mail.yahoo.com> Hello, I am getting CSS/JS/IMG error shown below while proxying subdirectory to a domain folder, [error] 13991#13991: *26 open() "/var/www/x1.com/public_html/templates/home/js/script.js" failed (2: No such file or directory), client: 68.5.183.249, server: www.x1.com, request: "GET /templates/home/js/script.js HTTP/1.1", host: "www.x1.com", referrer: "http://www.x1.com/home" I was trying to proxy from a subdomain in a different server to the main domain x1.com's ? x1.com/home subdirectory, and here is my server blocck location ^~ /home? ? ? ? { ? ? ? ? ? ? ? ? proxy_pass http://Z.YYY.com/home; ? ? ? ? ? ? ? ? #Proxy Settings? ? ? ? ? ? ? ? proxy_redirect ? ? off;? ? ? ? ? ? ? ? #proxy_set_header ? Host ? ? ? ? ? ?$http_host;? ? ? ? ? ? ? ? #proxy_set_header ? X-Real-IP ? ? ? ?$remote_addr;? ? ? ? ? ? ? ? #proxy_set_header ? X-Forwarded-For ?$proxy_add_x_forwarded_for;? ? ? ? ? ? ? ??? ? ? ? } Any suggestion will be greatly appreciated. Thanks, On Sunday, November 6, 2016 10:41 PM, "nginx-devel-request at nginx.org" wrote: Welcome to the nginx-devel at nginx.org mailing list! You were successfully subscribed to the mailing list. You'll be able to send message in a few minutes. To post to this list, send your message to: ? nginx-devel at nginx.org General information about the mailing list is at: ? http://mailman.nginx.org/mailman/listinfo/nginx-devel If you ever want to unsubscribe or change your options (eg, switch to or from digest mode, change your password, etc.), visit your subscription page at: ? http://mailman.nginx.org/mailman/options/nginx-devel/czerny599%40yahoo.com You can also make such adjustments via email by sending a message to: ? nginx-devel-request at nginx.org with the word `help' in the subject or body (don't include the quotes), and you will get back a message with instructions. You must know your password to change your options (including changing the password, itself) or to unsubscribe without confirmation.? It is: ? kuang3 Normally, Mailman will remind you of your nginx.org mailing list passwords once every month, although you can disable this if you prefer.? This reminder will also include instructions on how to unsubscribe or change your account options.? There is also a button on your options page that will email your current password to you. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Mon Nov 7 10:23:42 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 7 Nov 2016 13:23:42 +0300 Subject: Help on NGINX css/js/image error 18679 In-Reply-To: <1595096195.1959252.1478501688681@mail.yahoo.com> References: <1595096195.1959252.1478501688681@mail.yahoo.com> Message-ID: <20161107102342.GA73038@mdounin.ru> Hello! On Mon, Nov 07, 2016 at 06:54:48AM +0000, laser via nginx-devel wrote: > Hello, I am getting CSS/JS/IMG error shown below while proxying subdirectory to a domain folder, [error] 13991#13991: *26 open() "/var/www/x1.com/public_html/templates/home/js/script.js" failed (2: No such file or directory), client: 68.5.183.249, server: www.x1.com, request: "GET /templates/home/js/script.js HTTP/1.1", host: "www.x1.com", referrer: "http://www.x1.com/home" > I was trying to proxy from a subdomain in a different server to the main domain x1.com's ? x1.com/home subdirectory, and here is my server blocck > location ^~ /home? ? ? ? { > ? ? ? ? ? ? ? ? proxy_pass http://Z.YYY.com/home; > ? ? ? ? ? ? ? ? #Proxy Settings? ? ? ? ? ? ? ? proxy_redirect ? ? off;? ? ? ? ? ? ? ? #proxy_set_header ? Host ? ? ? ? ? ?$http_host;? ? ? ? ? ? ? ? #proxy_set_header ? X-Real-IP ? ? ? ?$remote_addr;? ? ? ? ? ? ? ? #proxy_set_header ? X-Forwarded-For ?$proxy_add_x_forwarded_for;? ? ? ? ? ? ? ??? ? ? ? } > Any suggestion will be greatly appreciated. Your question doesn't look relevant to the nginx-devel@ mailing list. Please use nginx@ mailing list instead. Thank you. -- Maxim Dounin http://nginx.org/ From hucong.c at foxmail.com Tue Nov 8 14:56:56 2016 From: hucong.c at foxmail.com (=?utf-8?B?6IOh6IGqIChodWNjKQ==?=) Date: Tue, 8 Nov 2016 22:56:56 +0800 Subject: Maybe a little optimization - Yes? Message-ID: Hi, Maybe a little optimization. I am not sure whether nginx intends to do it. And this his is the result of nginx-tests: All tests successful. Files=270, Tests=3328, 259 wallclock secs ( 1.35 usr 0.69 sys + 39.76 cusr 9.54 csys = 51.34 CPU) Result: PASS # HG changeset patch # User hucongcong # Date 1478615841 -28800 # Tue Nov 08 22:37:21 2016 +0800 # Node ID 4eb871095d2703fbc4ef55edd918bfd9a4011610 # Parent 92ad1c92bcf93310bf59447dd581cac37af87adb Optimize some code. *) It is not necessary to traverse *busy and link the *out when *out == NULL. *) Only call ngx_array_init() in main request to avoid extra initialization in subrequest. diff -r 92ad1c92bcf9 -r 4eb871095d27 src/core/ngx_buf.c --- a/src/core/ngx_buf.c Fri Nov 04 19:12:19 2016 +0300 +++ b/src/core/ngx_buf.c Tue Nov 08 22:37:21 2016 +0800 @@ -189,7 +189,7 @@ if (*busy == NULL) { *busy = *out; - } else { + } else if (*out != NULL) { for (cl = *busy; cl->next; cl = cl->next) { /* void */ } cl->next = *out; diff -r 92ad1c92bcf9 -r 4eb871095d27 src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c Fri Nov 04 19:12:19 2016 +0300 +++ b/src/http/modules/ngx_http_range_filter_module.c Tue Nov 08 22:37:21 2016 +0800 @@ -224,12 +224,6 @@ ctx->offset = r->headers_out.content_offset; - if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t)) - != NGX_OK) - { - return NGX_ERROR; - } - ranges = r->single_range ? 1 : clcf->max_ranges; switch (ngx_http_range_parse(r, ctx, ranges)) { @@ -291,6 +285,12 @@ } } + if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t)) + != NGX_OK) + { + return NGX_ERROR; + } + p = r->headers_in.range->value.data + 6; size = 0; content_length = r->headers_out.content_length_n; From vbart at nginx.com Wed Nov 9 09:36:29 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 09 Nov 2016 09:36:29 +0000 Subject: [njs] String.startsWith() and String.endsWith() methods. Message-ID: details: http://hg.nginx.org/njs/rev/cfd1e7ae9a07 branches: changeset: 242:cfd1e7ae9a07 user: Valentin Bartenev date: Wed Nov 09 12:37:59 2016 +0300 description: String.startsWith() and String.endsWith() methods. diffstat: njs/njs_string.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 45 +++++++++++++++++++ 2 files changed, 152 insertions(+), 0 deletions(-) diffs (186 lines): diff -r ad4b6e0b5014 -r cfd1e7ae9a07 njs/njs_string.c --- a/njs/njs_string.c Sun Nov 06 16:03:29 2016 +0300 +++ b/njs/njs_string.c Wed Nov 09 12:37:59 2016 +0300 @@ -83,6 +83,8 @@ static nxt_noinline void njs_string_slic njs_value_t *args, nxt_uint_t nargs); static njs_ret_t njs_string_from_char_code(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); +static njs_ret_t njs_string_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, nxt_bool_t starts); static njs_ret_t njs_string_match_multiple(njs_vm_t *vm, njs_value_t *args, njs_regexp_pattern_t *pattern); static njs_ret_t njs_string_split_part_add(njs_vm_t *vm, njs_array_t *array, @@ -1441,6 +1443,95 @@ done: } +static njs_ret_t +njs_string_prototype_starts_with(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) +{ + return njs_string_starts_or_ends_with(vm, args, nargs, 1); +} + + +static njs_ret_t +njs_string_prototype_ends_with(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) +{ + return njs_string_starts_or_ends_with(vm, args, nargs, 0); +} + + +static njs_ret_t +njs_string_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, nxt_bool_t starts) +{ + ssize_t index, length, search_length; + const u_char *p, *end; + const njs_value_t *retval; + njs_string_prop_t string, search; + + retval = &njs_value_true; + + if (nargs > 1) { + search_length = njs_string_prop(&search, &args[1]); + + if (search_length == 0) { + goto done; + } + + length = njs_string_prop(&string, &args[0]); + + index = (nargs > 2) ? args[2].data.u.number : -1; + + if (starts) { + if (index < 0) { + index = 0; + } + + if (length - index < search_length) { + goto small; + } + + } else { + if (index < 0 || index > length) { + index = length; + } + + index -= search_length; + + if (index < 0) { + goto small; + } + } + + end = string.start + string.size; + + if (string.size == (size_t) length) { + /* Byte or ASCII string. */ + p = string.start + index; + + } else { + /* UTF-8 string. */ + p = njs_string_offset(string.start, end, index); + } + + if ((size_t) (end - p) >= search.size + && memcmp(p, search.start, search.size) == 0) + { + goto done; + } + } + +small: + + retval = &njs_value_false; + +done: + + vm->retval = *retval; + + return NXT_OK; +} + + /* * njs_string_offset() assumes that index is correct * and the optional offset map has been initialized. @@ -3075,6 +3166,22 @@ static const njs_object_prop_t njs_stri NJS_STRING_OBJECT_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("startsWith"), + .value = njs_native_function(njs_string_prototype_starts_with, 0, + NJS_STRING_OBJECT_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG), + }, + + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("endsWith"), + .value = njs_native_function(njs_string_prototype_ends_with, 0, + NJS_STRING_OBJECT_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("toLowerCase"), diff -r ad4b6e0b5014 -r cfd1e7ae9a07 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sun Nov 06 16:03:29 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Nov 09 12:37:59 2016 +0300 @@ -3291,6 +3291,51 @@ static njs_unit_test_t njs_test[] = { nxt_string("'??? ??? ????????'.includes('?????', 9)"), nxt_string("false") }, + { nxt_string("''.startsWith('')"), + nxt_string("true") }, + + { nxt_string("'12345'.startsWith()"), + nxt_string("false") }, + + { nxt_string("'abc'.startsWith('abc')"), + nxt_string("true") }, + + { nxt_string("'abc'.startsWith('abc', 1)"), + nxt_string("false") }, + + { nxt_string("'abc'.startsWith('abc', -1)"), + nxt_string("true") }, + + { nxt_string("'??? ??? ????????'.startsWith('?????', 8)"), + nxt_string("true") }, + + { nxt_string("'??? ??? ????????'.startsWith('?????', 9)"), + nxt_string("false") }, + + { nxt_string("''.endsWith('')"), + nxt_string("true") }, + + { nxt_string("'12345'.endsWith()"), + nxt_string("false") }, + + { nxt_string("'abc'.endsWith('abc')"), + nxt_string("true") }, + + { nxt_string("'abc'.endsWith('abc', 4)"), + nxt_string("true") }, + + { nxt_string("'abc'.endsWith('abc', 1)"), + nxt_string("false") }, + + { nxt_string("'abc'.endsWith('abc', -1)"), + nxt_string("true") }, + + { nxt_string("'??? ??? ????????'.endsWith('?????', 13)"), + nxt_string("true") }, + + { nxt_string("'??? ??? ????????'.endsWith('?????', 14)"), + nxt_string("false") }, + { nxt_string("'ABC'.toLowerCase()"), nxt_string("abc") }, From vbart at nginx.com Wed Nov 9 09:59:26 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 09 Nov 2016 09:59:26 +0000 Subject: [njs] Math.hypot() method. Message-ID: details: http://hg.nginx.org/njs/rev/8e800470d756 branches: changeset: 243:8e800470d756 user: Valentin Bartenev date: Tue Nov 08 22:09:40 2016 +0300 description: Math.hypot() method. diffstat: njs/njs_math.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 21 +++++++++++++++++++++ 2 files changed, 67 insertions(+), 0 deletions(-) diffs (101 lines): diff -r cfd1e7ae9a07 -r 8e800470d756 njs/njs_math.c --- a/njs/njs_math.c Wed Nov 09 12:37:59 2016 +0300 +++ b/njs/njs_math.c Tue Nov 08 22:09:40 2016 +0300 @@ -19,6 +19,7 @@ #include #include #include +#include static njs_ret_t @@ -197,6 +198,44 @@ njs_object_math_floor(njs_vm_t *vm, njs_ static njs_ret_t +njs_object_math_hypot(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + nxt_uint_t i; + + for (i = 1; i < nargs; i++) { + if (!njs_is_numeric(&args[i])) { + vm->frame->trap_scratch.data.u.value = &args[i]; + + return NJS_TRAP_NUMBER_ARG; + } + } + + num = (nargs > 1) ? fabs(args[1].data.u.number) : 0; + + for (i = 2; i < nargs; i++) { + num = hypot(num, args[i].data.u.number); + + if (num == HUGE_VAL) { + /* HUGE_VAL is equal to INFINITY on IEEE-754 systems. */ + + if (nxt_slow_path(errno == ERANGE)) { + vm->exception = &njs_exception_range_error; + return NXT_ERROR; + } + + break; + } + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_log(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -551,6 +590,13 @@ static const njs_object_prop_t njs_math NJS_SKIP_ARG, NJS_NUMBER_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("hypot"), + .value = njs_native_function(njs_object_math_hypot, 0, 0), + }, + { .type = NJS_METHOD, .name = njs_string("log"), diff -r cfd1e7ae9a07 -r 8e800470d756 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Nov 09 12:37:59 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Nov 08 22:09:40 2016 +0300 @@ -5519,6 +5519,27 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.abs('abc')"), nxt_string("NaN") }, + { nxt_string("Math.hypot()"), + nxt_string("0") }, + + { nxt_string("Math.hypot(1, 2, 'abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.hypot(1, NaN, 3)"), + nxt_string("NaN") }, + + { nxt_string("Math.hypot(1, NaN, -Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.hypot(-42)"), + nxt_string("42") }, + + { nxt_string("Math.hypot(8, -15)"), + nxt_string("17") }, + + { nxt_string("Math.hypot(3, -4, 12.0, '84', 132)"), + nxt_string("157") }, + { nxt_string("Math.max()"), nxt_string("-Infinity") }, From vbart at nginx.com Wed Nov 9 11:34:59 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 09 Nov 2016 11:34:59 +0000 Subject: [njs] String.indexOf() and String.includes() simplification. Message-ID: details: http://hg.nginx.org/njs/rev/c8862eb2eb94 branches: changeset: 244:c8862eb2eb94 user: Valentin Bartenev date: Wed Nov 09 14:34:32 2016 +0300 description: String.indexOf() and String.includes() simplification. diffstat: njs/njs_string.c | 16 ++-------------- 1 files changed, 2 insertions(+), 14 deletions(-) diffs (61 lines): diff -r 8e800470d756 -r c8862eb2eb94 njs/njs_string.c --- a/njs/njs_string.c Tue Nov 08 22:09:40 2016 +0300 +++ b/njs/njs_string.c Wed Nov 09 14:34:32 2016 +0300 @@ -1220,10 +1220,6 @@ njs_string_prototype_index_of(njs_vm_t * length = njs_string_prop(&string, &args[0]); search_length = njs_string_prop(&search, &args[1]); - if (length < search_length) { - goto small; - } - index = 0; if (nargs > 2) { @@ -1234,7 +1230,7 @@ njs_string_prototype_index_of(njs_vm_t * } } - if (index < length) { + if (length - index >= search_length) { end = string.start + string.size; if (string.size == (size_t) length) { @@ -1272,8 +1268,6 @@ njs_string_prototype_index_of(njs_vm_t * } } -small: - index = -1; done: @@ -1393,10 +1387,6 @@ njs_string_prototype_includes(njs_vm_t * length = njs_string_prop(&string, &args[0]); - if (length < search_length) { - goto small; - } - index = 0; if (nargs > 2) { @@ -1407,7 +1397,7 @@ njs_string_prototype_includes(njs_vm_t * } } - if (index < length) { + if (length - index >= search_length) { end = string.start + string.size; if (string.size == (size_t) length) { @@ -1431,8 +1421,6 @@ njs_string_prototype_includes(njs_vm_t * } } -small: - retval = &njs_value_false; done: From igor at sysoev.ru Wed Nov 9 12:07:51 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 09 Nov 2016 12:07:51 +0000 Subject: [njs] Style and small miscellaneous fixes. Message-ID: details: http://hg.nginx.org/njs/rev/7a42d1e83ae2 branches: changeset: 245:7a42d1e83ae2 user: Igor Sysoev date: Wed Nov 09 15:04:40 2016 +0300 description: Style and small miscellaneous fixes. diffstat: njs/njs_disassembler.c | 2 +- njs/njs_string.c | 3 +-- njs/njs_vm.c | 14 +++++++------- njs/njs_vm.h | 3 ++- njs/test/njs_unit_test.c | 3 ++- nxt/nxt_rbtree.c | 11 +++-------- nxt/nxt_utf8.h | 1 - nxt/test/random_unit_test.c | 2 +- 8 files changed, 17 insertions(+), 22 deletions(-) diffs (157 lines): diff -r c8862eb2eb94 -r 7a42d1e83ae2 njs/njs_disassembler.c --- a/njs/njs_disassembler.c Wed Nov 09 14:34:32 2016 +0300 +++ b/njs/njs_disassembler.c Wed Nov 09 15:04:40 2016 +0300 @@ -151,7 +151,7 @@ njs_disassembler(njs_vm_t *vm) code = vm->code->start; n = vm->code->items; - while(n != 0) { + while (n != 0) { njs_disassemble(code->start, code->end); code++; n--; diff -r c8862eb2eb94 -r 7a42d1e83ae2 njs/njs_string.c --- a/njs/njs_string.c Wed Nov 09 14:34:32 2016 +0300 +++ b/njs/njs_string.c Wed Nov 09 15:04:40 2016 +0300 @@ -607,7 +607,6 @@ njs_string_prototype_concat(njs_vm_t *vm } for (i = 0; i < nargs; i++) { - if (!njs_is_string(&args[i])) { vm->frame->trap_scratch.data.u.value = &args[i]; @@ -3210,7 +3209,7 @@ static const njs_object_prop_t njs_stri .type = NJS_METHOD, .name = njs_string("match"), .value = njs_native_function(njs_string_prototype_match, 0, - NJS_STRING_ARG, NJS_REGEXP_ARG), + NJS_STRING_OBJECT_ARG, NJS_REGEXP_ARG), }, { diff -r c8862eb2eb94 -r 7a42d1e83ae2 njs/njs_vm.c --- a/njs/njs_vm.c Wed Nov 09 14:34:32 2016 +0300 +++ b/njs/njs_vm.c Wed Nov 09 15:04:40 2016 +0300 @@ -79,10 +79,10 @@ static njs_ret_t njs_object_property_que static njs_ret_t njs_method_private_copy(njs_vm_t *vm, njs_property_query_t *pq); static nxt_noinline uint32_t njs_integer_value(double num); -static nxt_noinline njs_ret_t njs_values_equal(njs_value_t *val1, - njs_value_t *val2); -static nxt_noinline njs_ret_t njs_values_compare(njs_value_t *val1, - njs_value_t *val2); +static nxt_noinline njs_ret_t njs_values_equal(const njs_value_t *val1, + 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_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); @@ -1879,7 +1879,7 @@ njs_vmcode_not_equal(njs_vm_t *vm, njs_v static nxt_noinline njs_ret_t -njs_values_equal(njs_value_t *val1, njs_value_t *val2) +njs_values_equal(const njs_value_t *val1, const njs_value_t *val2) { /* Void and null are equal and not comparable with anything else. */ if (njs_is_null_or_void(val1)) { @@ -1967,7 +1967,7 @@ njs_vmcode_greater_or_equal(njs_vm_t *vm */ static nxt_noinline njs_ret_t -njs_values_compare(njs_value_t *val1, njs_value_t *val2) +njs_values_compare(const njs_value_t *val1, const njs_value_t *val2) { if (nxt_fast_path(njs_is_numeric(val1) || njs_is_numeric(val2))) { @@ -2030,7 +2030,7 @@ njs_vmcode_strict_not_equal(njs_vm_t *vm nxt_noinline nxt_bool_t -njs_values_strict_equal(njs_value_t *val1, njs_value_t *val2) +njs_values_strict_equal(const njs_value_t *val1, const njs_value_t *val2) { size_t size; const u_char *start1, *start2; diff -r c8862eb2eb94 -r 7a42d1e83ae2 njs/njs_vm.h --- a/njs/njs_vm.h Wed Nov 09 14:34:32 2016 +0300 +++ b/njs/njs_vm.h Wed Nov 09 15:04:40 2016 +0300 @@ -1007,7 +1007,8 @@ njs_ret_t njs_vmcode_catch(njs_vm_t *vm, njs_ret_t njs_vmcode_finally(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval); -nxt_bool_t njs_values_strict_equal(njs_value_t *val1, njs_value_t *val2); +nxt_bool_t njs_values_strict_equal(const njs_value_t *val1, + const njs_value_t *val2); njs_ret_t njs_normalize_args(njs_vm_t *vm, njs_value_t *args, uint8_t *args_types, nxt_uint_t nargs); diff -r c8862eb2eb94 -r 7a42d1e83ae2 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Nov 09 14:34:32 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Nov 09 15:04:40 2016 +0300 @@ -6218,10 +6218,11 @@ main(int argc, char **argv) "fibo(32).length"); static nxt_str_t fibo_bytes = nxt_string( + "var a = '\\x80'.toBytes();" "function fibo(n) {" " if (n > 1)" " return fibo(n - 1) + fibo(n - 2)" - " return '\\x80'.toBytes()" + " return a" "}" "fibo(32).length"); diff -r c8862eb2eb94 -r 7a42d1e83ae2 nxt/nxt_rbtree.c --- a/nxt/nxt_rbtree.c Wed Nov 09 14:34:32 2016 +0300 +++ b/nxt/nxt_rbtree.c Wed Nov 09 15:04:40 2016 +0300 @@ -17,7 +17,8 @@ static void nxt_rbtree_insert_fixup(nxt_rbtree_node_t *node); -static void nxt_rbtree_delete_fixup(nxt_rbtree_t *tree, nxt_rbtree_node_t *node); +static void nxt_rbtree_delete_fixup(nxt_rbtree_t *tree, + nxt_rbtree_node_t *node); nxt_inline void nxt_rbtree_left_rotate(nxt_rbtree_node_t *node); nxt_inline void nxt_rbtree_right_rotate(nxt_rbtree_node_t *node); nxt_inline void nxt_rbtree_parent_relink(nxt_rbtree_node_t *subst, @@ -28,13 +29,7 @@ nxt_inline void nxt_rbtree_parent_relink #define NXT_RBTREE_RED 1 -#define nxt_rbtree_set_callback_type(tree, type) \ - (tree)->sentinel.spare = type - -#define nxt_rbtree_has_insertion_callback(tree) \ - ((tree)->sentinel.spare != 0) - -#define nxt_rbtree_comparison_callback(tree) \ +#define nxt_rbtree_comparison_callback(tree) \ ((nxt_rbtree_compare_t) (tree)->sentinel.right) diff -r c8862eb2eb94 -r 7a42d1e83ae2 nxt/nxt_utf8.h --- a/nxt/nxt_utf8.h Wed Nov 09 14:34:32 2016 +0300 +++ b/nxt/nxt_utf8.h Wed Nov 09 15:04:40 2016 +0300 @@ -76,7 +76,6 @@ nxt_utf8_prev(const u_char *p) } - #define nxt_utf8_size(u) \ ((u < 0x80) ? 1 : ((u < 0x0800) ? 2 : ((u < 0x10000) ? 3 : 4))) diff -r c8862eb2eb94 -r 7a42d1e83ae2 nxt/test/random_unit_test.c --- a/nxt/test/random_unit_test.c Wed Nov 09 14:34:32 2016 +0300 +++ b/nxt/test/random_unit_test.c Wed Nov 09 15:04:40 2016 +0300 @@ -15,7 +15,7 @@ static nxt_int_t -random_unit_test() +random_unit_test(void) { nxt_uint_t n; nxt_random_t r; From mdounin at mdounin.ru Wed Nov 9 18:07:30 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 9 Nov 2016 21:07:30 +0300 Subject: Maybe a little optimization - Yes? In-Reply-To: References: Message-ID: <20161109180729.GG73038@mdounin.ru> Hello! On Tue, Nov 08, 2016 at 10:56:56PM +0800, ?? (hucc) wrote: > Hi, > > Maybe a little optimization. I am not sure whether nginx intends to do it. > > And this his is the result of nginx-tests: > All tests successful. > Files=270, Tests=3328, 259 wallclock secs ( 1.35 usr 0.69 sys + 39.76 cusr 9.54 csys = 51.34 CPU) > Result: PASS > > # HG changeset patch > # User hucongcong > # Date 1478615841 -28800 > # Tue Nov 08 22:37:21 2016 +0800 > # Node ID 4eb871095d2703fbc4ef55edd918bfd9a4011610 > # Parent 92ad1c92bcf93310bf59447dd581cac37af87adb > Optimize some code. > > *) It is not necessary to traverse *busy and link the *out when *out == NULL. > *) Only call ngx_array_init() in main request to avoid extra initialization in subrequest. A bulleted list in the patch description is a good indicator that there should be more than one patch. > > diff -r 92ad1c92bcf9 -r 4eb871095d27 src/core/ngx_buf.c > --- a/src/core/ngx_buf.c Fri Nov 04 19:12:19 2016 +0300 > +++ b/src/core/ngx_buf.c Tue Nov 08 22:37:21 2016 +0800 > @@ -189,7 +189,7 @@ > if (*busy == NULL) { > *busy = *out; > > - } else { > + } else if (*out != NULL) { Style: it should be (*out), the "!= NULL" part is not needed. Compare to the "cl->next" test below: > for (cl = *busy; cl->next; cl = cl->next) { /* void */ } > > cl->next = *out; > diff -r 92ad1c92bcf9 -r 4eb871095d27 src/http/modules/ngx_http_range_filter_module.c > --- a/src/http/modules/ngx_http_range_filter_module.c Fri Nov 04 19:12:19 2016 +0300 > +++ b/src/http/modules/ngx_http_range_filter_module.c Tue Nov 08 22:37:21 2016 +0800 > @@ -224,12 +224,6 @@ > > ctx->offset = r->headers_out.content_offset; > > - if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t)) > - != NGX_OK) > - { > - return NGX_ERROR; > - } > - > ranges = r->single_range ? 1 : clcf->max_ranges; > > switch (ngx_http_range_parse(r, ctx, ranges)) { > @@ -291,6 +285,12 @@ > } > } > > + if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t)) > + != NGX_OK) > + { > + return NGX_ERROR; > + } > + > p = r->headers_in.range->value.data + 6; > size = 0; > content_length = r->headers_out.content_length_n; Please use [diff] showfunc=1 in your Mercurial configuration (~/.hgrc) to simplify reading patches. Thanks. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Nov 9 18:20:48 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 9 Nov 2016 21:20:48 +0300 Subject: [PATCH] proxy-protocol dst variables and proxy-proxy-protocol In-Reply-To: References: <1474200506-9206-1-git-send-email-bjornar.ness@gmail.com> Message-ID: <20161109182048.GH73038@mdounin.ru> Hello! On Thu, Nov 03, 2016 at 08:37:04PM +0100, Bj?rnar Ness wrote: > Maxim: what needs change to get this merged? Followup will be mail pp > support, which I saw a patch for today from somone else. If this was a question to me, then the answer is: I'm not convinced this should be merged. For the use case of PROXY protocol bypass a more logical solution would be to avoid removing the PROXY protocol header at all. If one needs to bypass it and extract the information at the same time, something similar to ssl preread as recently implemented in the stream module might be a better solution. If you have some ideas on how to properly support PROXY protocol in mail - please comment on the relevant patch. -- Maxim Dounin http://nginx.org/ From bjornar.ness at gmail.com Wed Nov 9 19:52:14 2016 From: bjornar.ness at gmail.com (=?UTF-8?Q?Bj=C3=B8rnar_Ness?=) Date: Wed, 9 Nov 2016 20:52:14 +0100 Subject: [PATCH] proxy-protocol dst variables and proxy-proxy-protocol In-Reply-To: <20161109182048.GH73038@mdounin.ru> References: <1474200506-9206-1-git-send-email-bjornar.ness@gmail.com> <20161109182048.GH73038@mdounin.ru> Message-ID: On Nov 9, 2016 19:20, "Maxim Dounin" wrote: > > Hello! > > On Thu, Nov 03, 2016 at 08:37:04PM +0100, Bj?rnar Ness wrote: > > > Maxim: what needs change to get this merged? Followup will be mail pp > > support, which I saw a patch for today from somone else. > > If this was a question to me, then the answer is: > > I'm not convinced this should be merged. For the use case of > PROXY protocol bypass a more logical solution would be to avoid > removing the PROXY protocol header at all. If one needs to bypass > it and extract the information at the same time, something similar > to ssl preread as recently implemented in the stream module might > be a better solution. The usecase for getting access to the dst variables is that we have the: external LB -> nginx -> foo setup as mentioned earlier, and we want to take decisions based on the destination inside nginx, this may for example be a multi-brand setup, where the original destination address is a part of the query key to a database. This will allow us to just do database changes, and nginx will immediately be able to "see" for what destination this request was for. The separate, but related usecase is the "proxy-proxy-protocol" usecase, where the upstream also needs the original ip/port src/destination data for logging or decisionmaking. For this reason, I think it is practical to store the proxy protocol header as a whole with ptr's in the connection struct, but I am fine with changing this to inet_addr for example, will be more loc but a little less memory use. > If you have some ideas on how to properly support PROXY protocol > in mail - please comment on the relevant patch. Reason for mentioning it here, is the mail proxy-protocol patch has the functionality mentioned here as a dependency. Both exim and dovecot understands proxy-protocol, and I want to pass it on after the auth is done, hence proxy-proxy-protocol. Regards, -- Bj?rnar From mdounin at mdounin.ru Wed Nov 9 23:52:23 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 10 Nov 2016 02:52:23 +0300 Subject: [PATCH] proxy-protocol dst variables and proxy-proxy-protocol In-Reply-To: References: <1474200506-9206-1-git-send-email-bjornar.ness@gmail.com> <20161109182048.GH73038@mdounin.ru> Message-ID: <20161109235223.GI73038@mdounin.ru> Hello! On Wed, Nov 09, 2016 at 08:52:14PM +0100, Bj?rnar Ness wrote: > On Nov 9, 2016 19:20, "Maxim Dounin" wrote: > > > > Hello! > > > > On Thu, Nov 03, 2016 at 08:37:04PM +0100, Bj?rnar Ness wrote: > > > > > Maxim: what needs change to get this merged? Followup will be mail pp > > > support, which I saw a patch for today from somone else. > > > > If this was a question to me, then the answer is: > > > > I'm not convinced this should be merged. For the use case of > > PROXY protocol bypass a more logical solution would be to avoid > > removing the PROXY protocol header at all. If one needs to bypass > > it and extract the information at the same time, something similar > > to ssl preread as recently implemented in the stream module might > > be a better solution. > > The usecase for getting access to the dst variables is that we have the: > > external LB -> nginx -> foo > > setup as mentioned earlier, and we want to take decisions based on the > destination inside nginx, this may for example be a multi-brand setup, where > the original destination address is a part of the query key to a database. > This will allow us to just do database changes, and nginx will immediately > be able to "see" for what destination this request was for. > > The separate, but related usecase is the "proxy-proxy-protocol" usecase, > where the upstream also needs the original ip/port src/destination data for > logging or decisionmaking. > > For this reason, I think it is practical to store the proxy protocol header as > a whole with ptr's in the connection struct, but I am fine with changing this > to inet_addr for example, will be more loc but a little less memory use. The implementation of PROXY protocol in nginx basically mimics what is available via X-Forwarded-For in http. Extending it with destination data may simplify some use cases. But it will also complicate things and will make other use cases less intuitive. It is also more or less clear that destination can be identified using a separate destination within nginx itself. As previously said, I'm not convinced this should be merged, as suggested changes have obvious downsides in common cases and only beneficial for very specific use cases. > > If you have some ideas on how to properly support PROXY protocol > > in mail - please comment on the relevant patch. > > Reason for mentioning it here, is the mail proxy-protocol patch has the > functionality mentioned here as a dependency. Both exim and dovecot > understands proxy-protocol, and I want to pass it on after the auth is done, > hence proxy-proxy-protocol. Current question is: What "listen ... proxy_protocol" should mean in case of mail. In other modules, it just means that PROXY protocol header is parsed and appropriate variables are available for use. It would be good to have similar meaning in mail, but there are realip module and no variables in mail. In the stream module similar problem was resolved by not introducing "listen ... proxy_protocol" till variables support was added, and by adding realip module at the same time. May be there are better options. I certainly dislike what is currently suggested, that is, just passing an address provided via PROXY protocol to backends via XCLIENT. Introducing PROXY protocol to backends instead of XCLIENT looks as a separate thing. -- Maxim Dounin http://nginx.org/ From bjornar.ness at gmail.com Thu Nov 10 00:06:54 2016 From: bjornar.ness at gmail.com (=?UTF-8?Q?Bj=C3=B8rnar_Ness?=) Date: Thu, 10 Nov 2016 01:06:54 +0100 Subject: [PATCH] proxy-protocol dst variables and proxy-proxy-protocol In-Reply-To: <20161109235223.GI73038@mdounin.ru> References: <1474200506-9206-1-git-send-email-bjornar.ness@gmail.com> <20161109182048.GH73038@mdounin.ru> <20161109235223.GI73038@mdounin.ru> Message-ID: 2016-11-10 0:52 GMT+01:00 Maxim Dounin : > Hello! > > On Wed, Nov 09, 2016 at 08:52:14PM +0100, Bj?rnar Ness wrote: > >> On Nov 9, 2016 19:20, "Maxim Dounin" wrote: > > The implementation of PROXY protocol in nginx basically mimics > what is available via X-Forwarded-For in http. > > Extending it with destination data may simplify some use cases. > But it will also complicate things and will make other use cases > less intuitive. It is also more or less clear that destination > can be identified using a separate destination within nginx > itself.n It is true that the way proxy protocol support in nginx is currently implemented, it discards half of the information available, and only gives us access to the src part. I think this is strange "halfway" implementation anyway. > As previously said, I'm not convinced this should be merged, as > suggested changes have obvious downsides in common cases and only > beneficial for very specific use cases. When one uses proxy-protocol, one allways has something in front that generates it. Using multiple configurations (can be _lots_) and having to do configuration management/reloads/whatever, seems like going backwards. The overhead of this impl if proxy protocol is not used in listed is just a couple ptr's, and can for sure be reduced at the cost of more complex code. >> > If you have some ideas on how to properly support PROXY protocol >> > in mail - please comment on the relevant patch. >> >> Reason for mentioning it here, is the mail proxy-protocol patch has the >> functionality mentioned here as a dependency. Both exim and dovecot >> understands proxy-protocol, and I want to pass it on after the auth is done, >> hence proxy-proxy-protocol. > > Current question is: > > What "listen ... proxy_protocol" should mean in case of mail. In > other modules, it just means that PROXY protocol header is parsed > and appropriate variables are available for use. It would be good > to have similar meaning in mail, but there are realip module and > no variables in mail. But Auth module can get the variables passed via headers, which is certainly a usecase, also, to be able to send same proxy protocol header out as you get in, the proxy-proxy-protocol scenario, it needs to be stored somewhere. This will work seemlessly on both mail, http and stream when proxy-protocol is enabled in both listen and outgoing, think of it as a "transparent smart-proxy" :) > In the stream module similar problem was resolved by not > introducing "listen ... proxy_protocol" till variables support was > added, and by adding realip module at the same time. May be there > are better options. > > I certainly dislike what is currently suggested, that is, just > passing an address provided via PROXY protocol to backends via > XCLIENT. > > Introducing PROXY protocol to backends instead of XCLIENT looks > as a separate thing. I think adding more support for XCLIENT these days is not needed, as the software in common use today supports proxy protocol native. -- Bj(/)rnar From hucong.c at foxmail.com Thu Nov 10 02:30:34 2016 From: hucong.c at foxmail.com (=?utf-8?B?6IOh6IGqIChodWNjKQ==?=) Date: Thu, 10 Nov 2016 10:30:34 +0800 Subject: [PATCH] Core: slight optimization in ngx_chain_update_chains() Message-ID: Hi, I found that sometimes the *out is NULL when i was reading the code of ngx_event_pipe.c . So it is not necessary to traverse *busy when *out == NULL in ngx_chain_update_chains(). # HG changeset patch # User hucongcong # Date 1478744273 -28800 # Thu Nov 10 10:17:53 2016 +0800 # Node ID c7b6269faec0d2ee6b4f4f625db8c219b5d0b010 # Parent 92ad1c92bcf93310bf59447dd581cac37af87adb Core: slight optimization in ngx_chain_update_chains(). It is not necessary to traverse *busy and link the *out when *out == NULL. diff -r 92ad1c92bcf9 -r c7b6269faec0 src/core/ngx_buf.c --- a/src/core/ngx_buf.c Fri Nov 04 19:12:19 2016 +0300 +++ b/src/core/ngx_buf.c Thu Nov 10 10:17:53 2016 +0800 @@ -189,7 +189,7 @@ ngx_chain_update_chains(ngx_pool_t *p, n if (*busy == NULL) { *busy = *out; - } else { + } else if (*out) { for (cl = *busy; cl->next; cl = cl->next) { /* void */ } cl->next = *out; From hucong.c at foxmail.com Thu Nov 10 03:05:38 2016 From: hucong.c at foxmail.com (=?utf-8?B?6IOh6IGqIChodWNjKQ==?=) Date: Thu, 10 Nov 2016 11:05:38 +0800 Subject: [PATCH] Http range_filter: only initialize ctx->ranges in main request. Message-ID: Hi, This is the second patch. But the function name does not show up, actually ngx_http_range_header_filter() shoud intead of @@ -224,12 +224,6 @@ parse: # HG changeset patch # User hucongcong # Date 1478745892 -28800 # Thu Nov 10 10:44:52 2016 +0800 # Node ID 32838ae5fe67e7b3c628458e267a90ea1b4994a7 # Parent c7b6269faec0d2ee6b4f4f625db8c219b5d0b010 Http range_filter: only initialize ctx->ranges in main request. It is not necessary to initialize ctx->ranges in all request, because ctx->ranges in subrequest will be reassigned to ctx->ranges of main request. diff -r c7b6269faec0 -r 32838ae5fe67 src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c Thu Nov 10 10:17:53 2016 +0800 +++ b/src/http/modules/ngx_http_range_filter_module.c Thu Nov 10 10:44:52 2016 +0800 @@ -224,12 +224,6 @@ parse: ctx->offset = r->headers_out.content_offset; - if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t)) - != NGX_OK) - { - return NGX_ERROR; - } - ranges = r->single_range ? 1 : clcf->max_ranges; switch (ngx_http_range_parse(r, ctx, ranges)) { @@ -291,6 +285,12 @@ ngx_http_range_parse(ngx_http_request_t } } + if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t)) + != NGX_OK) + { + return NGX_ERROR; + } + p = r->headers_in.range->value.data + 6; size = 0; content_length = r->headers_out.content_length_n; From vbart at nginx.com Thu Nov 10 12:33:22 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 10 Nov 2016 12:33:22 +0000 Subject: [njs] Fixed building with GCC ASan. Message-ID: details: http://hg.nginx.org/njs/rev/d8b1e2576409 branches: changeset: 246:d8b1e2576409 user: Valentin Bartenev date: Thu Nov 10 15:33:02 2016 +0300 description: Fixed building with GCC ASan. diffstat: nxt/auto/memalign | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diffs (27 lines): diff -r 7a42d1e83ae2 -r d8b1e2576409 nxt/auto/memalign --- a/nxt/auto/memalign Wed Nov 09 15:04:40 2016 +0300 +++ b/nxt/auto/memalign Thu Nov 10 15:33:02 2016 +0300 @@ -18,6 +18,8 @@ nxt_feature_test="#include if (posix_memalign(&p, 4096, 4096) != 0) return 1; + + free(p); return 0; }" . ${NXT_AUTO}feature @@ -35,8 +37,13 @@ if [ $nxt_found = no ]; then nxt_feature_test="#include int main(void) { - if (memalign(4096, 4096) == NULL) + void *p; + + p = memalign(4096, 4096) + if (p == NULL) return 1; + + free(p); return 0; }" . ${NXT_AUTO}feature From vbart at nginx.com Thu Nov 10 13:19:50 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 10 Nov 2016 13:19:50 +0000 Subject: [njs] Fixed building on Solaris after d8b1e2576409. Message-ID: details: http://hg.nginx.org/njs/rev/9f6d26f5f99b branches: changeset: 247:9f6d26f5f99b user: Valentin Bartenev date: Thu Nov 10 16:19:13 2016 +0300 description: Fixed building on Solaris after d8b1e2576409. diffstat: nxt/auto/memalign | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r d8b1e2576409 -r 9f6d26f5f99b nxt/auto/memalign --- a/nxt/auto/memalign Thu Nov 10 15:33:02 2016 +0300 +++ b/nxt/auto/memalign Thu Nov 10 16:19:13 2016 +0300 @@ -39,7 +39,7 @@ if [ $nxt_found = no ]; then int main(void) { void *p; - p = memalign(4096, 4096) + p = memalign(4096, 4096); if (p == NULL) return 1; From vbart at nginx.com Thu Nov 10 13:48:28 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 10 Nov 2016 13:48:28 +0000 Subject: [njs] Removed misused __attribute__((malloc)). Message-ID: details: http://hg.nginx.org/njs/rev/60c2930eb951 branches: changeset: 248:60c2930eb951 user: Valentin Bartenev date: Thu Nov 10 16:47:52 2016 +0300 description: Removed misused __attribute__((malloc)). According to the documentation: | This tells the compiler that a function is malloc-like, i.e., that the | pointer P returned by the function cannot alias any other pointer valid | when the function returns, and moreover no pointers to valid objects | occur in any storage addressed by P. The njs_string_alloc() allocates a storage for a string and makes the storage accessible via the passed "value" argument. The function also returns an intermediate pointer which is used only for string content initialization and then discarded. Since the pointer is not stored anywhere after the initialization, GCC with -O or higher optimisation levels rightfully optimizes out the initialization. diffstat: njs/njs_string.h | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (13 lines): diff -r 9f6d26f5f99b -r 60c2930eb951 njs/njs_string.h --- a/njs/njs_string.h Thu Nov 10 16:19:13 2016 +0300 +++ b/njs/njs_string.h Thu Nov 10 16:47:52 2016 +0300 @@ -112,8 +112,7 @@ njs_string_length(njs_utf8_t utf8, u_cha njs_ret_t njs_string_new(njs_vm_t *vm, njs_value_t *value, const u_char *start, uint32_t size, uint32_t length); u_char *njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint32_t size, - uint32_t length) - NXT_MALLOC_LIKE; + uint32_t length); void njs_string_copy(njs_value_t *dst, njs_value_t *src); njs_ret_t njs_string_validate(njs_vm_t *vm, njs_string_prop_t *string, njs_value_t *value); From mdounin at mdounin.ru Thu Nov 10 14:59:42 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 10 Nov 2016 17:59:42 +0300 Subject: [PATCH] proxy-protocol dst variables and proxy-proxy-protocol In-Reply-To: References: <1474200506-9206-1-git-send-email-bjornar.ness@gmail.com> <20161109182048.GH73038@mdounin.ru> <20161109235223.GI73038@mdounin.ru> Message-ID: <20161110145941.GJ73038@mdounin.ru> Hello! On Thu, Nov 10, 2016 at 01:06:54AM +0100, Bj?rnar Ness wrote: [...] > > Current question is: > > > > What "listen ... proxy_protocol" should mean in case of mail. In > > other modules, it just means that PROXY protocol header is parsed > > and appropriate variables are available for use. It would be good > > to have similar meaning in mail, but there are realip module and > > no variables in mail. > > But Auth module can get the variables passed via headers, which is > certainly a usecase, also, to be able to send same proxy protocol header out > as you get in, the proxy-proxy-protocol scenario, it needs to be > stored somewhere. > This will work seemlessly on both mail, http and stream when proxy-protocol is > enabled in both listen and outgoing, think of it as a "transparent > smart-proxy" :) It looks like then only use case you have in mind is nginx between some frontend which adds a PROXY protocol header and a backend which is able to accept such a header. Certainly this is not the only real use case, but just one of multiple possible ones. Other use cases include: - nginx behind some balancer which adds PROXY protocol, and a backend which doesn't understand PROXY protocol behind it; - nginx in front of a backend which understands PROXY protocol, and nothing in front of nginx. Also, every time I see the word "smart" I start thinking about security problems introduced along the way. > > In the stream module similar problem was resolved by not > > introducing "listen ... proxy_protocol" till variables support was > > added, and by adding realip module at the same time. May be there > > are better options. > > > > I certainly dislike what is currently suggested, that is, just > > passing an address provided via PROXY protocol to backends via > > XCLIENT. > > > > Introducing PROXY protocol to backends instead of XCLIENT looks > > as a separate thing. > > I think adding more support for XCLIENT these days is not needed, as the > software in common use today supports proxy protocol native. This doesn't seem to take into account the fact that PROXY protocol can only pass addresses, while XCLIENT is able to provide various other information like a client login, hostname and so on. -- Maxim Dounin http://nginx.org/ From vbart at nginx.com Thu Nov 10 15:55:09 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 10 Nov 2016 15:55:09 +0000 Subject: [njs] Improved UTF-8 offset map related macros (no functional ch... Message-ID: details: http://hg.nginx.org/njs/rev/187882f1895a branches: changeset: 249:187882f1895a user: Valentin Bartenev date: Thu Nov 10 18:45:10 2016 +0300 description: Improved UTF-8 offset map related macros (no functional changes). diffstat: njs/njs_parser.c | 4 +- njs/njs_string.c | 61 ++++++++++++++++++++++++++----------------------------- njs/njs_string.h | 14 ++++++++++-- njs/njs_vm.c | 2 +- 4 files changed, 43 insertions(+), 38 deletions(-) diffs (250 lines): diff -r 60c2930eb951 -r 187882f1895a njs/njs_parser.c --- a/njs/njs_parser.c Thu Nov 10 16:47:52 2016 +0300 +++ b/njs/njs_parser.c Thu Nov 10 18:45:10 2016 +0300 @@ -1984,7 +1984,7 @@ njs_parser_string_create(njs_vm_t *vm, n if (nxt_fast_path(p != NULL)) { memcpy(p, src->start, src->length); - if (length > NJS_STRING_MAP_OFFSET && (size_t) length != src->length) { + if (length > NJS_STRING_MAP_STRIDE && (size_t) length != src->length) { njs_string_offset_map_init(p, src->length); } @@ -2144,7 +2144,7 @@ njs_parser_escape_string_create(njs_vm_t } if (start != NULL) { - if (length > NJS_STRING_MAP_OFFSET && length != size) { + if (length > NJS_STRING_MAP_STRIDE && length != size) { njs_string_offset_map_init(start, size); } diff -r 60c2930eb951 -r 187882f1895a njs/njs_string.c --- a/njs/njs_string.c Thu Nov 10 16:47:52 2016 +0300 +++ b/njs/njs_string.c Thu Nov 10 18:45:10 2016 +0300 @@ -179,7 +179,7 @@ njs_string_new(njs_vm_t *vm, njs_value_t if (nxt_fast_path(p != NULL)) { memcpy(p, start, size); - if (size != length && length >= NJS_STRING_MAP_OFFSET) { + if (size != length && length >= NJS_STRING_MAP_STRIDE) { njs_string_offset_map_init(p, size); } @@ -216,9 +216,8 @@ njs_string_alloc(njs_vm_t *vm, njs_value value->data.external0 = 0; value->data.string_size = size; - if (size != length && length > NJS_STRING_MAP_OFFSET) { - total = nxt_align_size(size, sizeof(uint32_t)); - total += ((length - 1) / NJS_STRING_MAP_OFFSET) * sizeof(uint32_t); + if (size != length && length > NJS_STRING_MAP_STRIDE) { + total = njs_string_map_offset(size) + njs_string_map_size(length); } else { total = size; @@ -293,14 +292,13 @@ njs_string_validate(njs_vm_t *vm, njs_st return length; } - if (length > NJS_STRING_MAP_OFFSET) { + if (length > NJS_STRING_MAP_STRIDE) { /* * Reallocate the long string with offset map * after the string. */ - new_size = nxt_align_size(size, sizeof(uint32_t)); - new_size += ((length - 1) / NJS_STRING_MAP_OFFSET) - * sizeof(uint32_t); + new_size = njs_string_map_offset(size) + + njs_string_map_size(length); start = nxt_mem_cache_alloc(vm->mem_cache_pool, new_size); if (nxt_slow_path(start == NULL)) { @@ -473,15 +471,15 @@ njs_string_offset_map_init(const u_char const u_char *p, *end; end = start + size; - map = (uint32_t *) nxt_align_ptr(end, sizeof(uint32_t)); + map = njs_string_map_start(end); p = start; n = 0; - offset = NJS_STRING_MAP_OFFSET; + offset = NJS_STRING_MAP_STRIDE; do { if (offset == 0) { map[n++] = p - start; - offset = NJS_STRING_MAP_OFFSET; + offset = NJS_STRING_MAP_STRIDE; } /* The UTF-8 string should be valid since its length is known. */ @@ -651,7 +649,7 @@ njs_string_prototype_concat(njs_vm_t *vm p += string.size; } - if (length >= NJS_STRING_MAP_OFFSET && size != length) { + if (length >= NJS_STRING_MAP_STRIDE && size != length) { njs_string_offset_map_init(start, size); } @@ -685,7 +683,7 @@ njs_string_prototype_from_utf8(njs_vm_t if (length >= 0) { - if (length < NJS_STRING_MAP_OFFSET || (size_t) length == slice.length) { + if (length < NJS_STRING_MAP_STRIDE || (size_t) length == slice.length) { /* ASCII or short UTF-8 string. */ return njs_string_create(vm, &vm->retval, string.start, slice.length, length); @@ -769,7 +767,7 @@ njs_string_prototype_from_bytes(njs_vm_t s = nxt_utf8_encode(s, *p); } - if (slice.length >= NJS_STRING_MAP_OFFSET || size != slice.length) { + if (slice.length >= NJS_STRING_MAP_STRIDE || size != slice.length) { njs_string_offset_map_init(start, size); } } @@ -1530,13 +1528,13 @@ njs_string_offset(const u_char *start, c uint32_t *map; nxt_uint_t skip; - if (index >= NJS_STRING_MAP_OFFSET) { - map = (uint32_t *) nxt_align_ptr(end, sizeof(uint32_t)); - - start += map[index / NJS_STRING_MAP_OFFSET - 1]; + if (index >= NJS_STRING_MAP_STRIDE) { + map = njs_string_map_start(end); + + start += map[index / NJS_STRING_MAP_STRIDE - 1]; } - for (skip = index % NJS_STRING_MAP_OFFSET; skip != 0; skip--) { + for (skip = index % NJS_STRING_MAP_STRIDE; skip != 0; skip--) { start = nxt_utf8_next(start, end); } @@ -1562,16 +1560,16 @@ njs_string_index(njs_string_prop_t *stri last = 0; index = 0; - if (string->length >= NJS_STRING_MAP_OFFSET) { + if (string->length >= NJS_STRING_MAP_STRIDE) { end = string->start + string->size; - map = (uint32_t *) nxt_align_ptr(end, sizeof(uint32_t)); - - while (index + NJS_STRING_MAP_OFFSET < string->length + map = njs_string_map_start(end); + + while (index + NJS_STRING_MAP_STRIDE < string->length && *map <= offset) { last = *map++; - index += NJS_STRING_MAP_OFFSET; + index += NJS_STRING_MAP_STRIDE; } } @@ -1631,7 +1629,7 @@ njs_string_prototype_to_lower_case(njs_v size--; } - if (string.length >= NJS_STRING_MAP_OFFSET) { + if (string.length >= NJS_STRING_MAP_STRIDE) { njs_string_offset_map_init(start, string.size); } } @@ -1683,7 +1681,7 @@ njs_string_prototype_to_upper_case(njs_v size--; } - if (string.length >= NJS_STRING_MAP_OFFSET) { + if (string.length >= NJS_STRING_MAP_STRIDE) { njs_string_offset_map_init(start, string.size); } } @@ -1867,7 +1865,7 @@ njs_string_prototype_repeat(njs_vm_t *vm n--; } - if (length >= NJS_STRING_MAP_OFFSET && size != length) { + if (length >= NJS_STRING_MAP_STRIDE && size != length) { njs_string_offset_map_init(start, size); } @@ -2884,7 +2882,7 @@ njs_string_replace_join(njs_vm_t *vm, nj /* GC: release valid values. */ } - if (length >= NJS_STRING_MAP_OFFSET && size != length) { + if (length >= NJS_STRING_MAP_STRIDE && size != length) { njs_string_offset_map_init(string, size); } @@ -3655,10 +3653,9 @@ njs_value_index(njs_vm_t *vm, njs_parser length = src->data.u.string->length; - if (size != length && length > NJS_STRING_MAP_OFFSET) { - size = nxt_align_size(size, sizeof(uint32_t)); - size += ((length - 1) / NJS_STRING_MAP_OFFSET) - * sizeof(uint32_t); + if (size != length && length > NJS_STRING_MAP_STRIDE) { + size = njs_string_map_offset(size) + + njs_string_map_size(length); } } diff -r 60c2930eb951 -r 187882f1895a njs/njs_string.h --- a/njs/njs_string.h Thu Nov 10 16:47:52 2016 +0300 +++ b/njs/njs_string.h Thu Nov 10 18:45:10 2016 +0300 @@ -31,7 +31,15 @@ * division and remainder operations but no less than 16 because the maximum * length of short string inlined in njs_value_t is less than 16 bytes. */ -#define NJS_STRING_MAP_OFFSET 32 +#define NJS_STRING_MAP_STRIDE 32 + +#define njs_string_map_offset(size) nxt_align_size((size), sizeof(uint32_t)) + +#define njs_string_map_start(p) \ + ((uint32_t *) nxt_align_ptr((p), sizeof(uint32_t))) + +#define njs_string_map_size(length) \ + (((length - 1) / NJS_STRING_MAP_STRIDE) * sizeof(uint32_t)) /* * The JavaScript standard states that strings are stored in UTF-16. @@ -44,7 +52,7 @@ * encoding does not allow to get quickly a character at specified position. * To speed up this search a map of offsets is stored after the UTF-8 string. * The map is aligned to uint32_t and contains byte positions of each - * NJS_STRING_MAP_OFFSET UTF-8 character except zero position. The map + * NJS_STRING_MAP_STRIDE UTF-8 character except zero position. The map * can be allocated and updated on demand. If a string come outside * JavaScript as byte sequnece just to be concatenated or to be used in * regular expressions the offset map is not required. @@ -53,7 +61,7 @@ * 1) if the length is zero hence it is a byte string; * 2) if the size and length are equal so the string contains only ASCII * characters map is not required; - * 3) if the length is less than NJS_STRING_MAP_OFFSET. + * 3) if the length is less than NJS_STRING_MAP_STRIDE. * * The current implementation does not support Unicode surrogate pairs. * If offset in map points to surrogate pair then the previous offset diff -r 60c2930eb951 -r 187882f1895a njs/njs_vm.c --- a/njs/njs_vm.c Thu Nov 10 16:47:52 2016 +0300 +++ b/njs/njs_vm.c Thu Nov 10 18:45:10 2016 +0300 @@ -1556,7 +1556,7 @@ njs_vmcode_addition(njs_vm_t *vm, njs_va (void) memcpy(start, string1.start, string1.size); (void) memcpy(start + string1.size, string2.start, string2.size); - if (length >= NJS_STRING_MAP_OFFSET && size != length) { + if (length >= NJS_STRING_MAP_STRIDE && size != length) { njs_string_offset_map_init(start, size); } From vbart at nginx.com Thu Nov 10 15:55:11 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 10 Nov 2016 15:55:11 +0000 Subject: [njs] On-demand initialization of UTF-8 strings offset map. Message-ID: details: http://hg.nginx.org/njs/rev/adf61ca4267b branches: changeset: 250:adf61ca4267b user: Valentin Bartenev date: Thu Nov 10 18:54:28 2016 +0300 description: On-demand initialization of UTF-8 strings offset map. diffstat: njs/njs_string.c | 70 ++++++++++++++++++++++--------------------------------- njs/njs_string.h | 6 ++-- njs/njs_vm.c | 4 --- 3 files changed, 31 insertions(+), 49 deletions(-) diffs (229 lines): diff -r 187882f1895a -r adf61ca4267b njs/njs_string.c --- a/njs/njs_string.c Thu Nov 10 18:45:10 2016 +0300 +++ b/njs/njs_string.c Thu Nov 10 18:54:28 2016 +0300 @@ -178,11 +178,6 @@ njs_string_new(njs_vm_t *vm, njs_value_t if (nxt_fast_path(p != NULL)) { memcpy(p, start, size); - - if (size != length && length >= NJS_STRING_MAP_STRIDE) { - njs_string_offset_map_init(p, size); - } - return NXT_OK; } @@ -194,7 +189,7 @@ nxt_noinline u_char * njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint32_t size, uint32_t length) { - uint32_t total; + uint32_t total, map_offset, *map; njs_string_t *string; value->type = NJS_STRING; @@ -217,9 +212,11 @@ njs_string_alloc(njs_vm_t *vm, njs_value value->data.string_size = size; if (size != length && length > NJS_STRING_MAP_STRIDE) { - total = njs_string_map_offset(size) + njs_string_map_size(length); + map_offset = njs_string_map_offset(size); + total = map_offset + njs_string_map_size(length); } else { + map_offset = 0; total = size; } @@ -233,6 +230,11 @@ njs_string_alloc(njs_vm_t *vm, njs_value string->length = length; string->retain = 1; + if (map_offset != 0) { + map = (uint32_t *) (string->start + map_offset); + map[0] = 0; + } + return string->start; } @@ -251,15 +253,16 @@ njs_string_copy(njs_value_t *dst, njs_va /* * njs_string_validate() validates an UTF-8 string, evaluates its length, - * sets njs_string_prop_t struct, and initializes offset map if it is required. + * sets njs_string_prop_t struct. */ nxt_noinline njs_ret_t njs_string_validate(njs_vm_t *vm, njs_string_prop_t *string, njs_value_t *value) { - u_char *start; - size_t new_size; - ssize_t size, length; + u_char *start; + size_t new_size, map_offset; + ssize_t size, length; + uint32_t *map; size = value->short_string.size; @@ -297,8 +300,8 @@ njs_string_validate(njs_vm_t *vm, njs_st * Reallocate the long string with offset map * after the string. */ - new_size = njs_string_map_offset(size) - + njs_string_map_size(length); + map_offset = njs_string_map_offset(size); + new_size = map_offset + njs_string_map_size(length); start = nxt_mem_cache_alloc(vm->mem_cache_pool, new_size); if (nxt_slow_path(start == NULL)) { @@ -309,7 +312,8 @@ njs_string_validate(njs_vm_t *vm, njs_st string->start = start; value->data.u.string->start = start; - njs_string_offset_map_init(start, size); + map = (uint32_t *) (start + map_offset); + map[0] = 0; } } @@ -649,10 +653,6 @@ njs_string_prototype_concat(njs_vm_t *vm p += string.size; } - if (length >= NJS_STRING_MAP_STRIDE && size != length) { - njs_string_offset_map_init(start, size); - } - return NXT_OK; } @@ -766,10 +766,6 @@ njs_string_prototype_from_bytes(njs_vm_t for (p = string.start; p < end; p++) { s = nxt_utf8_encode(s, *p); } - - if (slice.length >= NJS_STRING_MAP_STRIDE || size != slice.length) { - njs_string_offset_map_init(start, size); - } } return NXT_OK; @@ -1518,8 +1514,7 @@ done: /* - * njs_string_offset() assumes that index is correct - * and the optional offset map has been initialized. + * njs_string_offset() assumes that index is correct. */ nxt_noinline const u_char * @@ -1531,6 +1526,10 @@ njs_string_offset(const u_char *start, c if (index >= NJS_STRING_MAP_STRIDE) { map = njs_string_map_start(end); + if (map[0] == 0) { + njs_string_offset_map_init(start, end - start); + } + start += map[index / NJS_STRING_MAP_STRIDE - 1]; } @@ -1543,8 +1542,7 @@ njs_string_offset(const u_char *start, c /* - * njs_string_index() assumes that offset is correct - * and the optional offset map has been initialized. + * njs_string_index() assumes that offset is correct. */ nxt_noinline uint32_t @@ -1565,6 +1563,10 @@ njs_string_index(njs_string_prop_t *stri end = string->start + string->size; map = njs_string_map_start(end); + if (map[0] == 0) { + njs_string_offset_map_init(string->start, string->size); + } + while (index + NJS_STRING_MAP_STRIDE < string->length && *map <= offset) { @@ -1628,10 +1630,6 @@ njs_string_prototype_to_lower_case(njs_v p = nxt_utf8_encode(p, nxt_utf8_lower_case(&s, end)); size--; } - - if (string.length >= NJS_STRING_MAP_STRIDE) { - njs_string_offset_map_init(start, string.size); - } } return NXT_OK; @@ -1680,10 +1678,6 @@ njs_string_prototype_to_upper_case(njs_v p = nxt_utf8_encode(p, nxt_utf8_upper_case(&s, end)); size--; } - - if (string.length >= NJS_STRING_MAP_STRIDE) { - njs_string_offset_map_init(start, string.size); - } } return NXT_OK; @@ -1865,10 +1859,6 @@ njs_string_prototype_repeat(njs_vm_t *vm n--; } - if (length >= NJS_STRING_MAP_STRIDE && size != length) { - njs_string_offset_map_init(start, size); - } - return NXT_OK; } @@ -2882,10 +2872,6 @@ njs_string_replace_join(njs_vm_t *vm, nj /* GC: release valid values. */ } - if (length >= NJS_STRING_MAP_STRIDE && size != length) { - njs_string_offset_map_init(string, size); - } - nxt_array_destroy(&r->parts, &njs_array_mem_proto, vm->mem_cache_pool); return NXT_OK; diff -r 187882f1895a -r adf61ca4267b njs/njs_string.h --- a/njs/njs_string.h Thu Nov 10 18:45:10 2016 +0300 +++ b/njs/njs_string.h Thu Nov 10 18:54:28 2016 +0300 @@ -53,9 +53,9 @@ * To speed up this search a map of offsets is stored after the UTF-8 string. * The map is aligned to uint32_t and contains byte positions of each * NJS_STRING_MAP_STRIDE UTF-8 character except zero position. The map - * can be allocated and updated on demand. If a string come outside - * JavaScript as byte sequnece just to be concatenated or to be used in - * regular expressions the offset map is not required. + * can be initialized on demand. If a string come outside JavaScript as + * byte sequnece just to be concatenated or to be used in regular expressions + * the offset map is not required. * * The map is not allocated: * 1) if the length is zero hence it is a byte string; diff -r 187882f1895a -r adf61ca4267b njs/njs_vm.c --- a/njs/njs_vm.c Thu Nov 10 18:45:10 2016 +0300 +++ b/njs/njs_vm.c Thu Nov 10 18:54:28 2016 +0300 @@ -1556,10 +1556,6 @@ njs_vmcode_addition(njs_vm_t *vm, njs_va (void) memcpy(start, string1.start, string1.size); (void) memcpy(start + string1.size, string2.start, string2.size); - if (length >= NJS_STRING_MAP_STRIDE && size != length) { - njs_string_offset_map_init(start, size); - } - return sizeof(njs_vmcode_3addr_t); } From vbart at nginx.com Thu Nov 10 16:18:28 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 10 Nov 2016 16:18:28 +0000 Subject: [njs] Moved njs_string_offset_map_init() closer to its usage. Message-ID: details: http://hg.nginx.org/njs/rev/0939df226d5c branches: changeset: 251:0939df226d5c user: Valentin Bartenev date: Thu Nov 10 19:09:13 2016 +0300 description: Moved njs_string_offset_map_init() closer to its usage. No functional changes. diffstat: njs/njs_string.c | 58 ++++++++++++++++++++++++++++---------------------------- njs/njs_string.h | 2 +- 2 files changed, 30 insertions(+), 30 deletions(-) diffs (94 lines): diff -r adf61ca4267b -r 0939df226d5c njs/njs_string.c --- a/njs/njs_string.c Thu Nov 10 18:54:28 2016 +0300 +++ b/njs/njs_string.c Thu Nov 10 19:09:13 2016 +0300 @@ -466,35 +466,6 @@ njs_string_prototype_length(njs_vm_t *vm } -nxt_noinline void -njs_string_offset_map_init(const u_char *start, size_t size) -{ - size_t offset; - uint32_t *map; - nxt_uint_t n; - const u_char *p, *end; - - end = start + size; - map = njs_string_map_start(end); - p = start; - n = 0; - offset = NJS_STRING_MAP_STRIDE; - - do { - if (offset == 0) { - map[n++] = p - start; - offset = NJS_STRING_MAP_STRIDE; - } - - /* The UTF-8 string should be valid since its length is known. */ - p = nxt_utf8_next(p, end); - - offset--; - - } while (p < end); -} - - nxt_bool_t njs_string_eq(const njs_value_t *v1, const njs_value_t *v2) { @@ -1588,6 +1559,35 @@ njs_string_index(njs_string_prop_t *stri } +nxt_noinline void +njs_string_offset_map_init(const u_char *start, size_t size) +{ + size_t offset; + uint32_t *map; + nxt_uint_t n; + const u_char *p, *end; + + end = start + size; + map = njs_string_map_start(end); + p = start; + n = 0; + offset = NJS_STRING_MAP_STRIDE; + + do { + if (offset == 0) { + map[n++] = p - start; + offset = NJS_STRING_MAP_STRIDE; + } + + /* The UTF-8 string should be valid since its length is known. */ + p = nxt_utf8_next(p, end); + + offset--; + + } while (p < end); +} + + /* * String.toLowerCase(). * The method supports only simple folding. For example, Turkish "?" diff -r adf61ca4267b -r 0939df226d5c njs/njs_string.h --- a/njs/njs_string.h Thu Nov 10 18:54:28 2016 +0300 +++ b/njs/njs_string.h Thu Nov 10 19:09:13 2016 +0300 @@ -128,7 +128,6 @@ nxt_noinline size_t njs_string_prop(njs_ njs_value_t *value); njs_ret_t njs_string_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -void njs_string_offset_map_init(const u_char *start, size_t size); nxt_bool_t njs_string_eq(const njs_value_t *val1, const njs_value_t *val2); nxt_int_t njs_string_cmp(const njs_value_t *val1, const njs_value_t *val2); njs_ret_t njs_string_slice(njs_vm_t *vm, njs_value_t *dst, @@ -137,6 +136,7 @@ const u_char *njs_string_offset(const u_ size_t index); nxt_noinline uint32_t njs_string_index(njs_string_prop_t *string, uint32_t offset); +void njs_string_offset_map_init(const u_char *start, size_t size); njs_ret_t njs_primitive_value_to_string(njs_vm_t *vm, njs_value_t *dst, const njs_value_t *src); double njs_string_to_number(njs_value_t *value, nxt_bool_t exact); From mdounin at mdounin.ru Thu Nov 10 16:55:00 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 10 Nov 2016 19:55:00 +0300 Subject: [PATCH] Core: slight optimization in ngx_chain_update_chains() In-Reply-To: References: Message-ID: <20161110165500.GK73038@mdounin.ru> Hello! On Thu, Nov 10, 2016 at 10:30:34AM +0800, ?? (hucc) wrote: > Hi, > > I found that sometimes the *out is NULL when i was reading the code > of ngx_event_pipe.c . So it is not necessary to traverse *busy when > *out == NULL in ngx_chain_update_chains(). > > # HG changeset patch > # User hucongcong > # Date 1478744273 -28800 > # Thu Nov 10 10:17:53 2016 +0800 > # Node ID c7b6269faec0d2ee6b4f4f625db8c219b5d0b010 > # Parent 92ad1c92bcf93310bf59447dd581cac37af87adb > Core: slight optimization in ngx_chain_update_chains(). > > It is not necessary to traverse *busy and link the *out > when *out == NULL. > > diff -r 92ad1c92bcf9 -r c7b6269faec0 src/core/ngx_buf.c > --- a/src/core/ngx_buf.c Fri Nov 04 19:12:19 2016 +0300 > +++ b/src/core/ngx_buf.c Thu Nov 10 10:17:53 2016 +0800 > @@ -189,7 +189,7 @@ ngx_chain_update_chains(ngx_pool_t *p, n > if (*busy == NULL) { > *busy = *out; > > - } else { > + } else if (*out) { > for (cl = *busy; cl->next; cl = cl->next) { /* void */ } > > cl->next = *out; Looking into this again I tend to think that better solution would be to test *out in additional if around all operations with *out, like this (diff -w for clarity): @@ -186,6 +186,7 @@ ngx_chain_update_chains(ngx_pool_t *p, n { ngx_chain_t *cl; + if (*out) { if (*busy == NULL) { *busy = *out; @@ -196,6 +197,7 @@ ngx_chain_update_chains(ngx_pool_t *p, n } *out = NULL; + } while (*busy) { cl = *busy; Your patch updated to do this: # HG changeset patch # User hucongcong # Date 1478744273 -28800 # Thu Nov 10 10:17:53 2016 +0800 # Node ID 40c2f3e06d2378dea729eae9ddc381928853238d # Parent 92ad1c92bcf93310bf59447dd581cac37af87adb Core: slight optimization in ngx_chain_update_chains(). It is not necessary to traverse *busy and link the *out when *out is NULL. diff --git a/src/core/ngx_buf.c b/src/core/ngx_buf.c --- a/src/core/ngx_buf.c +++ b/src/core/ngx_buf.c @@ -186,17 +186,19 @@ ngx_chain_update_chains(ngx_pool_t *p, n { ngx_chain_t *cl; - if (*busy == NULL) { - *busy = *out; + if (*out) { + if (*busy == NULL) { + *busy = *out; - } else { - for (cl = *busy; cl->next; cl = cl->next) { /* void */ } + } else { + for (cl = *busy; cl->next; cl = cl->next) { /* void */ } - cl->next = *out; + cl->next = *out; + } + + *out = NULL; } - *out = NULL; - while (*busy) { cl = *busy; -- Maxim Dounin http://nginx.org/ From hucong.c at foxmail.com Fri Nov 11 02:38:55 2016 From: hucong.c at foxmail.com (=?utf-8?B?6IOh6IGqIChodWNjKQ==?=) Date: Fri, 11 Nov 2016 10:38:55 +0800 Subject: [PATCH] Core: slight optimization in ngx_chain_update_chains() In-Reply-To: <20161110165500.GK73038@mdounin.ru> References: <20161110165500.GK73038@mdounin.ru> Message-ID: Hello! On Fri, Nov 11, 2016 at 0:55 AM, Maxim Dounin wrote: >Looking into this again I tend to think that better solution would >be to test *out in additional if around all operations with *out, >like this (diff -w for clarity): > >@@ -186,6 +186,7 @@ ngx_chain_update_chains(ngx_pool_t *p, n > { > ngx_chain_t *cl; > >+ if (*out) { > if (*busy == NULL) { > *busy = *out; > >@@ -196,6 +197,7 @@ ngx_chain_update_chains(ngx_pool_t *p, n > } > > *out = NULL; >+ } > > while (*busy) { > cl = *busy; Yes, it`s truly better! Regards, -hucc -------------- next part -------------- An HTML attachment was scrubbed... URL: From xray at randoman.ru Fri Nov 11 05:06:30 2016 From: xray at randoman.ru (Sergey S. Kovalev) Date: Fri, 11 Nov 2016 12:06:30 +0700 Subject: Receiving sockets with SCM_RIGHTS Message-ID: <454b3438-c4b5-4c1f-32f5-ecf3c6d4cdf5@randoman.ru> Hello! Recently I posted a patch for receiving sockets from another processes using SCM_RIGHTS messages. Since there is no observable activity on that, I want to discuss - is it a good idea to have such functionality in nginx core? May be there are some concepts, which I still don't know? Regards, Sergey. From igor at sysoev.ru Fri Nov 11 14:38:45 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 11 Nov 2016 14:38:45 +0000 Subject: [njs] Now the empty regexp pattern is created on compile stage only. Message-ID: details: http://hg.nginx.org/njs/rev/9f66db825663 branches: changeset: 252:9f66db825663 user: Igor Sysoev date: Fri Nov 11 17:28:47 2016 +0300 description: Now the empty regexp pattern is created on compile stage only. This speeds up njs_vm_clone() operation twice. diffstat: njs/njs_builtin.c | 2 +- njs/njs_regexp.c | 31 +++++++++++++++---------------- njs/njs_string.c | 23 ++++++++++++++--------- njs/njs_vm.h | 3 ++- njs/njscript.c | 13 +++++++++++-- 5 files changed, 43 insertions(+), 29 deletions(-) diffs (164 lines): diff -r 0939df226d5c -r 9f66db825663 njs/njs_builtin.c --- a/njs/njs_builtin.c Thu Nov 10 19:09:13 2016 +0300 +++ b/njs/njs_builtin.c Fri Nov 11 17:28:47 2016 +0300 @@ -230,7 +230,7 @@ njs_builtin_objects_create(njs_vm_t *vm) } prototypes[NJS_PROTOTYPE_REGEXP].regexp.pattern = - vm->empty_regexp.data.u.regexp->pattern; + vm->shared->empty_regexp_pattern; constructors = vm->shared->constructors; diff -r 0939df226d5c -r 9f66db825663 njs/njs_regexp.c --- a/njs/njs_regexp.c Thu Nov 10 19:09:13 2016 +0300 +++ b/njs/njs_regexp.c Fri Nov 11 17:28:47 2016 +0300 @@ -65,8 +65,7 @@ njs_regexp_init(njs_vm_t *vm) vm->regex_context->trace = &vm->trace; - return njs_regexp_create(vm, &vm->empty_regexp, (u_char *) "(?:)", - sizeof("(?:)") - 1, 0); + return NXT_OK; } @@ -128,25 +127,25 @@ njs_regexp_create(njs_vm_t *vm, njs_valu if (length != 0) { pattern = njs_regexp_pattern_create(vm, start, length, flags); - - if (nxt_fast_path(pattern != NULL)) { - regexp = njs_regexp_alloc(vm, pattern); - - if (nxt_fast_path(regexp != NULL)) { - value->data.u.regexp = regexp; - value->type = NJS_REGEXP; - value->data.truth = 1; - - return NXT_OK; - } + if (nxt_slow_path(pattern == NULL)) { + return NXT_ERROR; } - return NXT_ERROR; + } else { + pattern = vm->shared->empty_regexp_pattern; } - *value = vm->empty_regexp; + regexp = njs_regexp_alloc(vm, pattern); - return NXT_OK; + if (nxt_fast_path(regexp != NULL)) { + value->data.u.regexp = regexp; + value->type = NJS_REGEXP; + value->data.truth = 1; + + return NXT_OK; + } + + return NXT_ERROR; } diff -r 0939df226d5c -r 9f66db825663 njs/njs_string.c --- a/njs/njs_string.c Thu Nov 10 19:09:13 2016 +0300 +++ b/njs/njs_string.c Fri Nov 11 17:28:47 2016 +0300 @@ -1946,9 +1946,11 @@ njs_string_prototype_match(njs_vm_t *vm, njs_string_prop_t string; njs_regexp_pattern_t *pattern; - arguments[0] = vm->empty_regexp; arguments[1] = args[0]; + string.start = NULL; + string.size = 0; + if (nargs > 1) { if (njs_is_regexp(&args[1])) { @@ -1964,21 +1966,24 @@ njs_string_prototype_match(njs_vm_t *vm, */ arguments[0] = args[1]; - } else if (njs_is_string(&args[1])) { + goto match; + } + + if (njs_is_string(&args[1])) { /* string1.match(string2) is the same as /string2/.exec(string1). */ - (void) njs_string_prop(&string, &args[1]); - - ret = njs_regexp_create(vm, &arguments[0], string.start, - string.size, 0); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } } /* A void value. */ } + ret = njs_regexp_create(vm, &arguments[0], string.start, string.size, 0); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + +match: + return njs_regexp_prototype_exec(vm, arguments, nargs, unused); } diff -r 0939df226d5c -r 9f66db825663 njs/njs_vm.h --- a/njs/njs_vm.h Thu Nov 10 19:09:13 2016 +0300 +++ b/njs/njs_vm.h Fri Nov 11 17:28:47 2016 +0300 @@ -845,7 +845,6 @@ struct njs_vm_s { nxt_regex_context_t *regex_context; nxt_regex_match_data_t *single_match_data; - njs_value_t empty_regexp; nxt_array_t *code; /* of njs_vm_code_t */ @@ -875,6 +874,8 @@ struct njs_vm_shared_s { */ njs_object_prototype_t prototypes[NJS_PROTOTYPE_MAX]; njs_function_t constructors[NJS_CONSTRUCTOR_MAX]; + + njs_regexp_pattern_t *empty_regexp_pattern; }; diff -r 0939df226d5c -r 9f66db825663 njs/njscript.c --- a/njs/njscript.c Thu Nov 10 19:09:13 2016 +0300 +++ b/njs/njscript.c Fri Nov 11 17:28:47 2016 +0300 @@ -102,8 +102,9 @@ njs_vm_t * njs_vm_create(nxt_mem_cache_pool_t *mcp, njs_vm_shared_t **shared, nxt_lvlhsh_t *externals) { - njs_vm_t *vm; - nxt_int_t ret; + njs_vm_t *vm; + nxt_int_t ret; + njs_regexp_pattern_t *pattern; if (mcp == NULL) { mcp = nxt_mem_cache_pool_create(&njs_vm_mem_cache_pool_proto, NULL, @@ -145,6 +146,14 @@ njs_vm_create(nxt_mem_cache_pool_t *mcp, nxt_lvlhsh_init(&vm->shared->values_hash); + pattern = njs_regexp_pattern_create(vm, (u_char *) "(?:)", + sizeof("(?:)") - 1, 0); + if (nxt_slow_path(pattern == NULL)) { + return NULL; + } + + vm->shared->empty_regexp_pattern = pattern; + ret = njs_builtin_objects_create(vm); if (nxt_slow_path(ret != NXT_OK)) { return NULL; From igor at sysoev.ru Fri Nov 11 15:12:40 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 11 Nov 2016 15:12:40 +0000 Subject: [njs] Removed irrelevant overhead in clone/destroy benchmark. Message-ID: details: http://hg.nginx.org/njs/rev/91640c0405f4 branches: changeset: 253:91640c0405f4 user: Igor Sysoev date: Fri Nov 11 18:12:13 2016 +0300 description: Removed irrelevant overhead in clone/destroy benchmark. diffstat: njs/test/njs_unit_test.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r 9f66db825663 -r 91640c0405f4 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Nov 11 17:28:47 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Nov 11 18:12:13 2016 +0300 @@ -6198,8 +6198,8 @@ main(int argc, char **argv) { nxt_bool_t disassemble; - static nxt_str_t script = nxt_string("1"); - static nxt_str_t result = nxt_string("1"); + static nxt_str_t script = nxt_string("null"); + static nxt_str_t result = nxt_string("null"); static nxt_str_t fibo_number = nxt_string( "function fibo(n) {" From mdounin at mdounin.ru Fri Nov 11 19:10:47 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 11 Nov 2016 19:10:47 +0000 Subject: [nginx] Core: slight optimization in ngx_chain_update_chains(). Message-ID: details: http://hg.nginx.org/nginx/rev/40c2f3e06d23 branches: changeset: 6797:40c2f3e06d23 user: hucongcong date: Thu Nov 10 10:17:53 2016 +0800 description: Core: slight optimization in ngx_chain_update_chains(). It is not necessary to traverse *busy and link the *out when *out is NULL. diffstat: src/core/ngx_buf.c | 16 +++++++++------- 1 files changed, 9 insertions(+), 7 deletions(-) diffs (30 lines): diff --git a/src/core/ngx_buf.c b/src/core/ngx_buf.c --- a/src/core/ngx_buf.c +++ b/src/core/ngx_buf.c @@ -186,17 +186,19 @@ ngx_chain_update_chains(ngx_pool_t *p, n { ngx_chain_t *cl; - if (*busy == NULL) { - *busy = *out; + if (*out) { + if (*busy == NULL) { + *busy = *out; - } else { - for (cl = *busy; cl->next; cl = cl->next) { /* void */ } + } else { + for (cl = *busy; cl->next; cl = cl->next) { /* void */ } - cl->next = *out; + cl->next = *out; + } + + *out = NULL; } - *out = NULL; - while (*busy) { cl = *busy; From mdounin at mdounin.ru Fri Nov 11 19:10:50 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 11 Nov 2016 19:10:50 +0000 Subject: [nginx] Range filter: only initialize ctx->ranges in main request. Message-ID: details: http://hg.nginx.org/nginx/rev/2decd6b34306 branches: changeset: 6798:2decd6b34306 user: hucongcong date: Thu Nov 10 10:44:52 2016 +0800 description: Range filter: only initialize ctx->ranges in main request. It is not necessary to initialize ctx->ranges in all request, because ctx->ranges in subrequest will be reassigned to ctx->ranges of main request. diffstat: src/http/modules/ngx_http_range_filter_module.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diffs (29 lines): diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -224,12 +224,6 @@ parse: ctx->offset = r->headers_out.content_offset; - if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t)) - != NGX_OK) - { - return NGX_ERROR; - } - ranges = r->single_range ? 1 : clcf->max_ranges; switch (ngx_http_range_parse(r, ctx, ranges)) { @@ -291,6 +285,12 @@ ngx_http_range_parse(ngx_http_request_t } } + if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t)) + != NGX_OK) + { + return NGX_ERROR; + } + p = r->headers_in.range->value.data + 6; size = 0; content_length = r->headers_out.content_length_n; From mdounin at mdounin.ru Fri Nov 11 19:11:13 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 11 Nov 2016 22:11:13 +0300 Subject: [PATCH] Core: slight optimization in ngx_chain_update_chains() In-Reply-To: References: <20161110165500.GK73038@mdounin.ru> Message-ID: <20161111191113.GL73038@mdounin.ru> Hello! On Fri, Nov 11, 2016 at 10:38:55AM +0800, ?? (hucc) wrote: > Hello! > > > On Fri, Nov 11, 2016 at 0:55 AM, Maxim Dounin wrote: > > >Looking into this again I tend to think that better solution would > >be to test *out in additional if around all operations with *out, > >like this (diff -w for clarity): > > > >@@ -186,6 +186,7 @@ ngx_chain_update_chains(ngx_pool_t *p, n > > { > > ngx_chain_t *cl; > > > >+ if (*out) { > > if (*busy == NULL) { > > *busy = *out; > > > >@@ -196,6 +197,7 @@ ngx_chain_update_chains(ngx_pool_t *p, n > > } > > > > *out = NULL; > >+ } > > > > while (*busy) { > > cl = *busy; > > Yes, it`s truly better! Committed, thanks. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Fri Nov 11 19:13:59 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 11 Nov 2016 22:13:59 +0300 Subject: [PATCH] Http range_filter: only initialize ctx->ranges in main request. In-Reply-To: References: Message-ID: <20161111191358.GM73038@mdounin.ru> Hello! On Thu, Nov 10, 2016 at 11:05:38AM +0800, ?? (hucc) wrote: > Hi, > > This is the second patch. But the function name does not show up, actually > ngx_http_range_header_filter() shoud intead of > @@ -224,12 +224,6 @@ parse: That's fine, "show functions" in fact means "show last line without leading spaces". This still makes reading diffs much easier. > # HG changeset patch > # User hucongcong > # Date 1478745892 -28800 > # Thu Nov 10 10:44:52 2016 +0800 > # Node ID 32838ae5fe67e7b3c628458e267a90ea1b4994a7 > # Parent c7b6269faec0d2ee6b4f4f625db8c219b5d0b010 > Http range_filter: only initialize ctx->ranges in main request. > > It is not necessary to initialize ctx->ranges in all request, because > ctx->ranges in subrequest will be reassigned to ctx->ranges of main > request. > > diff -r c7b6269faec0 -r 32838ae5fe67 src/http/modules/ngx_http_range_filter_module.c > --- a/src/http/modules/ngx_http_range_filter_module.c Thu Nov 10 10:17:53 2016 +0800 > +++ b/src/http/modules/ngx_http_range_filter_module.c Thu Nov 10 10:44:52 2016 +0800 > @@ -224,12 +224,6 @@ parse: > > ctx->offset = r->headers_out.content_offset; > > - if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t)) > - != NGX_OK) > - { > - return NGX_ERROR; > - } > - > ranges = r->single_range ? 1 : clcf->max_ranges; > > switch (ngx_http_range_parse(r, ctx, ranges)) { > @@ -291,6 +285,12 @@ ngx_http_range_parse(ngx_http_request_t > } > } > > + if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t)) > + != NGX_OK) > + { > + return NGX_ERROR; > + } > + > p = r->headers_in.range->value.data + 6; > size = 0; > content_length = r->headers_out.content_length_n; Committed, thanks. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Mon Nov 14 13:55:47 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 14 Nov 2016 16:55:47 +0300 Subject: [PATCH] Follow OpenSSL's switch from AES128 to AES256 for session tickets In-Reply-To: <20161106230940.GA9951@lirum.at> References: <5719a734584d23a6bcd2.1478388248@spencer.quelltextlich.at> <20161106215448.GB27676@lirum.at> <20161106230940.GA9951@lirum.at> Message-ID: <20161114135547.GD8196@mdounin.ru> Hello! On Mon, Nov 07, 2016 at 12:09:40AM +0100, Christian Klinger via nginx-devel wrote: > # HG changeset patch > # User Christian Klinger > # Date 1478473338 -3600 > # Node ID 36f66e94771dd39e8948ba1023e5ca0677655840 > # Parent 92ad1c92bcf93310bf59447dd581cac37af87adb > SSL: switch from AES128 to AES256 for TLS Session Tickets. > > OpenSSL switched from AES128 to AES256 for de-/encryption of session > tickets in May 2016 (commit 05df5c2036f1244fe3df70de7d8079a5d86b999d), > while we still used AES128, if `ssl_session_ticket_key` was set. > > Using AES128 for session tickets means that even when using an AES256 > cipher suite, the session's master key (and hence the whole > connection) is effectively only protected by AES128, which silently > weakens encryption. > > Hence, we follow OpenSSL's lead and switch from AES128 to AES256 for > session tickets, if `ssl_session_ticket_key` is set. > > While the switch from AES128 to AES256 warrants reading additional > 16 bytes from the key file, we nonetheless increase by 32 bytes, > reading a total of 80 bytes instead of previously 48 bytes. > The additional 16 bytes flow into the key for the SHA256 HMAC. > Previously, the SHA256 HMAC only used a 16 byte key, and thereby used > only half of SHA256 HMAC's 32 byte key space. We now provide a 32 byte > key to the SHA256 HMAC and finally fully use the available key space. > > diff -r 92ad1c92bcf9 -r 36f66e94771d src/event/ngx_event_openssl.c > --- a/src/event/ngx_event_openssl.c Fri Nov 04 19:12:19 2016 +0300 > +++ b/src/event/ngx_event_openssl.c Mon Nov 07 00:02:18 2016 +0100 > @@ -2832,7 +2832,7 @@ > 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]; > ssize_t n; > ngx_str_t *path; > ngx_file_t file; > @@ -2875,13 +2875,13 @@ > goto failed; > } > > - if (ngx_file_size(&fi) != 48) { > + if (ngx_file_size(&fi) != 80) { > ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, > - "\"%V\" must be 48 bytes", &file.name); > + "\"%V\" must be 80 bytes", &file.name); > goto failed; > } I don't think that breaking compatibility with previous configurations is a good idea, even for advanced features. And in this particular case it is trivial to preserve one. # HG changeset patch # User Maxim Dounin # Date 1479131639 -10800 # Mon Nov 14 16:53:59 2016 +0300 # Node ID 4e57f6096c0c9c64e8bae0bdc09d892b34db8845 # Parent b5f9e76d4f297a3885d696e8f3af0d84b6a4aaca SSL: support AES256 encryption of tickets. This implies changing ticket key size from 48 to 80 bytes, as both HMAC and AES keys are 32 bytes now. Previous format is still supported though emits a warning. OpenSSL switched to using AES256 in 1.1.0, and so do we. While here, order of HMAC and AES keys reverted to make the implementation compatible with keys used by OpenSSL with SSL_CTX_set_tlsext_ticket_keys(). Prodded by Christian Klinger. 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 @@ -2832,7 +2832,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; @@ -2875,13 +2876,21 @@ ngx_ssl_session_ticket_keys(ngx_conf_t * goto failed; } - if (ngx_file_size(&fi) != 48) { + size = ngx_file_size(&fi); + + if (size == 48) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "\"%V\" uses deprecated 48 bytes format, " + "use 80 bytes instead", + &file.name); + + } else if (size != 80) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"%V\" must be 48 bytes", &file.name); + "\"%V\" must be 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, @@ -2889,10 +2898,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; } @@ -2901,9 +2910,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, @@ -2948,6 +2966,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; @@ -2962,7 +2981,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 @@ -2984,6 +3002,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; @@ -2996,12 +3023,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); @@ -3030,13 +3057,22 @@ ngx_ssl_session_ticket_key_callback(ngx_ ngx_hex_dump(buf, key[i].name, 16) - buf, buf, (i == 0) ? " (default)" : ""); + if (key[0].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 -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Mon Nov 14 14:25:11 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 14 Nov 2016 14:25:11 +0000 Subject: [nginx] Upstream: handling of upstream SSL handshake timeouts. Message-ID: details: http://hg.nginx.org/nginx/rev/d8d037f20484 branches: changeset: 6799:d8d037f20484 user: Maxim Dounin date: Mon Nov 14 17:21:06 2016 +0300 description: Upstream: handling of upstream SSL handshake timeouts. Previously SSL handshake timeouts were not properly logged, and resulted in 502 errors instead of 504 (ticket #1126). diffstat: src/http/ngx_http_upstream.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diffs (17 lines): diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -1666,6 +1666,13 @@ ngx_http_upstream_ssl_handshake(ngx_conn return; } + if (c->write->timedout) { + c = r->connection; + ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); + ngx_http_run_posted_requests(c); + return; + } + failed: c = r->connection; From mdounin at mdounin.ru Tue Nov 15 13:20:42 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 15 Nov 2016 13:20:42 +0000 Subject: [nginx] Fixed a typo, removed an empty line. Message-ID: details: http://hg.nginx.org/nginx/rev/49d7dbd25a27 branches: changeset: 6800:49d7dbd25a27 user: Maxim Dounin date: Mon Nov 14 21:55:44 2016 +0300 description: Fixed a typo, removed an empty line. diffstat: docs/xml/nginx/changes.xml | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (20 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 @@ -790,7 +790,6 @@ and tries to avoid cache keys zone overf ? ????? ????? ?????????? ????????? "task already active" ? "second aio post". - "task already active" and "second aio post" alerts might appear in logs when using the "sendfile" and "aio" directives with subrequests. @@ -18140,7 +18139,7 @@ nginx did not omit the "#fragment" part -POP3 ?????? ???????????? AUTH LOIGN PLAIN ? CRAM-MD5. +POP3 ?????? ???????????? AUTH LOGIN PLAIN ? CRAM-MD5. the POP3 proxy supports the AUTH LOGIN PLAIN and CRAM-MD5. From igor at sysoev.ru Tue Nov 15 15:02:46 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 15 Nov 2016 15:02:46 +0000 Subject: [njs] Native methods and non-constructor functions must throw Message-ID: details: http://hg.nginx.org/njs/rev/d2ab98ea87ad branches: changeset: 254:d2ab98ea87ad user: Igor Sysoev date: Tue Nov 15 17:43:05 2016 +0300 description: Native methods and non-constructor functions must throw TypeError exception if they are called as constructor. diffstat: njs/njs_builtin.c | 1 + njs/njs_vm.c | 22 +++++++++++++++++----- njs/njs_vm.h | 16 +++------------- njs/test/njs_unit_test.c | 6 ++++++ 4 files changed, 27 insertions(+), 18 deletions(-) diffs (127 lines): diff -r 91640c0405f4 -r d2ab98ea87ad njs/njs_builtin.c --- a/njs/njs_builtin.c Fri Nov 11 18:12:13 2016 +0300 +++ b/njs/njs_builtin.c Tue Nov 15 17:43:05 2016 +0300 @@ -237,6 +237,7 @@ njs_builtin_objects_create(njs_vm_t *vm) for (i = NJS_CONSTRUCTOR_OBJECT; i < NJS_CONSTRUCTOR_MAX; i++) { constructors[i].object.shared = 0; constructors[i].native = 1; + constructors[i].ctor = 1; constructors[i].args_offset = 1; constructors[i].u.native = native_constructors[i].native; constructors[i].args_types[0] = native_constructors[i].args_types[0]; diff -r 91640c0405f4 -r d2ab98ea87ad njs/njs_vm.c --- a/njs/njs_vm.c Fri Nov 11 18:12:13 2016 +0300 +++ b/njs/njs_vm.c Tue Nov 15 17:43:05 2016 +0300 @@ -2152,6 +2152,7 @@ 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; @@ -2160,13 +2161,17 @@ njs_vmcode_function_frame(njs_vm_t *vm, 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; + } + ret = njs_function_native_frame(vm, function, &njs_value_void, - NULL, (uintptr_t) nargs, 0, - func->code.ctor); + NULL, (uintptr_t) nargs, 0, ctor); if (nxt_fast_path(ret == NXT_OK)) { return sizeof(njs_vmcode_function_frame_t); @@ -2175,7 +2180,7 @@ njs_vmcode_function_frame(njs_vm_t *vm, return ret; } - if (func->code.ctor) { + if (ctor) { object = njs_function_new_object(vm, value); if (nxt_slow_path(object == NULL)) { return NXT_ERROR; @@ -2191,7 +2196,7 @@ njs_vmcode_function_frame(njs_vm_t *vm, } ret = njs_function_frame(vm, function, this, NULL, (uintptr_t) nargs, - func->code.ctor); + ctor); if (nxt_fast_path(ret == NXT_OK)) { return sizeof(njs_vmcode_function_frame_t); @@ -2200,6 +2205,8 @@ njs_vmcode_function_frame(njs_vm_t *vm, return ret; } +fail: + vm->exception = &njs_exception_type_error; return NXT_ERROR; @@ -2329,8 +2336,13 @@ njs_vmcode_method_call(njs_vm_t *vm, njs 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, method->code.ctor); + 0, 0); if (nxt_fast_path(ret == NXT_OK)) { njs_retain(object); diff -r 91640c0405f4 -r d2ab98ea87ad njs/njs_vm.h --- a/njs/njs_vm.h Fri Nov 11 18:12:13 2016 +0300 +++ b/njs/njs_vm.h Tue Nov 15 17:43:05 2016 +0300 @@ -230,20 +230,10 @@ struct njs_function_s { uint8_t args_types[NJS_ARGS_TYPES_MAX]; uint8_t args_offset; - - /* - * TODO Shared - * When function object is used as value: in assignments, - * as function argument, as property and as object to get properties. - */ + uint8_t continuation_size; -#if (NXT_64BIT) - uint8_t native; - uint8_t continuation_size; -#else - uint8_t native; - uint8_t continuation_size; -#endif + uint8_t native:1; + uint8_t ctor:1; union { njs_function_lambda_t *lambda; diff -r 91640c0405f4 -r d2ab98ea87ad njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Nov 11 18:12:13 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Nov 15 17:43:05 2016 +0300 @@ -4223,6 +4223,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("var F = function (){}; typeof F.prototype"), nxt_string("object") }, + { nxt_string("new decodeURI('%00')"), + nxt_string("TypeError")}, + + { nxt_string("new ''.toString"), + nxt_string("TypeError")}, + { nxt_string("function F() { return Number }" "var o = new (F())(5);" "typeof o +' '+ o"), From mdounin at mdounin.ru Tue Nov 15 15:16:02 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 15 Nov 2016 15:16:02 +0000 Subject: [nginx] nginx-1.11.6-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/5e371426b3bc branches: changeset: 6801:5e371426b3bc user: Maxim Dounin date: Tue Nov 15 18:11:46 2016 +0300 description: nginx-1.11.6-RELEASE diffstat: docs/xml/nginx/changes.xml | 130 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 130 insertions(+), 0 deletions(-) diffs (140 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,136 @@ + + + + +?????? ?????????? $ssl_client_s_dn ? $ssl_client_i_dn +??????? ?? ??????????????? RFC 2253 (RFC 4514); +???????? ? ?????? ??????? ???????? ????? ?????????? +$ssl_client_s_dn_legacy ? $ssl_client_i_dn_legacy. + + +format of the $ssl_client_s_dn and $ssl_client_i_dn variables +has been changed to follow RFC 2253 (RFC 4514); +values in the old format are available in +the $ssl_client_s_dn_legacy and $ssl_client_i_dn_legacy variables. + + + + + +??? ?????????? ????????? ?????? ? ???????? ???? +??? ?????? ????????????? ?? ? ????????? ??????????? ??? ????????? ??????, +? ? ??? ?? ???????????, ??? ? ??????????????? ????? ? ????. + + +when storing temporary files in a cache directory +they will be stored in the same subdirectories as corresponding cache files +instead of a separate subdirectory for temporary files. + + + + + +????????? ?????? ?????????????? EXTERNAL +? ???????? ??????-???????.
+??????? Robert Norris. +
+ +EXTERNAL authentication mechanism support +in mail proxy.
+Thanks to Robert Norris. +
+
+ + + +????????? WebP ? ?????? ngx_http_image_filter_module. + + +WebP support in the ngx_http_image_filter_module. + + + + + +????????? proxy_method ???????????? ??????????.
+??????? ??????? ?????????. +
+ +variables support in the "proxy_method" directive.
+Thanks to Dmitry Lazurkin. +
+
+ + + +????????? http2_max_requests ? ?????? ngx_http_v2_module. + + +the "http2_max_requests" directive in the ngx_http_v2_module. + + + + + +????????? proxy_cache_max_range_offset, fastcgi_cache_max_range_offset, +scgi_cache_max_range_offset ? uwsgi_cache_max_range_offset. + + +the "proxy_cache_max_range_offset", "fastcgi_cache_max_range_offset", +"scgi_cache_max_range_offset", and "uwsgi_cache_max_range_offset" directives. + + + + + +??????? ?????????? ?????? ??????? ????????? ????? ???????? ??????????? ????? +??? ????????????? HTTP/2. + + +graceful shutdown of old worker processes might require infinite time +when using HTTP/2. + + + + + +? ?????? ngx_http_mp4_module. + + +in the ngx_http_mp4_module. + + + + + +??? ????????????? WebSocket-?????????? ? ?????????? ??????????? +? ????? ????? ?????????? ????????? "ignore long locked inactive cache entry". + + +"ignore long locked inactive cache entry" alerts might appear in logs +when proxying WebSocket connections with caching enabled. + + + + + +???? ?? ????? SSL handshake ? ???????? ?????????? ???????, +nginx ?????? ?? ????? ? ??? +? ????????? ????? ? ????? 502 ?????? 504. + + +nginx did not write anything to log +and returned a response with code 502 instead of 504 +when a timeout occurred during an SSL handshake to a backend. + + + +
+ + From mdounin at mdounin.ru Tue Nov 15 15:16:05 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 15 Nov 2016 15:16:05 +0000 Subject: [nginx] release-1.11.6 tag Message-ID: details: http://hg.nginx.org/nginx/rev/6a26016e9a13 branches: changeset: 6802:6a26016e9a13 user: Maxim Dounin date: Tue Nov 15 18:11:46 2016 +0300 description: release-1.11.6 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -404,3 +404,4 @@ 4d3b3a13a8cf5fc3351a7f167d1c13325e00f21c b83a067949a3384a49fd3d943eb8d0997b31f87b release-1.11.3 953512ca02c6f63b4fcbbc3e10d0d9835896bf99 release-1.11.4 5253015a339aaca0a3111473d3e931b6d4752393 release-1.11.5 +5e371426b3bcba4312ce08606194b89b758927d1 release-1.11.6 From igor at sysoev.ru Tue Nov 15 15:28:53 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 15 Nov 2016 15:28:53 +0000 Subject: [njs] Version 0.1.5. Message-ID: details: http://hg.nginx.org/njs/rev/9c813c2bb2ac branches: changeset: 255:9c813c2bb2ac user: Igor Sysoev date: Tue Nov 15 18:28:18 2016 +0300 description: Version 0.1.5. diffstat: Makefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (10 lines): diff -r d2ab98ea87ad -r 9c813c2bb2ac Makefile --- a/Makefile Tue Nov 15 17:43:05 2016 +0300 +++ b/Makefile Tue Nov 15 18:28:18 2016 +0300 @@ -1,5 +1,5 @@ -NJS_VER = 0.1.4 +NJS_VER = 0.1.5 NXT_LIB = nxt From igor at sysoev.ru Tue Nov 15 15:28:55 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 15 Nov 2016 15:28:55 +0000 Subject: [njs] Added tag 0.1.5 for changeset 9c813c2bb2ac Message-ID: details: http://hg.nginx.org/njs/rev/9b9f46b55de2 branches: changeset: 256:9b9f46b55de2 user: Igor Sysoev date: Tue Nov 15 18:28:35 2016 +0300 description: Added tag 0.1.5 for changeset 9c813c2bb2ac diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 9c813c2bb2ac -r 9b9f46b55de2 .hgtags --- a/.hgtags Tue Nov 15 18:28:18 2016 +0300 +++ b/.hgtags Tue Nov 15 18:28:35 2016 +0300 @@ -3,3 +3,4 @@ 0039a747d25a3e08792c23c43b75768896724031 5b066b4db54c17dc0a9a72948474f36957462e87 0.1.2 360449773d51e7f451e5396e27021badc6b86085 0.1.3 508689c1fb94c23f6b24be087c1dc63b2f9e6654 0.1.4 +9c813c2bb2acfd5b6e9d1e9b6699af928baea15a 0.1.5 From vbart at nginx.com Wed Nov 16 09:50:37 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 16 Nov 2016 09:50:37 +0000 Subject: [njs] Unit tests for all Math methods. Message-ID: details: http://hg.nginx.org/njs/rev/87b49eec0c34 branches: changeset: 257:87b49eec0c34 user: Valentin Bartenev date: Wed Nov 16 12:49:52 2016 +0300 description: Unit tests for all Math methods. diffstat: njs/test/njs_unit_test.c | 360 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 360 insertions(+), 0 deletions(-) diffs (398 lines): diff -r 9b9f46b55de2 -r 87b49eec0c34 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Nov 15 18:28:35 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Nov 16 12:49:52 2016 +0300 @@ -5513,6 +5513,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.PI"), nxt_string("3.14159") }, + { nxt_string("Math.abs()"), + nxt_string("NaN") }, + { nxt_string("Math.abs(5)"), nxt_string("5") }, @@ -5525,6 +5528,243 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.abs('abc')"), nxt_string("NaN") }, + { nxt_string("Math.acos()"), + nxt_string("NaN") }, + + { nxt_string("Math.acos(NaN)"), + nxt_string("NaN") }, + + { nxt_string("Math.acos('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.acos(1.1)"), + nxt_string("NaN") }, + + { nxt_string("Math.acos(-1.1)"), + nxt_string("NaN") }, + + { nxt_string("Math.acos('1')"), + nxt_string("0") }, + + { nxt_string("Math.acos(0) - Math.PI/2"), + nxt_string("0") }, + + { nxt_string("Math.asin()"), + nxt_string("NaN") }, + + { nxt_string("Math.asin(NaN)"), + nxt_string("NaN") }, + + { nxt_string("Math.asin('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.asin(1.1)"), + nxt_string("NaN") }, + + { nxt_string("Math.asin(-1.1)"), + nxt_string("NaN") }, + + { nxt_string("Math.asin(0)"), + nxt_string("0") }, + + { nxt_string("Math.asin('-0')"), + nxt_string("-0") }, + + { nxt_string("Math.asin(1) - Math.PI/2"), + nxt_string("0") }, + + { nxt_string("Math.atan()"), + nxt_string("NaN") }, + + { nxt_string("Math.atan(NaN)"), + nxt_string("NaN") }, + + { nxt_string("Math.atan('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.atan('Infinity') - Math.PI/2"), + nxt_string("0") }, + + { nxt_string("Math.atan(-Infinity) + Math.PI/2"), + nxt_string("0") }, + + { nxt_string("Math.atan(0)"), + nxt_string("0") }, + + { nxt_string("Math.atan('-0')"), + nxt_string("-0") }, + + { nxt_string("Math.atan(1) - Math.PI/4"), + nxt_string("0") }, + + { nxt_string("Math.atan2()"), + nxt_string("NaN") }, + + { nxt_string("Math.atan2(1)"), + nxt_string("NaN") }, + + { nxt_string("Math.atan2('abc', 1)"), + nxt_string("NaN") }, + + { nxt_string("Math.atan2(1, 0) - Math.PI/2"), + nxt_string("0") }, + + { nxt_string("Math.atan2('1', -0) - Math.PI/2"), + nxt_string("0") }, + + { nxt_string("Math.atan2(0, '1')"), + nxt_string("0") }, + + { nxt_string("Math.atan2(0, 0)"), + nxt_string("0") }, + + { nxt_string("Math.atan2(0, -0) - Math.PI"), + nxt_string("0") }, + + { nxt_string("Math.atan2('0', -1) - Math.PI"), + nxt_string("0") }, + + { nxt_string("Math.atan2(-0, '0.1')"), + nxt_string("-0") }, + + { nxt_string("Math.atan2(-0, 0)"), + nxt_string("-0") }, + + { nxt_string("Math.atan2(-0, -0) + Math.PI"), + nxt_string("0") }, + + { nxt_string("Math.atan2('-0', '-1') + Math.PI"), + nxt_string("0") }, + + { nxt_string("Math.atan2(-0.1, 0) + Math.PI/2"), + nxt_string("0") }, + + { nxt_string("Math.atan2(-1, -0) + Math.PI/2"), + nxt_string("0") }, + + { nxt_string("Math.atan2(1, 'Infinity')"), + nxt_string("0") }, + + { nxt_string("Math.atan2(0.1, -Infinity) - Math.PI"), + nxt_string("0") }, + + { nxt_string("Math.atan2(-1, Infinity)"), + nxt_string("-0") }, + + { nxt_string("Math.atan2('-0.1', -Infinity) + Math.PI"), + nxt_string("0") }, + + { nxt_string("Math.atan2(Infinity, -5) - Math.PI/2"), + nxt_string("0") }, + + { nxt_string("Math.atan2(-Infinity, 5) + Math.PI/2"), + nxt_string("0") }, + + { nxt_string("Math.atan2('Infinity', 'Infinity') - Math.PI/4"), + nxt_string("0") }, + + { nxt_string("Math.atan2(Infinity, -Infinity) - 3*Math.PI/4"), + nxt_string("0") }, + + { nxt_string("Math.atan2(-Infinity, 'Infinity') + Math.PI/4"), + nxt_string("0") }, + + { nxt_string("Math.atan2('-Infinity', -Infinity) + 3*Math.PI/4"), + nxt_string("0") }, + + { nxt_string("Math.atan2(1, 1) - Math.atan2(-5, -5) - Math.PI"), + nxt_string("0") }, + + { nxt_string("Math.ceil()"), + nxt_string("NaN") }, + + { nxt_string("Math.ceil('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.ceil(0)"), + nxt_string("0") }, + + { nxt_string("Math.ceil('-0')"), + nxt_string("-0") }, + + { nxt_string("Math.ceil('Infinity')"), + nxt_string("Infinity") }, + + { nxt_string("Math.ceil(-Infinity)"), + nxt_string("-Infinity") }, + + { nxt_string("Math.ceil(-0.9)"), + nxt_string("-0") }, + + { nxt_string("Math.ceil(3.1)"), + nxt_string("4") }, + + { nxt_string("Math.cos()"), + nxt_string("NaN") }, + + { nxt_string("Math.cos('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.cos('0')"), + nxt_string("1") }, + + { nxt_string("Math.cos(-0)"), + nxt_string("1") }, + + { nxt_string("Math.cos(Infinity)"), + nxt_string("NaN") }, + + { nxt_string("Math.cos(-Infinity)"), + nxt_string("NaN") }, + + { nxt_string("Math.cos(Math.PI*2)"), + nxt_string("1") }, + + { nxt_string("Math.exp()"), + nxt_string("NaN") }, + + { nxt_string("Math.exp('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.exp('0')"), + nxt_string("1") }, + + { nxt_string("Math.exp(-0)"), + nxt_string("1") }, + + { nxt_string("Math.exp(Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.exp(-Infinity)"), + nxt_string("0") }, + + { nxt_string("Math.exp(1) - Math.E"), + nxt_string("0") }, + + { nxt_string("Math.floor()"), + nxt_string("NaN") }, + + { nxt_string("Math.floor('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.floor(0)"), + nxt_string("0") }, + + { nxt_string("Math.floor('-0')"), + nxt_string("-0") }, + + { nxt_string("Math.floor('Infinity')"), + nxt_string("Infinity") }, + + { nxt_string("Math.floor(-Infinity)"), + nxt_string("-Infinity") }, + + { nxt_string("Math.floor(0.9)"), + nxt_string("0") }, + + { nxt_string("Math.floor(-3.1)"), + nxt_string("-4") }, + { nxt_string("Math.hypot()"), nxt_string("0") }, @@ -5546,6 +5786,30 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.hypot(3, -4, 12.0, '84', 132)"), nxt_string("157") }, + { nxt_string("Math.log()"), + nxt_string("NaN") }, + + { nxt_string("Math.log('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.log(-1)"), + nxt_string("NaN") }, + + { nxt_string("Math.log(0)"), + nxt_string("-Infinity") }, + + { nxt_string("Math.log('-0')"), + nxt_string("-Infinity") }, + + { nxt_string("Math.log(1)"), + nxt_string("0") }, + + { nxt_string("Math.log(Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.log(Math.E)"), + nxt_string("1") }, + { nxt_string("Math.max()"), nxt_string("-Infinity") }, @@ -5579,6 +5843,39 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.pow()"), nxt_string("NaN") }, + { nxt_string("var a = Math.random(); a >= 0 && a < 1"), + nxt_string("true") }, + + { nxt_string("Math.round()"), + nxt_string("NaN") }, + + { nxt_string("Math.round('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.round(0)"), + nxt_string("0") }, + + { nxt_string("Math.round('-0')"), + nxt_string("-0") }, + + { nxt_string("Math.round('Infinity')"), + nxt_string("Infinity") }, + + { nxt_string("Math.round(-Infinity)"), + nxt_string("-Infinity") }, + + { nxt_string("Math.round(0.4)"), + nxt_string("0") }, + + { nxt_string("Math.round('0.5')"), + nxt_string("1") }, + + { nxt_string("Math.round('-0.4')"), + nxt_string("-0") }, + + { nxt_string("Math.round(-0.5)"), + nxt_string("-1") }, + { nxt_string("Math.sign(5)"), nxt_string("1") }, @@ -5597,6 +5894,69 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.sign()"), nxt_string("NaN") }, + { nxt_string("Math.sin()"), + nxt_string("NaN") }, + + { nxt_string("Math.sin('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.sin('0')"), + nxt_string("0") }, + + { nxt_string("Math.sin(-0)"), + nxt_string("-0") }, + + { nxt_string("Math.sin(Infinity)"), + nxt_string("NaN") }, + + { nxt_string("Math.sin(-Infinity)"), + nxt_string("NaN") }, + + { nxt_string("Math.sin(-Math.PI/2)"), + nxt_string("-1") }, + + { nxt_string("Math.sqrt()"), + nxt_string("NaN") }, + + { nxt_string("Math.sqrt('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.sqrt('0')"), + nxt_string("0") }, + + { nxt_string("Math.sqrt(-0)"), + nxt_string("-0") }, + + { nxt_string("Math.sqrt(Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.sqrt(-0.1)"), + nxt_string("NaN") }, + + { nxt_string("Math.sqrt('9.0')"), + nxt_string("3") }, + + { nxt_string("Math.tan()"), + nxt_string("NaN") }, + + { nxt_string("Math.tan('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.tan('0')"), + nxt_string("0") }, + + { nxt_string("Math.tan(-0)"), + nxt_string("-0") }, + + { nxt_string("Math.tan(Infinity)"), + nxt_string("NaN") }, + + { nxt_string("Math.tan(-Infinity)"), + nxt_string("NaN") }, + + { nxt_string("Math.tan(Math.PI/3) + Math.tan(-Math.PI/3)"), + nxt_string("0") }, + { nxt_string("Math.trunc(3.9)"), nxt_string("3") }, From vbart at nginx.com Wed Nov 16 09:50:39 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 16 Nov 2016 09:50:39 +0000 Subject: [njs] Refactored Math methods. Message-ID: details: http://hg.nginx.org/njs/rev/56bf74dccca1 branches: changeset: 258:56bf74dccca1 user: Valentin Bartenev date: Wed Nov 16 12:49:53 2016 +0300 description: Refactored Math methods. diffstat: njs/njs_math.c | 94 ++++++++++++++++++++++++++++----------------------------- 1 files changed, 46 insertions(+), 48 deletions(-) diffs (287 lines): diff -r 87b49eec0c34 -r 56bf74dccca1 njs/njs_math.c --- a/njs/njs_math.c Wed Nov 16 12:49:52 2016 +0300 +++ b/njs/njs_math.c Wed Nov 16 12:49:53 2016 +0300 @@ -29,13 +29,13 @@ njs_object_math_abs(njs_vm_t *vm, njs_va double num; if (nargs > 1) { - num = args[1].data.u.number; + num = fabs(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, fabs(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -48,13 +48,13 @@ njs_object_math_acos(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = args[1].data.u.number; + num = acos(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, acos(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -67,13 +67,13 @@ njs_object_math_asin(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = args[1].data.u.number; + num = asin(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, asin(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -86,13 +86,13 @@ njs_object_math_atan(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = args[1].data.u.number; + num = atan(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, atan(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -102,20 +102,19 @@ static njs_ret_t njs_object_math_atan2(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - double y, x; + double num, y, x; - y = NAN; - x = NAN; + if (nargs > 2) { + y = args[1].data.u.number; + x = args[2].data.u.number; - if (nargs > 1) { - y = args[1].data.u.number; + num = atan2(y, x); + + } else { + num = NAN; } - if (nargs > 2) { - x = args[2].data.u.number; - } - - njs_number_set(&vm->retval, atan2(y, x)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -128,13 +127,13 @@ njs_object_math_ceil(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = args[1].data.u.number; + num = ceil(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, ceil(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -147,13 +146,13 @@ njs_object_math_cos(njs_vm_t *vm, njs_va double num; if (nargs > 1) { - num = args[1].data.u.number; + num = cos(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, cos(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -166,13 +165,13 @@ njs_object_math_exp(njs_vm_t *vm, njs_va double num; if (nargs > 1) { - num = args[1].data.u.number; + num = exp(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, exp(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -185,13 +184,13 @@ njs_object_math_floor(njs_vm_t *vm, njs_ double num; if (nargs > 1) { - num = args[1].data.u.number; + num = floor(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, floor(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -242,13 +241,13 @@ njs_object_math_log(njs_vm_t *vm, njs_va double num; if (nargs > 1) { - num = args[1].data.u.number; + num = log(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, log(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -320,20 +319,19 @@ static njs_ret_t njs_object_math_pow(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - double base, exponent; + double num, base, exponent; - base = NAN; - exponent = NAN; + if (nargs > 2) { + base = args[1].data.u.number; + exponent = args[2].data.u.number; - if (nargs > 1) { - base = args[1].data.u.number; + num = pow(base, exponent); + + } else { + num = NAN; } - if (nargs > 2) { - exponent = args[2].data.u.number; - } - - njs_number_set(&vm->retval, pow(base, exponent)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -360,13 +358,13 @@ njs_object_math_round(njs_vm_t *vm, njs_ double num; if (nargs > 1) { - num = args[1].data.u.number; + num = round(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, round(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -402,13 +400,13 @@ njs_object_math_sin(njs_vm_t *vm, njs_va double num; if (nargs > 1) { - num = args[1].data.u.number; + num = sin(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, sin(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -421,13 +419,13 @@ njs_object_math_sqrt(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = args[1].data.u.number; + num = sqrt(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, sqrt(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -440,13 +438,13 @@ njs_object_math_tan(njs_vm_t *vm, njs_va double num; if (nargs > 1) { - num = args[1].data.u.number; + num = tan(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, tan(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } @@ -459,13 +457,13 @@ njs_object_math_trunc(njs_vm_t *vm, njs_ double num; if (nargs > 1) { - num = args[1].data.u.number; + num = trunc(args[1].data.u.number); } else { num = NAN; } - njs_number_set(&vm->retval, trunc(num)); + njs_number_set(&vm->retval, num); return NXT_OK; } From vbart at nginx.com Wed Nov 16 09:50:41 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 16 Nov 2016 09:50:41 +0000 Subject: [njs] Removed checking for range errors in Math.hypot(). Message-ID: details: http://hg.nginx.org/njs/rev/8253ecba7ad6 branches: changeset: 259:8253ecba7ad6 user: Valentin Bartenev date: Wed Nov 16 12:49:53 2016 +0300 description: Removed checking for range errors in Math.hypot(). It seems other interpreters do not return an exception in this case. diffstat: njs/njs_math.c | 10 +--------- 1 files changed, 1 insertions(+), 9 deletions(-) diffs (27 lines): diff -r 56bf74dccca1 -r 8253ecba7ad6 njs/njs_math.c --- a/njs/njs_math.c Wed Nov 16 12:49:53 2016 +0300 +++ b/njs/njs_math.c Wed Nov 16 12:49:53 2016 +0300 @@ -19,7 +19,6 @@ #include #include #include -#include static njs_ret_t @@ -216,14 +215,7 @@ njs_object_math_hypot(njs_vm_t *vm, njs_ for (i = 2; i < nargs; i++) { num = hypot(num, args[i].data.u.number); - if (num == HUGE_VAL) { - /* HUGE_VAL is equal to INFINITY on IEEE-754 systems. */ - - if (nxt_slow_path(errno == ERANGE)) { - vm->exception = &njs_exception_range_error; - return NXT_ERROR; - } - + if (num == INFINITY) { break; } } From igor at sysoev.ru Wed Nov 16 12:22:07 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 16 Nov 2016 12:22:07 +0000 Subject: [njs] Fixed unit tests on FreeBSD. Message-ID: details: http://hg.nginx.org/njs/rev/73e4b9ddb4df branches: changeset: 260:73e4b9ddb4df user: Igor Sysoev date: Wed Nov 16 15:21:03 2016 +0300 description: Fixed unit tests on FreeBSD. diffstat: njs/test/njs_unit_test.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (18 lines): diff -r 8253ecba7ad6 -r 73e4b9ddb4df njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Nov 16 12:49:53 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Nov 16 15:21:03 2016 +0300 @@ -5738,8 +5738,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.exp(-Infinity)"), nxt_string("0") }, - { nxt_string("Math.exp(1) - Math.E"), - nxt_string("0") }, + /* + * The difference is 2 * Number.EPSILON on FreeBSD + * and zero on other platforms. + */ + { nxt_string("Math.exp(1) - Math.E <= 2 * Number.EPSILON"), + nxt_string("true") }, { nxt_string("Math.floor()"), nxt_string("NaN") }, From igor at sysoev.ru Wed Nov 16 12:22:09 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 16 Nov 2016 12:22:09 +0000 Subject: [njs] A workround for Solaris bugs in acos() and asin(). Message-ID: details: http://hg.nginx.org/njs/rev/f402a8c64d7a branches: changeset: 261:f402a8c64d7a user: Igor Sysoev date: Wed Nov 16 15:21:07 2016 +0300 description: A workround for Solaris bugs in acos() and asin(). diffstat: njs/njs_math.c | 22 ++++++++++++++++++++-- 1 files changed, 20 insertions(+), 2 deletions(-) diffs (39 lines): diff -r 73e4b9ddb4df -r f402a8c64d7a njs/njs_math.c --- a/njs/njs_math.c Wed Nov 16 15:21:03 2016 +0300 +++ b/njs/njs_math.c Wed Nov 16 15:21:07 2016 +0300 @@ -47,7 +47,16 @@ njs_object_math_acos(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = acos(args[1].data.u.number); + num = args[1].data.u.number; + +#if (NXT_SOLARIS) + /* On Solaris acos(x) returns 0 for x > 1. */ + if (fabs(num) > 1.0) { + num = NAN; + } +#endif + + num = acos(num); } else { num = NAN; @@ -66,7 +75,16 @@ njs_object_math_asin(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = asin(args[1].data.u.number); + num = args[1].data.u.number; + +#if (NXT_SOLARIS) + /* On Solaris asin(x) returns 0 for x > 1. */ + if (fabs(num) > 1.0) { + num = NAN; + } +#endif + + num = asin(num); } else { num = NAN; From sasha at instartlogic.com Thu Nov 17 00:36:12 2016 From: sasha at instartlogic.com (Aleksandr Kupriyanov) Date: Wed, 16 Nov 2016 18:36:12 -0600 Subject: Add directive to allow underscores in hostnames Message-ID: -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- # HG changeset patch # User Aleksandr Kupriyanov # Date 1479340749 21600 # Node ID af947b854971993f318417c70c3818147b320a0d # Parent 6a26016e9a138102798a7ec3e74747fbd6018f82 Add directive to allow underscores in hostnames Two equivalent requests generate different responses: 1. --------------- GET http://host_1.home/ HTTP/1.1 Host: host_1.home ... HTTP/1.1 400 Bad Request Server: nginx/1.X.XX ------------------ 2. --------------- GET / HTTP/1.1 Host: host_1.home ... HTTP/1.1 200 OK Server: nginx/1.X.XX ------------------ To avoid that a new directive is proposed: Syntax: underscores_in_hostname on | off; Default: underscores_in_headers off; Context: http, server Enables or disables the use of underscores in host names of client request line. See a discussion about underscores in DNS here: http://domainkeys.sourceforge.net/underscore.html diff -r 6a26016e9a13 -r af947b854971 src/http/ngx_http.h --- a/src/http/ngx_http.h Tue Nov 15 18:11:46 2016 +0300 +++ b/src/http/ngx_http.h Wed Nov 16 17:59:09 2016 -0600 @@ -89,7 +89,8 @@ int ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg); #endif -ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b); +ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b, + ngx_uint_t underscores_in_hostname); ngx_int_t ngx_http_parse_uri(ngx_http_request_t *r); ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes); diff -r 6a26016e9a13 -r af947b854971 src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Tue Nov 15 18:11:46 2016 +0300 +++ b/src/http/ngx_http_core_module.c Wed Nov 16 17:59:09 2016 -0600 @@ -264,6 +264,13 @@ offsetof(ngx_http_core_srv_conf_t, underscores_in_headers), NULL }, + { ngx_string("underscores_in_hostname"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_core_srv_conf_t, underscores_in_hostname), + NULL }, + { ngx_string("location"), NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, ngx_http_core_location, @@ -3420,6 +3427,7 @@ cscf->ignore_invalid_headers = NGX_CONF_UNSET; cscf->merge_slashes = NGX_CONF_UNSET; cscf->underscores_in_headers = NGX_CONF_UNSET; + cscf->underscores_in_hostname = NGX_CONF_UNSET; return cscf; } @@ -3463,6 +3471,9 @@ ngx_conf_merge_value(conf->underscores_in_headers, prev->underscores_in_headers, 0); + ngx_conf_merge_value(conf->underscores_in_hostname, + prev->underscores_in_hostname, 0); + if (conf->server_names.nelts == 0) { /* the array has 4 empty preallocated elements, so push cannot fail */ sn = ngx_array_push(&conf->server_names); diff -r 6a26016e9a13 -r af947b854971 src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h Tue Nov 15 18:11:46 2016 +0300 +++ b/src/http/ngx_http_core_module.h Wed Nov 16 17:59:09 2016 -0600 @@ -192,6 +192,7 @@ ngx_flag_t ignore_invalid_headers; ngx_flag_t merge_slashes; ngx_flag_t underscores_in_headers; + ngx_flag_t underscores_in_hostname; unsigned listen:1; #if (NGX_PCRE) diff -r 6a26016e9a13 -r af947b854971 src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c Tue Nov 15 18:11:46 2016 +0300 +++ b/src/http/ngx_http_parse.c Wed Nov 16 17:59:09 2016 -0600 @@ -101,7 +101,8 @@ /* gcc, icc, msvc and others compile these switches as an jump table */ ngx_int_t -ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b) +ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b, + ngx_uint_t underscores_in_hostname) { u_char c, ch, *p, *m; enum { @@ -357,7 +358,8 @@ break; } - if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-') { + if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-' || + (ch == '_' && underscores_in_hostname)) { break; } diff -r 6a26016e9a13 -r af947b854971 src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Tue Nov 15 18:11:46 2016 +0300 +++ b/src/http/ngx_http_request.c Wed Nov 16 17:59:09 2016 -0600 @@ -922,6 +922,7 @@ ngx_str_t host; ngx_connection_t *c; ngx_http_request_t *r; + ngx_http_core_srv_conf_t *cscf; c = rev->data; r = c->data; @@ -948,7 +949,10 @@ } } - rc = ngx_http_parse_request_line(r, r->header_in); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); + + rc = ngx_http_parse_request_line(r, r->header_in, + cscf->underscores_in_hostname); if (rc == NGX_OK) { From mdounin at mdounin.ru Thu Nov 17 17:10:15 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 17 Nov 2016 20:10:15 +0300 Subject: Add directive to allow underscores in hostnames In-Reply-To: References: Message-ID: <20161117171014.GB8196@mdounin.ru> Hello! On Wed, Nov 16, 2016 at 06:36:12PM -0600, Aleksandr Kupriyanov wrote: > > # HG changeset patch > # User Aleksandr Kupriyanov > # Date 1479340749 21600 > # Node ID af947b854971993f318417c70c3818147b320a0d > # Parent 6a26016e9a138102798a7ec3e74747fbd6018f82 > Add directive to allow underscores in hostnames > > Two equivalent requests generate different responses: > > 1. --------------- > GET http://host_1.home/ HTTP/1.1 > Host: host_1.home > ... > HTTP/1.1 400 Bad Request > Server: nginx/1.X.XX > ------------------ > > 2. --------------- > GET / HTTP/1.1 > Host: host_1.home > ... > HTTP/1.1 200 OK > Server: nginx/1.X.XX > ------------------ > > To avoid that a new directive is proposed: > > Syntax: underscores_in_hostname on | off; > Default: underscores_in_headers off; > Context: http, server > > Enables or disables the use of underscores in host names of > client request line. > > See a discussion about underscores in DNS here: > http://domainkeys.sourceforge.net/underscore.html Shouldn't we just allow underscores in ngx_http_parse_request_line() instead? It doesn't looks like there are reasons to keep the test that strict. In case of underscores_in_headers there a clear security reason: headers are exposed via the HTTP_* variables in CGI, and via $http_* variables in nginx itself, and this makes headers with underscores indistinguishable from ones with dash, and creates an attack vector. I don't see such a problem with underscores in hostname when it's passed via the request line - especially keeping in mind that we don't enforce such a limitation via the Host header. -- Maxim Dounin http://nginx.org/ From sasha at instartlogic.com Thu Nov 17 17:35:40 2016 From: sasha at instartlogic.com (Aleksandr Kupriyanov) Date: Thu, 17 Nov 2016 11:35:40 -0600 Subject: Add directive to allow underscores in hostnames In-Reply-To: <20161117171014.GB8196@mdounin.ru> References: <20161117171014.GB8196@mdounin.ru> Message-ID: I totally agree. Actually, i was going to submit only a fix with allowing underscores in ngx_http_parse_request_line() . But there were some doubts... On Thu, Nov 17, 2016 at 11:10 AM, Maxim Dounin wrote: > Hello! > > On Wed, Nov 16, 2016 at 06:36:12PM -0600, Aleksandr Kupriyanov wrote: > > > com%2F&sa=D&sntz=1&usg=AFrqEzc4puDXYOgyifEWrSJrJIfW1sViFg> > > > # HG changeset patch > > # User Aleksandr Kupriyanov > > # Date 1479340749 21600 > > # Node ID af947b854971993f318417c70c3818147b320a0d > > # Parent 6a26016e9a138102798a7ec3e74747fbd6018f82 > > Add directive to allow underscores in hostnames > > > > Two equivalent requests generate different responses: > > > > 1. --------------- > > GET http://host_1.home/ HTTP/1.1 > > Host: host_1.home > > ... > > HTTP/1.1 400 Bad Request > > Server: nginx/1.X.XX > > ------------------ > > > > 2. --------------- > > GET / HTTP/1.1 > > Host: host_1.home > > ... > > HTTP/1.1 200 OK > > Server: nginx/1.X.XX > > ------------------ > > > > To avoid that a new directive is proposed: > > > > Syntax: underscores_in_hostname on | off; > > Default: underscores_in_headers off; > > Context: http, server > > > > Enables or disables the use of underscores in host names of > > client request line. > > > > See a discussion about underscores in DNS here: > > http://domainkeys.sourceforge.net/underscore.html > > Shouldn't we just allow underscores in > ngx_http_parse_request_line() instead? It doesn't looks like > there are reasons to keep the test that strict. > > In case of underscores_in_headers there a clear security reason: > headers are exposed via the HTTP_* variables in CGI, and via > $http_* variables in nginx itself, and this makes headers with > underscores indistinguishable from ones with dash, and creates an > attack vector. > > I don't see such a problem with underscores in hostname when it's > passed via the request line - especially keeping in mind that we > don't enforce such a limitation via the Host header. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- World's First Endpoint-Aware Application Delivery Solution *Aleksandr **Kupriyanov* Email: sasha at instartlogic.com Instart Logic | 450 Lambert Ave, Palo Alto, CA 94306 | instartlogic.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From teward at dark-net.net Thu Nov 17 18:21:30 2016 From: teward at dark-net.net (Thomas Ward) Date: Thu, 17 Nov 2016 13:21:30 -0500 Subject: Add directive to allow underscores in hostnames In-Reply-To: <20161117171014.GB8196@mdounin.ru> References: <20161117171014.GB8196@mdounin.ru> Message-ID: Correct me if I am wrong but the discussion of underscores in DNS does not apply to hostnames. The discussion referenced states as such, and only touches on underscores as a part of DNS attributes and internals, not as part of hostnames. It even says as such that hostnames are *not permitted* to have underscores. By extension of that, should not the Host header should be a hostname or a requested hostname and therefore obey the requirements for a Hostname at the bare minimum? *Sent from my iPhone. Please excuse any typos, as they are likely to happen by accident.* > On Nov 17, 2016, at 12:10, Maxim Dounin wrote: > > Hello! > >> On Wed, Nov 16, 2016 at 06:36:12PM -0600, Aleksandr Kupriyanov wrote: >> >> > >> # HG changeset patch >> # User Aleksandr Kupriyanov >> # Date 1479340749 21600 >> # Node ID af947b854971993f318417c70c3818147b320a0d >> # Parent 6a26016e9a138102798a7ec3e74747fbd6018f82 >> Add directive to allow underscores in hostnames >> >> Two equivalent requests generate different responses: >> >> 1. --------------- >> GET http://host_1.home/ HTTP/1.1 >> Host: host_1.home >> ... >> HTTP/1.1 400 Bad Request >> Server: nginx/1.X.XX >> ------------------ >> >> 2. --------------- >> GET / HTTP/1.1 >> Host: host_1.home >> ... >> HTTP/1.1 200 OK >> Server: nginx/1.X.XX >> ------------------ >> >> To avoid that a new directive is proposed: >> >> Syntax: underscores_in_hostname on | off; >> Default: underscores_in_headers off; >> Context: http, server >> >> Enables or disables the use of underscores in host names of >> client request line. >> >> See a discussion about underscores in DNS here: >> http://domainkeys.sourceforge.net/underscore.html > > Shouldn't we just allow underscores in > ngx_http_parse_request_line() instead? It doesn't looks like > there are reasons to keep the test that strict. > > In case of underscores_in_headers there a clear security reason: > headers are exposed via the HTTP_* variables in CGI, and via > $http_* variables in nginx itself, and this makes headers with > underscores indistinguishable from ones with dash, and creates an > attack vector. > > I don't see such a problem with underscores in hostname when it's > passed via the request line - especially keeping in mind that we > don't enforce such a limitation via the Host header. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From sasha at instartlogic.com Thu Nov 17 18:34:03 2016 From: sasha at instartlogic.com (Aleksandr Kupriyanov) Date: Thu, 17 Nov 2016 12:34:03 -0600 Subject: Add directive to allow underscores in hostnames In-Reply-To: References: <20161117171014.GB8196@mdounin.ru> Message-ID: De facto, some "big guys" already use underscores in their host names: sasha at kernel.home:~$ host cow_fb_cdn0-a.akamaihd.net cow_fb_cdn0-a.akamaihd.net is an alias for cow_fb_cdn0-a.akamaihd.net.edgesuite.net. cow_fb_cdn0-a.akamaihd.net.edgesuite.net is an alias for a1877.g.akamai.net. a1877.g.akamai.net has address 104.73.160.114 a1877.g.akamai.net has address 104.73.160.64 sasha at kernel.home:~$ On Thu, Nov 17, 2016 at 12:21 PM, Thomas Ward wrote: > Correct me if I am wrong but the discussion of underscores in DNS does not > apply to hostnames. The discussion referenced states as such, and only > touches on underscores as a part of DNS attributes and internals, not as > part of hostnames. It even says as such that hostnames are *not permitted* > to have underscores. > > By extension of that, should not the Host header should be a hostname or a > requested hostname and therefore obey the requirements for a Hostname at > the bare minimum? > > > *Sent from my iPhone. Please excuse any typos, as they are likely to > happen by accident.* > > > On Nov 17, 2016, at 12:10, Maxim Dounin wrote: > > > > Hello! > > > >> On Wed, Nov 16, 2016 at 06:36:12PM -0600, Aleksandr Kupriyanov wrote: > >> > >> com%2F&sa=D&sntz=1&usg=AFrqEzc4puDXYOgyifEWrSJrJIfW1sViFg> > > > >> # HG changeset patch > >> # User Aleksandr Kupriyanov > >> # Date 1479340749 21600 > >> # Node ID af947b854971993f318417c70c3818147b320a0d > >> # Parent 6a26016e9a138102798a7ec3e74747fbd6018f82 > >> Add directive to allow underscores in hostnames > >> > >> Two equivalent requests generate different responses: > >> > >> 1. --------------- > >> GET http://host_1.home/ HTTP/1.1 > >> Host: host_1.home > >> ... > >> HTTP/1.1 400 Bad Request > >> Server: nginx/1.X.XX > >> ------------------ > >> > >> 2. --------------- > >> GET / HTTP/1.1 > >> Host: host_1.home > >> ... > >> HTTP/1.1 200 OK > >> Server: nginx/1.X.XX > >> ------------------ > >> > >> To avoid that a new directive is proposed: > >> > >> Syntax: underscores_in_hostname on | off; > >> Default: underscores_in_headers off; > >> Context: http, server > >> > >> Enables or disables the use of underscores in host names of > >> client request line. > >> > >> See a discussion about underscores in DNS here: > >> http://domainkeys.sourceforge.net/underscore.html > > > > Shouldn't we just allow underscores in > > ngx_http_parse_request_line() instead? It doesn't looks like > > there are reasons to keep the test that strict. > > > > In case of underscores_in_headers there a clear security reason: > > headers are exposed via the HTTP_* variables in CGI, and via > > $http_* variables in nginx itself, and this makes headers with > > underscores indistinguishable from ones with dash, and creates an > > attack vector. > > > > I don't see such a problem with underscores in hostname when it's > > passed via the request line - especially keeping in mind that we > > don't enforce such a limitation via the Host header. > > > > -- > > Maxim Dounin > > http://nginx.org/ > > > > _______________________________________________ > > nginx-devel mailing list > > nginx-devel at nginx.org > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- World's First Endpoint-Aware Application Delivery Solution *Aleksandr **Kupriyanov* Email: sasha at instartlogic.com Instart Logic | 450 Lambert Ave, Palo Alto, CA 94306 | instartlogic.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From teward at dark-net.net Thu Nov 17 19:25:03 2016 From: teward at dark-net.net (Thomas Ward) Date: Thu, 17 Nov 2016 14:25:03 -0500 Subject: Add directive to allow underscores in hostnames In-Reply-To: References: <20161117171014.GB8196@mdounin.ru> Message-ID: <0df2af09-c237-1e3e-5aaf-632a5850efff@dark-net.net> I think the confusion that I have here is what lies in what is actually permitted for A and AAAA records, and what we define as a host name. I can't find specific RFCs, but A and AAAA records don't permit underscores. Aliases are permitted to have anything (such as the underscore), like other domain name records. That said, we need to carefully define whether we're permitting the request for *hostnames* or *domain names*. Hostnames per RFC are not permitted underscores. Aliases (CNAMEs) are allowed underscores, but are called domain names, not host names, at the most technical DNS level. Given this, I retract my part about hosts with underscores invalid for NGINX, provided we expand "hostname" and "requested Host" to be different. I would say we allow domain names that are valid, though we should also imply further restrictions on the allowed location of underscores in the Host request: (1) A requested host beginning with an underscore (_foobar.baz.net for example) should be invalid - there are some rules in RFCs with regards to single-underscore prepended names. (2) A requested host should not just end with an underscore at the end or at the end of the domain part (foobar.baz_), similar to how hyphens are involved here. Both of those are invalid either way, but my opinion now is that we should not just blindly permit all underscores in the request. Thomas On 11/17/2016 01:34 PM, Aleksandr Kupriyanov wrote: > De facto, some "big guys" already use underscores in their host names: > > sasha at kernel.home:~$ host cow_fb_cdn0-a.akamaihd.net > > cow_fb_cdn0-a.akamaihd.net is an > alias for cow_fb_cdn0-a.akamaihd.net.edgesuite.net > . > cow_fb_cdn0-a.akamaihd.net.edgesuite.net > is an alias for > a1877.g.akamai.net . > a1877.g.akamai.net has address 104.73.160.114 > a1877.g.akamai.net has address 104.73.160.64 > sasha at kernel.home:~$ > > > On Thu, Nov 17, 2016 at 12:21 PM, Thomas Ward > wrote: > > Correct me if I am wrong but the discussion of underscores in DNS > does not apply to hostnames. The discussion referenced states as > such, and only touches on underscores as a part of DNS attributes > and internals, not as part of hostnames. It even says as such > that hostnames are *not permitted* to have underscores. > > By extension of that, should not the Host header should be a > hostname or a requested hostname and therefore obey the > requirements for a Hostname at the bare minimum? > > > *Sent from my iPhone. Please excuse any typos, as they are likely > to happen by accident.* > > > On Nov 17, 2016, at 12:10, Maxim Dounin > wrote: > > > > Hello! > > > >> On Wed, Nov 16, 2016 at 06:36:12PM -0600, Aleksandr Kupriyanov > wrote: > >> > >> > > > > > >> # HG changeset patch > >> # User Aleksandr Kupriyanov > > >> # Date 1479340749 21600 > >> # Node ID af947b854971993f318417c70c3818147b320a0d > >> # Parent 6a26016e9a138102798a7ec3e74747fbd6018f82 > >> Add directive to allow underscores in hostnames > >> > >> Two equivalent requests generate different responses: > >> > >> 1. --------------- > >> GET http://host_1.home/ HTTP/1.1 > >> Host: host_1.home > >> ... > >> HTTP/1.1 400 Bad Request > >> Server: nginx/1.X.XX > >> ------------------ > >> > >> 2. --------------- > >> GET / HTTP/1.1 > >> Host: host_1.home > >> ... > >> HTTP/1.1 200 OK > >> Server: nginx/1.X.XX > >> ------------------ > >> > >> To avoid that a new directive is proposed: > >> > >> Syntax: underscores_in_hostname on | off; > >> Default: underscores_in_headers off; > >> Context: http, server > >> > >> Enables or disables the use of underscores in host names of > >> client request line. > >> > >> See a discussion about underscores in DNS here: > >> http://domainkeys.sourceforge.net/underscore.html > > > > > Shouldn't we just allow underscores in > > ngx_http_parse_request_line() instead? It doesn't looks like > > there are reasons to keep the test that strict. > > > > In case of underscores_in_headers there a clear security reason: > > headers are exposed via the HTTP_* variables in CGI, and via > > $http_* variables in nginx itself, and this makes headers with > > underscores indistinguishable from ones with dash, and creates an > > attack vector. > > > > I don't see such a problem with underscores in hostname when it's > > passed via the request line - especially keeping in mind that we > > don't enforce such a limitation via the Host header. > > > > -- > > Maxim Dounin > > http://nginx.org/ > > > > _______________________________________________ > > nginx-devel mailing list > > nginx-devel at nginx.org > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > > > -- > > World's First Endpoint-Aware Application Delivery Solution > > *Aleksandr **Kupriyanov* > > Email: sasha at instartlogic.com > Instart Logic | 450 Lambert Ave, Palo Alto, CA 94306 | > instartlogic.com > > > > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Fri Nov 18 14:27:20 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 18 Nov 2016 14:27:20 +0000 Subject: [njs] More Math methods from ES6. Message-ID: details: http://hg.nginx.org/njs/rev/4f4bda866d8e branches: changeset: 262:4f4bda866d8e user: Valentin Bartenev date: Fri Nov 18 17:25:25 2016 +0300 description: More Math methods from ES6. diffstat: njs/njs_math.c | 333 +++++++++++++++++++++++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 292 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 625 insertions(+), 0 deletions(-) diffs (820 lines): diff -r f402a8c64d7a -r 4f4bda866d8e njs/njs_math.c --- a/njs/njs_math.c Wed Nov 16 15:21:07 2016 +0300 +++ b/njs/njs_math.c Fri Nov 18 17:25:25 2016 +0300 @@ -69,6 +69,25 @@ njs_object_math_acos(njs_vm_t *vm, njs_v static njs_ret_t +njs_object_math_acosh(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = acosh(args[1].data.u.number); + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_asin(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -97,6 +116,25 @@ njs_object_math_asin(njs_vm_t *vm, njs_v static njs_ret_t +njs_object_math_asinh(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = asinh(args[1].data.u.number); + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_atan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -138,6 +176,44 @@ njs_object_math_atan2(njs_vm_t *vm, njs_ static njs_ret_t +njs_object_math_atanh(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = atanh(args[1].data.u.number); + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_cbrt(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = cbrt(args[1].data.u.number); + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_ceil(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -176,6 +252,25 @@ njs_object_math_cos(njs_vm_t *vm, njs_va static njs_ret_t +njs_object_math_cosh(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = cosh(args[1].data.u.number); + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_exp(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -195,6 +290,25 @@ njs_object_math_exp(njs_vm_t *vm, njs_va static njs_ret_t +njs_object_math_expm1(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = expm1(args[1].data.u.number); + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_floor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -214,6 +328,25 @@ njs_object_math_floor(njs_vm_t *vm, njs_ static njs_ret_t +njs_object_math_fround(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = (float) args[1].data.u.number; + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_hypot(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -264,6 +397,72 @@ njs_object_math_log(njs_vm_t *vm, njs_va static njs_ret_t +njs_object_math_log10(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = log10(args[1].data.u.number); + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_log1p(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = log1p(args[1].data.u.number); + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_log2(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + +#if (NXT_SOLARIS) + /* On Solaris 10 log(-1) returns -Infinity. */ + if (num < 0) { + num = NAN; + } +#endif + + num = log2(num); + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_max(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -423,6 +622,25 @@ njs_object_math_sin(njs_vm_t *vm, njs_va static njs_ret_t +njs_object_math_sinh(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = sinh(args[1].data.u.number); + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_sqrt(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -461,6 +679,25 @@ njs_object_math_tan(njs_vm_t *vm, njs_va static njs_ret_t +njs_object_math_tanh(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = tanh(args[1].data.u.number); + + } else { + num = NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_trunc(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -549,6 +786,14 @@ static const njs_object_prop_t njs_math NJS_SKIP_ARG, NJS_NUMBER_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("acosh"), + .value = njs_native_function(njs_object_math_acosh, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("asin"), @@ -556,6 +801,14 @@ static const njs_object_prop_t njs_math NJS_SKIP_ARG, NJS_NUMBER_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("asinh"), + .value = njs_native_function(njs_object_math_asinh, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("atan"), @@ -570,6 +823,22 @@ static const njs_object_prop_t njs_math NJS_SKIP_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("atanh"), + .value = njs_native_function(njs_object_math_atanh, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("cbrt"), + .value = njs_native_function(njs_object_math_cbrt, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("ceil"), @@ -584,6 +853,14 @@ static const njs_object_prop_t njs_math NJS_SKIP_ARG, NJS_NUMBER_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("cosh"), + .value = njs_native_function(njs_object_math_cosh, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("exp"), @@ -591,6 +868,14 @@ static const njs_object_prop_t njs_math NJS_SKIP_ARG, NJS_NUMBER_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("expm1"), + .value = njs_native_function(njs_object_math_expm1, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("floor"), @@ -601,6 +886,14 @@ static const njs_object_prop_t njs_math /* ES6. */ { .type = NJS_METHOD, + .name = njs_string("fround"), + .value = njs_native_function(njs_object_math_fround, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + /* ES6. */ + { + .type = NJS_METHOD, .name = njs_string("hypot"), .value = njs_native_function(njs_object_math_hypot, 0, 0), }, @@ -612,6 +905,30 @@ static const njs_object_prop_t njs_math NJS_SKIP_ARG, NJS_NUMBER_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("log10"), + .value = njs_native_function(njs_object_math_log10, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("log1p"), + .value = njs_native_function(njs_object_math_log1p, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("log2"), + .value = njs_native_function(njs_object_math_log2, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("max"), @@ -659,6 +976,14 @@ static const njs_object_prop_t njs_math NJS_SKIP_ARG, NJS_NUMBER_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("sinh"), + .value = njs_native_function(njs_object_math_sinh, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("sqrt"), @@ -676,6 +1001,14 @@ static const njs_object_prop_t njs_math /* ES6. */ { .type = NJS_METHOD, + .name = njs_string("tanh"), + .value = njs_native_function(njs_object_math_tanh, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + /* ES6. */ + { + .type = NJS_METHOD, .name = njs_string("trunc"), .value = njs_native_function(njs_object_math_trunc, 0, NJS_SKIP_ARG, NJS_NUMBER_ARG), diff -r f402a8c64d7a -r 4f4bda866d8e njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Nov 16 15:21:07 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Nov 18 17:25:25 2016 +0300 @@ -5549,6 +5549,29 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.acos(0) - Math.PI/2"), nxt_string("0") }, + { nxt_string("Math.acosh()"), + nxt_string("NaN") }, + + { nxt_string("Math.acosh('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.acosh(0.9)"), + nxt_string("NaN") }, + + { nxt_string("Math.acosh(1)"), + nxt_string("0") }, + + { nxt_string("Math.acosh('Infinity')"), + nxt_string("Infinity") }, + + /* + * The difference is 2 * Number.EPSILON on FreeBSD + * and zero on other platforms. + */ + { nxt_string("Math.abs(Math.cosh(1) - (1/Math.E + Math.E)/2)" + " <= 2 * Number.EPSILON"), + nxt_string("true") }, + { nxt_string("Math.asin()"), nxt_string("NaN") }, @@ -5573,6 +5596,27 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.asin(1) - Math.PI/2"), nxt_string("0") }, + { nxt_string("Math.asinh()"), + nxt_string("NaN") }, + + { nxt_string("Math.asinh('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.asinh(0)"), + nxt_string("0") }, + + { nxt_string("Math.asinh('-0')"), + nxt_string("-0") }, + + { nxt_string("Math.asinh(Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.asinh(-Infinity)"), + nxt_string("-Infinity") }, + + { nxt_string("Math.asinh((Math.E - 1/Math.E)/2)"), + nxt_string("1") }, + { nxt_string("Math.atan()"), nxt_string("NaN") }, @@ -5675,6 +5719,62 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.atan2(1, 1) - Math.atan2(-5, -5) - Math.PI"), nxt_string("0") }, + { nxt_string("Math.atanh()"), + nxt_string("NaN") }, + + { nxt_string("Math.atanh('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.atanh(-1.1)"), + nxt_string("NaN") }, + + { nxt_string("Math.atanh(1.1)"), + nxt_string("NaN") }, + + { nxt_string("Math.atanh(1)"), + nxt_string("Infinity") }, + + { nxt_string("Math.atanh('-1')"), + nxt_string("-Infinity") }, + + { nxt_string("Math.atanh(0)"), + nxt_string("0") }, + + { nxt_string("Math.atanh(-0)"), + nxt_string("-0") }, + + /* + * The difference is Number.EPSILON on Linux/i686 + * and zero on other platforms. + */ + { nxt_string("Math.abs(1 - Math.atanh((Math.E - 1)/(Math.E + 1)) * 2)" + " <= Number.EPSILON"), + nxt_string("true") }, + + { nxt_string("Math.cbrt()"), + nxt_string("NaN") }, + + { nxt_string("Math.cbrt('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.cbrt(0)"), + nxt_string("0") }, + + { nxt_string("Math.cbrt('-0')"), + nxt_string("-0") }, + + { nxt_string("Math.cbrt(Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.cbrt(-Infinity)"), + nxt_string("-Infinity") }, + + { nxt_string("Math.cbrt('27')"), + nxt_string("3") }, + + { nxt_string("Math.cbrt(-1)"), + nxt_string("-1") }, + { nxt_string("Math.ceil()"), nxt_string("NaN") }, @@ -5720,6 +5820,32 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.cos(Math.PI*2)"), nxt_string("1") }, + { nxt_string("Math.cosh()"), + nxt_string("NaN") }, + + { nxt_string("Math.cosh('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.cosh('0')"), + nxt_string("1") }, + + { nxt_string("Math.cosh(-0)"), + nxt_string("1") }, + + { nxt_string("Math.cosh(Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.cosh(-Infinity)"), + nxt_string("Infinity") }, + + /* + * The difference is Number.EPSILON on FreeBSD + * and zero on other platforms. + */ + { nxt_string("Math.abs(Math.cosh(1) - (1/Math.E + Math.E)/2)" + " <= Number.EPSILON"), + nxt_string("true") }, + { nxt_string("Math.exp()"), nxt_string("NaN") }, @@ -5745,6 +5871,31 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.exp(1) - Math.E <= 2 * Number.EPSILON"), nxt_string("true") }, + { nxt_string("Math.expm1()"), + nxt_string("NaN") }, + + { nxt_string("Math.expm1('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.expm1('0')"), + nxt_string("0") }, + + { nxt_string("Math.expm1(-0)"), + nxt_string("-0") }, + + { nxt_string("Math.expm1(Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.expm1(-Infinity)"), + nxt_string("-1") }, + + /* + * The difference is 2 * Number.EPSILON on FreeBSD, Solaris, + * and MacOSX and zero on other platforms. + */ + { nxt_string("Math.abs(1 + Math.expm1(1) - Math.E) <= 2 * Number.EPSILON"), + nxt_string("true") }, + { nxt_string("Math.floor()"), nxt_string("NaN") }, @@ -5769,6 +5920,33 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.floor(-3.1)"), nxt_string("-4") }, + { nxt_string("Math.fround()"), + nxt_string("NaN") }, + + { nxt_string("Math.fround('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.fround(0)"), + nxt_string("0") }, + + { nxt_string("Math.fround('-0')"), + nxt_string("-0") }, + + { nxt_string("Math.fround('Infinity')"), + nxt_string("Infinity") }, + + { nxt_string("Math.fround(-Infinity)"), + nxt_string("-Infinity") }, + + { nxt_string("Math.fround('-1.5')"), + nxt_string("-1.5") }, + + { nxt_string("Math.fround(16777216)"), + nxt_string("16777216") }, + + { nxt_string("Math.fround(-16777217)"), + nxt_string("-16777216") }, + { nxt_string("Math.hypot()"), nxt_string("0") }, @@ -5814,6 +5992,78 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.log(Math.E)"), nxt_string("1") }, + { nxt_string("Math.log10()"), + nxt_string("NaN") }, + + { nxt_string("Math.log10('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.log10(-1)"), + nxt_string("NaN") }, + + { nxt_string("Math.log10(0)"), + nxt_string("-Infinity") }, + + { nxt_string("Math.log10('-0')"), + nxt_string("-Infinity") }, + + { nxt_string("Math.log10(1)"), + nxt_string("0") }, + + { nxt_string("Math.log10(Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.log10(1000)"), + nxt_string("3") }, + + { nxt_string("Math.log1p()"), + nxt_string("NaN") }, + + { nxt_string("Math.log1p('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.log1p(-2)"), + nxt_string("NaN") }, + + { nxt_string("Math.log1p('-1')"), + nxt_string("-Infinity") }, + + { nxt_string("Math.log1p(0)"), + nxt_string("0") }, + + { nxt_string("Math.log1p(-0)"), + nxt_string("-0") }, + + { nxt_string("Math.log1p(Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.log1p(Math.E - 1)"), + nxt_string("1") }, + + { nxt_string("Math.log2()"), + nxt_string("NaN") }, + + { nxt_string("Math.log2('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.log2(-1)"), + nxt_string("NaN") }, + + { nxt_string("Math.log2(0)"), + nxt_string("-Infinity") }, + + { nxt_string("Math.log2('-0')"), + nxt_string("-Infinity") }, + + { nxt_string("Math.log2(1)"), + nxt_string("0") }, + + { nxt_string("Math.log2(Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.log2(128)"), + nxt_string("7") }, + { nxt_string("Math.max()"), nxt_string("-Infinity") }, @@ -5919,6 +6169,27 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.sin(-Math.PI/2)"), nxt_string("-1") }, + { nxt_string("Math.sinh()"), + nxt_string("NaN") }, + + { nxt_string("Math.sinh('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.sinh('0')"), + nxt_string("0") }, + + { nxt_string("Math.sinh(-0)"), + nxt_string("-0") }, + + { nxt_string("Math.sinh(Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.sinh(-Infinity)"), + nxt_string("-Infinity") }, + + { nxt_string("Math.sinh(1) - (Math.E - 1/Math.E)/2"), + nxt_string("0") }, + { nxt_string("Math.sqrt()"), nxt_string("NaN") }, @@ -5961,6 +6232,27 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.tan(Math.PI/3) + Math.tan(-Math.PI/3)"), nxt_string("0") }, + { nxt_string("Math.tanh()"), + nxt_string("NaN") }, + + { nxt_string("Math.tanh('abc')"), + nxt_string("NaN") }, + + { nxt_string("Math.tanh('0')"), + nxt_string("0") }, + + { nxt_string("Math.tanh(-0)"), + nxt_string("-0") }, + + { nxt_string("Math.tanh(Infinity)"), + nxt_string("1") }, + + { nxt_string("Math.tanh(-Infinity)"), + nxt_string("-1") }, + + { nxt_string("Math.tanh(0.5) - (Math.E - 1)/(Math.E + 1)"), + nxt_string("0") }, + { nxt_string("Math.trunc(3.9)"), nxt_string("3") }, From vbart at nginx.com Fri Nov 18 14:27:22 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 18 Nov 2016 14:27:22 +0000 Subject: [njs] Improved unit test for Math.exp(1). Message-ID: details: http://hg.nginx.org/njs/rev/f06c2b48ff78 branches: changeset: 263:f06c2b48ff78 user: Valentin Bartenev date: Fri Nov 18 17:25:45 2016 +0300 description: Improved unit test for Math.exp(1). diffstat: njs/test/njs_unit_test.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 4f4bda866d8e -r f06c2b48ff78 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Nov 18 17:25:25 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Nov 18 17:25:45 2016 +0300 @@ -5868,7 +5868,7 @@ static njs_unit_test_t njs_test[] = * The difference is 2 * Number.EPSILON on FreeBSD * and zero on other platforms. */ - { nxt_string("Math.exp(1) - Math.E <= 2 * Number.EPSILON"), + { nxt_string("Math.abs(Math.exp(1) - Math.E) <= 2 * Number.EPSILON"), nxt_string("true") }, { nxt_string("Math.expm1()"), From vakul.garg at nxp.com Sat Nov 19 04:12:39 2016 From: vakul.garg at nxp.com (Vakul Garg) Date: Sat, 19 Nov 2016 04:12:39 +0000 Subject: NGINx async SSL handshake Message-ID: Hi I am a newbie to nginx. I am integrating a public key hardware accelerator in OpenSSL using engine interface. The engine is async capable. Recently openssl-1.1.0 has added support for ASYNC_JOB. IIUC, nginx would also require changes in order to do SSL handshake in async way. Any pointers where can I get the nginx code changes done for async openssl Regards Vakul -------------- next part -------------- An HTML attachment was scrubbed... URL: From savetherbtz at gmail.com Sat Nov 19 08:29:54 2016 From: savetherbtz at gmail.com (Alexey Ivanov) Date: Sat, 19 Nov 2016 00:29:54 -0800 Subject: NGINx async SSL handshake In-Reply-To: References: Message-ID: +Brian Will from Intel, to correct me if I'm wrong. My two cents here(Intel Quick Assist specific, based on conversations during Nginx.Conf): 1) Even without hardware offload async handshake helps in cases where you have high TLS connection rates, because right now handshake is basically a 2ms+ blocking operation(specific timing depend on AVX/AVX2 support[0]) inside the event loop. Therefore after some TLS connection rate nginx performance falls off the cliff. 2) Hardware offload numbers look very impressive[1](TL;DR: 5x improvement for RSA 2048, for ECDSA, imho, it is neither impressive, nor needed). Also they prove asymmetric part of the accelerator to be future proof, so that it is possible to add new handshake types(e.g. Ed25519). Disclaimer: we did not test that hardware yet. As for patches, you can check 01.org for: a) nginx openssl async: https://01.org/sites/default/files/page/nginx-1.10.0-async.l.0.3.0-001_0.tgz b) zlib[2]: https://01.org/sites/default/files/page/zlib_shim_0.4.9-001.tgz (Full list of docs: https://01.org/packet-processing/intel%C2%AE-quickassist-technology-drivers-and-patches ) Question for Brian/Maxim: are you planning on integrating it into mainline nginx? 1000+ line diffs are usually rather hard to integrate. [0] FWIW, speaking about OpenSSL performance: using OpenSSL 1.0.2 + Intel Xeon v2 processors with AVX2 gives 2x performance boost(over OpenSSL 1.0.1 and v1). [1] https://twitter.com/SaveTheRbtz/status/773962669166428161 [2] There are also cloudflare and intel patches for zlib for faster deflation (i.e. compression only) > On Nov 18, 2016, at 8:12 PM, Vakul Garg wrote: > > Hi > > I am a newbie to nginx. > I am integrating a public key hardware accelerator in OpenSSL using engine interface. > The engine is async capable. > > Recently openssl-1.1.0 has added support for ASYNC_JOB. > IIUC, nginx would also require changes in order to do SSL handshake in async way. > > Any pointers where can I get the nginx code changes done for async openssl > > Regards > > Vakul > _______________________________________________ > 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 vbart at nginx.com Sat Nov 19 19:18:03 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Sat, 19 Nov 2016 19:18:03 +0000 Subject: [njs] Math.imul() method. Message-ID: details: http://hg.nginx.org/njs/rev/91dc07616b19 branches: changeset: 264:91dc07616b19 user: Valentin Bartenev date: Sat Nov 19 22:20:06 2016 +0300 description: Math.imul() method. diffstat: njs/njs_math.c | 31 ++++++++++++++++++++++++++ njs/njs_number.c | 25 +++++++++++++++++++++ njs/njs_number.h | 1 + njs/njs_vm.c | 52 ++++++++++-------------------------------- njs/test/njs_unit_test.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 39 deletions(-) diffs (276 lines): diff -r f06c2b48ff78 -r 91dc07616b19 njs/njs_math.c --- a/njs/njs_math.c Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/njs_math.c Sat Nov 19 22:20:06 2016 +0300 @@ -378,6 +378,29 @@ njs_object_math_hypot(njs_vm_t *vm, njs_ static njs_ret_t +njs_object_math_imul(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + uint32_t a, b; + + if (nargs > 2) { + a = njs_number_to_integer(args[1].data.u.number); + b = njs_number_to_integer(args[2].data.u.number); + + num = (int32_t) (a * b); + + } else { + num = 0; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_log(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -898,6 +921,14 @@ static const njs_object_prop_t njs_math .value = njs_native_function(njs_object_math_hypot, 0, 0), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("imul"), + .value = njs_native_function(njs_object_math_imul, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("log"), diff -r f06c2b48ff78 -r 91dc07616b19 njs/njs_number.c --- a/njs/njs_number.c Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/njs_number.c Sat Nov 19 22:20:06 2016 +0300 @@ -741,3 +741,28 @@ njs_number_parse_float(njs_vm_t *vm, njs return NXT_OK; } + + +nxt_noinline uint32_t +njs_number_to_integer(double num) +{ + int64_t i64; + + /* + * ECMAScript 5.1: integer must be modulo 2^32. + * 2^53 is the largest integer number which can be stored in the IEEE-754 + * format and numbers less than 2^53 can be just converted to int64_t + * eliding more expensive fmod() operation. Then the int64 integer is + * truncated to uint32_t. The NaN can be converted to 0x8000000000000000 + * and becomes 0 after truncation. fmod() of the infinity returns NaN. + */ + + if (num < 0 || num > 9007199254740992.0) { + i64 = fmod(num, 4294967296.0); + + } else { + i64 = num; + } + + return (uint32_t) i64; +} diff -r f06c2b48ff78 -r 91dc07616b19 njs/njs_number.h --- a/njs/njs_number.h Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/njs_number.h Sat Nov 19 22:20:06 2016 +0300 @@ -27,6 +27,7 @@ njs_ret_t njs_number_parse_int(njs_vm_t nxt_uint_t nargs, njs_index_t unused); njs_ret_t njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); +nxt_noinline uint32_t njs_number_to_integer(double num); extern const njs_object_init_t njs_number_constructor_init; diff -r f06c2b48ff78 -r 91dc07616b19 njs/njs_vm.c --- a/njs/njs_vm.c Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/njs_vm.c Sat Nov 19 22:20:06 2016 +0300 @@ -78,7 +78,6 @@ static njs_ret_t njs_object_property_que njs_property_query_t *pq, njs_value_t *value, njs_object_t *object); static njs_ret_t njs_method_private_copy(njs_vm_t *vm, njs_property_query_t *pq); -static nxt_noinline uint32_t njs_integer_value(double num); static nxt_noinline njs_ret_t njs_values_equal(const njs_value_t *val1, const njs_value_t *val2); static nxt_noinline njs_ret_t njs_values_compare(const njs_value_t *val1, @@ -1639,8 +1638,8 @@ njs_vmcode_left_shift(njs_vm_t *vm, njs_ if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_integer_value(val1->data.u.number); - num2 = njs_integer_value(val2->data.u.number); + num1 = njs_number_to_integer(val1->data.u.number); + num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(&vm->retval, num1 << (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); @@ -1658,8 +1657,8 @@ njs_vmcode_right_shift(njs_vm_t *vm, njs if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_integer_value(val1->data.u.number); - num2 = njs_integer_value(val2->data.u.number); + num1 = njs_number_to_integer(val1->data.u.number); + num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(&vm->retval, num1 >> (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); @@ -1678,8 +1677,8 @@ njs_vmcode_unsigned_right_shift(njs_vm_t if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_integer_value(val1->data.u.number); - num2 = njs_integer_value(val2->data.u.number); + num1 = njs_number_to_integer(val1->data.u.number); + num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(&vm->retval, num1 >> (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); @@ -1745,7 +1744,7 @@ njs_vmcode_bitwise_not(njs_vm_t *vm, njs int32_t num; if (nxt_fast_path(njs_is_numeric(value))) { - num = njs_integer_value(value->data.u.number); + num = njs_number_to_integer(value->data.u.number); njs_number_set(&vm->retval, ~num); return sizeof(njs_vmcode_2addr_t); @@ -1762,8 +1761,8 @@ njs_vmcode_bitwise_and(njs_vm_t *vm, njs if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_integer_value(val1->data.u.number); - num2 = njs_integer_value(val2->data.u.number); + num1 = njs_number_to_integer(val1->data.u.number); + num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(&vm->retval, num1 & num2); return sizeof(njs_vmcode_3addr_t); @@ -1780,8 +1779,8 @@ njs_vmcode_bitwise_xor(njs_vm_t *vm, njs if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_integer_value(val1->data.u.number); - num2 = njs_integer_value(val2->data.u.number); + num1 = njs_number_to_integer(val1->data.u.number); + num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(&vm->retval, num1 ^ num2); return sizeof(njs_vmcode_3addr_t); @@ -1798,8 +1797,8 @@ njs_vmcode_bitwise_or(njs_vm_t *vm, njs_ if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_integer_value(val1->data.u.number); - num2 = njs_integer_value(val2->data.u.number); + num1 = njs_number_to_integer(val1->data.u.number); + num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(&vm->retval, num1 | num2); return sizeof(njs_vmcode_3addr_t); @@ -1809,31 +1808,6 @@ njs_vmcode_bitwise_or(njs_vm_t *vm, njs_ } -static nxt_noinline uint32_t -njs_integer_value(double num) -{ - int64_t i64; - - /* - * ECMAScript 5.1: integer must be modulo 2^32. - * 2^53 is the largest integer number which can be stored in the IEEE-754 - * format and numbers less than 2^53 can be just converted to int64_t - * eliding more expensive fmod() operation. Then the int64 integer is - * truncated to uint32_t. The NaN can be converted to 0x8000000000000000 - * and becomes 0 after truncation. fmod() of the infinity returns NaN. - */ - - if (num < 0 || num > 9007199254740992.0) { - i64 = fmod(num, 4294967296.0); - - } else { - i64 = num; - } - - return (uint32_t) i64; -} - - njs_ret_t njs_vmcode_equal(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2) { diff -r f06c2b48ff78 -r 91dc07616b19 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/test/njs_unit_test.c Sat Nov 19 22:20:06 2016 +0300 @@ -5968,6 +5968,63 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.hypot(3, -4, 12.0, '84', 132)"), nxt_string("157") }, + { nxt_string("Math.imul()"), + nxt_string("0") }, + + { nxt_string("Math.imul(1)"), + nxt_string("0") }, + + { nxt_string("Math.imul('a', 1)"), + nxt_string("0") }, + + { nxt_string("Math.imul(1, NaN)"), + nxt_string("0") }, + + { nxt_string("Math.imul(2, '3')"), + nxt_string("6") }, + + { nxt_string("Math.imul('3.9', -2.1)"), + nxt_string("-6") }, + + { nxt_string("Math.imul(2, 2147483647)"), + nxt_string("-2") }, + + { nxt_string("Math.imul(Number.MAX_SAFE_INTEGER, 2)"), + nxt_string("-2") }, + + { nxt_string("Math.imul(1, Number.MAX_SAFE_INTEGER + 1)"), + nxt_string("0") }, + + { nxt_string("Math.imul(2, Number.MIN_SAFE_INTEGER)"), + nxt_string("2") }, + + { nxt_string("Math.imul(Number.MIN_SAFE_INTEGER - 1, 1)"), + nxt_string("0") }, + + { nxt_string("Math.imul(2, 4294967297)"), + nxt_string("2") }, + + { nxt_string("Math.imul(-4294967297, 4294967297)"), + nxt_string("-1") }, + + { nxt_string("Math.imul(4294967297, -4294967298)"), + nxt_string("-2") }, + + { nxt_string("Math.imul(-4294967290, 4294967290)"), + nxt_string("-36") }, + + { nxt_string("Math.imul(-Infinity, 1)"), + nxt_string("0") }, + + { nxt_string("Math.imul(1, Infinity)"), + nxt_string("0") }, + + { nxt_string("Math.imul(Number.MAX_VALUE, 1)"), + nxt_string("0") }, + + { nxt_string("Math.imul(1, -Number.MAX_VALUE)"), + nxt_string("0") }, + { nxt_string("Math.log()"), nxt_string("NaN") }, From vbart at nginx.com Sat Nov 19 19:18:10 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Sat, 19 Nov 2016 19:18:10 +0000 Subject: [njs] Optimized conversion of negative numbers to integer. Message-ID: details: http://hg.nginx.org/njs/rev/9f0f13857c46 branches: changeset: 265:9f0f13857c46 user: Valentin Bartenev date: Sat Nov 19 22:20:06 2016 +0300 description: Optimized conversion of negative numbers to integer. There is no reason to use fmod() for all negative numbers. The numbers in range [-2^53, 2^53] can be converted directly to int64_t. diffstat: njs/njs_number.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diffs (27 lines): diff -r 91dc07616b19 -r 9f0f13857c46 njs/njs_number.c --- a/njs/njs_number.c Sat Nov 19 22:20:06 2016 +0300 +++ b/njs/njs_number.c Sat Nov 19 22:20:06 2016 +0300 @@ -749,15 +749,16 @@ njs_number_to_integer(double num) int64_t i64; /* - * ECMAScript 5.1: integer must be modulo 2^32. - * 2^53 is the largest integer number which can be stored in the IEEE-754 - * format and numbers less than 2^53 can be just converted to int64_t - * eliding more expensive fmod() operation. Then the int64 integer is - * truncated to uint32_t. The NaN can be converted to 0x8000000000000000 - * and becomes 0 after truncation. fmod() of the infinity returns NaN. + * ES5.1: integer must be modulo 2^32. + * 2^53 is the largest integer number which can be stored safely + * in the IEEE-754 format and numbers less than 2^53 can be just + * converted to int64_t eliding more expensive fmod() operation. + * Then the int64 integer is truncated to uint32_t. The NaN is + * converted to 0x8000000000000000 and becomes 0 after truncation. + * fmod() of the Infinity returns NaN. */ - if (num < 0 || num > 9007199254740992.0) { + if (fabs(num) > 9007199254740992.0) { i64 = fmod(num, 4294967296.0); } else { From hucong.c at foxmail.com Mon Nov 21 09:40:52 2016 From: hucong.c at foxmail.com (=?utf-8?B?6IOh6IGqIChodWNjKQ==?=) Date: Mon, 21 Nov 2016 17:40:52 +0800 Subject: [PATCH] Mp4: fixed setting wrong mdat atom size in very rare cases. Message-ID: Hi, # HG changeset patch # User hucongcong # Date 1479719580 -28800 # Mon Nov 21 17:13:00 2016 +0800 # Node ID f43feabe2e45ec102ffbe36428ccb504ff1526d2 # Parent 6a26016e9a138102798a7ec3e74747fbd6018f82 Mp4: fixed setting wrong mdat atom size in very rare cases. diff -r 6a26016e9a13 -r f43feabe2e45 src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c Tue Nov 15 18:11:46 2016 +0300 +++ b/src/http/modules/ngx_http_mp4_module.c Mon Nov 21 17:13:00 2016 +0800 @@ -1229,7 +1229,7 @@ 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) 0xfffffff7) { 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 vakul.garg at nxp.com Mon Nov 21 11:24:27 2016 From: vakul.garg at nxp.com (Vakul Garg) Date: Mon, 21 Nov 2016 11:24:27 +0000 Subject: NGINx async SSL handshake In-Reply-To: References: Message-ID: Hi Thanks. The link you provided is what I have been looking for. https://01.org/sites/default/files/page/nginx-1.10.0-async.l.0.3.0-001_0.tgz However I am not sure why it is not there on https://01.org/packet-processing/downloads Regards Vakul -----Original Message----- From: nginx-devel [mailto:nginx-devel-bounces at nginx.org] On Behalf Of Alexey Ivanov Sent: Saturday, November 19, 2016 2:00 PM To: nginx-devel at nginx.org Cc: brian.will at intel.com Subject: Re: NGINx async SSL handshake +Brian Will from Intel, to correct me if I'm wrong. My two cents here(Intel Quick Assist specific, based on conversations during Nginx.Conf): 1) Even without hardware offload async handshake helps in cases where you have high TLS connection rates, because right now handshake is basically a 2ms+ blocking operation(specific timing depend on AVX/AVX2 support[0]) inside the event loop. Therefore after some TLS connection rate nginx performance falls off the cliff. 2) Hardware offload numbers look very impressive[1](TL;DR: 5x improvement for RSA 2048, for ECDSA, imho, it is neither impressive, nor needed). Also they prove asymmetric part of the accelerator to be future proof, so that it is possible to add new handshake types(e.g. Ed25519). Disclaimer: we did not test that hardware yet. As for patches, you can check 01.org for: a) nginx openssl async: https://01.org/sites/default/files/page/nginx-1.10.0-async.l.0.3.0-001_0.tgz b) zlib[2]: https://01.org/sites/default/files/page/zlib_shim_0.4.9-001.tgz (Full list of docs: https://01.org/packet-processing/intel%C2%AE-quickassist-technology-drivers-and-patches ) Question for Brian/Maxim: are you planning on integrating it into mainline nginx? 1000+ line diffs are usually rather hard to integrate. [0] FWIW, speaking about OpenSSL performance: using OpenSSL 1.0.2 + Intel Xeon v2 processors with AVX2 gives 2x performance boost(over OpenSSL 1.0.1 and v1). [1] https://twitter.com/SaveTheRbtz/status/773962669166428161 [2] There are also cloudflare and intel patches for zlib for faster deflation (i.e. compression only) > On Nov 18, 2016, at 8:12 PM, Vakul Garg wrote: > > Hi > > I am a newbie to nginx. > I am integrating a public key hardware accelerator in OpenSSL using engine interface. > The engine is async capable. > > Recently openssl-1.1.0 has added support for ASYNC_JOB. > IIUC, nginx would also require changes in order to do SSL handshake in async way. > > Any pointers where can I get the nginx code changes done for async openssl > > Regards > > Vakul > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From mdounin at mdounin.ru Mon Nov 21 13:07:27 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 21 Nov 2016 16:07:27 +0300 Subject: [PATCH] Mp4: fixed setting wrong mdat atom size in very rare cases. In-Reply-To: References: Message-ID: <20161121130727.GH8196@mdounin.ru> Hello! On Mon, Nov 21, 2016 at 05:40:52PM +0800, ?? (hucc) wrote: > Hi, > > # HG changeset patch > # User hucongcong > # Date 1479719580 -28800 > # Mon Nov 21 17:13:00 2016 +0800 > # Node ID f43feabe2e45ec102ffbe36428ccb504ff1526d2 > # Parent 6a26016e9a138102798a7ec3e74747fbd6018f82 > Mp4: fixed setting wrong mdat atom size in very rare cases. > > diff -r 6a26016e9a13 -r f43feabe2e45 src/http/modules/ngx_http_mp4_module.c > --- a/src/http/modules/ngx_http_mp4_module.c Tue Nov 15 18:11:46 2016 +0300 > +++ b/src/http/modules/ngx_http_mp4_module.c Mon Nov 21 17:13:00 2016 +0800 > @@ -1229,7 +1229,7 @@ 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) 0xfffffff7) { > atom_size = 1; > atom_header_size = sizeof(ngx_mp4_atom_header64_t); > ngx_mp4_set_64value(atom_header + sizeof(ngx_mp4_atom_header_t), You may want to elaborate more about what are you trying to fix here. Current code uses 32-bit atom headers for sizes up to maximum unsigned 32-bit value, 0xffffffff. And this seems to perfectly agree with the specification. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Mon Nov 21 13:50:34 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 21 Nov 2016 13:50:34 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/8bd659ff4231 branches: changeset: 6803:8bd659ff4231 user: Maxim Dounin date: Mon Nov 21 16:49:17 2016 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1011006 -#define NGINX_VERSION "1.11.6" +#define nginx_version 1011007 +#define NGINX_VERSION "1.11.7" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From mdounin at mdounin.ru Mon Nov 21 13:50:37 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 21 Nov 2016 13:50:37 +0000 Subject: [nginx] Configure: honor dependencies of dynamic modules. Message-ID: details: http://hg.nginx.org/nginx/rev/2c7a2d75938a branches: changeset: 6804:2c7a2d75938a user: Maxim Dounin date: Mon Nov 21 16:49:19 2016 +0300 description: Configure: honor dependencies of dynamic modules. Dependencies of dynamic modules are added to NGX_ADDON_DEPS (and it is now used for dynamic modules) to be in line with what happens in case of static compilation. To avoid duplication, MAIL_DEPS and STREAM_DEPS are no longer passed to auto/module when these modules are compiled as dynamic ones. Mail and stream dependencies are handled explicitly via corresponding variables. diffstat: auto/make | 17 +++-------------- auto/module | 4 ++++ auto/modules | 4 ++-- 3 files changed, 9 insertions(+), 16 deletions(-) diffs (83 lines): diff --git a/auto/make b/auto/make --- a/auto/make +++ b/auto/make @@ -156,7 +156,7 @@ fi ngx_all_srcs="$ngx_all_srcs $MISC_SRCS" -if test -n "$NGX_ADDON_SRCS"; then +if test -n "$NGX_ADDON_SRCS$DYNAMIC_MODULES"; then cat << END >> $NGX_MAKEFILE @@ -499,17 +499,6 @@ else ngx_perl_cc="$ngx_perl_cc \$(ALL_INCS)" fi -ngx_obj_deps="\$(CORE_DEPS)" -if [ $HTTP != NO ]; then - ngx_obj_deps="$ngx_obj_deps \$(HTTP_DEPS)" -fi -if [ $MAIL != NO ]; then - ngx_obj_deps="$ngx_obj_deps \$(MAIL_DEPS)" -fi -if [ $STREAM != NO ]; then - ngx_obj_deps="$ngx_obj_deps \$(STREAM_DEPS)" -fi - for ngx_module in $DYNAMIC_MODULES do eval ngx_module_srcs="\$${ngx_module}_SRCS" @@ -665,7 +654,7 @@ END cat << END >> $NGX_MAKEFILE -$ngx_obj: $ngx_obj_deps$ngx_cont$ngx_src +$ngx_obj: \$(ADDON_DEPS)$ngx_cont$ngx_src $ngx_perl_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX END @@ -673,7 +662,7 @@ END cat << END >> $NGX_MAKEFILE -$ngx_obj: $ngx_obj_deps$ngx_cont$ngx_src +$ngx_obj: \$(ADDON_DEPS)$ngx_cont$ngx_src $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX END diff --git a/auto/module b/auto/module --- a/auto/module +++ b/auto/module @@ -35,6 +35,10 @@ if [ "$ngx_module_link" = DYNAMIC ]; the CORE_INCS="$CORE_INCS $ngx_module_incs" fi + if test -n "$ngx_module_deps"; then + NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_module_deps" + fi + libs= for lib in $ngx_module_libs do diff --git a/auto/modules b/auto/modules --- a/auto/modules +++ b/auto/modules @@ -1252,7 +1252,7 @@ if [ $MAIL != NO ]; then elif [ $MAIL = DYNAMIC ]; then ngx_module_name=$MAIL_MODULES ngx_module_incs= - ngx_module_deps=$MAIL_DEPS + ngx_module_deps= ngx_module_srcs=$MAIL_SRCS ngx_module_libs= ngx_module_link=DYNAMIC @@ -1272,7 +1272,7 @@ if [ $STREAM != NO ]; then elif [ $STREAM = DYNAMIC ]; then ngx_module_name=$STREAM_MODULES ngx_module_incs= - ngx_module_deps=$STREAM_DEPS + ngx_module_deps= ngx_module_srcs=$STREAM_SRCS ngx_module_libs= ngx_module_link=DYNAMIC From hucong.c at foxmail.com Mon Nov 21 14:04:25 2016 From: hucong.c at foxmail.com (=?utf-8?B?6IOh6IGqIChodWNjKQ==?=) Date: Mon, 21 Nov 2016 22:04:25 +0800 Subject: [PATCH] Mp4: fixed setting wrong mdat atom size in very rarecases. In-Reply-To: <20161121130727.GH8196@mdounin.ru> References: <20161121130727.GH8196@mdounin.ru> Message-ID: Hi, On Mon, Nov 21, 2016 at 9:07 PM +0300, Maxim Dounin wrote: >Hello! > >On Mon, Nov 21, 2016 at 05:40:52PM +0800, ?? (hucc) wrote: > >> Hi, >> >> # HG changeset patch >> # User hucongcong >> # Date 1479719580 -28800 >> # Mon Nov 21 17:13:00 2016 +0800 >> # Node ID f43feabe2e45ec102ffbe36428ccb504ff1526d2 >> # Parent 6a26016e9a138102798a7ec3e74747fbd6018f82 >> Mp4: fixed setting wrong mdat atom size in very rare cases. >> >> diff -r 6a26016e9a13 -r f43feabe2e45 src/http/modules/ngx_http_mp4_module.c >> --- a/src/http/modules/ngx_http_mp4_module.c Tue Nov 15 18:11:46 2016 +0300 >> +++ b/src/http/modules/ngx_http_mp4_module.c Mon Nov 21 17:13:00 2016 +0800 >> @@ -1229,7 +1229,7 @@ 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) 0xfffffff7) { >> atom_size = 1; >> atom_header_size = sizeof(ngx_mp4_atom_header64_t); >> ngx_mp4_set_64value(atom_header + sizeof(ngx_mp4_atom_header_t), > >You may want to elaborate more about what are you trying to fix >here. > >Current code uses 32-bit atom headers for sizes up to maximum >unsigned 32-bit value, 0xffffffff. And this seems to perfectly >agree with the specification. Well, atom size is the sum of atom header size and atom data size. And the specification says that the first 4 bytes are set to one when the atom size is greater than 0xffffffff, which means atom header size should be considered when the comparison takes place between atom data size and the maximum unsigned 32-bit value. We can image that atom_data_size is 0xfffffff9, and the first 4 bytes will be set to the sum of sizeof(ngx_mp4_atom_header_t) and atom_data_size, then the error is obvious. Regards, -hucc From mdounin at mdounin.ru Mon Nov 21 14:25:58 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 21 Nov 2016 17:25:58 +0300 Subject: [PATCH] Mp4: fixed setting wrong mdat atom size in very rarecases. In-Reply-To: References: <20161121130727.GH8196@mdounin.ru> Message-ID: <20161121142557.GI8196@mdounin.ru> Hello! On Mon, Nov 21, 2016 at 10:04:25PM +0800, ?? (hucc) wrote: > Hi, > > On Mon, Nov 21, 2016 at 9:07 PM +0300, Maxim Dounin wrote: > > >Hello! > > > >On Mon, Nov 21, 2016 at 05:40:52PM +0800, ?? (hucc) wrote: > > > >> Hi, > >> > >> # HG changeset patch > >> # User hucongcong > >> # Date 1479719580 -28800 > >> # Mon Nov 21 17:13:00 2016 +0800 > >> # Node ID f43feabe2e45ec102ffbe36428ccb504ff1526d2 > >> # Parent 6a26016e9a138102798a7ec3e74747fbd6018f82 > >> Mp4: fixed setting wrong mdat atom size in very rare cases. > >> > >> diff -r 6a26016e9a13 -r f43feabe2e45 src/http/modules/ngx_http_mp4_module.c > >> --- a/src/http/modules/ngx_http_mp4_module.c Tue Nov 15 18:11:46 2016 +0300 > >> +++ b/src/http/modules/ngx_http_mp4_module.c Mon Nov 21 17:13:00 2016 +0800 > >> @@ -1229,7 +1229,7 @@ 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) 0xfffffff7) { > >> atom_size = 1; > >> atom_header_size = sizeof(ngx_mp4_atom_header64_t); > >> ngx_mp4_set_64value(atom_header + sizeof(ngx_mp4_atom_header_t), > > > >You may want to elaborate more about what are you trying to fix > >here. > > > >Current code uses 32-bit atom headers for sizes up to maximum > >unsigned 32-bit value, 0xffffffff. And this seems to perfectly > >agree with the specification. > > Well, atom size is the sum of atom header size and atom data size. > And the specification says that the first 4 bytes are set to one > when the atom size is greater than 0xffffffff, which means atom > header size should be considered when the comparison takes place > between atom data size and the maximum unsigned 32-bit value. > We can image that atom_data_size is 0xfffffff9, and the first 4 bytes > will be set to the sum of sizeof(ngx_mp4_atom_header_t) and > atom_data_size, then the error is obvious. Ah, ok, I see the problem now. Please clarify things in the commit log as well. It also make sense to use sizeof() explicitly, instead of introducing a magic number, e.g.: @@ -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), -- Maxim Dounin http://nginx.org/ From hucong.c at foxmail.com Mon Nov 21 15:10:25 2016 From: hucong.c at foxmail.com (=?utf-8?B?6IOh6IGqIChodWNjKQ==?=) Date: Mon, 21 Nov 2016 23:10:25 +0800 Subject: [PATCH] Mp4: fixed setting wrong mdat atom size in very rarecases. In-Reply-To: <20161121142557.GI8196@mdounin.ru> References: <20161121130727.GH8196@mdounin.ru> <20161121142557.GI8196@mdounin.ru> Message-ID: Hi, On Mon, Nov 21, 2016 at 10:26 PM +0300, Maxim Dounin wrote: >Ah, ok, I see the problem now. Please clarify things in the >commit log as well. > >It also make sense to use sizeof() explicitly, instead of >introducing a magic number, e.g.: Thanks?There is the new patch. # HG changeset patch # User hucongcong # Date 1479740605 -28800 # Mon Nov 21 23:03:25 2016 +0800 # Node ID 7a1a6f7b989d4c44523333293265d58663ac7ff4 # 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 7a1a6f7b989d 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 Mon Nov 21 23:03:25 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 + sizeof(ngx_mp4_atom_header_t) + > (uint64_t) 0xffffffff) + { 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 vbart at nginx.com Mon Nov 21 20:37:29 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Mon, 21 Nov 2016 23:37:29 +0300 Subject: [PATCH] Mp4: fixed setting wrong mdat atom size in very rarecases. In-Reply-To: References: <20161121142557.GI8196@mdounin.ru> Message-ID: <2766424.N7GUhy8r5P@vbart-laptop> On Monday 21 November 2016 23:10:25 ?? wrote: > Hi, > > On Mon, Nov 21, 2016 at 10:26 PM +0300, Maxim Dounin wrote: > > >Ah, ok, I see the problem now. Please clarify things in the > >commit log as well. > > > >It also make sense to use sizeof() explicitly, instead of > >introducing a magic number, e.g.: > > Thanks?There is the new patch. > > # HG changeset patch > # User hucongcong > # Date 1479740605 -28800 > # Mon Nov 21 23:03:25 2016 +0800 > # Node ID 7a1a6f7b989d4c44523333293265d58663ac7ff4 > # 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 7a1a6f7b989d 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 Mon Nov 21 23:03:25 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 + sizeof(ngx_mp4_atom_header_t) > + > (uint64_t) 0xffffffff) > + { > atom_size = 1; > atom_header_size = sizeof(ngx_mp4_atom_header64_t); > ngx_mp4_set_64value(atom_header + sizeof(ngx_mp4_atom_header_t), 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. wbr, Valentin V. Bartenev From vbart at nginx.com Mon Nov 21 21:04:58 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Mon, 21 Nov 2016 21:04:58 +0000 Subject: [njs] Math.clz32 method. Message-ID: details: http://hg.nginx.org/njs/rev/fd2a05f9eacf branches: changeset: 266:fd2a05f9eacf user: Valentin Bartenev date: Tue Nov 22 00:06:46 2016 +0300 description: Math.clz32 method. diffstat: njs/njs_math.c | 29 +++++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 27 +++++++++++++++++++++++++++ nxt/auto/clang | 14 ++++++++++++++ nxt/nxt_clang.h | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 0 deletions(-) diffs (149 lines): diff -r 9f0f13857c46 -r fd2a05f9eacf njs/njs_math.c --- a/njs/njs_math.c Sat Nov 19 22:20:06 2016 +0300 +++ b/njs/njs_math.c Tue Nov 22 00:06:46 2016 +0300 @@ -233,6 +233,27 @@ njs_object_math_ceil(njs_vm_t *vm, njs_v static njs_ret_t +njs_object_math_clz32(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + uint32_t ui32; + + if (nargs > 1) { + ui32 = njs_number_to_integer(args[1].data.u.number); + num = nxt_leading_zeros(ui32); + + } else { + num = 32; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_cos(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -869,6 +890,14 @@ static const njs_object_prop_t njs_math NJS_SKIP_ARG, NJS_NUMBER_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("clz32"), + .value = njs_native_function(njs_object_math_clz32, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("cos"), diff -r 9f0f13857c46 -r fd2a05f9eacf njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sat Nov 19 22:20:06 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Nov 22 00:06:46 2016 +0300 @@ -5799,6 +5799,33 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.ceil(3.1)"), nxt_string("4") }, + { nxt_string("Math.clz32()"), + nxt_string("32") }, + + { nxt_string("Math.clz32('abc')"), + nxt_string("32") }, + + { nxt_string("Math.clz32(NaN)"), + nxt_string("32") }, + + { nxt_string("Math.clz32(Infinity)"), + nxt_string("32") }, + + { nxt_string("Math.clz32('1')"), + nxt_string("31") }, + + { nxt_string("Math.clz32(0)"), + nxt_string("32") }, + + { nxt_string("Math.clz32('65535')"), + nxt_string("16") }, + + { nxt_string("Math.clz32(-1)"), + nxt_string("0") }, + + { nxt_string("Math.clz32(4294967298)"), + nxt_string("30") }, + { nxt_string("Math.cos()"), nxt_string("NaN") }, diff -r 9f0f13857c46 -r fd2a05f9eacf nxt/auto/clang --- a/nxt/auto/clang Sat Nov 19 22:20:06 2016 +0300 +++ b/nxt/auto/clang Tue Nov 22 00:06:46 2016 +0300 @@ -203,6 +203,20 @@ nxt_feature_test="int main(void) { . ${NXT_AUTO}feature +nxt_feature="GCC __builtin_clz()" +nxt_feature_name=NXT_HAVE_BUILTIN_CLZ +nxt_feature_run=no +nxt_feature_incs= +nxt_feature_libs= +nxt_feature_test="int main(void) { + if (__builtin_clz(1) != 31) { + return 1; + } + return 0; + }" +. ${NXT_AUTO}feature + + nxt_feature="GCC __attribute__ visibility" nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_VISIBILITY nxt_feature_run=no diff -r 9f0f13857c46 -r fd2a05f9eacf nxt/nxt_clang.h --- a/nxt/nxt_clang.h Sat Nov 19 22:20:06 2016 +0300 +++ b/nxt/nxt_clang.h Tue Nov 22 00:06:46 2016 +0300 @@ -52,6 +52,38 @@ #endif +#if (NXT_HAVE_BUILTIN_CLZ) +#define nxt_leading_zeros(x) (((x) == 0) ? 32 : __builtin_clz(x)) + +#else + +nxt_inline uint32_t +nxt_leading_zeros(uint32_t x) +{ + uint32_t n; + + /* + * There is no sense to optimize this function, since almost + * all platforms nowadays support the built-in instruction. + */ + + if (x == 0) { + return 32; + } + + n = 0; + + while ((x & 0x80000000) == 0) { + n++; + x <<= 1; + } + + return n; +} + +#endif + + #if (NXT_HAVE_GCC_ATTRIBUTE_VISIBILITY) #define NXT_EXPORT __attribute__((visibility("default"))) From hucong.c at foxmail.com Tue Nov 22 06:13:11 2016 From: hucong.c at foxmail.com (=?utf-8?B?6IOh6IGqIChodWNjKQ==?=) Date: Tue, 22 Nov 2016 14:13:11 +0800 Subject: [PATCH] Mp4: fixed setting wrong mdat atom size in very rarecases. In-Reply-To: <2766424.N7GUhy8r5P@vbart-laptop> References: <20161121142557.GI8196@mdounin.ru> <2766424.N7GUhy8r5P@vbart-laptop> Message-ID: 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), From maurice at teridion.com Tue Nov 22 12:03:32 2016 From: maurice at teridion.com (Maurice Tfilin) Date: Tue, 22 Nov 2016 14:03:32 +0200 Subject: ssl_client_certificate support in ngx_stream_ssl_module Message-ID: Hi, Are there any plans to support ssl_client_certificate in ngx_stream_ssl_module? A patch was previously submitted (https://marc.ttias.be/nginx- devel/2015-11/msg00009.php), but eventually it was not commited -- Regards, Maurice -------------- next part -------------- An HTML attachment was scrubbed... URL: From maxim at nginx.com Tue Nov 22 12:11:20 2016 From: maxim at nginx.com (Maxim Konovalov) Date: Tue, 22 Nov 2016 15:11:20 +0300 Subject: ssl_client_certificate support in ngx_stream_ssl_module In-Reply-To: References: Message-ID: <7ad37a4c-5127-a0d5-c6d8-a50dbe720607@nginx.com> Hi Maurice, On 11/22/16 3:03 PM, Maurice Tfilin wrote: > Hi, > > Are there any plans to support ssl_client_certificate in > ngx_stream_ssl_module? > > A patch was previously submitted > (https://marc.ttias.be/nginx-devel/2015-11/msg00009.php > ), but > eventually it was not commited > We have this work planned. Hope to have something committable later this year or yearly 2017. -- Maxim Konovalov From babak at farrokhi.net Wed Nov 23 07:48:12 2016 From: babak at farrokhi.net (Babak Farrokhi) Date: Wed, 23 Nov 2016 11:18:12 +0330 Subject: [PATCH] Add support for HTTP 451 Return Code (RFC 7725) Message-ID: Hello, A recent RFC (7725) has introduced HTTP Return Code 451 to be returned when access to a resource is forbidden for legal reasons [1]. In addition to the return code, HTTP server may return an additional ?Link? field in HTTP header. The new header should be formatted as below: Link: ; rel="blocked-by" Please also note that the new Relation Name (blocked-by) is also added to IANA Link Relation Type Registry [2]. A user may simply return a 451 code based on a condition or additionally provide a link to a URL (usually pointed to the applicable legislation or regulation): if ($http_user_agent !~ MSIE) { return 451 https://spqr.example.org/legislatione; } if ($http_user_agent ~* (Wget) ) { return 451; } Here is the proposed patch: # HG changeset patch # User Babak Farrokhi # Date 1479886479 -12600 # Wed Nov 23 11:04:39 2016 +0330 # Node ID d56f78822c5bcaa8bde2d95c862d06491618154c # Parent 2c7a2d75938a31044552b0a6cd6edaebdaf0bd69 Add support for HTTP 451 Return Code (RFC 7725) RFC 7725 introduced HTTP 451 ?Unavailable For Legal Reasons? return code, to be returned when the user requests a resource which cannot be served for legal reasons. It also introduces an optional "Link" header field that should contain a link to relevant webpage (e.g. legal documents) with following format: Link: ; rel="blocked-by" A user can now configure nginx to return this code using a return clause in configuration file: if ($http_user_agent !~ MSIE) { return 451 https://spqr.example.org/legislatione; } if ($http_user_agent ~* (Wget) ) { return 451; } Please note that the URL is optional and if not specified, no "Link" field will be added to header. diff -r 2c7a2d75938a -r d56f78822c5b src/http/modules/perl/nginx.pm --- a/src/http/modules/perl/nginx.pm Mon Nov 21 16:49:19 2016 +0300 +++ b/src/http/modules/perl/nginx.pm Wed Nov 23 11:04:39 2016 +0330 @@ -88,6 +88,7 @@ use constant HTTP_REQUEST_URI_TOO_LARGE => 414; use constant HTTP_UNSUPPORTED_MEDIA_TYPE => 415; use constant HTTP_RANGE_NOT_SATISFIABLE => 416; +use constant HTTP_NOT_ALLOWED_LEGALLY => 451; use constant HTTP_INTERNAL_SERVER_ERROR => 500; use constant HTTP_SERVER_ERROR => 500; diff -r 2c7a2d75938a -r d56f78822c5b src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Mon Nov 21 16:49:19 2016 +0300 +++ b/src/http/ngx_http_core_module.c Wed Nov 23 11:04:39 2016 +0330 @@ -1862,6 +1862,7 @@ ngx_str_t val; ngx_buf_t *b; ngx_chain_t out; + ngx_str_t link; if (ngx_http_discard_request_body(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; @@ -1873,6 +1874,32 @@ return NGX_HTTP_INTERNAL_SERVER_ERROR; } + if (status == NGX_HTTP_NOT_ALLOWED_LEGALLY) { + ngx_http_clear_link(r); + + r->headers_out.link = ngx_list_push(&r->headers_out.headers); + if (r->headers_out.link == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + r->headers_out.link->hash = 1; + ngx_str_set(&r->headers_out.link->key, "Link"); + + link.data = ngx_pcalloc(r->pool, val.len + + ngx_strlen("<>; rel=\"blocked-by\"")); + if (link.data == NULL) { + r->headers_out.link->hash = 0; + return NGX_ERROR; + } + + link.len = ngx_sprintf(link.data, "<%s>; rel=\"blocked-by\"", + val.data) - link.data; + + r->headers_out.link->value = link; + + return status; + } + if (status == NGX_HTTP_MOVED_PERMANENTLY || status == NGX_HTTP_MOVED_TEMPORARILY || status == NGX_HTTP_SEE_OTHER diff -r 2c7a2d75938a -r d56f78822c5b src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h Mon Nov 21 16:49:19 2016 +0300 +++ b/src/http/ngx_http_core_module.h Wed Nov 23 11:04:39 2016 +0330 @@ -570,6 +570,13 @@ r->headers_out.location = NULL; \ } +#define ngx_http_clear_link(r) \ + \ + if (r->headers_out.link) { \ + r->headers_out.link->hash = 0; \ + r->headers_out.link = NULL; \ + } + #define ngx_http_clear_etag(r) \ \ if (r->headers_out.etag) { \ diff -r 2c7a2d75938a -r d56f78822c5b src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c Mon Nov 21 16:49:19 2016 +0300 +++ b/src/http/ngx_http_header_filter_module.c Wed Nov 23 11:04:39 2016 +0330 @@ -100,12 +100,38 @@ ngx_null_string, /* "419 unused" */ ngx_null_string, /* "420 unused" */ ngx_string("421 Misdirected Request"), + ngx_null_string, /* "422 Unprocessable Entity" */ + ngx_null_string, /* "423 Locked" */ + ngx_null_string, /* "424 Failed Dependency" */ + ngx_null_string, /* "425 unused" */ + ngx_null_string, /* "426 Upgrade Required" */ + ngx_null_string, /* "427 unused" */ + ngx_null_string, /* "428 Precondition Required" */ + ngx_null_string, /* "429 Too Many Requests" */ + ngx_null_string, /* "430 unused" */ + ngx_null_string, /* "431 Request Header Fields Too Large" */ + ngx_null_string, /* "432 unused" */ + ngx_null_string, /* "433 unused" */ + ngx_null_string, /* "434 unused" */ + ngx_null_string, /* "435 unused" */ + ngx_null_string, /* "436 unused" */ + ngx_null_string, /* "437 unused" */ + ngx_null_string, /* "438 unused" */ + ngx_null_string, /* "439 unused" */ + ngx_null_string, /* "440 unused" */ + ngx_null_string, /* "441 unused" */ + ngx_null_string, /* "442 unused" */ + ngx_null_string, /* "443 unused" */ + ngx_null_string, /* "444 unused" */ + ngx_null_string, /* "445 unused" */ + ngx_null_string, /* "446 unused" */ + ngx_null_string, /* "447 unused" */ + ngx_null_string, /* "448 unused" */ + ngx_null_string, /* "449 unused" */ + ngx_null_string, /* "450 unused" */ + ngx_string("451 Unavailable For Legal Reasons"), - /* ngx_null_string, */ /* "422 Unprocessable Entity" */ - /* ngx_null_string, */ /* "423 Locked" */ - /* ngx_null_string, */ /* "424 Failed Dependency" */ - -#define NGX_HTTP_LAST_4XX 422 +#define NGX_HTTP_LAST_4XX 452 #define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX) ngx_string("500 Internal Server Error"), @@ -133,6 +159,7 @@ offsetof(ngx_http_headers_out_t, content_length) }, { ngx_string("Content-Encoding"), offsetof(ngx_http_headers_out_t, content_encoding) }, + { ngx_string("Link"), offsetof(ngx_http_headers_out_t, link) }, { ngx_string("Location"), offsetof(ngx_http_headers_out_t, location) }, { ngx_string("Last-Modified"), offsetof(ngx_http_headers_out_t, last_modified) }, diff -r 2c7a2d75938a -r d56f78822c5b src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h Mon Nov 21 16:49:19 2016 +0300 +++ b/src/http/ngx_http_request.h Wed Nov 23 11:04:39 2016 +0330 @@ -97,6 +97,7 @@ #define NGX_HTTP_RANGE_NOT_SATISFIABLE 416 #define NGX_HTTP_MISDIRECTED_REQUEST 421 +#define NGX_HTTP_NOT_ALLOWED_LEGALLY 451 /* Our own HTTP codes */ @@ -253,6 +254,7 @@ ngx_table_elt_t *date; ngx_table_elt_t *content_length; ngx_table_elt_t *content_encoding; + ngx_table_elt_t *link; ngx_table_elt_t *location; ngx_table_elt_t *refresh; ngx_table_elt_t *last_modified; diff -r 2c7a2d75938a -r d56f78822c5b src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c Mon Nov 21 16:49:19 2016 +0300 +++ b/src/http/ngx_http_special_response.c Wed Nov 23 11:04:39 2016 +0330 @@ -217,6 +217,12 @@ "

421 Misdirected Request

" CRLF ; +static char ngx_http_error_451_page[] = +"" CRLF +"451 Unavailable For Legal Reasons" CRLF +"" CRLF +"

451 Unavailable For Legal Reasons

" CRLF +; static char ngx_http_error_494_page[] = "" CRLF @@ -347,8 +353,38 @@ ngx_null_string, /* 419 */ ngx_null_string, /* 420 */ ngx_string(ngx_http_error_421_page), + ngx_null_string, /* 422 */ + ngx_null_string, /* 423 */ + ngx_null_string, /* 424 */ + ngx_null_string, /* 425 */ + ngx_null_string, /* 426 */ + ngx_null_string, /* 427 */ + ngx_null_string, /* 428 */ + ngx_null_string, /* 429 */ + ngx_null_string, /* 430 */ + ngx_null_string, /* 431 */ + ngx_null_string, /* 432 */ + ngx_null_string, /* 433 */ + ngx_null_string, /* 434 */ + ngx_null_string, /* 435 */ + ngx_null_string, /* 436 */ + ngx_null_string, /* 437 */ + ngx_null_string, /* 438 */ + ngx_null_string, /* 439 */ + ngx_null_string, /* 440 */ + ngx_null_string, /* 441 */ + ngx_null_string, /* 442 */ + ngx_null_string, /* 443 */ + ngx_null_string, /* 444 */ + ngx_null_string, /* 445 */ + ngx_null_string, /* 446 */ + ngx_null_string, /* 447 */ + ngx_null_string, /* 448 */ + ngx_null_string, /* 449 */ + ngx_null_string, /* 450 */ + ngx_string(ngx_http_error_451_page), /* 451, Unavailable For Legal Reasons */ -#define NGX_HTTP_LAST_4XX 422 +#define NGX_HTTP_LAST_4XX 452 #define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX) ngx_string(ngx_http_error_494_page), /* 494, request header too large */ [1] https://datatracker.ietf.org/doc/rfc7725/?include_text=1 [2] http://www.iana.org/assignments/link-relations/link-relations.xhtml Kind Regards, -- Babak Farrokhi https://github.com/farrokhi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 931 bytes Desc: OpenPGP digital signature URL: From dren.dk at gmail.com Thu Nov 24 13:15:17 2016 From: dren.dk at gmail.com (Flemming Frandsen) Date: Thu, 24 Nov 2016 14:15:17 +0100 Subject: Fix for issue 857: RFC-7230 compliant forwarding of client certificates Message-ID: Hi, I've been bitten by issue 857: https://trac.nginx.org/nginx/ticket/857 I terminate TLS in nginx, but I need access to the full client certificate in the backend, so to that end I've been using $ssl_client_cert, but now I've upgraded the application to a version that is RFC 7230 compliant and that means blowing up when multi-line headers are seen. As there's no reason to have newlines in a PEM file, my fix for #857 is to remove all the newlines, as my PEM parser in the application already ignores all newlines this works perfectly for me. I think simply removing the newlines is a much better solution than url encoding the newlines as less code (in my case none at all) is needed to deal with no newlines than urldecoding. -- Flemming Frandsen - YAPH - http://osaa.dk - http://dren.dk/ -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: issue-857.patch Type: text/x-patch Size: 2595 bytes Desc: not available URL: From mdounin at mdounin.ru Thu Nov 24 13:39:14 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 24 Nov 2016 16:39:14 +0300 Subject: Fix for issue 857: RFC-7230 compliant forwarding of client certificates In-Reply-To: References: Message-ID: <20161124133914.GT8196@mdounin.ru> Hello! On Thu, Nov 24, 2016 at 02:15:17PM +0100, Flemming Frandsen wrote: > Hi, I've been bitten by issue 857: https://trac.nginx.org/nginx/ticket/857 > > I terminate TLS in nginx, but I need access to the full client certificate > in the backend, so to that end I've been using $ssl_client_cert, but now > I've upgraded the application to a version that is RFC 7230 compliant and > that means blowing up when multi-line headers are seen. > > > As there's no reason to have newlines in a PEM file, my fix for #857 is to > remove all the newlines, as my PEM parser in the application already > ignores all newlines this works perfectly for me. > > I think simply removing the newlines is a much better solution than url > encoding the newlines as less code (in my case none at all) is needed to > deal with no newlines than urldecoding. The problem with removing newlines is that it requires custom code to recover original PEM format. -- Maxim Dounin http://nginx.org/ From dren.dk at gmail.com Thu Nov 24 19:57:35 2016 From: dren.dk at gmail.com (Flemming Frandsen) Date: Thu, 24 Nov 2016 20:57:35 +0100 Subject: Fix for issue 857: RFC-7230 compliant forwarding of client certificates In-Reply-To: <20161124133914.GT8196@mdounin.ru> References: <20161124133914.GT8196@mdounin.ru> Message-ID: Yes, that's correct, but: 1: You'd need custom code to url decode the header anyway and ignoring lack of newlines is simpler. 2: No existing parser will handle url decoding of the header without changes, but some might work without the newlines. 3: You don't need to recover the original PEM format as newlines are optional for any reasonable base64 parser. If anything, it could be argued that the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- bits should be removed too as that's of no use to the base64 decoder and has to be removed to get started parsing the actual content anyway. Without the begin and end bits someone who is really interested in getting a complete PEM file out of the header could very easily slap the start and end lines around a line-wrapped base64 content. If you're really unhappy with my proposed solution, then I can try to fix up the url encoding patch that was posted earlier, though I still think it's silly to go to such lengths to preserve newlines that nobody wants. On Thu, Nov 24, 2016 at 2:39 PM, Maxim Dounin wrote: > Hello! > > On Thu, Nov 24, 2016 at 02:15:17PM +0100, Flemming Frandsen wrote: > > > Hi, I've been bitten by issue 857: https://trac.nginx.org/nginx/ > ticket/857 > > > > I terminate TLS in nginx, but I need access to the full client > certificate > > in the backend, so to that end I've been using $ssl_client_cert, but now > > I've upgraded the application to a version that is RFC 7230 compliant and > > that means blowing up when multi-line headers are seen. > > > > > > As there's no reason to have newlines in a PEM file, my fix for #857 is > to > > remove all the newlines, as my PEM parser in the application already > > ignores all newlines this works perfectly for me. > > > > I think simply removing the newlines is a much better solution than url > > encoding the newlines as less code (in my case none at all) is needed to > > deal with no newlines than urldecoding. > > The problem with removing newlines is that it requires custom code > to recover original PEM format. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Flemming Frandsen - YAPH - http://osaa.dk - http://dren.dk/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Fri Nov 25 11:58:30 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 25 Nov 2016 14:58:30 +0300 Subject: Fix for issue 857: RFC-7230 compliant forwarding of client certificates In-Reply-To: References: <20161124133914.GT8196@mdounin.ru> Message-ID: <20161125115830.GW8196@mdounin.ru> Hello! On Thu, Nov 24, 2016 at 08:57:35PM +0100, Flemming Frandsen wrote: > Yes, that's correct, but: > > 1: You'd need custom code to url decode the header anyway and ignoring lack > of newlines is simpler. URL decoding is available out of the box in most environments. That is, recovering original PEM is as simple as wrapping a reference to a header into a function call. > 2: No existing parser will handle url decoding of the header without > changes, but some might work without the newlines. You may want to name a few. And we already use URL encoding in out mail module, so the are good reasons to keep things consistent. > 3: You don't need to recover the original PEM format as newlines are > optional for any reasonable base64 parser. They aren't optional at least for OpenSSL itself. > If anything, it could be argued that the -----BEGIN CERTIFICATE----- and > -----END CERTIFICATE----- bits should be removed too as that's of no use to > the base64 decoder and has to be removed to get started parsing the actual > content anyway. > > Without the begin and end bits someone who is really interested in getting > a complete PEM file out of the header could very easily slap the start and > end lines around a line-wrapped base64 content. Such approach was already considered when working on the mail implementation of client certificates support. Essentially, this provides Base64-encoded certificate in DER format. This is certainly better than just removing newlines, yet urlencoding is considered to be better in most cases. > If you're really unhappy with my proposed solution, then I can try to fix > up the url encoding patch that was posted earlier, though I still think > it's silly to go to such lengths to preserve newlines that nobody wants. There is no problem with preparing any patch. And there were already quite a few. The main problem here is naming things: that is, how things are expected to be named in the future, and how transition is expected to look like. The situation when $ssl_client_cert variable is not usable in most if not all cases looks at least strange. We probably need to switch it back to original meaning of PEM-encoded certificate (now available as $ssl_client_raw_cert). And it would be enough if we have some trivial functions like urlencode/urldecode available (see ticket #52) - but, unfortunately, we don't have them now. So at least urlencoded variant is needed ($ssl_client_escaped_cert?). And the next question is what to do with current $ssl_client_cert, as we need to preserve compatibility at least somehow for people who currently use certificate with tabs added as a multiline header. Another possible approach might be to change $ssl_client_cert to use spaces (tabs?) instead of newline + tab. This should be compatible with what most servers provide as a result of parsing multi-line header, and implies less changes. This needs an additional investigation though. -- Maxim Dounin http://nginx.org/ From dren.dk at gmail.com Fri Nov 25 14:06:06 2016 From: dren.dk at gmail.com (Flemming Frandsen) Date: Fri, 25 Nov 2016 15:06:06 +0100 Subject: Fix for issue 857: RFC-7230 compliant forwarding of client certificates In-Reply-To: <20161125115830.GW8196@mdounin.ru> References: <20161124133914.GT8196@mdounin.ru> <20161125115830.GW8196@mdounin.ru> Message-ID: On Fri, Nov 25, 2016 at 12:58 PM, Maxim Dounin wrote: > > 2: No existing parser will handle url decoding of the header without > > changes, but some might work without the newlines. > > You may want to name a few. > Well, ok, mine worked out of the box, because the server changed newlines to spaces before I got the value in my application. I'm using Jetty, which is quite popular in Java circles, so I suspect a lot of people would be unsurprised to find the newlines replaced by spaces, like you suggested. And we already use URL encoding in out mail module, so the are > good reasons to keep things consistent. > Yes, that's true. > 3: You don't need to recover the original PEM format as newlines are > > optional for any reasonable base64 parser. > > They aren't optional at least for OpenSSL itself. > Yes, I think I did find a comment somewhere that said that openssl wanted a max line length. > If you're really unhappy with my proposed solution, then I can try to fix > > up the url encoding patch that was posted earlier, though I still think > > it's silly to go to such lengths to preserve newlines that nobody wants. > > There is no problem with preparing any patch. And there > were already quite a few. >From where I sit it looks like this problem was reported about a year ago without any solution being merged, so I just want try to help things along. > The main problem here is naming things: > that is, how things are expected to be named in the future, and how > transition is expected to look like. The situation when > $ssl_client_cert variable is not usable in most if not all cases > looks at least strange. > I agree wholeheartedly. So at least urlencoded variant is needed ($ssl_client_escaped_cert?). Yes, and at least it's consistent with the other solution as you noted. And the next > question is what to do with current $ssl_client_cert, as we need > to preserve compatibility at least somehow for people who > currently use certificate with tabs added as a multiline header. > I'm afraid I don't know what this means, care to elaborate? Do you mean people who simply set a header to $ssl_client_cert? Another possible approach might be to change $ssl_client_cert to > use spaces (tabs?) instead of newline + tab. This should be > compatible with what most servers provide as a result of parsing > multi-line header, and implies less changes. This needs an > additional investigation though. > I'd be very happy with this as the only change as my server already gives me exactly this value when I ask for the header, so my application would not even notice the change. -- Flemming Frandsen - YAPH - http://osaa.dk - http://dren.dk/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From alon.blayergat at gmail.com Sun Nov 27 12:27:56 2016 From: alon.blayergat at gmail.com (Alon Blayer-Gat) Date: Sun, 27 Nov 2016 14:27:56 +0200 Subject: [PATCH] Http gunzip: additional configuration Message-ID: 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. Changes do not present any backward incompatibility. Directives changes summary: gunzip (on|types|always|off) Context: http, server, location, if in location Default: off off Disable gunzip on Enable gunzip for clients that doesn't support it. always Enable gunzip even if clients support it. types Enable gunzip for clients that doesn't support it. but for mime types specified by the gunzip_types directive. gunzip_types mime-type ...; Context: http, server, location, if in location Default: gunzip_types text/html; # HG changeset patch # User Alon Blayer-Gat # Date 1480245650 -7200 # Sun Nov 27 13:20:50 2016 +0200 # Node ID d7223bbfd5b3e631ee09f876150583d18bd2d092 # Parent 2c7a2d75938a31044552b0a6cd6edaebdaf0bd69 http gunzip: additional configurations allow within 'if in location', gunzip 'always' or 'types' for mime-types # HG changeset patch # User Alon Blayer-Gat # Date 1480245650 -7200 # Sun Nov 27 13:20:50 2016 +0200 # Node ID d7223bbfd5b3e631ee09f876150583d18bd2d092 # Parent 2c7a2d75938a31044552b0a6cd6edaebdaf0bd69 http gunzip: additional configurations allow within 'if in location', gunzip 'always' or 'types' for mime-types diff -r 2c7a2d75938a -r d7223bbfd5b3 src/http/modules/ngx_http_gunzip_filter_module.c --- a/src/http/modules/ngx_http_gunzip_filter_module.c Mon Nov 21 16:49:19 2016 +0300 +++ b/src/http/modules/ngx_http_gunzip_filter_module.c Sun Nov 27 13:20:50 2016 +0200 @@ -13,9 +13,17 @@ #include +#define NGX_HTTP_GUNZIP_OFF 0 +#define NGX_HTTP_GUNZIP_ON 1 +#define NGX_HTTP_GUNZIP_ALWAYS 2 +#define NGX_HTTP_GUNZIP_TYPES 3 + + typedef struct { - ngx_flag_t enable; + ngx_uint_t enable; ngx_bufs_t bufs; + ngx_hash_t types; + ngx_array_t *types_keys; } ngx_http_gunzip_conf_t; @@ -62,14 +70,24 @@ void *parent, void *child); +static ngx_conf_enum_t ngx_http_gunzip[] = { + { ngx_string("off"), NGX_HTTP_GUNZIP_OFF }, + { ngx_string("on"), NGX_HTTP_GUNZIP_ON }, + { ngx_string("always"), NGX_HTTP_GUNZIP_ALWAYS }, + { ngx_string("types"), NGX_HTTP_GUNZIP_TYPES }, + { ngx_null_string, 0 } +}; + + static ngx_command_t ngx_http_gunzip_filter_commands[] = { { ngx_string("gunzip"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF + |NGX_CONF_TAKE1, + ngx_conf_set_enum_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_gunzip_conf_t, enable), - NULL }, + &ngx_http_gunzip }, { ngx_string("gunzip_buffers"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, @@ -78,6 +96,13 @@ offsetof(ngx_http_gunzip_conf_t, bufs), NULL }, + { ngx_string("gunzip_types"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, + ngx_http_types_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_gunzip_conf_t, types_keys), + &ngx_http_html_default_types[0] }, + ngx_null_command }; @@ -126,10 +151,10 @@ conf = ngx_http_get_module_loc_conf(r, ngx_http_gunzip_filter_module); /* TODO support multiple content-codings */ - /* TODO always gunzip - due to configuration or module request */ + /* TODO ignore content encoding? */ - if (!conf->enable + if (conf->enable == NGX_HTTP_GUNZIP_OFF || r->headers_out.content_encoding == NULL || r->headers_out.content_encoding->value.len != 4 || ngx_strncasecmp(r->headers_out.content_encoding->value.data, @@ -140,14 +165,22 @@ r->gzip_vary = 1; - if (!r->gzip_tested) { - if (ngx_http_gzip_ok(r) == NGX_OK) { + if (conf->enable == NGX_HTTP_GUNZIP_ON) { + if (!r->gzip_tested) { + if (ngx_http_gzip_ok(r) == NGX_OK) { + return ngx_http_next_header_filter(r); + } + + } else if (r->gzip_ok) { return ngx_http_next_header_filter(r); } - - } else if (r->gzip_ok) { - return ngx_http_next_header_filter(r); } + else if (conf->enable == NGX_HTTP_GUNZIP_TYPES + && ngx_http_test_content_type(r, &conf->types) == NULL) + { + return ngx_http_next_header_filter(r); + } + /* else always gunzip - conf->enable == NGX_HTTP_GUNZIP_ALWAYS) */ ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gunzip_ctx_t)); if (ctx == NULL) { @@ -651,9 +684,11 @@ * set by ngx_pcalloc(): * * conf->bufs.num = 0; + * conf->types = { NULL }; + * conf->types_keys = NULL; */ - conf->enable = NGX_CONF_UNSET; + conf->enable = NGX_CONF_UNSET_UINT; return conf; } @@ -670,6 +705,14 @@ ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, (128 * 1024) / ngx_pagesize, ngx_pagesize); + if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types, + &prev->types_keys, &prev->types, + ngx_http_html_default_types) + != NGX_OK) + { + return NGX_CONF_ERROR; + } + return NGX_CONF_OK; } From dren.dk at gmail.com Mon Nov 28 09:20:28 2016 From: dren.dk at gmail.com (Flemming Frandsen) Date: Mon, 28 Nov 2016 10:20:28 +0100 Subject: Fix for issue 857: RFC-7230 compliant forwarding of client certificates In-Reply-To: <20161125115830.GW8196@mdounin.ru> References: <20161124133914.GT8196@mdounin.ru> <20161125115830.GW8196@mdounin.ru> Message-ID: On Fri, Nov 25, 2016 at 12:58 PM, Maxim Dounin wrote: > Another possible approach might be to change $ssl_client_cert to > use spaces (tabs?) instead of newline + tab. This should be > compatible with what most servers provide as a result of parsing > multi-line header, and implies less changes. This needs an > additional investigation though. > Hi, I've found some more support for doing exactly this: https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 " Any LWS that occurs between field-content MAY be replaced with a single SP before interpreting the field value or forwarding the message downstream. " As far as I know LWS includes the newline-whitespace sequence. It seems to me quite clear that any compliant interpreter of header values should be insensitive to the switch from any amount of linear white space ce to a single space within the header value. -- Flemming Frandsen - YAPH - http://osaa.dk - http://dren.dk/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From eran.kornblau at kaltura.com Mon Nov 28 10:58:01 2016 From: eran.kornblau at kaltura.com (Eran Kornblau) Date: Mon, 28 Nov 2016 10:58:01 +0000 Subject: Add support for 'nocache' flag to map directive Message-ID: Hi all, I created this post yesterday - https://forum.nginx.org/read.php?10,271197 And thought about submitting a patch for it. Before I do, I wanted to check with you whether this is something you'll be willing to accept (assuming the implementation is correct, according to standards, doesn't break things etc.) In short, the idea is to add an optional flag to the map directive that make the map module pass NGX_HTTP_VAR_NOCACHEABLE in its call to ngx_http_add_variable. The conf structure will look like: map $input_var $output_var nocache { default 0; "some value" 1; } Thank you, Eran -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Mon Nov 28 16:21:41 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Mon, 28 Nov 2016 16:21:41 +0000 Subject: [nginx] HTTP/2: fixed saving preread buffer to temp file (ticket #1143). Message-ID: details: http://hg.nginx.org/nginx/rev/52bd8cc17f34 branches: changeset: 6805:52bd8cc17f34 user: Valentin Bartenev date: Mon Nov 28 19:19:21 2016 +0300 description: HTTP/2: fixed saving preread buffer to temp file (ticket #1143). Previously, a request body bigger than "client_body_buffer_size" wasn't written into a temporary file if it has been pre-read entirely. The preread buffer is freed after processing, thus subsequent use of it might result in sending corrupted body or cause a segfault. diffstat: src/http/v2/ngx_http_v2.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 2c7a2d75938a -r 52bd8cc17f34 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Mon Nov 21 16:49:19 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Mon Nov 28 19:19:21 2016 +0300 @@ -3575,6 +3575,9 @@ 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; + rb->buf = ngx_calloc_buf(r->pool); if (rb->buf != NULL) { From sorin.v.manole at gmail.com Tue Nov 29 05:18:39 2016 From: sorin.v.manole at gmail.com (Sorin Manole) Date: Tue, 29 Nov 2016 05:18:39 +0000 Subject: Add support for 'nocache' flag to map directive In-Reply-To: References: Message-ID: Would it make sense to add nocacheable if input_var or one of the variables in the value options is nocacheable? On Mon, 28 Nov 2016 at 12:58, Eran Kornblau wrote: > Hi all, > > > > I created this post yesterday - https://forum.nginx.org/read.php?10,271197 > > And thought about submitting a patch for it. > > Before I do, I wanted to check with you whether this is something you?ll > be willing to accept > (assuming the implementation is correct, according to standards, doesn?t > break things etc.) > > > > In short, the idea is to add an optional flag to the map directive that > make the map module > pass NGX_HTTP_VAR_NOCACHEABLE in its call to ngx_http_add_variable. > > The conf structure will look like: > > map $input_var $output_var nocache { > > default 0; > > "some value" 1; > > } > > > > Thank you, > > > > Eran > _______________________________________________ > 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 eran.kornblau at kaltura.com Tue Nov 29 08:07:14 2016 From: eran.kornblau at kaltura.com (Eran Kornblau) Date: Tue, 29 Nov 2016 08:07:14 +0000 Subject: Add support for 'nocache' flag to map directive In-Reply-To: References: Message-ID: > > From: nginx-devel [mailto:nginx-devel-bounces at nginx.org] On Behalf Of Sorin Manole > Sent: Tuesday, November 29, 2016 7:19 AM > To: nginx-devel at nginx.org > Subject: Re: Add support for 'nocache' flag to map directive > > Would it make sense to add nocacheable if input_var or one of the variables in the value options is nocacheable? > Yes, that makes perfect sense to me, but that will be harder to implement, for example, when the map block is initialized, I'm not sure whether all the variables it references have already been added. If they were not, it will not know they are 'nocacheable', and it will require some post processing step (maybe in postconfiguration) to go over the tree of variable references and update nocacheable (there could be a map block that uses a variable created in another map block etc.) So, while not ideal, I think adding a flag that the user will have to manually set is an acceptable compromise. If the forum prefers the more automated solution, I'm willing to try to tackle that as well, but will need some high level guidance on how you'd like that implemented. Please let me know what you think Thank you, Eran From orgads at gmail.com Tue Nov 29 09:32:03 2016 From: orgads at gmail.com (Orgad Shaneh) Date: Tue, 29 Nov 2016 11:32:03 +0200 Subject: [PATCH] Use .exe for binaries for all win32 compilers Message-ID: 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\" From orgads at gmail.com Tue Nov 29 11:13:27 2016 From: orgads at gmail.com (Orgad Shaneh) Date: Tue, 29 Nov 2016 13:13:27 +0200 Subject: [PATCH] Fix MinGW64 compilation Message-ID: # 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 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_*) NGX_PLATFORM=win32 ;; esac From shuxinyang.oss at gmail.com Tue Nov 29 21:30:25 2016 From: shuxinyang.oss at gmail.com (Shuxin Yang) Date: Tue, 29 Nov 2016 13:30:25 -0800 Subject: Why not remove UNIX domain socket before bind Message-ID: <423e461b-75fc-70a6-8f22-65681e54a7fa@gmail.com> Hi, There: Is there any reason not to delete UNIX domain socket before bind? It is bit inconvenient when : 1). debugging: previous debugging session quit prematurely without erasing the UNIX domain socket, and the subsequent debugging session only see "address already in use" error message, and have to delete the socket, and launch debugger again. 2). Writing deploy script. We need to make sure UNIX domain sockets are completely delete before launching Nginx; also care must be taken to keep the script and config file in sync, which is sometimes bit annoying. Thanks Shuxin From piotrsikora at google.com Wed Nov 30 01:08:04 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 29 Nov 2016 17:08:04 -0800 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: 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. Best regards, Piotr Sikora From piotrsikora at google.com Wed Nov 30 01:08:39 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 29 Nov 2016 17:08:39 -0800 Subject: [PATCH 1 of 2] HTTP: add support for "429 Too Many Requests" response (RFC6585) In-Reply-To: <1eec5355ef1e4a8b0aec.1476863503@piotrsikora.sfo.corp.google.com> References: <1eec5355ef1e4a8b0aec.1476863503@piotrsikora.sfo.corp.google.com> Message-ID: Hey, > # HG changeset patch > # User Piotr Sikora > # Date 1476859139 25200 > # Tue Oct 18 23:38:59 2016 -0700 > # Node ID 1eec5355ef1e4a8b0aecebdec84c744734c0d36e > # Parent 8081e1f3ab8b9ccb4e2d7f9240cbfb8e404a3c95 > HTTP: add support for "429 Too Many Requests" response (RFC6585). > > This change adds reason phrase in status line and pretty response body > when "429" status code is used in "return", "limit_conn_status" and/or > "limit_req_status" directives. > > It also adds "http_429" parameter to "proxy_next_upstream" for retrying > rate-limited requests, and to "proxy_cache_use_stale" for serving stale > cached responses after being rate-limited. Ping. Best regards, Piotr Sikora From aauren at gmail.com Wed Nov 30 03:36:27 2016 From: aauren at gmail.com (Aaron U'Ren) Date: Tue, 29 Nov 2016 21:36:27 -0600 Subject: Add auto Option to autoindex module Message-ID: I recently came across the need to have multiple formats returned from the autoindex module based on the client. When a human hits the index page I needed it returned in HTML format. However, when an application fetched the index page it was much simpler for it to digest and parse JSON or XML. With the current autoindex module you could only specify a single format in the configuration. It occurred to me that it might sometimes be better to have an option to allow the user agent to choose what format it wanted from the autoindex module rather than it being defined statically by the server's configuration. So I made a small patch that introduces a 5th "auto" option in addition to html, json, jsonp, and xml. With this option enabled the nginx server reads the "Accept" header from the user agent's request and if it is able to satisfy the format it will send the response in that format. Otherwise it will gracefully fall back to serving the response in the default html format. Fair warning, my C is pretty rusty and I'm not at all that familiar with the nginx code base, but I was able to put together and successfully test the following patch on my machine. Let me know what you guys think. ------------------------------------------------------------------------------------------------------------------------ # HG changeset patch # User Aaron U'Ren # Date 1480475469 21600 # Tue Nov 29 21:11:09 2016 -0600 # Node ID a34bccf9c164fe2bca85c3f9d6fa1bea59fcea42 # Parent 52bd8cc17f34bbebcb4d2ce3651b40af7d572d55 add auto format option to autoindex module Currently, you can only specify a single format (json, html, javascript, xml) for autoindex to return to the client. This change adds an "auto" option that obeys the client's Accept header (if one is present) to return a specific index format based on the clients request. diff -r 52bd8cc17f34 -r a34bccf9c164 src/http/modules/ngx_http_autoindex_module.c --- a/src/http/modules/ngx_http_autoindex_module.c Mon Nov 28 19:19:21 2016 +0300 +++ b/src/http/modules/ngx_http_autoindex_module.c Tue Nov 29 21:11:09 2016 -0600 @@ -49,6 +49,7 @@ #define NGX_HTTP_AUTOINDEX_JSON 1 #define NGX_HTTP_AUTOINDEX_JSONP 2 #define NGX_HTTP_AUTOINDEX_XML 3 +#define NGX_HTTP_AUTOINDEX_AUTO 4 #define NGX_HTTP_AUTOINDEX_PREALLOCATE 50 @@ -80,6 +81,7 @@ { ngx_string("json"), NGX_HTTP_AUTOINDEX_JSON }, { ngx_string("jsonp"), NGX_HTTP_AUTOINDEX_JSONP }, { ngx_string("xml"), NGX_HTTP_AUTOINDEX_XML }, + { ngx_string("auto"), NGX_HTTP_AUTOINDEX_AUTO }, { ngx_null_string, 0 } }; @@ -152,7 +154,7 @@ static ngx_int_t ngx_http_autoindex_handler(ngx_http_request_t *r) { - u_char *last, *filename; + u_char *last, *filename, *accept_header; size_t len, allocated, root; ngx_err_t err; ngx_buf_t *b; @@ -200,6 +202,19 @@ format = alcf->format; +#if (NGX_HTTP_HEADERS) + if (format == NGX_HTTP_AUTOINDEX_AUTO) { + accept_header = r->headers_in.accept->value.data; + if (ngx_strncmp(accept_header, "application/javascript", 22) == 0) { + format = NGX_HTTP_AUTOINDEX_JSONP; + } else if (ngx_strncmp(accept_header, "application/json", 16) == 0) { + format = NGX_HTTP_AUTOINDEX_JSON; + } else if (ngx_strncmp(accept_header, "text/xml", 8) == 0) { + format = NGX_HTTP_AUTOINDEX_XML; + } + } +#endif + if (format == NGX_HTTP_AUTOINDEX_JSONP) { if (ngx_http_autoindex_jsonp_callback(r, &callback) != NGX_OK) { return NGX_HTTP_BAD_REQUEST; ------------------------------------------------------------------------------------------------------------------------ -Aaron -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: a34bccf9c164fe2bca85c3f9d6fa1bea59fcea42.patch Type: text/x-patch Size: 2396 bytes Desc: not available URL: From datong at cloudflare.com Wed Nov 30 07:11:32 2016 From: datong at cloudflare.com (Datong Sun) Date: Tue, 29 Nov 2016 23:11:32 -0800 Subject: Why not remove UNIX domain socket before bind In-Reply-To: <423e461b-75fc-70a6-8f22-65681e54a7fa@gmail.com> References: <423e461b-75fc-70a6-8f22-65681e54a7fa@gmail.com> Message-ID: Hello Shuxin, I have seen the same issue before. As far as I can tell this is simply a bug instead of by design (correct me if I'm wrong). I can also confirm that nginx will leave behind the listening socket file when terminated with SIGQUIT. There has been a bug report opened more than a year ago ( https://trac.nginx.org/nginx/ticket/753) but still not being fixed. Thanks, Datong On Tue, Nov 29, 2016 at 1:30 PM, Shuxin Yang wrote: > Hi, There: > > Is there any reason not to delete UNIX domain socket before bind? It > is bit inconvenient when : > > 1). debugging: previous debugging session quit prematurely without erasing > the UNIX domain socket, and the subsequent debugging session only see > "address already in use" error message, and have to delete the socket, and > launch debugger again. > > 2). Writing deploy script. We need to make sure UNIX domain sockets are > completely delete before launching Nginx; also care must be taken to keep > the script and config file in sync, which is sometimes bit annoying. > > > Thanks > > Shuxin > > > > _______________________________________________ > 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 shuxinyang.oss at gmail.com Wed Nov 30 07:39:39 2016 From: shuxinyang.oss at gmail.com (Shuxin Yang) Date: Tue, 29 Nov 2016 23:39:39 -0800 Subject: Why not remove UNIX domain socket before bind In-Reply-To: References: <423e461b-75fc-70a6-8f22-65681e54a7fa@gmail.com> Message-ID: Hi, Datong: I don't think fixing #753 resolves all the trouble: it does not help for scenario 1 at all. For scenario 2, it only help if nginx is terminated by SIGQUIT; however, Nginx could be killed by other signals, say SIGKILL. Thanks Shuxin On 11/29/2016 11:11 PM, Datong Sun via nginx-devel wrote: > Hello Shuxin, > > I have seen the same issue before. As far as I can tell this is simply > a bug instead of by design (correct me if I'm wrong). I can also > confirm that nginx will leave behind the listening socket file when > terminated with SIGQUIT. There has been a bug report opened more than > a year ago (https://trac.nginx.org/nginx/ticket/753) but still not > being fixed. > > Thanks, > Datong > > On Tue, Nov 29, 2016 at 1:30 PM, Shuxin Yang > wrote: > > Hi, There: > > Is there any reason not to delete UNIX domain socket before > bind? It is bit inconvenient when : > > 1). debugging: previous debugging session quit prematurely without > erasing the UNIX domain socket, and the subsequent debugging > session only see "address already in use" error message, and have > to delete the socket, and launch debugger again. > > 2). Writing deploy script. We need to make sure UNIX domain > sockets are completely delete before launching Nginx; also care > must be taken to keep the script and config file in sync, which is > sometimes bit annoying. > > > Thanks > > Shuxin > > > > _______________________________________________ > 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 > > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Wed Nov 30 10:23:40 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Wed, 30 Nov 2016 13:23:40 +0300 Subject: Add auto Option to autoindex module In-Reply-To: References: Message-ID: <2042606.M28vC0MzFi@vbart-laptop> On Tuesday 29 November 2016 21:36:27 Aaron U'Ren wrote: > I recently came across the need to have multiple formats returned from the > autoindex module based on the client. When a human hits the index page I > needed it returned in HTML format. However, when an application fetched the > index page it was much simpler for it to digest and parse JSON or XML. With > the current autoindex module you could only specify a single format in the > configuration. > > It occurred to me that it might sometimes be better to have an option to > allow the user agent to choose what format it wanted from the autoindex > module rather than it being defined statically by the server's > configuration. So I made a small patch that introduces a 5th "auto" option > in addition to html, json, jsonp, and xml. This should be implemented by adding support for variables in the directive. > > With this option enabled the nginx server reads the "Accept" header from > the user agent's request and if it is able to satisfy the format it will > send the response in that format. Otherwise it will gracefully fall back to > serving the response in the default html format. > > Fair warning, my C is pretty rusty and I'm not at all that familiar with > the nginx code base, but I was able to put together and successfully test > the following patch on my machine. > > Let me know what you guys think. > [..] Please check specification for the Accept header. It provides much richer semantics than what you test. wbr, Valentin V. Bartenev From igor at sysoev.ru Wed Nov 30 11:15:18 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 30 Nov 2016 11:15:18 +0000 Subject: [njs] Fixed nginx modules building introduced in 9b37882ad552. Message-ID: details: http://hg.nginx.org/njs/rev/adfb758ad872 branches: changeset: 267:adfb758ad872 user: Igor Sysoev date: Wed Nov 30 14:10:49 2016 +0300 description: Fixed nginx modules building introduced in 9b37882ad552. Removed old third party module addition method. diffstat: nginx/config | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (23 lines): diff -r fd2a05f9eacf -r adfb758ad872 nginx/config --- a/nginx/config Tue Nov 22 00:06:46 2016 +0300 +++ b/nginx/config Wed Nov 30 14:10:49 2016 +0300 @@ -4,6 +4,7 @@ if [ $HTTP != NO ]; then ngx_module_type=HTTP ngx_module_name=ngx_http_js_module ngx_module_incs="$ngx_addon_dir/../nxt $ngx_addon_dir/../njs" + ngx_module_deps="$ngx_addon_dir/../build/libnjs.a" ngx_module_srcs="$ngx_addon_dir/ngx_http_js_module.c" ngx_module_libs="PCRE $ngx_addon_dir/../build/libnjs.a -lm" @@ -14,10 +15,9 @@ if [ $STREAM != NO ]; then ngx_module_type=STREAM ngx_module_name=ngx_stream_js_module ngx_module_incs="$ngx_addon_dir/../nxt $ngx_addon_dir/../njs" + ngx_module_deps="$ngx_addon_dir/../build/libnjs.a" ngx_module_srcs="$ngx_addon_dir/ngx_stream_js_module.c" ngx_module_libs="PCRE $ngx_addon_dir/../build/libnjs.a -lm" . auto/module fi - -LINK_DEPS="$LINK_DEPS $ngx_addon_dir/../build/libnjs.a" From igor at sysoev.ru Wed Nov 30 11:53:37 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 30 Nov 2016 11:53:37 +0000 Subject: [njs] Added more dependencies on nxt_auto_config.h. Message-ID: details: http://hg.nginx.org/njs/rev/86c35adbd3f9 branches: changeset: 268:86c35adbd3f9 user: Igor Sysoev date: Wed Nov 30 14:53:15 2016 +0300 description: Added more dependencies on nxt_auto_config.h. diffstat: Makefile | 14 +++++++------- nxt/Makefile | 1 + nxt/auto/configure | 7 ------- nxt/test/Makefile | 1 + 4 files changed, 9 insertions(+), 14 deletions(-) diffs (67 lines): diff -r adfb758ad872 -r 86c35adbd3f9 Makefile --- a/Makefile Wed Nov 30 14:10:49 2016 +0300 +++ b/Makefile Wed Nov 30 14:53:15 2016 +0300 @@ -7,14 +7,8 @@ NXT_LIB = nxt NXT_BUILDDIR = build -unconfigured: - @echo - @echo " Please run ./configure before make" - @echo - -main: $(NXT_BUILDDIR)/libnjs.a - $(NXT_BUILDDIR)/libnjs.a: \ + $(NXT_LIB)/nxt_auto_config.h \ $(NXT_BUILDDIR)/njscript.o \ $(NXT_BUILDDIR)/njs_vm.o \ $(NXT_BUILDDIR)/njs_boolean.o \ @@ -97,6 +91,12 @@ dist: tar czf njs-$(NJS_VER).tar.gz njs-$(NJS_VER) rm -rf njs-$(NJS_VER) +$(NXT_LIB)/nxt_auto_config.h: + @echo + @echo " Please run ./configure before make" + @echo + @exit 1 + $(NXT_BUILDDIR)/njscript.o: \ $(NXT_BUILDDIR)/libnxt.a \ njs/njs_vm.h \ diff -r adfb758ad872 -r 86c35adbd3f9 nxt/Makefile --- a/nxt/Makefile Wed Nov 30 14:10:49 2016 +0300 +++ b/nxt/Makefile Wed Nov 30 14:53:15 2016 +0300 @@ -3,6 +3,7 @@ NXT_LIB = nxt $(NXT_BUILDDIR)/libnxt.a: \ + $(NXT_LIB)/nxt_auto_config.h \ $(NXT_BUILDDIR)/nxt_djb_hash.o \ $(NXT_BUILDDIR)/nxt_utf8.o \ $(NXT_BUILDDIR)/nxt_array.o \ diff -r adfb758ad872 -r 86c35adbd3f9 nxt/auto/configure --- a/nxt/auto/configure Wed Nov 30 14:10:49 2016 +0300 +++ b/nxt/auto/configure Wed Nov 30 14:53:15 2016 +0300 @@ -55,10 +55,3 @@ END . ${NXT_AUTO}memalign . ${NXT_AUTO}getrandom . ${NXT_AUTO}pcre - - -cat << END >> $NXT_MAKEFILE_CONF - -target: main - -END diff -r adfb758ad872 -r 86c35adbd3f9 nxt/test/Makefile --- a/nxt/test/Makefile Wed Nov 30 14:10:49 2016 +0300 +++ b/nxt/test/Makefile Wed Nov 30 14:53:15 2016 +0300 @@ -1,5 +1,6 @@ lib_test: \ + $(NXT_LIB)/nxt_auto_config.h \ $(NXT_BUILDDIR)/random_unit_test \ $(NXT_BUILDDIR)/rbtree_unit_test \ $(NXT_BUILDDIR)/lvlhsh_unit_test \ From mdounin at mdounin.ru Wed Nov 30 14:57:19 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 30 Nov 2016 17:57:19 +0300 Subject: Why not remove UNIX domain socket before bind In-Reply-To: <423e461b-75fc-70a6-8f22-65681e54a7fa@gmail.com> References: <423e461b-75fc-70a6-8f22-65681e54a7fa@gmail.com> Message-ID: <20161130145719.GA8196@mdounin.ru> 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/ From aauren at gmail.com Wed Nov 30 16:00:22 2016 From: aauren at gmail.com (Aaron U'Ren) Date: Wed, 30 Nov 2016 10:00:22 -0600 Subject: Add auto Option to autoindex module In-Reply-To: <2042606.M28vC0MzFi@vbart-laptop> References: <2042606.M28vC0MzFi@vbart-laptop> Message-ID: Valentin- Thanks for the response. I had a couple of questions regarding your statements... This should be implemented by adding support for variables in the directive. I take it that you mean this to be implemented by something like: > set $autoindex_type "html" > > if ($http_accept ~* json) { > set $autoindex_type "json"; > } > > location ... { > autoindex_format $autoindex_type; > ... > } Making autoindex_format accept a variable would be another way to accomplish the functionality that I need, but I would argue that it puts a stronger burden on the configuration to make the autoindex module comply with the user agent's "Accept" header than should be necessary. It seems to me, that the default operation of the autoindex module should be to supply the index listing in a format that the user's agent can accept, and then allow the server administrator to override that functionality through configuration if they have a need. To my understanding that is the way the Accept header usually works. Please check specification for the Accept header. It provides much richer semantics > than what you test. I see what you're saying in regards to my limited tests. I was coding for my use case instead of everything that the Accept header can contain. I can submit a patch that more fully parses the Accept header by breaking it apart on commas and matching whatever type the autoindex module can provide starting with first with the most specific and moving my way back. Also, I should return a 406 response in the event that I'm not able to match instead of falling through to HTML. Would that cover everything additional that you would want to see? Also, I wanted to check with you, if I do the work to expand my testing of the Accept header would you be willing to accept the patch? Or would you be unwilling to merge a patch like this because the only functionality you're interested in adding is the support for variables in the autoindex_format directive? -Aaron On Wed, Nov 30, 2016 at 4:23 AM, Valentin V. Bartenev wrote: > On Tuesday 29 November 2016 21:36:27 Aaron U'Ren wrote: > > I recently came across the need to have multiple formats returned from > the > > autoindex module based on the client. When a human hits the index page I > > needed it returned in HTML format. However, when an application fetched > the > > index page it was much simpler for it to digest and parse JSON or XML. > With > > the current autoindex module you could only specify a single format in > the > > configuration. > > > > It occurred to me that it might sometimes be better to have an option to > > allow the user agent to choose what format it wanted from the autoindex > > module rather than it being defined statically by the server's > > configuration. So I made a small patch that introduces a 5th "auto" > option > > in addition to html, json, jsonp, and xml. > > This should be implemented by adding support for variables in the > directive. > > > > > > With this option enabled the nginx server reads the "Accept" header from > > the user agent's request and if it is able to satisfy the format it will > > send the response in that format. Otherwise it will gracefully fall back > to > > serving the response in the default html format. > > > > Fair warning, my C is pretty rusty and I'm not at all that familiar with > > the nginx code base, but I was able to put together and successfully test > > the following patch on my machine. > > > > Let me know what you guys think. > > > [..] > > Please check specification for the Accept header. It provides much richer > semantics than what you test. > > wbr, Valentin V. Bartenev > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From shuxinyang.oss at gmail.com Wed Nov 30 16:29:59 2016 From: shuxinyang.oss at gmail.com (Shuxin Yang) Date: Wed, 30 Nov 2016 08:29:59 -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: <218061e8-3fb4-c5f1-dfda-f05a4eb069ca@gmail.com> Hi, Maxim: Thank you very much ! I think b) is good reason, a) is pretty weak: The /the/path/to/unix/domain/socket is a constant string instead of a variable; IMHO, it's unlikely to accidentally delete a wrong file due to typo. Thanks Shuxin On 11/30/16 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. > From vbart at nginx.com Wed Nov 30 16:55:04 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Wed, 30 Nov 2016 19:55:04 +0300 Subject: Add auto Option to autoindex module In-Reply-To: References: <2042606.M28vC0MzFi@vbart-laptop> Message-ID: <4629983.Zua86ZkJKX@vbart-workstation> On Wednesday 30 November 2016 10:00:22 Aaron U'Ren wrote: > Valentin- > > Thanks for the response. I had a couple of questions regarding your > statements... > > This should be implemented by adding support for variables in the directive. > > > I take it that you mean this to be implemented by something like: > > > set $autoindex_type "html" > > > > if ($http_accept ~* json) { > > set $autoindex_type "json"; > > } > > > > location ... { > > autoindex_format $autoindex_type; > > ... > > } > It's better to use the "map" directive: map $http_accept $autoindex_type { default html; ~json json; ... } > > Making autoindex_format accept a variable would be another way to > accomplish the functionality that I need, but I would argue that it puts a > stronger burden on the configuration to make the autoindex module comply > with the user agent's "Accept" header than should be necessary. It seems to > me, that the default operation of the autoindex module should be to supply > the index listing in a format that the user's agent can accept, and then > allow the server administrator to override that functionality through > configuration if they have a need. To my understanding that is the way the > Accept header usually works. XML and JSON formats are mostly needed for internal (the xslt module in nginx) or external (the xhr requests from browsers) processing. In case of the xslt module, the output after translation can be different from XML. > > Please check specification for the Accept header. It provides much > richer semantics > > than what you test. > > > I see what you're saying in regards to my limited tests. I was coding for > my use case instead of everything that the Accept header can contain. I can > submit a patch that more fully parses the Accept header by breaking it > apart on commas and matching whatever type the autoindex module can provide > starting with first with the most specific and moving my way back. Also, I > should return a 406 response in the event that I'm not able to match > instead of falling through to HTML. Would that cover everything additional > that you would want to see? There are not only commas in the "Accept" header need to be processed. There are also relative weights and type-ranges. Proper processing of the "Accept" header is quite complicated task, and you're the first in my memory who ever asked about such functionality for many years. Other users may have different idea about how to handle the "Accept" header, or may want to check some other request parameters. So accepting variables here look like a much better and more flexible solution. > > Also, I wanted to check with you, if I do the work to expand my testing of > the Accept header would you be willing to accept the patch? Or would you be > unwilling to merge a patch like this because the only functionality you're > interested in adding is the support for variables in the autoindex_format > directive? > The patch won't be accented as it solves your specific use-case, and it will introduce a lot of new complicated code for proper handling of the "Accept" header. wbr, Valentin V. Bartenev